From: Zebiolo Date: Thu, 30 Sep 2010 07:32:28 +0000 (+0000) Subject: git-svn-id: https://casparcg.svn.sourceforge.net/svnroot/casparcg/server/branches... X-Git-Tag: 2.0.1~980 X-Git-Url: https://git.sesse.net/?a=commitdiff_plain;h=d055b46c17b3b39b4fd2c36e99fb5b0fde128872;p=casparcg git-svn-id: https://casparcg.svn.sourceforge.net/svnroot/casparcg/server/branches/2.0.0.0@149 362d55ac-95cf-4e76-9f9a-cbaa9c17b72d --- diff --git a/core/Server.vcxproj b/core/Server.vcxproj new file mode 100644 index 000000000..3a2428ce5 --- /dev/null +++ b/core/Server.vcxproj @@ -0,0 +1,613 @@ + + + + + Debug + Win32 + + + no bluefish + Win32 + + + ReleaseProfiling + Win32 + + + Release + Win32 + + + + {79388C20-6499-4BF6-B8B9-D8C33D7D4DDD} + Server + Win32Proj + server + + + + Application + Unicode + + + Application + Unicode + true + + + Application + Unicode + + + Application + Unicode + true + false + + + + + + + + + + + + + + + + + + + + + + + <_ProjectFileVersion>10.0.30319.1 + $(ProjectDir)build\ + debug\ + true + $(ProjectDir)build\ + $(ProjectDir)build\ + release\ + release\ + false + false + $(SolutionDir)$(Configuration)\ + $(Configuration)\ + false + C:\Lokala Filer\SDK\ffmpeg\src\ffmpeg-export-2008-11-05\libavcodec\i386;$(SourcePath) + + + + + + + + Disabled + %(AdditionalIncludeDirectories) + true + Async + EnableFastChecks + true + MultiThreadedDebugDLL + NotSet + true + Use + true + Level3 + EditAndContinue + _CRT_SECURE_NO_WARNINGS;TBB_USE_THREADING_TOOLS=1;%(PreprocessorDefinitions) + true + + + sfml-audio-d.lib;sfml-window-d.lib;OpenGL32.lib;FreeImage.lib;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) + + + %(AdditionalLibraryDirectories) + LIBC.LIB;%(IgnoreSpecificDefaultLibraries) + true + $(TargetDir)$(TargetName).pdb + true + + + Console + false + + + MachineX86 + + + + + + + + + + + + + MaxSpeed + AnySuitable + true + Speed + %(AdditionalIncludeDirectories) + Async + MultiThreadedDLL + StreamingSIMDExtensions2 + true + Use + Level3 + ProgramDatabase + true + NDEBUG;_VC80_UPGRADE=0x0710;%(PreprocessorDefinitions) + + + + + + + sfml-audio.lib;sfml-window.lib;OpenGL32.lib;FreeImage.lib;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) + + + %(AdditionalLibraryDirectories) + LIBC.lib;%(IgnoreSpecificDefaultLibraries) + true + true + true + Console + + + + + false + false + + + MachineX86 + + + + + + + + + + + + + MaxSpeed + AnySuitable + true + Speed + %(AdditionalIncludeDirectories) + Async + MultiThreadedDLL + StreamingSIMDExtensions2 + true + Use + Level3 + ProgramDatabase + true + TBB_USE_THREADING_TOOLS=1;NDEBUG;_VC80_UPGRADE=0x0710;%(PreprocessorDefinitions) + + + + + + + OpenGL32.lib;FreeImage.lib;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) + + + %(AdditionalLibraryDirectories) + LIBC.lib;%(IgnoreSpecificDefaultLibraries) + true + true + true + Console + + + + + false + false + + + MachineX86 + + + + + + + + + + + + + Disabled + AnySuitable + true + Speed + %(AdditionalIncludeDirectories) + DISABLE_BLUEFISH;%(PreprocessorDefinitions) + Async + MultiThreadedDebugDLL + StreamingSIMDExtensions2 + true + Use + Level3 + ProgramDatabase + + + + + + + OpenGL32.lib;FreeImage.lib;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) + + + %(AdditionalLibraryDirectories) + LIBC.lib;%(IgnoreSpecificDefaultLibraries) + true + true + true + Console + + + + + false + false + + + MachineX86 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + ../../StdAfx.h + ../../StdAfx.h + ../../StdAfx.h + ../../StdAfx.h + + + ../../StdAfx.h + ../../StdAfx.h + ../../StdAfx.h + ../../StdAfx.h + + + ../../StdAfx.h + ../../StdAfx.h + ../../StdAfx.h + ../../StdAfx.h + + + NotUsing + NotUsing + NotUsing + NotUsing + + + ../../StdAfx.h + ../../StdAfx.h + ../../StdAfx.h + ../../StdAfx.h + + + ../../StdAfx.h + ../../StdAfx.h + ../../StdAfx.h + ../../StdAfx.h + + + ../../StdAfx.h + ../../StdAfx.h + ../../StdAfx.h + ../../StdAfx.h + + + ../StdAfx.h + ../StdAfx.h + ../StdAfx.h + ../StdAfx.h + + + ..\stdafx.h + ..\stdafx.h + ..\stdafx.h + ..\stdafx.h + + + ../../StdAfx.h + ../../StdAfx.h + ../../StdAfx.h + ../../StdAfx.h + + + ../../../StdAfx.h + ../../../StdAfx.h + ../../../StdAfx.h + ../../../StdAfx.h + + + ../../StdAfx.h + ../../StdAfx.h + ../../StdAfx.h + ../../StdAfx.h + + + ../../StdAfx.h + ../../StdAfx.h + ../../StdAfx.h + ../../StdAfx.h + + + ../../../StdAfx.h + ../../../StdAfx.h + ../../../StdAfx.h + ../../../StdAfx.h + + + ../../../StdAfx.h + ../../../StdAfx.h + ../../../StdAfx.h + ../../../StdAfx.h + + + ../../../StdAfx.h + ../../../StdAfx.h + ../../../StdAfx.h + ../../../StdAfx.h + + + ../../StdAfx.h + ../../StdAfx.h + ../../StdAfx.h + ../../StdAfx.h + + + ../../StdAfx.h + ../../StdAfx.h + ../../StdAfx.h + ../../StdAfx.h + + + NotUsing + NotUsing + NotUsing + NotUsing + + + ../../StdAfx.h + ../../StdAfx.h + ../../StdAfx.h + ../../StdAfx.h + + + ../../StdAfx.h + ../../StdAfx.h + ../../StdAfx.h + ../../StdAfx.h + + + ../../StdAfx.h + ../../StdAfx.h + ../../StdAfx.h + ../../StdAfx.h + + + ../../StdAfx.h + ../../StdAfx.h + ../../StdAfx.h + ../../StdAfx.h + + + ../../StdAfx.h + ../../StdAfx.h + ../../StdAfx.h + ../../StdAfx.h + + + ../../StdAfx.h + ../../StdAfx.h + ../../StdAfx.h + ../../StdAfx.h + + + ..\..\stdafx.h + ..\..\stdafx.h + ..\..\stdafx.h + ..\..\stdafx.h + + + ..\..\StdAfx.h + ..\..\StdAfx.h + ..\..\StdAfx.h + ..\..\StdAfx.h + + + ..\..\StdAfx.h + ..\..\StdAfx.h + ..\..\StdAfx.h + ..\..\StdAfx.h + + + ..\..\StdAfx.h + ..\..\StdAfx.h + ..\..\StdAfx.h + ..\..\StdAfx.h + + + ..\..\StdAfx.h + ..\..\StdAfx.h + ..\..\StdAfx.h + ..\..\StdAfx.h + + + ..\..\StdAfx.h + ..\..\StdAfx.h + ..\..\StdAfx.h + ..\..\StdAfx.h + + + ..\..\StdAfx.h + ..\..\StdAfx.h + ..\..\StdAfx.h + ..\..\StdAfx.h + + + ../StdAfx.h + ../StdAfx.h + ../StdAfx.h + ../StdAfx.h + + + ..\..\StdAfx.h + ..\..\StdAfx.h + ..\..\StdAfx.h + ..\..\StdAfx.h + + + ../StdAfx.h + ../StdAfx.h + ../StdAfx.h + ../StdAfx.h + + + ../StdAfx.h + ../StdAfx.h + ../StdAfx.h + ../StdAfx.h + + + false + false + + + ..\StdAfx.h + ..\StdAfx.h + ..\StdAfx.h + ..\StdAfx.h + + + ..\StdAfx.h + ..\StdAfx.h + ..\StdAfx.h + ..\StdAfx.h + + + + Create + Create + Create + Create + + + + + true + true + true + true + + + true + true + true + true + + + true + true + true + true + + + true + true + true + true + + + + + Designer + + + + + {02308602-7fe0-4253-b96e-22134919f56a} + + + + + + \ No newline at end of file diff --git a/core/Server.vcxproj.ampl.cfg b/core/Server.vcxproj.ampl.cfg new file mode 100644 index 000000000..3c0f59bac --- /dev/null +++ b/core/Server.vcxproj.ampl.cfg @@ -0,0 +1,7 @@ + + + 1 + + 1 + + diff --git a/core/Server.vcxproj.filters b/core/Server.vcxproj.filters new file mode 100644 index 000000000..bb1671a81 --- /dev/null +++ b/core/Server.vcxproj.filters @@ -0,0 +1,373 @@ + + + + + {0361bd88-1d96-4d86-b3ad-34d40e2319c6} + + + {db784096-c412-4d20-86f0-481e5e2979c5} + + + {69627759-fb18-42fa-8339-66ce27062c90} + + + {35d7835f-f813-4b4b-8d8d-8a35dfef68d3} + + + {3dab53b0-e0ef-4431-8c1d-9a973b269ae7} + + + {7217dee5-b7ca-4128-9994-03a844c06903} + + + {89e746b3-5d4d-4ff2-a66e-279b5371ac9d} + + + {aa3626b2-ad7a-4e84-8867-0f5868a21567} + + + {a5cb89d7-dbbb-4fca-b899-f53a069727b4} + + + {71accefc-1437-4e1d-9ff7-9de654a32df9} + + + {671d13be-c7e1-4f65-9909-03b7c8adcbde} + + + {78b16c14-bf29-4511-9122-684ff513dbf5} + + + {26bf9811-1954-46f5-86ce-ecdc26e6db16} + + + {fc25232a-cab1-4c79-962a-b51dc51161fb} + + + {3d4314f3-8a39-44e3-a0c9-9b833bb8f809} + + + {a6d6bcc9-7ef1-47a3-9800-76e71f2b3f62} + + + {4031dc0c-88e9-46b5-b279-955639dca8b7} + + + {f99e4727-2b1b-4009-a445-99b11b071e8e} + + + {57f477cb-9cff-4216-aab7-50b06df51f20} + + + {a94bc00a-4753-4bce-a777-6a3ea2ceca59} + + + {d33e8ddc-ccb4-4f4f-ad20-e788a796bb7b} + + + {300c491b-4f95-4b15-8d77-eff22fb4cd60} + + + {8355a891-c4db-4a0e-8ecc-795314127cdc} + + + {23166bfa-06eb-4da9-8a0d-1ae5eac4348b} + + + + + Source + + + Source\protocol\amcp + + + Source\protocol\amcp + + + Source\protocol\amcp + + + Source\protocol\amcp + + + Source\protocol\cii + + + Source\protocol\cii + + + Source\protocol\cii + + + Source\protocol\clk + + + Source\protocol\clk + + + Source\protocol\monitor + + + Source\renderer + + + Source\renderer + + + Source\renderer + + + Source\frame + + + Source\frame + + + Source\frame + + + Source\frame + + + Source\frame + + + Source\frame + + + Source + + + Source + + + Source\consumer\bluefish + + + Source\consumer\bluefish + + + Source\consumer\bluefish + + + Source\consumer\bluefish + + + Source\consumer\decklink + + + Source\consumer\decklink\interop + + + Source\consumer\oal + + + Source\consumer\ogl + + + Source\consumer + + + Source\producer\color + + + Source\producer\ffmpeg + + + Source\producer\ffmpeg + + + Source\producer\ffmpeg + + + Source\producer\ffmpeg\audio + + + Source\producer\ffmpeg\video + + + Source\producer\ffmpeg\video + + + Source\producer\ffmpeg\video + + + Source\producer\flash + + + Source\producer\flash + + + Source\producer\flash + + + Source\producer\flash\interop + + + Source\producer\flash\interop + + + Source\producer\flash\interop + + + Source\producer\image + + + Source\producer\image + + + Source\producer\image + + + Source\producer\transition + + + Source\protocol + + + + + Source + + + Source\protocol\amcp + + + Source\protocol\amcp + + + Source\protocol\amcp + + + Source\protocol\cii + + + Source\protocol\cii + + + Source\protocol\clk + + + Source\protocol\clk + + + Source\protocol\monitor + + + Source\renderer + + + Source\renderer + + + Source\frame + + + Source\frame + + + Source\frame + + + Source\frame + + + Source + + + Source + + + Source\consumer\bluefish + + + Source\consumer\bluefish + + + Source\consumer\bluefish + + + Source\consumer\decklink + + + Source\consumer\decklink\interop + + + Source\consumer\oal + + + Source\consumer\ogl + + + Source\producer\color + + + Source\producer\ffmpeg + + + Source\producer\ffmpeg + + + Source\producer\ffmpeg\audio + + + Source\producer\ffmpeg\video + + + Source\producer\ffmpeg\video + + + Source\producer\ffmpeg\video + + + Source\producer\flash + + + Source\producer\flash + + + Source\producer\flash + + + Source\producer\flash\interop + + + Source\producer\flash\interop + + + Source\producer\image + + + Source\producer\image + + + Source\producer\image + + + Source\producer\transition + + + Source\protocol + + + + + Source\consumer\decklink\interop + + + Source\consumer\decklink\interop + + + Source\consumer\decklink\interop + + + Source\producer\flash\interop + + + + + Source + + + \ No newline at end of file diff --git a/core/Server.vcxproj.insp.cfg b/core/Server.vcxproj.insp.cfg new file mode 100644 index 000000000..3c0f59bac --- /dev/null +++ b/core/Server.vcxproj.insp.cfg @@ -0,0 +1,7 @@ + + + 1 + + 1 + + diff --git a/core/Server.vcxproj.user b/core/Server.vcxproj.user new file mode 100644 index 000000000..695b5c78b --- /dev/null +++ b/core/Server.vcxproj.user @@ -0,0 +1,3 @@ + + + \ No newline at end of file diff --git a/core/StdAfx.cpp b/core/StdAfx.cpp new file mode 100644 index 000000000..2bd615bcd --- /dev/null +++ b/core/StdAfx.cpp @@ -0,0 +1,28 @@ +/* +* copyright (c) 2010 Sveriges Television AB +* +* This file is part of CasparCG. +* +* CasparCG is free software: you can redistribute it and/or modify +* it under the terms of the GNU General Public License as published by +* the Free Software Foundation, either version 3 of the License, or +* (at your option) any later version. +* +* CasparCG is distributed in the hope that it will be useful, +* but WITHOUT ANY WARRANTY; without even the implied warranty of +* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +* GNU General Public License for more details. + +* You should have received a copy of the GNU General Public License +* along with CasparCG. If not, see . +* +*/ + +// stdafx.cpp : source file that includes just the standard includes +// dma.pch will be the pre-compiled header +// stdafx.obj will contain the pre-compiled type information + +#include "stdafx.h" + +// TODO: reference any additional headers you need in STDAFX.H +// and not in this file diff --git a/core/StdAfx.h b/core/StdAfx.h new file mode 100644 index 000000000..a2fb9e35c --- /dev/null +++ b/core/StdAfx.h @@ -0,0 +1,69 @@ +/* +* copyright (c) 2010 Sveriges Television AB +* +* This file is part of CasparCG. +* +* CasparCG is free software: you can redistribute it and/or modify +* it under the terms of the GNU General Public License as published by +* the Free Software Foundation, either version 3 of the License, or +* (at your option) any later version. +* +* CasparCG is distributed in the hope that it will be useful, +* but WITHOUT ANY WARRANTY; without even the implied warranty of +* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +* GNU General Public License for more details. + +* You should have received a copy of the GNU General Public License +* along with CasparCG. If not, see . +* +*/ + +// stdafx.h : include file for standard system include files, +// or project specific include files that are used frequently, but +// are changed infrequently +// + +#pragma once + +#ifdef _MSC_VER +#pragma warning (disable : 4482) +#endif + +#if !defined(AFX_STDAFX_H__A9DB83DB_A9FD_11D0_BFD1_444553540000__INCLUDED_) +#define AFX_STDAFX_H__A9DB83DB_A9FD_11D0_BFD1_444553540000__INCLUDED_ + +#ifdef _DEBUG +#include +#endif + +#include "config.h" + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include + +#include +#include +#include + +#include "../common/utility/string_convert.h" + +#include "../common/log/Log.h" +#include "../common/exception/exceptions.h" +#include "../common/exception/win32_exception.h" + +#include + +#endif diff --git a/core/caspar.config b/core/caspar.config new file mode 100644 index 000000000..8a97e18b4 --- /dev/null +++ b/core/caspar.config @@ -0,0 +1,28 @@ + + + + C:\\casparcg\\Repository\\media\\ + C:\\casparcg\\Repository\\log\\ + C:\\casparcg\\Repository\\templates\\ + C:\\casparcg\\Repository\\data\\ + + + + PAL + + + 0 + uniform + true + + + + + + + 5250 + AMCP + + + \ No newline at end of file diff --git a/core/config.h b/core/config.h new file mode 100644 index 000000000..64d169472 --- /dev/null +++ b/core/config.h @@ -0,0 +1,23 @@ +#pragma once + +#define NOMINMAX + +#if defined(_MSC_VER) +# ifndef _SCL_SECURE_NO_WARNINGS +# define _SCL_SECURE_NO_WARNINGS +# endif +# ifndef _CRT_SECURE_NO_WARNINGS +# define _CRT_SECURE_NO_WARNINGS +# endif +#endif + +#define CASPAR_VERSION_STR "2.0.0.0" +#define CASPAR_VERSION_TAG "EXPERIMENTAL" + +#ifndef TEMPLATEHOST_VERSION +# define TEMPLATEHOST_VERSION 1700 +#endif + +#define TBB_USE_THREADING_TOOLS 1 + +//#define DISABLE_BLUEFISH diff --git a/core/consumer/bluefish/BlueFishVideoConsumer.cpp b/core/consumer/bluefish/BlueFishVideoConsumer.cpp new file mode 100644 index 000000000..bedaaa804 --- /dev/null +++ b/core/consumer/bluefish/BlueFishVideoConsumer.cpp @@ -0,0 +1,472 @@ +/* +* copyright (c) 2010 Sveriges Television AB +* +* This file is part of CasparCG. +* +* CasparCG is free software: you can redistribute it and/or modify +* it under the terms of the GNU General Public License as published by +* the Free Software Foundation, either version 3 of the License, or +* (at your option) any later version. +* +* CasparCG is distributed in the hope that it will be useful, +* but WITHOUT ANY WARRANTY; without even the implied warranty of +* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +* GNU General Public License for more details. + +* You should have received a copy of the GNU General Public License +* along with CasparCG. If not, see . +* +*/ + +#include "..\..\StdAfx.h" + +#ifndef DISABLE_BLUEFISH + +#include +#include "BlueFishVideoConsumer.h" +#include "BluefishPlaybackStrategy.h" + +#include +#include + +#if defined(_MSC_VER) +#pragma warning (push, 1) // TODO: Legacy code, just disable warnings +#endif + +namespace caspar { +namespace bluefish { + +/////////////////////////////////////////// +// BlueFishVideoConsumer::EnumerateDevices +// RETURNS: Number of identified bluefish-cards +int BlueFishVideoConsumer::EnumerateDevices() +{ + CASPAR_LOG(info) << "Bleufhsi SDK version: " << BlueVelvetVersion; + BlueVelvetPtr pSDK(BlueVelvetFactory4()); + + if(pSDK != 0) { + int deviceCount = 0; + pSDK->device_enumerate(deviceCount); + return deviceCount; + } + else + return 0; +} + + +/////////////////////////////////////////// +// BlueFishVideoConsumer::Create +// PARAMS: deviceIndex(index of the card that is to be wrapped in a consumer) +// RETURNS: a new BlueFishVideoConsumer-object for the specified card +// COMMENT: Creates and initializes a consumer that outputs video to a bluefish-card +frame_consumer_ptr BlueFishVideoConsumer::Create(const frame_format_desc& format_desc, unsigned int deviceIndex) +{ + BlueFishFrameConsumerPtr card(new BlueFishVideoConsumer(format_desc)); + if(card != 0 && card->SetupDevice(deviceIndex) == false) + card.reset(); + + return card; +} + +//////////////////////////////////////// +// BlueFishVideoConsumer constructor +BlueFishVideoConsumer::BlueFishVideoConsumer(const frame_format_desc& format_desc) : format_desc_(format_desc), pSDK_(BlueVelvetFactory4()), currentFormat_(frame_format::pal), _deviceIndex(0), hasEmbeddedAudio_(false) +{ + frameBuffer_.set_capacity(1); + thread_ = boost::thread([=]{Run();}); +} + +//////////////////////////////////////// +// BlueFishVideoConsumer destructor +BlueFishVideoConsumer::~BlueFishVideoConsumer() +{ + frameBuffer_.push(nullptr), + thread_.join(); + ReleaseDevice(); +} + +/*******************/ +/** METHODS **/ +/*******************/ + +unsigned long BlueFishVideoConsumer::VidFmtFromFrameFormat(frame_format fmt) +{ + switch(fmt) + { + case frame_format::pal: return VID_FMT_PAL; + case frame_format::ntsc: return VID_FMT_NTSC; + case frame_format::x576p2500: return ULONG_MAX; //not supported + case frame_format::x720p5000: return VID_FMT_720P_5000; + case frame_format::x720p5994: return VID_FMT_720P_5994; + case frame_format::x720p6000: return VID_FMT_720P_6000; + case frame_format::x1080p2397: return VID_FMT_1080P_2397; + case frame_format::x1080p2400: return VID_FMT_1080P_2400; + case frame_format::x1080i5000: return VID_FMT_1080I_5000; + case frame_format::x1080i5994: return VID_FMT_1080I_5994; + case frame_format::x1080i6000: return VID_FMT_1080I_6000; + case frame_format::x1080p2500: return VID_FMT_1080P_2500; + case frame_format::x1080p2997: return VID_FMT_1080P_2997; + case frame_format::x1080p3000: return VID_FMT_1080P_3000; + default: return ULONG_MAX; + } +} + +TCHAR* GetBluefishCardDesc(int cardType) +{ + switch(cardType) + { + case CRD_BLUEDEEP_LT: return TEXT("Deepblue LT"); // D64 Lite + case CRD_BLUEDEEP_SD: return TEXT("Iridium SD"); // Iridium SD + case CRD_BLUEDEEP_AV: return TEXT("Iridium AV"); // Iridium AV + case CRD_BLUEDEEP_IO: return TEXT("Deepblue IO"); // D64 Full + case CRD_BLUEWILD_AV: return TEXT("Wildblue AV"); // D64 AV + case CRD_IRIDIUM_HD: return TEXT("Iridium HD"); // * Iridium HD + case CRD_BLUEWILD_RT: return TEXT("Wildblue RT"); // D64 RT + case CRD_BLUEWILD_HD: return TEXT("Wildblue HD"); // * BadAss G2 + case CRD_REDDEVIL: return TEXT("Iridium Full"); // Iridium Full + case CRD_BLUEDEEP_HD: // * BadAss G2 variant, proposed, reserved + case CRD_BLUEDEEP_HDS: return TEXT("Reserved for \"BasAss G2"); // * BadAss G2 variant, proposed, reserved + case CRD_BLUE_ENVY: return TEXT("Blue envy"); // Mini Din + case CRD_BLUE_PRIDE: return TEXT("Blue pride"); //Mini Din Output + case CRD_BLUE_GREED: return TEXT("Blue greed"); + case CRD_BLUE_INGEST: return TEXT("Blue ingest"); + case CRD_BLUE_SD_DUALLINK: return TEXT("Blue SD duallink"); + case CRD_BLUE_CATALYST: return TEXT("Blue catalyst"); + case CRD_BLUE_SD_DUALLINK_PRO: return TEXT("Blue SD duallink pro"); + case CRD_BLUE_SD_INGEST_PRO: return TEXT("Blue SD ingest pro"); + case CRD_BLUE_SD_DEEPBLUE_LITE_PRO: return TEXT("Blue SD deepblue lite pro"); + case CRD_BLUE_SD_SINGLELINK_PRO: return TEXT("Blue SD singlelink pro"); + case CRD_BLUE_SD_IRIDIUM_AV_PRO: return TEXT("Blue SD iridium AV pro"); + case CRD_BLUE_SD_FIDELITY: return TEXT("Blue SD fidelity"); + case CRD_BLUE_SD_FOCUS: return TEXT("Blue SD focus"); + case CRD_BLUE_SD_PRIME: return TEXT("Blue SD prime"); + case CRD_BLUE_EPOCH_2K_CORE: return TEXT("Blue epoch 2k core"); + case CRD_BLUE_EPOCH_2K_ULTRA: return TEXT("Blue epoch 2k ultra"); + case CRD_BLUE_EPOCH_HORIZON: return TEXT("Blue epoch horizon"); + case CRD_BLUE_EPOCH_CORE: return TEXT("Blue epoch core"); + case CRD_BLUE_EPOCH_ULTRA: return TEXT("Blue epoch ultra"); + case CRD_BLUE_CREATE_HD: return TEXT("Blue create HD"); + case CRD_BLUE_CREATE_2K: return TEXT("Blue create 2k"); + case CRD_BLUE_CREATE_2K_ULTRA: return TEXT("Blue create 2k ultra"); + default: return TEXT("Unknown"); + } +} + +bool BlueFishVideoConsumer::SetupDevice(unsigned int deviceIndex) +{ + return this->DoSetupDevice(deviceIndex); +} + +/* +// Original initialization code +bool BlueFishVideoConsumer::DoSetupDevice(unsigned int deviceIndex, std::wstring strDesiredFrameFormat) +{ + _deviceIndex = deviceIndex; + + unsigned long memFmt = MEM_FMT_ARGB_PC, updFmt = UPD_FMT_FRAME, vidFmt = VID_FMT_PAL, resFmt = RES_FMT_NORMAL; + unsigned long desiredVideoFormat = VID_FMT_PAL; + int iDummy; + + int bufferIndex=0; //Bufferindex used when initializing the buffers + + if(strDesiredFrameFormat.size() == 0) + strDesiredFrameFormat = TEXT("PAL"); + + frame_format casparVideoFormat = caspar::get_video_format(strDesiredFrameFormat); + desiredVideoFormat = BlueFishVideoConsumer::VidFmtFromFrameFormat(casparVideoFormat); + currentFormat_ = casparVideoFormat != FFormatInvalid ? casparVideoFormat : FFormatPAL; + if(desiredVideoFormat == ULONG_MAX) { + LOG << TEXT("BLUECARD ERROR: Unsupported videomode: ") << strDesiredFrameFormat << TEXT(". (device") << _deviceIndex << TEXT(")"); + return false; + } + + if(BLUE_FAIL(pSDK_->device_attach(_deviceIndex, FALSE))) { + LOG << TEXT("BLUECARD ERROR: Failed to attach device") << _deviceIndex; + return false; + } + + if(desiredVideoFormat != VID_FMT_PAL) { + int videoModeCount = pSDK_->count_video_mode(); + for(int videoModeIndex=1; videoModeIndex <= videoModeCount; ++videoModeIndex) { + EVideoMode videoMode = pSDK_->enum_video_mode(videoModeIndex); + if(videoMode == desiredVideoFormat) { + vidFmt = videoMode; + } + } + } + + if(vidFmt == VID_FMT_PAL) { + strDesiredFrameFormat = TEXT("PAL"); + currentFormat_ = FFormatPAL; + } + + if(BLUE_FAIL(pSDK_->set_video_framestore_style(vidFmt, memFmt, updFmt, resFmt))) { + LOG << TEXT("BLUECARD ERROR: Failed to set videomode to ") << strDesiredFrameFormat << TEXT(". (device ") << _deviceIndex << TEXT(")"); + return false; + } + + LOG << TEXT("BLUECARD INFO: Successfully configured bluecard for ") << strDesiredFrameFormat << TEXT(". (device ") << _deviceIndex << TEXT(")"); + + if (pSDK_->has_output_key()) { + iDummy = TRUE; + int v4444 = FALSE, invert = FALSE, white = FALSE; + pSDK_->set_output_key(iDummy, v4444, invert, white); + } + + if(pSDK_->GetHDCardType(_deviceIndex) != CRD_HD_INVALID) { + pSDK_->Set_DownConverterSignalType((vidFmt == VID_FMT_PAL) ? SD_SDI : HD_SDI); + } + + + iDummy = FALSE; + pSDK_->set_vertical_flip(iDummy); + + // Get framestore parameters + if(BLUE_OK(pSDK_->render_buffer_sizeof(m_bufferCount, m_length, m_actual, m_golden))) { + LOG << TEXT("BLUECARD INFO: Buffers: ") << m_bufferCount << TEXT(", \"Length\": ") << m_length << TEXT(", Buffer size: ") << m_actual << TEXT(" (device ") << _deviceIndex << TEXT(")") << common::LogStream::Flush; + } + else { + LOG << TEXT("BLUECARD ERROR: Failed to get framestore parameters (device ") << _deviceIndex << TEXT(")"); + } + + pFrameManager_ = BluefishFrameManagerPtr(new BluefishFrameManager(pSDK_, currentFormat_, m_golden)); + + iDummy = TRUE; + pSDK_->set_output_video(iDummy); + + // Now specify video output buffer + pSDK_->render_buffer_update(0); + + pPlaybackControl_.reset(new FramePlaybackControl(FramePlaybackStrategyPtr(new BluefishPlaybackStrategy(this)))); + pPlaybackControl_->Start(); + + LOG << TEXT("BLUECARD INFO: Successfully initialized device ") << _deviceIndex; + return true; +} +*/ + +//New, improved(?) initialization code. +//Based on code sent from the bluefish-sdk support 2009-08-25. Email "RE: [sdk] Ang. RE: Issue with SD Lite Pro PCI-E" +bool BlueFishVideoConsumer::DoSetupDevice(unsigned int deviceIndex) +{ + _deviceIndex = deviceIndex; + + unsigned long memFmt = MEM_FMT_ARGB_PC, updFmt = UPD_FMT_FRAME, vidFmt = VID_FMT_PAL, resFmt = RES_FMT_NORMAL, engineMode = VIDEO_ENGINE_FRAMESTORE; + unsigned long desiredVideoFormat = VID_FMT_PAL; + int iDummy; + + int bufferIndex=0; //Bufferindex used when initializing the buffers + + if(BLUE_FAIL(pSDK_->device_attach(_deviceIndex, FALSE))) { + CASPAR_LOG(error) << "BLUECARD ERROR: Failed to attach device. (device " << _deviceIndex << TEXT(")"); + return false; + } + + int videoCardType = pSDK_->has_video_cardtype(); + CASPAR_LOG(info) << "BLUECARD INFO: Card type: " << GetBluefishCardDesc(videoCardType) << TEXT(". (device ") << _deviceIndex << TEXT(")"); + + desiredVideoFormat = BlueFishVideoConsumer::VidFmtFromFrameFormat(format_desc_.format); + currentFormat_ = format_desc_.format != frame_format::invalid ? format_desc_.format : frame_format::pal; + if(desiredVideoFormat == ULONG_MAX) { + CASPAR_LOG(error) << "BLUECARD ERROR: Unsupported videomode: " << format_desc_.name << TEXT(". (device ") << _deviceIndex << TEXT(")"); + return false; + } + + if(desiredVideoFormat != VID_FMT_PAL) { + int videoModeCount = pSDK_->count_video_mode(); + for(int videoModeIndex=1; videoModeIndex <= videoModeCount; ++videoModeIndex) { + EVideoMode videoMode = pSDK_->enum_video_mode(videoModeIndex); + if(videoMode == desiredVideoFormat) { + vidFmt = videoMode; + } + } + } + + if(vidFmt != desiredVideoFormat) { + CASPAR_LOG(error) << "BLUECARD ERROR: Failed to set desired videomode: " << format_desc_.name << TEXT(". (device ") << _deviceIndex << TEXT(")"); + } + + if(vidFmt == VID_FMT_PAL) { + currentFormat_ = frame_format::pal; + format_desc_ = frame_format_desc::format_descs[frame_format::pal]; + } + + DisableVideoOutput(); + + VARIANT value; + value.vt = VT_UI4; + + //Enable dual link output + value.ulVal = 1; + if(!BLUE_PASS(pSDK_->SetCardProperty(VIDEO_DUAL_LINK_OUTPUT, value))) { + CASPAR_LOG(error) << "BLUECARD ERROR: Failed to enable dual link. (device " << _deviceIndex << TEXT(")"); + return false; + } + + value.ulVal = Signal_FormatType_4224; + if(!BLUE_PASS(pSDK_->SetCardProperty(VIDEO_DUAL_LINK_OUTPUT_SIGNAL_FORMAT_TYPE, value))) { + CASPAR_LOG(error) << "BLUECARD ERROR: Failed to set dual link format type to 4:2:2:4. (device " << _deviceIndex << TEXT(")"); + return false; + } + + //Setting output Video mode + value.ulVal = vidFmt; + if(!BLUE_PASS(pSDK_->SetCardProperty(VIDEO_MODE, value))) { + CASPAR_LOG(error) << "BLUECARD ERROR: Failed to set videomode. (device " << _deviceIndex << TEXT(")"); + return false; + } + + //Select Update Mode for output + value.ulVal = updFmt; + if(!BLUE_PASS(pSDK_->SetCardProperty(VIDEO_UPDATE_TYPE, value))) { + CASPAR_LOG(error) << "BLUECARD ERROR: Failed to set update type. (device " << _deviceIndex << TEXT(")"); + return false; + } + + //Select output memory format + value.ulVal = memFmt; + if(!BLUE_PASS(pSDK_->SetCardProperty(VIDEO_MEMORY_FORMAT, value))) { + CASPAR_LOG(error) << "BLUECARD ERROR: Failed to set memory format. (device " << _deviceIndex << TEXT(")"); + return false; + } + + //SELECT IMAGE ORIENTATION + value.ulVal = ImageOrientation_Normal; + if(!BLUE_PASS(pSDK_->SetCardProperty(VIDEO_IMAGE_ORIENTATION, value))) { + CASPAR_LOG(error) << "BLUECARD ERROR: Failed to set image orientation to normal. (device " << _deviceIndex << TEXT(")"); + } + + value.ulVal = CGR_RANGE; + if(!BLUE_PASS(pSDK_->SetCardProperty(VIDEO_RGB_DATA_RANGE, value))) { + CASPAR_LOG(error) << "BLUECARD ERROR: Failed to set RGB data range to CGR. (device " << _deviceIndex << TEXT(")"); + } + + value.ulVal = MATRIX_709_CGR; + if(vidFmt == VID_FMT_PAL) { + value.ulVal = MATRIX_601_CGR; + } + if(!BLUE_PASS(pSDK_->SetCardProperty(VIDEO_PREDEFINED_COLOR_MATRIX, value))) { + CASPAR_LOG(error) << "BLUECARD ERROR: Failed to set colormatrix to " << (vidFmt == VID_FMT_PAL ? TEXT("601 CGR") : TEXT("709 CGR")) << TEXT(". (device ") << _deviceIndex << TEXT(")"); + } + + + //Disable embedded audio + value.ulVal = 1; + if(!BLUE_PASS(pSDK_->SetCardProperty(EMBEDDED_AUDIO_OUTPUT, value))) { + CASPAR_LOG(error) << "BLUECARD ERROR: Failed to enable embedded audio. (device " << _deviceIndex << TEXT(")"); + } + else { + CASPAR_LOG(info) << "BLUECARD INFO: Enabled embedded audio. (device " << _deviceIndex << TEXT(")"); + hasEmbeddedAudio_ = true; + } + + CASPAR_LOG(info) << "BLUECARD INFO: Successfully configured bluecard for " << format_desc_.name << TEXT(". (device ") << _deviceIndex << TEXT(")"); + + if (pSDK_->has_output_key()) { + iDummy = TRUE; + int v4444 = FALSE, invert = FALSE, white = FALSE; + pSDK_->set_output_key(iDummy, v4444, invert, white); + } + + if(pSDK_->GetHDCardType(_deviceIndex) != CRD_HD_INVALID) { + pSDK_->Set_DownConverterSignalType((vidFmt == VID_FMT_PAL) ? SD_SDI : HD_SDI); + } + + ULONG videoGolden = BlueVelvetGolden(vidFmt, memFmt, updFmt); + + pFrameManager_ = BluefishFrameManagerPtr(new BluefishFrameManager(pSDK_, currentFormat_, videoGolden)); + + pPlayback_ = std::make_shared(this); + + if(BLUE_FAIL(pSDK_->set_video_engine(engineMode))) { + CASPAR_LOG(error) << "BLUECARD ERROR: Failed to set vido engine. (device " << _deviceIndex << TEXT(")"); + return false; + } + + EnableVideoOutput(); + + CASPAR_LOG(info) << "BLUECARD INFO: Successfully initialized device " << _deviceIndex; + return true; +} + +bool BlueFishVideoConsumer::ReleaseDevice() +{ + pPlayback_.reset(); + + pFrameManager_.reset(); + DisableVideoOutput(); + + if(pSDK_) { + pSDK_->device_detach(); + } + + CASPAR_LOG(info) << "BLUECARD INFO: Successfully released device " << _deviceIndex; + return true; +} + +void BlueFishVideoConsumer::EnableVideoOutput() +{ + //Need sync. protection? + if(pSDK_) + { + VARIANT value; + value.vt = VT_UI4; + + //Deactivate channel + value.ulVal = 0; + if(!BLUE_PASS(pSDK_->SetCardProperty(VIDEO_BLACKGENERATOR, value))) { + CASPAR_LOG(error) << "BLUECARD ERROR: Failed to disable video output. (device " << _deviceIndex << TEXT(")"); + } + } +} + +void BlueFishVideoConsumer::DisableVideoOutput() +{ + //Need sync. protection? + if(pSDK_) + { + VARIANT value; + value.vt = VT_UI4; + + //Deactivate channel + value.ulVal = 1; + if(!BLUE_PASS(pSDK_->SetCardProperty(VIDEO_BLACKGENERATOR, value))) { + CASPAR_LOG(error) << "BLUECARD ERROR: Failed to disable video output. (device " << _deviceIndex << TEXT(")"); + } + } +} + +void BlueFishVideoConsumer::display(const frame_ptr& frame) +{ + if(frame == nullptr) + return; + + if(pException_ != nullptr) + std::rethrow_exception(pException_); + + frameBuffer_.push(frame); +} + +void BlueFishVideoConsumer::Run() +{ + while(true) + { + try + { + frame_ptr frame; + frameBuffer_.pop(frame); + if(frame == nullptr) + return; + + pPlayback_->display(frame); + } + catch(...) + { + pException_ = std::current_exception(); + } + } +} + +}} + +#endif \ No newline at end of file diff --git a/core/consumer/bluefish/BlueFishVideoConsumer.h b/core/consumer/bluefish/BlueFishVideoConsumer.h new file mode 100644 index 000000000..e62e0aad4 --- /dev/null +++ b/core/consumer/bluefish/BlueFishVideoConsumer.h @@ -0,0 +1,90 @@ +/* +* copyright (c) 2010 Sveriges Television AB +* +* This file is part of CasparCG. +* +* CasparCG is free software: you can redistribute it and/or modify +* it under the terms of the GNU General Public License as published by +* the Free Software Foundation, either version 3 of the License, or +* (at your option) any later version. +* +* CasparCG is distributed in the hope that it will be useful, +* but WITHOUT ANY WARRANTY; without even the implied warranty of +* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +* GNU General Public License for more details. + +* You should have received a copy of the GNU General Public License +* along with CasparCG. If not, see . +* +*/ +#pragma once + +#include "../../../common/concurrency/thread.h" +#include "BluefishException.h" +#include "BluefishFrameManager.h" +#include "../../consumer/frame_consumer.h" +#include "../../renderer/render_device.h" +#include +#include + +#define TIMEOUT 1000 + +class CBlueVelvet4; + +namespace caspar { + +namespace bluefish { + +typedef std::tr1::shared_ptr BlueVelvetPtr; + +class BlueFishVideoConsumer : public frame_consumer +{ + friend class BluefishPlaybackStrategy; + + BlueFishVideoConsumer(const frame_format_desc& format_desc); + BlueFishVideoConsumer(const BlueFishVideoConsumer&); + const BlueFishVideoConsumer& operator=(const BlueFishVideoConsumer&); + +public: + virtual ~BlueFishVideoConsumer(); + + static int EnumerateDevices(); + static frame_consumer_ptr Create(const frame_format_desc& format_desc, unsigned int deviceIndex); + + void display(const frame_ptr&); + + const frame_format_desc& get_frame_format_desc() const { return format_desc_; } + +private: + + void Run(); + + void EnableVideoOutput(); + void DisableVideoOutput(); + bool SetupDevice(unsigned int deviceIndex); + bool ReleaseDevice(); + + bool DoSetupDevice(unsigned int deviceIndex); + + BlueVelvetPtr pSDK_; + std::shared_ptr pPlayback_; + BluefishFrameManagerPtr pFrameManager_; + unsigned long m_bufferCount; + unsigned long m_length; + unsigned long m_actual; + unsigned long m_golden; + + unsigned long VidFmtFromFrameFormat(frame_format fmt); + + frame_format currentFormat_; + unsigned int _deviceIndex; + bool hasEmbeddedAudio_; + frame_format_desc format_desc_; + + std::exception_ptr pException_; + boost::thread thread_; + tbb::concurrent_bounded_queue frameBuffer_; +}; +typedef std::tr1::shared_ptr BlueFishFrameConsumerPtr; + +}} diff --git a/core/consumer/bluefish/BluefishException.h b/core/consumer/bluefish/BluefishException.h new file mode 100644 index 000000000..4ea18ebd9 --- /dev/null +++ b/core/consumer/bluefish/BluefishException.h @@ -0,0 +1,39 @@ +/* +* copyright (c) 2010 Sveriges Television AB +* +* This file is part of CasparCG. +* +* CasparCG is free software: you can redistribute it and/or modify +* it under the terms of the GNU General Public License as published by +* the Free Software Foundation, either version 3 of the License, or +* (at your option) any later version. +* +* CasparCG is distributed in the hope that it will be useful, +* but WITHOUT ANY WARRANTY; without even the implied warranty of +* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +* GNU General Public License for more details. + +* You should have received a copy of the GNU General Public License +* along with CasparCG. If not, see . +* +*/ + +#ifndef _CASPAR_BLUEFISHEXCEPTION_H__ +#define _CASPAR_BLUEFISHEXCEPTION_H__ + +#include + +namespace caspar { +namespace bluefish { + +class BluefishException : public std::exception +{ +public: + explicit BluefishException(const char* msg) : std::exception(msg) {} + ~BluefishException() {} +}; + +} //namespace bluefish +} //namespace caspar + +#endif //_CASPAR_BLUEFISHEXCEPTION_H__ \ No newline at end of file diff --git a/core/consumer/bluefish/BluefishFrameManager.cpp b/core/consumer/bluefish/BluefishFrameManager.cpp new file mode 100644 index 000000000..aa5352801 --- /dev/null +++ b/core/consumer/bluefish/BluefishFrameManager.cpp @@ -0,0 +1,191 @@ +/* +* copyright (c) 2010 Sveriges Television AB +* +* This file is part of CasparCG. +* +* CasparCG is free software: you can redistribute it and/or modify +* it under the terms of the GNU General Public License as published by +* the Free Software Foundation, either version 3 of the License, or +* (at your option) any later version. +* +* CasparCG is distributed in the hope that it will be useful, +* but WITHOUT ANY WARRANTY; without even the implied warranty of +* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +* GNU General Public License for more details. + +* You should have received a copy of the GNU General Public License +* along with CasparCG. If not, see . +* +*/ + +#include "..\..\StdAfx.h" + +#include +#include "BluefishFrameManager.h" +#include + +#define BUFFER_ID_USER_BASE (6) + +namespace caspar { +namespace bluefish { + +////////////////////// +// CardFrameInfo +// +CardFrameInfo::CardFrameInfo(BlueVelvetPtr pSDK, int dataSize, int bufferID) : pSDK_(pSDK), dataSize_(dataSize), pData_(0), bufferID_(bufferID) +{ + if(BLUE_FAIL(pSDK->system_buffer_map(reinterpret_cast(&pData_), bufferID))) + { + throw BluefishException("Failed to map buffer"); + } +} + +CardFrameInfo::~CardFrameInfo() +{ + try + { + if(pSDK_ != 0 && pData_ != 0) + pSDK_->system_buffer_unmap(pData_); + } + catch(...) {} +} + + +////////////////////// +// SystemFrameInfo +// +SystemFrameInfo::SystemFrameInfo(int dataSize, int bufferID) : dataSize_(dataSize), pData_(0), bufferID_(bufferID) +{ + pData_ = static_cast(::VirtualAlloc(NULL, dataSize_, MEM_COMMIT | MEM_RESERVE, PAGE_READWRITE)); + if(pData_ == 0) + { + throw BluefishException("Failed to allocate memory for frame"); + } + if(::VirtualLock(pData_, dataSize_) == 0) + { + throw BluefishException("Failed to lock memory for frame"); + } +} + +SystemFrameInfo::~SystemFrameInfo() +{ + try + { + if(pData_ != 0) + ::VirtualFree(pData_, 0, MEM_RELEASE); + } + catch(...) {} +} + +//////////////////////// +// BluefishVideoFrame +// +BluefishVideoFrame::BluefishVideoFrame(BluefishFrameManager* pFrameManager) : pFrameManager_(pFrameManager) +{ + if(pFrameManager_ != 0) + pInfo_ = pFrameManager_->GetBuffer(); + if(pInfo_ != nullptr) + { + size_ = pInfo_->size(); + data_ = pInfo_->GetPtr(); + buffer_id_ = pInfo_->GetBufferID(); + } + else + { + size_ = pFrameManager->get_frame_format_desc().size; + data_ = static_cast(scalable_aligned_malloc(16, size_)); + buffer_id_ = 0; + } +} + +BluefishVideoFrame::~BluefishVideoFrame() +{ + if(pFrameManager_ != 0 && pInfo_ != 0) + pFrameManager_->ReturnBuffer(pInfo_); + + if(pInfo_ != nullptr) + { + } + else + { + scalable_aligned_free(data_); + } +} + +////////////////////////////// +// BluefishVideoFrameFactory +// +BluefishFrameManager::BluefishFrameManager(BlueVelvetPtr pSDK, frame_format fmt, unsigned long optimalLength) : pSDK_(pSDK), format_(fmt) +{ + //const frame_format_desc& format_desc = frame_format_desc::format_descs[fmt]; + + SIZE_T workingSetMinSize = 0, workingSetMaxSize = 0; + if(::GetProcessWorkingSetSize(::GetCurrentProcess(), &workingSetMinSize, &workingSetMaxSize) != 0) + { + CASPAR_LOG(debug) << "WorkingSet size: min = " << workingSetMinSize << TEXT(", max = ") << workingSetMaxSize; + + workingSetMinSize += optimalLength * 6; + workingSetMaxSize += optimalLength * 6; + + if(::SetProcessWorkingSetSize(::GetCurrentProcess(), workingSetMinSize, workingSetMaxSize) == 0) + { + CASPAR_LOG(error) << "Failed to set workingset: min = " << workingSetMinSize << TEXT(", max = ") << workingSetMaxSize; + } + } + + //for(int cardBufferIndex = 0; cardBufferIndex < 4; ++cardBufferIndex) + //{ + // frameBuffers_.push_back(VideoFrameInfoPtr(new CardFrameInfo(pSDK, optimalLength, BUFFER_ID_VIDEO0 + cardBufferIndex))); + //} + for(int systemBufferIndex = 0; systemBufferIndex < 6; ++systemBufferIndex) + { + frameBuffers_.push_back(VideoFrameInfoPtr(new SystemFrameInfo(optimalLength, BUFFER_ID_USER_BASE + systemBufferIndex))); + } + + FrameInfoList::const_iterator it = frameBuffers_.begin(); + FrameInfoList::const_iterator end = frameBuffers_.end(); + for(; it != end; ++it) + { + if(BLUE_FAIL(pSDK_->system_buffer_assign((*it)->GetPtr(), (*it)->GetBufferID(), (*it)->size(), BUFFER_TYPE_VIDEO))) + { + throw BluefishException("Failed to assign buffer"); + } + } +} + +BluefishFrameManager::~BluefishFrameManager() +{ +} + +std::shared_ptr BluefishFrameManager::CreateFrame() +{ + return std::make_shared(this); +} + +const frame_format_desc& BluefishFrameManager::get_frame_format_desc() const +{ + return frame_format_desc::format_descs[format_]; +} + +VideoFrameInfoPtr BluefishFrameManager::GetBuffer() +{ + tbb::mutex::scoped_lock lock(mutex_); + VideoFrameInfoPtr pInfo; + + if(frameBuffers_.size() > 0) + { + pInfo = frameBuffers_.front(); + frameBuffers_.pop_front(); + } + + return pInfo; +} + +void BluefishFrameManager::ReturnBuffer(VideoFrameInfoPtr pInfo) +{ + tbb::mutex::scoped_lock lock(mutex_); + if(pInfo != 0) + frameBuffers_.push_back(pInfo); +} + +}} \ No newline at end of file diff --git a/core/consumer/bluefish/BluefishFrameManager.h b/core/consumer/bluefish/BluefishFrameManager.h new file mode 100644 index 000000000..e52d1467a --- /dev/null +++ b/core/consumer/bluefish/BluefishFrameManager.h @@ -0,0 +1,154 @@ +/* +* copyright (c) 2010 Sveriges Television AB +* +* This file is part of CasparCG. +* +* CasparCG is free software: you can redistribute it and/or modify +* it under the terms of the GNU General Public License as published by +* the Free Software Foundation, either version 3 of the License, or +* (at your option) any later version. +* +* CasparCG is distributed in the hope that it will be useful, +* but WITHOUT ANY WARRANTY; without even the implied warranty of +* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +* GNU General Public License for more details. + +* You should have received a copy of the GNU General Public License +* along with CasparCG. If not, see . +* +*/ + +#ifndef _CASPAR_BLUEFISHVIDEOFRAMEFACTORY_H__ +#define _CASPAR_BLUEFISHVIDEOFRAMEFACTORY_H__ + +#pragma once + +#include "..\..\frame\system_frame.h" +#include "..\..\frame\frame_format.h" +#include +#include +#include "BluefishException.h" + +#include + +class CBlueVelvet4; + +namespace caspar { +namespace bluefish { + +typedef std::tr1::shared_ptr BlueVelvetPtr; + +class VideoFrameInfo +{ +public: + VideoFrameInfo() {} + virtual ~VideoFrameInfo() {} + + virtual unsigned char* GetPtr() const = 0; + virtual int GetBufferID() const = 0; + virtual int size() const = 0; +}; +typedef std::tr1::shared_ptr VideoFrameInfoPtr; + +class CardFrameInfo : public VideoFrameInfo +{ +public: + CardFrameInfo(BlueVelvetPtr pSDK, int dataSize, int bufferID); + ~CardFrameInfo(); + + unsigned char* GetPtr() const { + return pData_; + } + int GetBufferID() const { + return bufferID_; + } + int size() const { + return dataSize_; + } + +private: + BlueVelvetPtr pSDK_; + unsigned char* pData_; + int bufferID_; + int dataSize_; +}; + +class SystemFrameInfo : public VideoFrameInfo +{ +public: + SystemFrameInfo(int dataSize, int bufferID); + ~SystemFrameInfo(); + + unsigned char* GetPtr() const { + return pData_; + } + int GetBufferID() const { + return bufferID_; + } + int size() const { + return dataSize_; + } + +private: + unsigned char* pData_; + int bufferID_; + int dataSize_; +}; + +class BluefishFrameManager +{ + friend class BluefishVideoFrame; + typedef std::list FrameInfoList; + + BluefishFrameManager(const BluefishFrameManager&); + const BluefishFrameManager& operator=(const BluefishFrameManager&); + +public: + BluefishFrameManager(BlueVelvetPtr pSDK, frame_format fmt, unsigned long optimalLength); + virtual ~BluefishFrameManager(); + + virtual std::shared_ptr CreateFrame(); + virtual const frame_format_desc& get_frame_format_desc() const; + +private: + VideoFrameInfoPtr GetBuffer(); + void ReturnBuffer(VideoFrameInfoPtr); + + BlueVelvetPtr pSDK_; + frame_format format_; + FrameInfoList frameBuffers_; + tbb::mutex mutex_; +}; +typedef std::tr1::shared_ptr BluefishFrameManagerPtr; + + +class BluefishVideoFrame : public frame +{ +public: + explicit BluefishVideoFrame(BluefishFrameManager* pFrameManager); + + virtual ~BluefishVideoFrame(); + + unsigned char* data() { return data_; } + + unsigned int size() const { return size_; } + + long meta_data() const { return buffer_id_; } + + void* tag() const + { + return pFrameManager_; + } +private: + unsigned char* data_; + long buffer_id_; + size_t size_; + VideoFrameInfoPtr pInfo_; + BluefishFrameManager* pFrameManager_; +}; + + +} //namespace bluefish +} //namespace caspar + +#endif //_CASPAR_BLUEFISHVIDEOFRAMEFACTORY_H__ \ No newline at end of file diff --git a/core/consumer/bluefish/BluefishPlaybackStrategy.cpp b/core/consumer/bluefish/BluefishPlaybackStrategy.cpp new file mode 100644 index 000000000..996966227 --- /dev/null +++ b/core/consumer/bluefish/BluefishPlaybackStrategy.cpp @@ -0,0 +1,135 @@ +/* +* copyright (c) 2010 Sveriges Television AB +* +* This file is part of CasparCG. +* +* CasparCG is free software: you can redistribute it and/or modify +* it under the terms of the GNU General Public License as published by +* the Free Software Foundation, either version 3 of the License, or +* (at your option) any later version. +* +* CasparCG is distributed in the hope that it will be useful, +* but WITHOUT ANY WARRANTY; without even the implied warranty of +* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +* GNU General Public License for more details. + +* You should have received a copy of the GNU General Public License +* along with CasparCG. If not, see . +* +*/ + +#include "../../StdAfx.h" + +#include "../../../common/image/image.h" +#include +#include + +#include + +#include "BluefishPlaybackStrategy.h" +#include "BluefishVideoConsumer.h" + +namespace caspar { namespace bluefish { + +using namespace caspar::common; + +struct BluefishPlaybackStrategy::Implementation +{ + Implementation(BlueFishVideoConsumer* pConsumer) : pConsumer_(pConsumer), currentReservedFrameIndex_(0) + { + auto frame = pConsumer->pFrameManager_->CreateFrame(); + if(frame != 0) + reservedFrames_.push_back(frame); + else { + throw std::exception("Failed to reserve temporary bluefishframe"); + } + frame.reset(); + + frame = pConsumer->pFrameManager_->CreateFrame(); + if(frame != 0) + reservedFrames_.push_back(frame); + else { + throw std::exception("Failed to reserve temporary bluefishframe"); + } + + memset(&hancStreamInfo_, 0, sizeof(hancStreamInfo_)); + } + std::shared_ptr GetReservedFrame() { + std::shared_ptr frame = reservedFrames_[currentReservedFrameIndex_]; + currentReservedFrameIndex_ ^= 1; + return frame; + } + + void DisplayFrame(const frame_ptr& frame) + { + if(frame != nullptr) { + if(pConsumer_->pFrameManager_.get() == reinterpret_cast(frame->tag())) { + DoRender(std::static_pointer_cast(frame)); + } + else { + std::shared_ptr pTempFrame = reservedFrames_[currentReservedFrameIndex_]; + if(frame->size() == pTempFrame->size()) { + common::image::copy(pTempFrame->data(), frame->data(), pTempFrame->size()); + DoRender(pTempFrame); + } + + currentReservedFrameIndex_ ^= 1; + } + } + else { + CASPAR_LOG(error) << "BLUEFISH: Tried to render frame with no data"; + } + } + + void DoRender(const std::shared_ptr& frame) { + static bool doLog = true; + static int frameID = 0; + // video synch + unsigned long fieldCount = 0; + pConsumer_->pSDK_->wait_output_video_synch(UPD_FMT_FRAME, fieldCount); + + // Host->PCI in_Frame buffer to the card buffer + pConsumer_->pSDK_->system_buffer_write_async(frame->data(), frame->size(), 0, frame->meta_data(), 0); + if(BLUE_FAIL(pConsumer_->pSDK_->render_buffer_update(frame->meta_data()))) { + /*pConsumer_->pSDK_->system_buffer_write_async(frame->data(), frame->size(), 0, frameID, 0); + if(BLUE_FAIL(pConsumer_->pSDK_->render_buffer_update(frameID))) {*/ + if(doLog) { + CASPAR_LOG(error) << "BLUEFISH: render_buffer_update failed"; + doLog = false; + } + } + else + doLog = true; + + frameID = (frameID+1) & 3; + } + + BlueFishVideoConsumer* pConsumer_; + std::vector> reservedFrames_; + int currentReservedFrameIndex_; + + hanc_stream_info_struct hancStreamInfo_; +}; + +BluefishPlaybackStrategy::BluefishPlaybackStrategy(BlueFishVideoConsumer* pConsumer) : pImpl_(new Implementation(pConsumer)) +{ } + +BluefishPlaybackStrategy::~BluefishPlaybackStrategy() +{ } +// +//FrameConsumer* BluefishPlaybackStrategy::GetConsumer() +//{ +// return pImpl_->pConsumer_; +//} +// +//frame_ptr BluefishPlaybackStrategy::GetReservedFrame() { +// return pImpl_->GetReservedFrame(); +//} + +void BluefishPlaybackStrategy::display(const frame_ptr& frame) +{ + return pImpl_->DisplayFrame(frame); +} + +} //namespace bluefish +} //namespace caspar \ No newline at end of file diff --git a/core/consumer/bluefish/BluefishPlaybackStrategy.h b/core/consumer/bluefish/BluefishPlaybackStrategy.h new file mode 100644 index 000000000..271e0c1ad --- /dev/null +++ b/core/consumer/bluefish/BluefishPlaybackStrategy.h @@ -0,0 +1,44 @@ +/* +* copyright (c) 2010 Sveriges Television AB +* +* This file is part of CasparCG. +* +* CasparCG is free software: you can redistribute it and/or modify +* it under the terms of the GNU General Public License as published by +* the Free Software Foundation, either version 3 of the License, or +* (at your option) any later version. +* +* CasparCG is distributed in the hope that it will be useful, +* but WITHOUT ANY WARRANTY; without even the implied warranty of +* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +* GNU General Public License for more details. + +* You should have received a copy of the GNU General Public License +* along with CasparCG. If not, see . +* +*/ + +#pragma once + +#include "../../frame/frame.h" +#include "../../consumer/frame_consumer.h" + +namespace caspar { +namespace bluefish { + +class BlueFishVideoConsumer; + +class BluefishPlaybackStrategy +{ + struct Implementation; + std::shared_ptr pImpl_; + +public: + explicit BluefishPlaybackStrategy(BlueFishVideoConsumer* pConsumer); + virtual ~BluefishPlaybackStrategy(); + + void display(const frame_ptr&); +}; + +} //namespace bluefish +} //namespace caspar diff --git a/core/consumer/decklink/DeckLinkAPI.idl b/core/consumer/decklink/DeckLinkAPI.idl new file mode 100644 index 000000000..0c055f70d --- /dev/null +++ b/core/consumer/decklink/DeckLinkAPI.idl @@ -0,0 +1,847 @@ +/* -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- +*/ + +/* DeckLinkAPI.idl */ + +import "unknwn.idl"; + +[uuid(D864517A-EDD5-466D-867D-C819F1C052BB), +version(1.0), helpstring("DeckLink API Library")] +library DeckLinkAPI +{ + +/* Type Declarations */ + +typedef LONGLONG BMDTimeValue; +typedef LONGLONG BMDTimeScale; +typedef unsigned long BMDTimecodeBCD; + +/* End Type Declarations */ + +/* Enumeration Mapping */ + +cpp_quote("typedef unsigned long BMDFrameFlags;") +cpp_quote("typedef unsigned long BMDVideoInputFlags;") +cpp_quote("typedef unsigned long BMDVideoInputFormatChangedEvents;") +cpp_quote("typedef unsigned long BMDDetectedVideoInputFormatFlags;") +cpp_quote("typedef unsigned long BMDTimecodeFlags;") +cpp_quote("typedef unsigned long BMDAnalogVideoFlags;") +cpp_quote("#if 0") +typedef enum _BMDFrameFlags BMDFrameFlags; +typedef enum _BMDVideoInputFlags BMDVideoInputFlags; +typedef enum _BMDVideoInputFormatChangedEvents BMDVideoInputFormatChangedEvents; +typedef enum _BMDDetectedVideoInputFormatFlags BMDDetectedVideoInputFormatFlags; +typedef enum _BMDTimecodeFlags BMDTimecodeFlags; +typedef enum _BMDAnalogVideoFlags BMDAnalogVideoFlags; +cpp_quote("#endif") + +/* End Enumeration Mapping */ + +/* Enum BMDDisplayMode - Video display modes */ + +typedef [v1_enum] enum _BMDDisplayMode { + bmdModeNTSC = /* 'ntsc' */ 0x6E747363, + bmdModeNTSC2398 = /* 'nt23' */ 0x6E743233, // 3:2 pulldown + bmdModePAL = /* 'pal ' */ 0x70616C20, + + /* HD 1080 Modes */ + + bmdModeHD1080p2398 = /* '23ps' */ 0x32337073, + bmdModeHD1080p24 = /* '24ps' */ 0x32347073, + bmdModeHD1080p25 = /* 'Hp25' */ 0x48703235, + bmdModeHD1080p2997 = /* 'Hp29' */ 0x48703239, + bmdModeHD1080p30 = /* 'Hp30' */ 0x48703330, + bmdModeHD1080i50 = /* 'Hi50' */ 0x48693530, + bmdModeHD1080i5994 = /* 'Hi59' */ 0x48693539, + bmdModeHD1080i6000 = /* 'Hi60' */ 0x48693630, // N.B. This _really_ is 60.00 Hz. + bmdModeHD1080p50 = /* 'Hp50' */ 0x48703530, + bmdModeHD1080p5994 = /* 'Hp59' */ 0x48703539, + bmdModeHD1080p6000 = /* 'Hp60' */ 0x48703630, // N.B. This _really_ is 60.00 Hz. + + /* HD 720 Modes */ + + bmdModeHD720p50 = /* 'hp50' */ 0x68703530, + bmdModeHD720p5994 = /* 'hp59' */ 0x68703539, + bmdModeHD720p60 = /* 'hp60' */ 0x68703630, + + /* 2k Modes */ + + bmdMode2k2398 = /* '2k23' */ 0x326B3233, + bmdMode2k24 = /* '2k24' */ 0x326B3234, + bmdMode2k25 = /* '2k25' */ 0x326B3235 +} BMDDisplayMode; + +/* End Enum BMDDisplayMode */ + +/* Enum BMDFieldDominance - Video field dominance */ + +typedef [v1_enum] enum _BMDFieldDominance { + bmdUnknownFieldDominance = 0, + bmdLowerFieldFirst = /* 'lowr' */ 0x6C6F7772, + bmdUpperFieldFirst = /* 'uppr' */ 0x75707072, + bmdProgressiveFrame = /* 'prog' */ 0x70726F67, + bmdProgressiveSegmentedFrame = /* 'psf ' */ 0x70736620 +} BMDFieldDominance; + +/* End Enum BMDFieldDominance */ + +/* Enum BMDPixelFormat - Video pixel formats supported for output/input */ + +typedef [v1_enum] enum _BMDPixelFormat { + bmdFormat8BitYUV = /* '2vuy' */ 0x32767579, + bmdFormat10BitYUV = /* 'v210' */ 0x76323130, + bmdFormat8BitARGB = 0x20, + bmdFormat8BitBGRA = /* 'BGRA' */ 0x42475241, + bmdFormat10BitRGB = /* 'r210' */ 0x72323130 +} BMDPixelFormat; + +/* End Enum BMDPixelFormat */ + +/* Enum BMDVideoOutputFlags - Flags to control the output of ancillary data along with video. */ + +typedef [v1_enum] enum _BMDVideoOutputFlags { + bmdVideoOutputFlagDefault = 0, + bmdVideoOutputRP188 = 1 << 0, + bmdVideoOutputVANC = 1 << 1 +} BMDVideoOutputFlags; + +/* End Enum BMDVideoOutputFlags */ + +/* Enum BMDFrameFlags - Frame flags */ + +[v1_enum] enum _BMDFrameFlags { + bmdFrameFlagDefault = 0, + bmdFrameFlagFlipVertical = 1 << 0, + + /* Flags that are valid only for frames returned through IDeckLinkInput */ + + bmdFrameHasNoInputSource = 1 << 31 +}; + +/* End Enum BMDFrameFlags */ + +/* Enum BMDVideoInputFlags - Flags applicable to video input */ + +[v1_enum] enum _BMDVideoInputFlags { + bmdVideoInputFlagDefault = 0, + bmdVideoInputEnableFormatDetection = 1 << 0 +}; + +/* End Enum BMDVideoInputFlags */ + +/* Enum BMDVideoInputFormatChangedEvents - Bitmask passed to the VideoInputFormatChanged notification to identify the properties of the input signal that have changed */ + +[v1_enum] enum _BMDVideoInputFormatChangedEvents { + bmdVideoInputDisplayModeChanged = 1 << 0, + bmdVideoInputFieldDominanceChanged = 1 << 1, + bmdVideoInputColorspaceChanged = 1 << 2 +}; + +/* End Enum BMDVideoInputFormatChangedEvents */ + +/* Enum BMDDetectedVideoInputFormatFlags - Flags passed to the VideoInputFormatChanged notification to describe the detected video input signal */ + +[v1_enum] enum _BMDDetectedVideoInputFormatFlags { + bmdDetectedVideoInputYCbCr422 = 1 << 0, + bmdDetectedVideoInputRGB444 = 1 << 1 +}; + +/* End Enum BMDDetectedVideoInputFormatFlags */ + +/* Enum BMDOutputFrameCompletionResult - Frame Completion Callback */ + +typedef [v1_enum] enum _BMDOutputFrameCompletionResult { + bmdOutputFrameCompleted, + bmdOutputFrameDisplayedLate, + bmdOutputFrameDropped, + bmdOutputFrameFlushed +} BMDOutputFrameCompletionResult; + +/* End Enum BMDOutputFrameCompletionResult */ + +/* Enum BMDAudioSampleRate - Audio sample rates supported for output/input */ + +typedef [v1_enum] enum _BMDAudioSampleRate { + bmdAudioSampleRate48kHz = 48000 +} BMDAudioSampleRate; + +/* End Enum BMDAudioSampleRate */ + +/* Enum BMDAudioSampleType - Audio sample sizes supported for output/input */ + +typedef [v1_enum] enum _BMDAudioSampleType { + bmdAudioSampleType16bitInteger = 16, + bmdAudioSampleType32bitInteger = 32 +} BMDAudioSampleType; + +/* End Enum BMDAudioSampleType */ + +/* Enum BMDAudioOutputStreamType - Audio output stream type */ + +typedef [v1_enum] enum _BMDAudioOutputStreamType { + bmdAudioOutputStreamContinuous, + bmdAudioOutputStreamContinuousDontResample, + bmdAudioOutputStreamTimestamped +} BMDAudioOutputStreamType; + +/* End Enum BMDAudioOutputStreamType */ + +/* Enum BMDDisplayModeSupport - Output mode supported flags */ + +typedef [v1_enum] enum _BMDDisplayModeSupport { + bmdDisplayModeNotSupported = 0, + bmdDisplayModeSupported, + bmdDisplayModeSupportedWithConversion +} BMDDisplayModeSupport; + +/* End Enum BMDDisplayModeSupport */ + +/* Enum BMDTimecodeFormat - Timecode formats for frame metadata */ + +typedef [v1_enum] enum _BMDTimecodeFormat { + bmdTimecodeRP188 = /* 'rp18' */ 0x72703138, + bmdTimecodeVITC = /* 'vitc' */ 0x76697463, + bmdTimecodeSerial = /* 'seri' */ 0x73657269 +} BMDTimecodeFormat; + +/* End Enum BMDTimecodeFormat */ + +/* Enum BMDTimecodeFlags - Timecode flags */ + +[v1_enum] enum _BMDTimecodeFlags { + bmdTimecodeFlagDefault = 0, + bmdTimecodeIsDropFrame = 1 << 0 +}; + +/* End Enum BMDTimecodeFlags */ + +/* Enum BMDVideoConnection - Video connection types */ + +typedef [v1_enum] enum _BMDVideoConnection { + bmdVideoConnectionSDI = /* 'sdi ' */ 0x73646920, + bmdVideoConnectionHDMI = /* 'hdmi' */ 0x68646D69, + bmdVideoConnectionOpticalSDI = /* 'opti' */ 0x6F707469, + bmdVideoConnectionComponent = /* 'cpnt' */ 0x63706E74, + bmdVideoConnectionComposite = /* 'cmst' */ 0x636D7374, + bmdVideoConnectionSVideo = /* 'svid' */ 0x73766964 +} BMDVideoConnection; + +/* End Enum BMDVideoConnection */ + +/* Enum BMDAnalogVideoFlags - Analog video display flags */ + +[v1_enum] enum _BMDAnalogVideoFlags { + bmdAnalogVideoFlagCompositeSetup75 = 1 << 0, + bmdAnalogVideoFlagComponentBetacamLevels = 1 << 1 +}; + +/* End Enum BMDAnalogVideoFlags */ + +/* Enum BMDAudioConnection - Audio connection types */ + +typedef [v1_enum] enum _BMDAudioConnection { + bmdAudioConnectionEmbedded = /* 'embd' */ 0x656D6264, + bmdAudioConnectionAESEBU = /* 'aes ' */ 0x61657320, + bmdAudioConnectionAnalog = /* 'anlg' */ 0x616E6C67 +} BMDAudioConnection; + +/* End Enum BMDAudioConnection */ + +/* Enum BMDVideoOutputConversionMode - Video/audio conversion mode */ + +typedef [v1_enum] enum _BMDVideoOutputConversionMode { + bmdNoVideoOutputConversion = /* 'none' */ 0x6E6F6E65, + bmdVideoOutputLetterboxDownonversion = /* 'ltbx' */ 0x6C746278, + bmdVideoOutputAnamorphicDownonversion = /* 'amph' */ 0x616D7068, + bmdVideoOutputHD720toHD1080Conversion = /* '720c' */ 0x37323063, + bmdVideoOutputHardwareLetterboxDownconversion = /* 'HWlb' */ 0x48576C62, + bmdVideoOutputHardwareAnamorphicDownconversion = /* 'HWam' */ 0x4857616D, + bmdVideoOutputHardwareCenterCutDownconversion = /* 'HWcc' */ 0x48576363 +} BMDVideoOutputConversionMode; + +/* End Enum BMDVideoOutputConversionMode */ + +/* Enum BMDVideoInputConversionMode - Video input conversion mode */ + +typedef [v1_enum] enum _BMDVideoInputConversionMode { + bmdNoVideoInputConversion = /* 'none' */ 0x6E6F6E65, + bmdVideoInputLetterboxDownconversionFromHD1080 = /* '10lb' */ 0x31306C62, + bmdVideoInputAnamorphicDownconversionFromHD1080 = /* '10am' */ 0x3130616D, + bmdVideoInputLetterboxDownconversionFromHD720 = /* '72lb' */ 0x37326C62, + bmdVideoInputAnamorphicDownconversionFromHD720 = /* '72am' */ 0x3732616D, + bmdVideoInputLetterboxUpconversion = /* 'lbup' */ 0x6C627570, + bmdVideoInputAnamorphicUpconversion = /* 'amup' */ 0x616D7570 +} BMDVideoInputConversionMode; + +/* End Enum BMDVideoInputConversionMode */ + +/* Enum BMDDeckLinkAttributeID - DeckLink Atribute ID */ + +typedef [v1_enum] enum _BMDDeckLinkAttributeID { + + /* Flags */ + + BMDDeckLinkSupportsInternalKeying = /* 'keyi' */ 0x6B657969, + BMDDeckLinkSupportsExternalKeying = /* 'keye' */ 0x6B657965, + BMDDeckLinkSupportsHDKeying = /* 'keyh' */ 0x6B657968, + BMDDeckLinkSupportsInputFormatDetection = /* 'infd' */ 0x696E6664, + BMDDeckLinkHasSerialPort = /* 'hspt' */ 0x68737074, + + /* Integers */ + + BMDDeckLinkMaximumAudioChannels = /* 'mach' */ 0x6D616368, + + /* Strings */ + + BMDDeckLinkSerialPortDeviceName = /* 'slpn' */ 0x736C706E +} BMDDeckLinkAttributeID; + +/* End Enum BMDDeckLinkAttributeID */ + +/* Enum BMDDeckLinkAPIInformationID - DeckLinkAPI information ID */ + +typedef [v1_enum] enum _BMDDeckLinkAPIInformationID { + BMDDeckLinkAPIVersion = /* 'vers' */ 0x76657273 +} BMDDeckLinkAPIInformationID; + +/* End Enum BMDDeckLinkAPIInformationID */ + +/* Forward Declarations */ + +interface IDeckLinkVideoOutputCallback; +interface IDeckLinkInputCallback; +interface IDeckLinkMemoryAllocator; +interface IDeckLinkAudioOutputCallback; +interface IDeckLinkIterator; +interface IDeckLinkAPIInformation; +interface IDeckLinkDisplayModeIterator; +interface IDeckLinkDisplayMode; +interface IDeckLink; +interface IDeckLinkOutput; +interface IDeckLinkInput; +interface IDeckLinkTimecode; +interface IDeckLinkVideoFrame; +interface IDeckLinkMutableVideoFrame; +interface IDeckLinkVideoInputFrame; +interface IDeckLinkVideoFrameAncillary; +interface IDeckLinkAudioInputPacket; +interface IDeckLinkScreenPreviewCallback; +interface IDeckLinkGLScreenPreviewHelper; +interface IDeckLinkConfiguration; +interface IDeckLinkAttributes; +interface IDeckLinkKeyer; + +/* End Forward Declarations */ + +/* Interface IDeckLinkVideoOutputCallback - Frame completion callback. */ + +[ + object, + uuid(E763A626-4A3C-49D1-BF13-E7AD3692AE52), + helpstring("Frame completion callback.") +] interface IDeckLinkVideoOutputCallback : IUnknown +{ + HRESULT ScheduledFrameCompleted([in] IDeckLinkVideoFrame *completedFrame, [in] BMDOutputFrameCompletionResult result); + HRESULT ScheduledPlaybackHasStopped(void); +}; + +/* End Interface IDeckLinkVideoOutputCallback */ + +/* Interface IDeckLinkInputCallback - Frame arrival callback. */ + +[ + object, + uuid(31D28EE7-88B6-4CB1-897A-CDBF79A26414), + helpstring("Frame arrival callback.") +] interface IDeckLinkInputCallback : IUnknown +{ + HRESULT VideoInputFormatChanged([in] BMDVideoInputFormatChangedEvents notificationEvents, [in] IDeckLinkDisplayMode *newDisplayMode, [in] BMDDetectedVideoInputFormatFlags detectedSignalFlags); + HRESULT VideoInputFrameArrived([in] IDeckLinkVideoInputFrame *videoFrame, [in] IDeckLinkAudioInputPacket *audioPacket); +}; + +/* End Interface IDeckLinkInputCallback */ + +/* Interface IDeckLinkMemoryAllocator - Memory allocator for video frames. */ + +[ + object, + uuid(B36EB6E7-9D29-4AA8-92EF-843B87A289E8), + local, + helpstring("Memory allocator for video frames.") +] interface IDeckLinkMemoryAllocator : IUnknown +{ + HRESULT AllocateBuffer(unsigned long bufferSize, [out] void **allocatedBuffer); + HRESULT ReleaseBuffer([in] void *buffer); + + HRESULT Commit(void); + HRESULT Decommit(void); +}; + +/* End Interface IDeckLinkMemoryAllocator */ + +/* Interface IDeckLinkAudioOutputCallback - Optional callback to allow audio samples to be pulled as required. */ + +[ + object, + uuid(403C681B-7F46-4A12-B993-2BB127084EE6), + local, + helpstring("Optional callback to allow audio samples to be pulled as required.") +] interface IDeckLinkAudioOutputCallback : IUnknown +{ + HRESULT RenderAudioSamples(BOOL preroll); +}; + +/* End Interface IDeckLinkAudioOutputCallback */ + +/* Interface IDeckLinkIterator - enumerates installed DeckLink hardware */ + +[ + object, + uuid(74E936FC-CC28-4A67-81A0-1E94E52D4E69), + helpstring("enumerates installed DeckLink hardware") +] interface IDeckLinkIterator : IUnknown +{ + HRESULT Next([out] IDeckLink **deckLinkInstance); +}; + +/* End Interface IDeckLinkIterator */ + +/* Interface IDeckLinkAPIInformation - DeckLinkAPI attribute interface */ + +[ + object, + uuid(7BEA3C68-730D-4322-AF34-8A7152B532A4), + helpstring("DeckLinkAPI attribute interface") +] interface IDeckLinkAPIInformation : IUnknown +{ + HRESULT GetFlag([in] BMDDeckLinkAPIInformationID cfgID, [out] BOOL *value); + HRESULT GetInt([in] BMDDeckLinkAPIInformationID cfgID, [out] LONGLONG *value); + HRESULT GetFloat([in] BMDDeckLinkAPIInformationID cfgID, [out] double *value); + HRESULT GetString([in] BMDDeckLinkAPIInformationID cfgID, [out] BSTR *value); +}; + +/* End Interface IDeckLinkAPIInformation */ + +/* Interface IDeckLinkDisplayModeIterator - enumerates over supported input/output display modes. */ + +[ + object, + uuid(455D741F-1779-4800-86F5-0B5D13D79751), + helpstring("enumerates over supported input/output display modes.") +] interface IDeckLinkDisplayModeIterator : IUnknown +{ + HRESULT Next([out] IDeckLinkDisplayMode **deckLinkDisplayMode); +}; + +/* End Interface IDeckLinkDisplayModeIterator */ + +/* Interface IDeckLinkDisplayMode - represents a display mode */ + +[ + object, + uuid(87451E84-2B7E-439E-A629-4393EA4A8550), + helpstring("represents a display mode") +] interface IDeckLinkDisplayMode : IUnknown +{ + HRESULT GetName([out] BSTR *name); + BMDDisplayMode GetDisplayMode(void); + long GetWidth(void); + long GetHeight(void); + HRESULT GetFrameRate([out] BMDTimeValue *frameDuration, [out] BMDTimeScale *timeScale); + BMDFieldDominance GetFieldDominance(void); +}; + +/* End Interface IDeckLinkDisplayMode */ + +/* Interface IDeckLink - represents a DeckLink device */ + +[ + object, + uuid(62BFF75D-6569-4E55-8D4D-66AA03829ABC), + helpstring("represents a DeckLink device") +] interface IDeckLink : IUnknown +{ + HRESULT GetModelName([out] BSTR *modelName); +}; + +/* End Interface IDeckLink */ + +/* Interface IDeckLinkOutput - Created by QueryInterface from IDeckLink. */ + +[ + object, + uuid(29228142-EB8C-4141-A621-F74026450955), + local, + helpstring("Created by QueryInterface from IDeckLink.") +] interface IDeckLinkOutput : 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 GetScheduledStreamTime(BMDTimeScale desiredTimeScale, [out] BMDTimeValue *streamTime, [out] double *playbackSpeed); + + /* Hardware Timing */ + + HRESULT GetHardwareReferenceClock(BMDTimeScale desiredTimeScale, [out] BMDTimeValue *hardwareTime, [out] BMDTimeValue *timeInFrame, [out] BMDTimeValue *ticksPerFrame); +}; + +/* End Interface IDeckLinkOutput */ + +/* Interface IDeckLinkInput - Created by QueryInterface from IDeckLink. */ + +[ + object, + uuid(300C135A-9F43-48E2-9906-6D7911D93CF1), + helpstring("Created by QueryInterface from IDeckLink.") +] interface IDeckLinkInput : 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 *theCallback); + + /* Hardware Timing */ + + HRESULT GetHardwareReferenceClock(BMDTimeScale desiredTimeScale, [out] BMDTimeValue *hardwareTime, [out] BMDTimeValue *timeInFrame, [out] BMDTimeValue *ticksPerFrame); +}; + +/* End Interface IDeckLinkInput */ + +/* Interface IDeckLinkTimecode - Used for video frame timecode representation. */ + +[ + object, + uuid(EFB9BCA6-A521-44F7-BD69-2332F24D9EE6), + helpstring("Used for video frame timecode representation.") +] interface IDeckLinkTimecode : IUnknown +{ + BMDTimecodeBCD GetBCD(void); + HRESULT GetComponents([out] unsigned char *hours, [out] unsigned char *minutes, [out] unsigned char *seconds, [out] unsigned char *frames); + HRESULT GetString([out] BSTR *timecode); + BMDTimecodeFlags GetFlags(void); +}; + +/* End Interface IDeckLinkTimecode */ + +/* Interface IDeckLinkVideoFrame - Interface to encapsulate a video frame; can be caller-implemented. */ + +[ + object, + uuid(A8D8238E-6B18-4196-99E1-5AF717B83D32), + local, + helpstring("Interface to encapsulate a video frame; can be caller-implemented.") +] interface IDeckLinkVideoFrame : IUnknown +{ + long GetWidth(void); + long GetHeight(void); + long GetRowBytes(void); + BMDPixelFormat GetPixelFormat(void); + BMDFrameFlags GetFlags(void); + HRESULT GetBytes([out] void **buffer); + + HRESULT GetTimecode(BMDTimecodeFormat format, [out] IDeckLinkTimecode **timecode); + HRESULT GetAncillaryData([out] IDeckLinkVideoFrameAncillary **ancillary); +}; + +/* End Interface IDeckLinkVideoFrame */ + +/* Interface IDeckLinkMutableVideoFrame - Created by IDeckLinkOutput::CreateVideoFrame. */ + +[ + object, + uuid(46FCEE00-B4E6-43D0-91C0-023A7FCEB34F), + local, + helpstring("Created by IDeckLinkOutput::CreateVideoFrame.") +] interface IDeckLinkMutableVideoFrame : IDeckLinkVideoFrame +{ + HRESULT SetFlags(BMDFrameFlags newFlags); + + HRESULT SetTimecode(BMDTimecodeFormat format, [in] IDeckLinkTimecode *timecode); + HRESULT SetTimecodeFromComponents(BMDTimecodeFormat format, unsigned char hours, unsigned char minutes, unsigned char seconds, unsigned char frames, BMDTimecodeFlags flags); + HRESULT SetAncillaryData([in] IDeckLinkVideoFrameAncillary *ancillary); +}; + +/* End Interface IDeckLinkMutableVideoFrame */ + +/* Interface IDeckLinkVideoInputFrame - Provided by the IDeckLinkVideoInput frame arrival callback. */ + +[ + object, + uuid(9A74FA41-AE9F-47AC-8CF4-01F42DD59965), + local, + helpstring("Provided by the IDeckLinkVideoInput frame arrival callback.") +] interface IDeckLinkVideoInputFrame : IDeckLinkVideoFrame +{ + HRESULT GetStreamTime([out] BMDTimeValue *frameTime, [out] BMDTimeValue *frameDuration, BMDTimeScale timeScale); + HRESULT GetHardwareReferenceTimestamp(BMDTimeScale timeScale, [out] BMDTimeValue *frameTime, [out] BMDTimeValue *frameDuration); +}; + +/* End Interface IDeckLinkVideoInputFrame */ + +/* Interface IDeckLinkVideoFrameAncillary - Obtained through QueryInterface() on an IDeckLinkVideoFrame object. */ + +[ + object, + uuid(732E723C-D1A4-4E29-9E8E-4A88797A0004), + local, + helpstring("Obtained through QueryInterface() on an IDeckLinkVideoFrame object.") +] interface IDeckLinkVideoFrameAncillary : IUnknown +{ + + HRESULT GetBufferForVerticalBlankingLine(unsigned long lineNumber, [out] void **buffer); + BMDPixelFormat GetPixelFormat(void); + BMDDisplayMode GetDisplayMode(void); +}; + +/* End Interface IDeckLinkVideoFrameAncillary */ + +/* Interface IDeckLinkAudioInputPacket - Provided by the IDeckLinkInput callback. */ + +[ + object, + uuid(E43D5870-2894-11DE-8C30-0800200C9A66), + local, + helpstring("Provided by the IDeckLinkInput callback.") +] interface IDeckLinkAudioInputPacket : IUnknown +{ + long GetSampleFrameCount(void); + HRESULT GetBytes([out] void **buffer); + HRESULT GetPacketTime([out] BMDTimeValue *packetTime, BMDTimeScale timeScale); +}; + +/* End Interface IDeckLinkAudioInputPacket */ + +/* Interface IDeckLinkScreenPreviewCallback - Screen preview callback */ + +[ + object, + uuid(373F499D-4B4D-4518-AD22-6354E5A5825E), + local, + helpstring("Screen preview callback") +] interface IDeckLinkScreenPreviewCallback : IUnknown +{ + HRESULT DrawFrame([in] IDeckLinkVideoFrame *theFrame); +}; + +/* End Interface IDeckLinkScreenPreviewCallback */ + +/* Interface IDeckLinkGLScreenPreviewHelper - Created with CoCreateInstance(). */ + +[ + object, + uuid(BA575CD9-A15E-497B-B2C2-F9AFE7BE4EBA), + local, + helpstring("Created with CoCreateInstance().") +] interface IDeckLinkGLScreenPreviewHelper : IUnknown +{ + + /* Methods must be called with OpenGL context set */ + + HRESULT InitializeGL(void); + HRESULT PaintGL(void); + HRESULT SetFrame([in] IDeckLinkVideoFrame *theFrame); +}; + +/* End Interface IDeckLinkGLScreenPreviewHelper */ + +/* Interface IDeckLinkConfiguration - Created by QueryInterface from IDeckLink. */ + +[ + object, + uuid(B8EAD569-B764-47F0-A73F-AE40DF6CBF10), + helpstring("Created by QueryInterface from IDeckLink.") +] interface IDeckLinkConfiguration : IUnknown +{ + HRESULT GetConfigurationValidator([out] IDeckLinkConfiguration **configObject); + HRESULT WriteConfigurationToPreferences(void); + + /* Video Output Configuration */ + + HRESULT SetVideoOutputFormat(BMDVideoConnection videoOutputConnection); + HRESULT IsVideoOutputActive(BMDVideoConnection videoOutputConnection, [out] BOOL *active); + + HRESULT SetAnalogVideoOutputFlags(BMDAnalogVideoFlags analogVideoFlags); + HRESULT GetAnalogVideoOutputFlags([out] BMDAnalogVideoFlags *analogVideoFlags); + + HRESULT EnableFieldFlickerRemovalWhenPaused(BOOL enable); + HRESULT IsEnabledFieldFlickerRemovalWhenPaused([out] BOOL *enabled); + + HRESULT Set444And3GBpsVideoOutput(BOOL enable444VideoOutput, BOOL enable3GbsOutput); + HRESULT Get444And3GBpsVideoOutput([out] BOOL *is444VideoOutputEnabled, [out] BOOL *threeGbsOutputEnabled); + + HRESULT SetVideoOutputConversionMode(BMDVideoOutputConversionMode conversionMode); + HRESULT GetVideoOutputConversionMode([out] BMDVideoOutputConversionMode *conversionMode); + + HRESULT Set_HD1080p24_to_HD1080i5994_Conversion(BOOL enable); + HRESULT Get_HD1080p24_to_HD1080i5994_Conversion([out] BOOL *enabled); + + /* Video Input Configuration */ + + HRESULT SetVideoInputFormat(BMDVideoConnection videoInputFormat); + HRESULT GetVideoInputFormat([out] BMDVideoConnection *videoInputFormat); + + HRESULT SetAnalogVideoInputFlags(BMDAnalogVideoFlags analogVideoFlags); + HRESULT GetAnalogVideoInputFlags([out] BMDAnalogVideoFlags *analogVideoFlags); + + HRESULT SetVideoInputConversionMode(BMDVideoInputConversionMode conversionMode); + HRESULT GetVideoInputConversionMode([out] BMDVideoInputConversionMode *conversionMode); + + HRESULT SetBlackVideoOutputDuringCapture(BOOL blackOutInCapture); + HRESULT GetBlackVideoOutputDuringCapture([out] BOOL *blackOutInCapture); + + HRESULT Set32PulldownSequenceInitialTimecodeFrame(unsigned long aFrameTimecode); + HRESULT Get32PulldownSequenceInitialTimecodeFrame([out] unsigned long *aFrameTimecode); + + HRESULT SetVancSourceLineMapping(unsigned long activeLine1VANCsource, unsigned long activeLine2VANCsource, unsigned long activeLine3VANCsource); + HRESULT GetVancSourceLineMapping([out] unsigned long *activeLine1VANCsource, [out] unsigned long *activeLine2VANCsource, [out] unsigned long *activeLine3VANCsource); + + /* Audio Input Configuration */ + + HRESULT SetAudioInputFormat(BMDAudioConnection audioInputFormat); + HRESULT GetAudioInputFormat([out] BMDAudioConnection *audioInputFormat); +}; + +/* End Interface IDeckLinkConfiguration */ + +/* Interface IDeckLinkAttributes - DeckLink Attribute interface */ + +[ + object, + uuid(ABC11843-D966-44CB-96E2-A1CB5D3135C4), + local, + helpstring("DeckLink Attribute interface") +] interface IDeckLinkAttributes : IUnknown +{ + HRESULT GetFlag([in] BMDDeckLinkAttributeID cfgID, [out] BOOL *value); + HRESULT GetInt([in] BMDDeckLinkAttributeID cfgID, [out] LONGLONG *value); + HRESULT GetFloat([in] BMDDeckLinkAttributeID cfgID, [out] double *value); + HRESULT GetString([in] BMDDeckLinkAttributeID cfgID, [out] BSTR *value); +}; + +/* End Interface IDeckLinkAttributes */ + +/* Interface IDeckLinkKeyer - DeckLink Keyer interface */ + +[ + object, + uuid(89AFCAF5-65F8-421E-98F7-96FE5F5BFBA3), + local, + helpstring("DeckLink Keyer interface") +] interface IDeckLinkKeyer : IUnknown +{ + HRESULT Enable([in] BOOL isExternal); + HRESULT SetLevel([in] unsigned char level); + HRESULT RampUp([in] unsigned long numberOfFrames); + HRESULT RampDown([in] unsigned long numberOfFrames); + HRESULT Disable(void); +}; + +/* End Interface IDeckLinkKeyer */ + +/* Coclasses */ + +importlib("stdole2.tlb"); + +[ + uuid(D9EDA3B3-2887-41FA-B724-017CF1EB1D37), + helpstring("CDeckLinkIterator Class") +] coclass CDeckLinkIterator +{ + [default] interface IDeckLinkIterator; +}; + +[ + uuid(D398CEE7-4434-4CA3-9BA6-5AE34556B905), + helpstring("CDeckLinkGLScreenPreviewHelper Class") +] coclass CDeckLinkGLScreenPreviewHelper +{ + [default] interface IDeckLinkGLScreenPreviewHelper; +}; + +/* End Coclasses */ + +// import deprecated interfaces +#include "DeckLinkAPI_v7_1.idl" +#include "DeckLinkAPI_v7_3.idl" +}; diff --git a/core/consumer/decklink/DeckLinkAPI_h.h b/core/consumer/decklink/DeckLinkAPI_h.h new file mode 100644 index 000000000..1321b0768 --- /dev/null +++ b/core/consumer/decklink/DeckLinkAPI_h.h @@ -0,0 +1,5584 @@ + + +/* this ALWAYS GENERATED file contains the definitions for the interfaces */ + + + /* File created by MIDL compiler version 7.00.0500 */ +/* at Wed Jan 13 09:58:01 2010 + */ +/* Compiler settings for .\consumers\declink\DeckLinkAPI.idl: + Oicf, W1, Zp8, env=Win32 (32b run) + protocol : dce , ms_ext, c_ext, robust + error checks: allocation ref bounds_check enum stub_data + VC __declspec() decoration level: + __declspec(uuid()), __declspec(selectany), __declspec(novtable) + DECLSPEC_UUID(), MIDL_INTERFACE() +*/ +//@@MIDL_FILE_HEADING( ) + +#pragma warning( disable: 4049 ) /* more than 64k source lines */ + + +/* verify that the version is high enough to compile this file*/ +#ifndef __REQUIRED_RPCNDR_H_VERSION__ +#define __REQUIRED_RPCNDR_H_VERSION__ 475 +#endif + +#include "rpc.h" +#include "rpcndr.h" + +#ifndef __RPCNDR_H_VERSION__ +#error this stub requires an updated version of +#endif // __RPCNDR_H_VERSION__ + + +#ifndef __DeckLinkAPI_h_h__ +#define __DeckLinkAPI_h_h__ + +#if defined(_MSC_VER) && (_MSC_VER >= 1020) +#pragma once +#endif + +/* Forward Declarations */ + +#ifndef __IDeckLinkVideoOutputCallback_FWD_DEFINED__ +#define __IDeckLinkVideoOutputCallback_FWD_DEFINED__ +typedef interface IDeckLinkVideoOutputCallback IDeckLinkVideoOutputCallback; +#endif /* __IDeckLinkVideoOutputCallback_FWD_DEFINED__ */ + + +#ifndef __IDeckLinkInputCallback_FWD_DEFINED__ +#define __IDeckLinkInputCallback_FWD_DEFINED__ +typedef interface IDeckLinkInputCallback IDeckLinkInputCallback; +#endif /* __IDeckLinkInputCallback_FWD_DEFINED__ */ + + +#ifndef __IDeckLinkMemoryAllocator_FWD_DEFINED__ +#define __IDeckLinkMemoryAllocator_FWD_DEFINED__ +typedef interface IDeckLinkMemoryAllocator IDeckLinkMemoryAllocator; +#endif /* __IDeckLinkMemoryAllocator_FWD_DEFINED__ */ + + +#ifndef __IDeckLinkAudioOutputCallback_FWD_DEFINED__ +#define __IDeckLinkAudioOutputCallback_FWD_DEFINED__ +typedef interface IDeckLinkAudioOutputCallback IDeckLinkAudioOutputCallback; +#endif /* __IDeckLinkAudioOutputCallback_FWD_DEFINED__ */ + + +#ifndef __IDeckLinkIterator_FWD_DEFINED__ +#define __IDeckLinkIterator_FWD_DEFINED__ +typedef interface IDeckLinkIterator IDeckLinkIterator; +#endif /* __IDeckLinkIterator_FWD_DEFINED__ */ + + +#ifndef __IDeckLinkAPIInformation_FWD_DEFINED__ +#define __IDeckLinkAPIInformation_FWD_DEFINED__ +typedef interface IDeckLinkAPIInformation IDeckLinkAPIInformation; +#endif /* __IDeckLinkAPIInformation_FWD_DEFINED__ */ + + +#ifndef __IDeckLinkDisplayModeIterator_FWD_DEFINED__ +#define __IDeckLinkDisplayModeIterator_FWD_DEFINED__ +typedef interface IDeckLinkDisplayModeIterator IDeckLinkDisplayModeIterator; +#endif /* __IDeckLinkDisplayModeIterator_FWD_DEFINED__ */ + + +#ifndef __IDeckLinkDisplayMode_FWD_DEFINED__ +#define __IDeckLinkDisplayMode_FWD_DEFINED__ +typedef interface IDeckLinkDisplayMode IDeckLinkDisplayMode; +#endif /* __IDeckLinkDisplayMode_FWD_DEFINED__ */ + + +#ifndef __IDeckLink_FWD_DEFINED__ +#define __IDeckLink_FWD_DEFINED__ +typedef interface IDeckLink IDeckLink; +#endif /* __IDeckLink_FWD_DEFINED__ */ + + +#ifndef __IDeckLinkOutput_FWD_DEFINED__ +#define __IDeckLinkOutput_FWD_DEFINED__ +typedef interface IDeckLinkOutput IDeckLinkOutput; +#endif /* __IDeckLinkOutput_FWD_DEFINED__ */ + + +#ifndef __IDeckLinkInput_FWD_DEFINED__ +#define __IDeckLinkInput_FWD_DEFINED__ +typedef interface IDeckLinkInput IDeckLinkInput; +#endif /* __IDeckLinkInput_FWD_DEFINED__ */ + + +#ifndef __IDeckLinkTimecode_FWD_DEFINED__ +#define __IDeckLinkTimecode_FWD_DEFINED__ +typedef interface IDeckLinkTimecode IDeckLinkTimecode; +#endif /* __IDeckLinkTimecode_FWD_DEFINED__ */ + + +#ifndef __IDeckLinkVideoFrame_FWD_DEFINED__ +#define __IDeckLinkVideoFrame_FWD_DEFINED__ +typedef interface IDeckLinkVideoFrame IDeckLinkVideoFrame; +#endif /* __IDeckLinkVideoFrame_FWD_DEFINED__ */ + + +#ifndef __IDeckLinkMutableVideoFrame_FWD_DEFINED__ +#define __IDeckLinkMutableVideoFrame_FWD_DEFINED__ +typedef interface IDeckLinkMutableVideoFrame IDeckLinkMutableVideoFrame; +#endif /* __IDeckLinkMutableVideoFrame_FWD_DEFINED__ */ + + +#ifndef __IDeckLinkVideoInputFrame_FWD_DEFINED__ +#define __IDeckLinkVideoInputFrame_FWD_DEFINED__ +typedef interface IDeckLinkVideoInputFrame IDeckLinkVideoInputFrame; +#endif /* __IDeckLinkVideoInputFrame_FWD_DEFINED__ */ + + +#ifndef __IDeckLinkVideoFrameAncillary_FWD_DEFINED__ +#define __IDeckLinkVideoFrameAncillary_FWD_DEFINED__ +typedef interface IDeckLinkVideoFrameAncillary IDeckLinkVideoFrameAncillary; +#endif /* __IDeckLinkVideoFrameAncillary_FWD_DEFINED__ */ + + +#ifndef __IDeckLinkAudioInputPacket_FWD_DEFINED__ +#define __IDeckLinkAudioInputPacket_FWD_DEFINED__ +typedef interface IDeckLinkAudioInputPacket IDeckLinkAudioInputPacket; +#endif /* __IDeckLinkAudioInputPacket_FWD_DEFINED__ */ + + +#ifndef __IDeckLinkScreenPreviewCallback_FWD_DEFINED__ +#define __IDeckLinkScreenPreviewCallback_FWD_DEFINED__ +typedef interface IDeckLinkScreenPreviewCallback IDeckLinkScreenPreviewCallback; +#endif /* __IDeckLinkScreenPreviewCallback_FWD_DEFINED__ */ + + +#ifndef __IDeckLinkGLScreenPreviewHelper_FWD_DEFINED__ +#define __IDeckLinkGLScreenPreviewHelper_FWD_DEFINED__ +typedef interface IDeckLinkGLScreenPreviewHelper IDeckLinkGLScreenPreviewHelper; +#endif /* __IDeckLinkGLScreenPreviewHelper_FWD_DEFINED__ */ + + +#ifndef __IDeckLinkConfiguration_FWD_DEFINED__ +#define __IDeckLinkConfiguration_FWD_DEFINED__ +typedef interface IDeckLinkConfiguration IDeckLinkConfiguration; +#endif /* __IDeckLinkConfiguration_FWD_DEFINED__ */ + + +#ifndef __IDeckLinkAttributes_FWD_DEFINED__ +#define __IDeckLinkAttributes_FWD_DEFINED__ +typedef interface IDeckLinkAttributes IDeckLinkAttributes; +#endif /* __IDeckLinkAttributes_FWD_DEFINED__ */ + + +#ifndef __IDeckLinkKeyer_FWD_DEFINED__ +#define __IDeckLinkKeyer_FWD_DEFINED__ +typedef interface IDeckLinkKeyer IDeckLinkKeyer; +#endif /* __IDeckLinkKeyer_FWD_DEFINED__ */ + + +#ifndef __CDeckLinkIterator_FWD_DEFINED__ +#define __CDeckLinkIterator_FWD_DEFINED__ + +#ifdef __cplusplus +typedef class CDeckLinkIterator CDeckLinkIterator; +#else +typedef struct CDeckLinkIterator CDeckLinkIterator; +#endif /* __cplusplus */ + +#endif /* __CDeckLinkIterator_FWD_DEFINED__ */ + + +#ifndef __CDeckLinkGLScreenPreviewHelper_FWD_DEFINED__ +#define __CDeckLinkGLScreenPreviewHelper_FWD_DEFINED__ + +#ifdef __cplusplus +typedef class CDeckLinkGLScreenPreviewHelper CDeckLinkGLScreenPreviewHelper; +#else +typedef struct CDeckLinkGLScreenPreviewHelper CDeckLinkGLScreenPreviewHelper; +#endif /* __cplusplus */ + +#endif /* __CDeckLinkGLScreenPreviewHelper_FWD_DEFINED__ */ + + +#ifndef __IDeckLinkDisplayModeIterator_v7_1_FWD_DEFINED__ +#define __IDeckLinkDisplayModeIterator_v7_1_FWD_DEFINED__ +typedef interface IDeckLinkDisplayModeIterator_v7_1 IDeckLinkDisplayModeIterator_v7_1; +#endif /* __IDeckLinkDisplayModeIterator_v7_1_FWD_DEFINED__ */ + + +#ifndef __IDeckLinkDisplayMode_v7_1_FWD_DEFINED__ +#define __IDeckLinkDisplayMode_v7_1_FWD_DEFINED__ +typedef interface IDeckLinkDisplayMode_v7_1 IDeckLinkDisplayMode_v7_1; +#endif /* __IDeckLinkDisplayMode_v7_1_FWD_DEFINED__ */ + + +#ifndef __IDeckLinkVideoFrame_v7_1_FWD_DEFINED__ +#define __IDeckLinkVideoFrame_v7_1_FWD_DEFINED__ +typedef interface IDeckLinkVideoFrame_v7_1 IDeckLinkVideoFrame_v7_1; +#endif /* __IDeckLinkVideoFrame_v7_1_FWD_DEFINED__ */ + + +#ifndef __IDeckLinkVideoInputFrame_v7_1_FWD_DEFINED__ +#define __IDeckLinkVideoInputFrame_v7_1_FWD_DEFINED__ +typedef interface IDeckLinkVideoInputFrame_v7_1 IDeckLinkVideoInputFrame_v7_1; +#endif /* __IDeckLinkVideoInputFrame_v7_1_FWD_DEFINED__ */ + + +#ifndef __IDeckLinkAudioInputPacket_v7_1_FWD_DEFINED__ +#define __IDeckLinkAudioInputPacket_v7_1_FWD_DEFINED__ +typedef interface IDeckLinkAudioInputPacket_v7_1 IDeckLinkAudioInputPacket_v7_1; +#endif /* __IDeckLinkAudioInputPacket_v7_1_FWD_DEFINED__ */ + + +#ifndef __IDeckLinkVideoOutputCallback_v7_1_FWD_DEFINED__ +#define __IDeckLinkVideoOutputCallback_v7_1_FWD_DEFINED__ +typedef interface IDeckLinkVideoOutputCallback_v7_1 IDeckLinkVideoOutputCallback_v7_1; +#endif /* __IDeckLinkVideoOutputCallback_v7_1_FWD_DEFINED__ */ + + +#ifndef __IDeckLinkInputCallback_v7_1_FWD_DEFINED__ +#define __IDeckLinkInputCallback_v7_1_FWD_DEFINED__ +typedef interface IDeckLinkInputCallback_v7_1 IDeckLinkInputCallback_v7_1; +#endif /* __IDeckLinkInputCallback_v7_1_FWD_DEFINED__ */ + + +#ifndef __IDeckLinkOutput_v7_1_FWD_DEFINED__ +#define __IDeckLinkOutput_v7_1_FWD_DEFINED__ +typedef interface IDeckLinkOutput_v7_1 IDeckLinkOutput_v7_1; +#endif /* __IDeckLinkOutput_v7_1_FWD_DEFINED__ */ + + +#ifndef __IDeckLinkInput_v7_1_FWD_DEFINED__ +#define __IDeckLinkInput_v7_1_FWD_DEFINED__ +typedef interface IDeckLinkInput_v7_1 IDeckLinkInput_v7_1; +#endif /* __IDeckLinkInput_v7_1_FWD_DEFINED__ */ + + +#ifndef __IDeckLinkInputCallback_v7_3_FWD_DEFINED__ +#define __IDeckLinkInputCallback_v7_3_FWD_DEFINED__ +typedef interface IDeckLinkInputCallback_v7_3 IDeckLinkInputCallback_v7_3; +#endif /* __IDeckLinkInputCallback_v7_3_FWD_DEFINED__ */ + + +#ifndef __IDeckLinkOutput_v7_3_FWD_DEFINED__ +#define __IDeckLinkOutput_v7_3_FWD_DEFINED__ +typedef interface IDeckLinkOutput_v7_3 IDeckLinkOutput_v7_3; +#endif /* __IDeckLinkOutput_v7_3_FWD_DEFINED__ */ + + +#ifndef __IDeckLinkInput_v7_3_FWD_DEFINED__ +#define __IDeckLinkInput_v7_3_FWD_DEFINED__ +typedef interface IDeckLinkInput_v7_3 IDeckLinkInput_v7_3; +#endif /* __IDeckLinkInput_v7_3_FWD_DEFINED__ */ + + +#ifndef __IDeckLinkVideoInputFrame_v7_3_FWD_DEFINED__ +#define __IDeckLinkVideoInputFrame_v7_3_FWD_DEFINED__ +typedef interface IDeckLinkVideoInputFrame_v7_3 IDeckLinkVideoInputFrame_v7_3; +#endif /* __IDeckLinkVideoInputFrame_v7_3_FWD_DEFINED__ */ + + +/* header files for imported files */ +#include "unknwn.h" + +#ifdef __cplusplus +extern "C"{ +#endif + + + +#ifndef __DeckLinkAPI_LIBRARY_DEFINED__ +#define __DeckLinkAPI_LIBRARY_DEFINED__ + +/* library DeckLinkAPI */ +/* [helpstring][version][uuid] */ + +typedef LONGLONG BMDTimeValue; + +typedef LONGLONG BMDTimeScale; + +typedef unsigned long BMDTimecodeBCD; + +typedef unsigned long BMDFrameFlags; +typedef unsigned long BMDVideoInputFlags; +typedef unsigned long BMDVideoInputFormatChangedEvents; +typedef unsigned long BMDDetectedVideoInputFormatFlags; +typedef unsigned long BMDTimecodeFlags; +typedef unsigned long BMDAnalogVideoFlags; +#if 0 +typedef enum _BMDFrameFlags BMDFrameFlags; + +typedef enum _BMDVideoInputFlags BMDVideoInputFlags; + +typedef enum _BMDVideoInputFormatChangedEvents BMDVideoInputFormatChangedEvents; + +typedef enum _BMDDetectedVideoInputFormatFlags BMDDetectedVideoInputFormatFlags; + +typedef enum _BMDTimecodeFlags BMDTimecodeFlags; + +typedef enum _BMDAnalogVideoFlags BMDAnalogVideoFlags; + +#endif +typedef /* [v1_enum] */ +enum _BMDDisplayMode + { bmdModeNTSC = 0x6e747363, + bmdModeNTSC2398 = 0x6e743233, + bmdModePAL = 0x70616c20, + bmdModeHD1080p2398 = 0x32337073, + bmdModeHD1080p24 = 0x32347073, + bmdModeHD1080p25 = 0x48703235, + bmdModeHD1080p2997 = 0x48703239, + bmdModeHD1080p30 = 0x48703330, + bmdModeHD1080i50 = 0x48693530, + bmdModeHD1080i5994 = 0x48693539, + bmdModeHD1080i6000 = 0x48693630, + bmdModeHD1080p50 = 0x48703530, + bmdModeHD1080p5994 = 0x48703539, + bmdModeHD1080p6000 = 0x48703630, + bmdModeHD720p50 = 0x68703530, + bmdModeHD720p5994 = 0x68703539, + bmdModeHD720p60 = 0x68703630, + bmdMode2k2398 = 0x326b3233, + bmdMode2k24 = 0x326b3234, + bmdMode2k25 = 0x326b3235 + } BMDDisplayMode; + +typedef /* [v1_enum] */ +enum _BMDFieldDominance + { bmdUnknownFieldDominance = 0, + bmdLowerFieldFirst = 0x6c6f7772, + bmdUpperFieldFirst = 0x75707072, + bmdProgressiveFrame = 0x70726f67, + bmdProgressiveSegmentedFrame = 0x70736620 + } BMDFieldDominance; + +typedef /* [v1_enum] */ +enum _BMDPixelFormat + { bmdFormat8BitYUV = 0x32767579, + bmdFormat10BitYUV = 0x76323130, + bmdFormat8BitARGB = 0x20, + bmdFormat8BitBGRA = 0x42475241, + bmdFormat10BitRGB = 0x72323130 + } BMDPixelFormat; + +typedef /* [v1_enum] */ +enum _BMDVideoOutputFlags + { bmdVideoOutputFlagDefault = 0, + bmdVideoOutputRP188 = ( 1 << 0 ) , + bmdVideoOutputVANC = ( 1 << 1 ) + } BMDVideoOutputFlags; + +/* [v1_enum] */ +enum _BMDFrameFlags + { bmdFrameFlagDefault = 0, + bmdFrameFlagFlipVertical = ( 1 << 0 ) , + bmdFrameHasNoInputSource = ( 1 << 31 ) + } ; +/* [v1_enum] */ +enum _BMDVideoInputFlags + { bmdVideoInputFlagDefault = 0, + bmdVideoInputEnableFormatDetection = ( 1 << 0 ) + } ; +/* [v1_enum] */ +enum _BMDVideoInputFormatChangedEvents + { bmdVideoInputDisplayModeChanged = ( 1 << 0 ) , + bmdVideoInputFieldDominanceChanged = ( 1 << 1 ) , + bmdVideoInputColorspaceChanged = ( 1 << 2 ) + } ; +/* [v1_enum] */ +enum _BMDDetectedVideoInputFormatFlags + { bmdDetectedVideoInputYCbCr422 = ( 1 << 0 ) , + bmdDetectedVideoInputRGB444 = ( 1 << 1 ) + } ; +typedef /* [v1_enum] */ +enum _BMDOutputFrameCompletionResult + { bmdOutputFrameCompleted = 0, + bmdOutputFrameDisplayedLate = ( bmdOutputFrameCompleted + 1 ) , + bmdOutputFrameDropped = ( bmdOutputFrameDisplayedLate + 1 ) , + bmdOutputFrameFlushed = ( bmdOutputFrameDropped + 1 ) + } BMDOutputFrameCompletionResult; + +typedef /* [v1_enum] */ +enum _BMDAudioSampleRate + { bmdAudioSampleRate48kHz = 48000 + } BMDAudioSampleRate; + +typedef /* [v1_enum] */ +enum _BMDAudioSampleType + { bmdAudioSampleType16bitInteger = 16, + bmdAudioSampleType32bitInteger = 32 + } BMDAudioSampleType; + +typedef /* [v1_enum] */ +enum _BMDAudioOutputStreamType + { bmdAudioOutputStreamContinuous = 0, + bmdAudioOutputStreamContinuousDontResample = ( bmdAudioOutputStreamContinuous + 1 ) , + bmdAudioOutputStreamTimestamped = ( bmdAudioOutputStreamContinuousDontResample + 1 ) + } BMDAudioOutputStreamType; + +typedef /* [v1_enum] */ +enum _BMDDisplayModeSupport + { bmdDisplayModeNotSupported = 0, + bmdDisplayModeSupported = ( bmdDisplayModeNotSupported + 1 ) , + bmdDisplayModeSupportedWithConversion = ( bmdDisplayModeSupported + 1 ) + } BMDDisplayModeSupport; + +typedef /* [v1_enum] */ +enum _BMDTimecodeFormat + { bmdTimecodeRP188 = 0x72703138, + bmdTimecodeVITC = 0x76697463, + bmdTimecodeSerial = 0x73657269 + } BMDTimecodeFormat; + +/* [v1_enum] */ +enum _BMDTimecodeFlags + { bmdTimecodeFlagDefault = 0, + bmdTimecodeIsDropFrame = ( 1 << 0 ) + } ; +typedef /* [v1_enum] */ +enum _BMDVideoConnection + { bmdVideoConnectionSDI = 0x73646920, + bmdVideoConnectionHDMI = 0x68646d69, + bmdVideoConnectionOpticalSDI = 0x6f707469, + bmdVideoConnectionComponent = 0x63706e74, + bmdVideoConnectionComposite = 0x636d7374, + bmdVideoConnectionSVideo = 0x73766964 + } BMDVideoConnection; + +/* [v1_enum] */ +enum _BMDAnalogVideoFlags + { bmdAnalogVideoFlagCompositeSetup75 = ( 1 << 0 ) , + bmdAnalogVideoFlagComponentBetacamLevels = ( 1 << 1 ) + } ; +typedef /* [v1_enum] */ +enum _BMDAudioConnection + { bmdAudioConnectionEmbedded = 0x656d6264, + bmdAudioConnectionAESEBU = 0x61657320, + bmdAudioConnectionAnalog = 0x616e6c67 + } BMDAudioConnection; + +typedef /* [v1_enum] */ +enum _BMDVideoOutputConversionMode + { bmdNoVideoOutputConversion = 0x6e6f6e65, + bmdVideoOutputLetterboxDownonversion = 0x6c746278, + bmdVideoOutputAnamorphicDownonversion = 0x616d7068, + bmdVideoOutputHD720toHD1080Conversion = 0x37323063, + bmdVideoOutputHardwareLetterboxDownconversion = 0x48576c62, + bmdVideoOutputHardwareAnamorphicDownconversion = 0x4857616d, + bmdVideoOutputHardwareCenterCutDownconversion = 0x48576363 + } BMDVideoOutputConversionMode; + +typedef /* [v1_enum] */ +enum _BMDVideoInputConversionMode + { bmdNoVideoInputConversion = 0x6e6f6e65, + bmdVideoInputLetterboxDownconversionFromHD1080 = 0x31306c62, + bmdVideoInputAnamorphicDownconversionFromHD1080 = 0x3130616d, + bmdVideoInputLetterboxDownconversionFromHD720 = 0x37326c62, + bmdVideoInputAnamorphicDownconversionFromHD720 = 0x3732616d, + bmdVideoInputLetterboxUpconversion = 0x6c627570, + bmdVideoInputAnamorphicUpconversion = 0x616d7570 + } BMDVideoInputConversionMode; + +typedef /* [v1_enum] */ +enum _BMDDeckLinkAttributeID + { BMDDeckLinkSupportsInternalKeying = 0x6b657969, + BMDDeckLinkSupportsExternalKeying = 0x6b657965, + BMDDeckLinkSupportsHDKeying = 0x6b657968, + BMDDeckLinkSupportsInputFormatDetection = 0x696e6664, + BMDDeckLinkHasSerialPort = 0x68737074, + BMDDeckLinkMaximumAudioChannels = 0x6d616368, + BMDDeckLinkSerialPortDeviceName = 0x736c706e + } BMDDeckLinkAttributeID; + +typedef /* [v1_enum] */ +enum _BMDDeckLinkAPIInformationID + { BMDDeckLinkAPIVersion = 0x76657273 + } BMDDeckLinkAPIInformationID; + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +EXTERN_C const IID LIBID_DeckLinkAPI; + +#ifndef __IDeckLinkVideoOutputCallback_INTERFACE_DEFINED__ +#define __IDeckLinkVideoOutputCallback_INTERFACE_DEFINED__ + +/* interface IDeckLinkVideoOutputCallback */ +/* [helpstring][uuid][object] */ + + +EXTERN_C const IID IID_IDeckLinkVideoOutputCallback; + +#if defined(__cplusplus) && !defined(CINTERFACE) + + MIDL_INTERFACE("E763A626-4A3C-49D1-BF13-E7AD3692AE52") + IDeckLinkVideoOutputCallback : public IUnknown + { + public: + virtual HRESULT STDMETHODCALLTYPE ScheduledFrameCompleted( + /* [in] */ IDeckLinkVideoFrame *completedFrame, + /* [in] */ BMDOutputFrameCompletionResult result) = 0; + + virtual HRESULT STDMETHODCALLTYPE ScheduledPlaybackHasStopped( void) = 0; + + }; + +#else /* C style interface */ + + typedef struct IDeckLinkVideoOutputCallbackVtbl + { + BEGIN_INTERFACE + + HRESULT ( STDMETHODCALLTYPE *QueryInterface )( + IDeckLinkVideoOutputCallback * This, + /* [in] */ REFIID riid, + /* [iid_is][out] */ + __RPC__deref_out void **ppvObject); + + ULONG ( STDMETHODCALLTYPE *AddRef )( + IDeckLinkVideoOutputCallback * This); + + ULONG ( STDMETHODCALLTYPE *Release )( + IDeckLinkVideoOutputCallback * This); + + HRESULT ( STDMETHODCALLTYPE *ScheduledFrameCompleted )( + IDeckLinkVideoOutputCallback * This, + /* [in] */ IDeckLinkVideoFrame *completedFrame, + /* [in] */ BMDOutputFrameCompletionResult result); + + HRESULT ( STDMETHODCALLTYPE *ScheduledPlaybackHasStopped )( + IDeckLinkVideoOutputCallback * This); + + END_INTERFACE + } IDeckLinkVideoOutputCallbackVtbl; + + interface IDeckLinkVideoOutputCallback + { + CONST_VTBL struct IDeckLinkVideoOutputCallbackVtbl *lpVtbl; + }; + + + +#ifdef COBJMACROS + + +#define IDeckLinkVideoOutputCallback_QueryInterface(This,riid,ppvObject) \ + ( (This)->lpVtbl -> QueryInterface(This,riid,ppvObject) ) + +#define IDeckLinkVideoOutputCallback_AddRef(This) \ + ( (This)->lpVtbl -> AddRef(This) ) + +#define IDeckLinkVideoOutputCallback_Release(This) \ + ( (This)->lpVtbl -> Release(This) ) + + +#define IDeckLinkVideoOutputCallback_ScheduledFrameCompleted(This,completedFrame,result) \ + ( (This)->lpVtbl -> ScheduledFrameCompleted(This,completedFrame,result) ) + +#define IDeckLinkVideoOutputCallback_ScheduledPlaybackHasStopped(This) \ + ( (This)->lpVtbl -> ScheduledPlaybackHasStopped(This) ) + +#endif /* COBJMACROS */ + + +#endif /* C style interface */ + + + + +#endif /* __IDeckLinkVideoOutputCallback_INTERFACE_DEFINED__ */ + + +#ifndef __IDeckLinkInputCallback_INTERFACE_DEFINED__ +#define __IDeckLinkInputCallback_INTERFACE_DEFINED__ + +/* interface IDeckLinkInputCallback */ +/* [helpstring][uuid][object] */ + + +EXTERN_C const IID IID_IDeckLinkInputCallback; + +#if defined(__cplusplus) && !defined(CINTERFACE) + + MIDL_INTERFACE("31D28EE7-88B6-4CB1-897A-CDBF79A26414") + IDeckLinkInputCallback : public IUnknown + { + public: + virtual HRESULT STDMETHODCALLTYPE VideoInputFormatChanged( + /* [in] */ BMDVideoInputFormatChangedEvents notificationEvents, + /* [in] */ IDeckLinkDisplayMode *newDisplayMode, + /* [in] */ BMDDetectedVideoInputFormatFlags detectedSignalFlags) = 0; + + virtual HRESULT STDMETHODCALLTYPE VideoInputFrameArrived( + /* [in] */ IDeckLinkVideoInputFrame *videoFrame, + /* [in] */ IDeckLinkAudioInputPacket *audioPacket) = 0; + + }; + +#else /* C style interface */ + + typedef struct IDeckLinkInputCallbackVtbl + { + BEGIN_INTERFACE + + HRESULT ( STDMETHODCALLTYPE *QueryInterface )( + IDeckLinkInputCallback * This, + /* [in] */ REFIID riid, + /* [iid_is][out] */ + __RPC__deref_out void **ppvObject); + + ULONG ( STDMETHODCALLTYPE *AddRef )( + IDeckLinkInputCallback * This); + + ULONG ( STDMETHODCALLTYPE *Release )( + IDeckLinkInputCallback * This); + + HRESULT ( STDMETHODCALLTYPE *VideoInputFormatChanged )( + IDeckLinkInputCallback * This, + /* [in] */ BMDVideoInputFormatChangedEvents notificationEvents, + /* [in] */ IDeckLinkDisplayMode *newDisplayMode, + /* [in] */ BMDDetectedVideoInputFormatFlags detectedSignalFlags); + + HRESULT ( STDMETHODCALLTYPE *VideoInputFrameArrived )( + IDeckLinkInputCallback * This, + /* [in] */ IDeckLinkVideoInputFrame *videoFrame, + /* [in] */ IDeckLinkAudioInputPacket *audioPacket); + + END_INTERFACE + } IDeckLinkInputCallbackVtbl; + + interface IDeckLinkInputCallback + { + CONST_VTBL struct IDeckLinkInputCallbackVtbl *lpVtbl; + }; + + + +#ifdef COBJMACROS + + +#define IDeckLinkInputCallback_QueryInterface(This,riid,ppvObject) \ + ( (This)->lpVtbl -> QueryInterface(This,riid,ppvObject) ) + +#define IDeckLinkInputCallback_AddRef(This) \ + ( (This)->lpVtbl -> AddRef(This) ) + +#define IDeckLinkInputCallback_Release(This) \ + ( (This)->lpVtbl -> Release(This) ) + + +#define IDeckLinkInputCallback_VideoInputFormatChanged(This,notificationEvents,newDisplayMode,detectedSignalFlags) \ + ( (This)->lpVtbl -> VideoInputFormatChanged(This,notificationEvents,newDisplayMode,detectedSignalFlags) ) + +#define IDeckLinkInputCallback_VideoInputFrameArrived(This,videoFrame,audioPacket) \ + ( (This)->lpVtbl -> VideoInputFrameArrived(This,videoFrame,audioPacket) ) + +#endif /* COBJMACROS */ + + +#endif /* C style interface */ + + + + +#endif /* __IDeckLinkInputCallback_INTERFACE_DEFINED__ */ + + +#ifndef __IDeckLinkMemoryAllocator_INTERFACE_DEFINED__ +#define __IDeckLinkMemoryAllocator_INTERFACE_DEFINED__ + +/* interface IDeckLinkMemoryAllocator */ +/* [helpstring][local][uuid][object] */ + + +EXTERN_C const IID IID_IDeckLinkMemoryAllocator; + +#if defined(__cplusplus) && !defined(CINTERFACE) + + MIDL_INTERFACE("B36EB6E7-9D29-4AA8-92EF-843B87A289E8") + IDeckLinkMemoryAllocator : public IUnknown + { + public: + virtual HRESULT STDMETHODCALLTYPE AllocateBuffer( + unsigned long bufferSize, + /* [out] */ void **allocatedBuffer) = 0; + + virtual HRESULT STDMETHODCALLTYPE ReleaseBuffer( + /* [in] */ void *buffer) = 0; + + virtual HRESULT STDMETHODCALLTYPE Commit( void) = 0; + + virtual HRESULT STDMETHODCALLTYPE Decommit( void) = 0; + + }; + +#else /* C style interface */ + + typedef struct IDeckLinkMemoryAllocatorVtbl + { + BEGIN_INTERFACE + + HRESULT ( STDMETHODCALLTYPE *QueryInterface )( + IDeckLinkMemoryAllocator * This, + /* [in] */ REFIID riid, + /* [iid_is][out] */ + __RPC__deref_out void **ppvObject); + + ULONG ( STDMETHODCALLTYPE *AddRef )( + IDeckLinkMemoryAllocator * This); + + ULONG ( STDMETHODCALLTYPE *Release )( + IDeckLinkMemoryAllocator * This); + + HRESULT ( STDMETHODCALLTYPE *AllocateBuffer )( + IDeckLinkMemoryAllocator * This, + unsigned long bufferSize, + /* [out] */ void **allocatedBuffer); + + HRESULT ( STDMETHODCALLTYPE *ReleaseBuffer )( + IDeckLinkMemoryAllocator * This, + /* [in] */ void *buffer); + + HRESULT ( STDMETHODCALLTYPE *Commit )( + IDeckLinkMemoryAllocator * This); + + HRESULT ( STDMETHODCALLTYPE *Decommit )( + IDeckLinkMemoryAllocator * This); + + END_INTERFACE + } IDeckLinkMemoryAllocatorVtbl; + + interface IDeckLinkMemoryAllocator + { + CONST_VTBL struct IDeckLinkMemoryAllocatorVtbl *lpVtbl; + }; + + + +#ifdef COBJMACROS + + +#define IDeckLinkMemoryAllocator_QueryInterface(This,riid,ppvObject) \ + ( (This)->lpVtbl -> QueryInterface(This,riid,ppvObject) ) + +#define IDeckLinkMemoryAllocator_AddRef(This) \ + ( (This)->lpVtbl -> AddRef(This) ) + +#define IDeckLinkMemoryAllocator_Release(This) \ + ( (This)->lpVtbl -> Release(This) ) + + +#define IDeckLinkMemoryAllocator_AllocateBuffer(This,bufferSize,allocatedBuffer) \ + ( (This)->lpVtbl -> AllocateBuffer(This,bufferSize,allocatedBuffer) ) + +#define IDeckLinkMemoryAllocator_ReleaseBuffer(This,buffer) \ + ( (This)->lpVtbl -> ReleaseBuffer(This,buffer) ) + +#define IDeckLinkMemoryAllocator_Commit(This) \ + ( (This)->lpVtbl -> Commit(This) ) + +#define IDeckLinkMemoryAllocator_Decommit(This) \ + ( (This)->lpVtbl -> Decommit(This) ) + +#endif /* COBJMACROS */ + + +#endif /* C style interface */ + + + + +#endif /* __IDeckLinkMemoryAllocator_INTERFACE_DEFINED__ */ + + +#ifndef __IDeckLinkAudioOutputCallback_INTERFACE_DEFINED__ +#define __IDeckLinkAudioOutputCallback_INTERFACE_DEFINED__ + +/* interface IDeckLinkAudioOutputCallback */ +/* [helpstring][local][uuid][object] */ + + +EXTERN_C const IID IID_IDeckLinkAudioOutputCallback; + +#if defined(__cplusplus) && !defined(CINTERFACE) + + MIDL_INTERFACE("403C681B-7F46-4A12-B993-2BB127084EE6") + IDeckLinkAudioOutputCallback : public IUnknown + { + public: + virtual HRESULT STDMETHODCALLTYPE RenderAudioSamples( + BOOL preroll) = 0; + + }; + +#else /* C style interface */ + + typedef struct IDeckLinkAudioOutputCallbackVtbl + { + BEGIN_INTERFACE + + HRESULT ( STDMETHODCALLTYPE *QueryInterface )( + IDeckLinkAudioOutputCallback * This, + /* [in] */ REFIID riid, + /* [iid_is][out] */ + __RPC__deref_out void **ppvObject); + + ULONG ( STDMETHODCALLTYPE *AddRef )( + IDeckLinkAudioOutputCallback * This); + + ULONG ( STDMETHODCALLTYPE *Release )( + IDeckLinkAudioOutputCallback * This); + + HRESULT ( STDMETHODCALLTYPE *RenderAudioSamples )( + IDeckLinkAudioOutputCallback * This, + BOOL preroll); + + END_INTERFACE + } IDeckLinkAudioOutputCallbackVtbl; + + interface IDeckLinkAudioOutputCallback + { + CONST_VTBL struct IDeckLinkAudioOutputCallbackVtbl *lpVtbl; + }; + + + +#ifdef COBJMACROS + + +#define IDeckLinkAudioOutputCallback_QueryInterface(This,riid,ppvObject) \ + ( (This)->lpVtbl -> QueryInterface(This,riid,ppvObject) ) + +#define IDeckLinkAudioOutputCallback_AddRef(This) \ + ( (This)->lpVtbl -> AddRef(This) ) + +#define IDeckLinkAudioOutputCallback_Release(This) \ + ( (This)->lpVtbl -> Release(This) ) + + +#define IDeckLinkAudioOutputCallback_RenderAudioSamples(This,preroll) \ + ( (This)->lpVtbl -> RenderAudioSamples(This,preroll) ) + +#endif /* COBJMACROS */ + + +#endif /* C style interface */ + + + + +#endif /* __IDeckLinkAudioOutputCallback_INTERFACE_DEFINED__ */ + + +#ifndef __IDeckLinkIterator_INTERFACE_DEFINED__ +#define __IDeckLinkIterator_INTERFACE_DEFINED__ + +/* interface IDeckLinkIterator */ +/* [helpstring][uuid][object] */ + + +EXTERN_C const IID IID_IDeckLinkIterator; + +#if defined(__cplusplus) && !defined(CINTERFACE) + + MIDL_INTERFACE("74E936FC-CC28-4A67-81A0-1E94E52D4E69") + IDeckLinkIterator : public IUnknown + { + public: + virtual HRESULT STDMETHODCALLTYPE Next( + /* [out] */ IDeckLink **deckLinkInstance) = 0; + + }; + +#else /* C style interface */ + + typedef struct IDeckLinkIteratorVtbl + { + BEGIN_INTERFACE + + HRESULT ( STDMETHODCALLTYPE *QueryInterface )( + IDeckLinkIterator * This, + /* [in] */ REFIID riid, + /* [iid_is][out] */ + __RPC__deref_out void **ppvObject); + + ULONG ( STDMETHODCALLTYPE *AddRef )( + IDeckLinkIterator * This); + + ULONG ( STDMETHODCALLTYPE *Release )( + IDeckLinkIterator * This); + + HRESULT ( STDMETHODCALLTYPE *Next )( + IDeckLinkIterator * This, + /* [out] */ IDeckLink **deckLinkInstance); + + END_INTERFACE + } IDeckLinkIteratorVtbl; + + interface IDeckLinkIterator + { + CONST_VTBL struct IDeckLinkIteratorVtbl *lpVtbl; + }; + + + +#ifdef COBJMACROS + + +#define IDeckLinkIterator_QueryInterface(This,riid,ppvObject) \ + ( (This)->lpVtbl -> QueryInterface(This,riid,ppvObject) ) + +#define IDeckLinkIterator_AddRef(This) \ + ( (This)->lpVtbl -> AddRef(This) ) + +#define IDeckLinkIterator_Release(This) \ + ( (This)->lpVtbl -> Release(This) ) + + +#define IDeckLinkIterator_Next(This,deckLinkInstance) \ + ( (This)->lpVtbl -> Next(This,deckLinkInstance) ) + +#endif /* COBJMACROS */ + + +#endif /* C style interface */ + + + + +#endif /* __IDeckLinkIterator_INTERFACE_DEFINED__ */ + + +#ifndef __IDeckLinkAPIInformation_INTERFACE_DEFINED__ +#define __IDeckLinkAPIInformation_INTERFACE_DEFINED__ + +/* interface IDeckLinkAPIInformation */ +/* [helpstring][uuid][object] */ + + +EXTERN_C const IID IID_IDeckLinkAPIInformation; + +#if defined(__cplusplus) && !defined(CINTERFACE) + + MIDL_INTERFACE("7BEA3C68-730D-4322-AF34-8A7152B532A4") + IDeckLinkAPIInformation : public IUnknown + { + public: + virtual HRESULT STDMETHODCALLTYPE GetFlag( + /* [in] */ BMDDeckLinkAPIInformationID cfgID, + /* [out] */ BOOL *value) = 0; + + virtual HRESULT STDMETHODCALLTYPE GetInt( + /* [in] */ BMDDeckLinkAPIInformationID cfgID, + /* [out] */ LONGLONG *value) = 0; + + virtual HRESULT STDMETHODCALLTYPE GetFloat( + /* [in] */ BMDDeckLinkAPIInformationID cfgID, + /* [out] */ double *value) = 0; + + virtual HRESULT STDMETHODCALLTYPE GetString( + /* [in] */ BMDDeckLinkAPIInformationID cfgID, + /* [out] */ BSTR *value) = 0; + + }; + +#else /* C style interface */ + + typedef struct IDeckLinkAPIInformationVtbl + { + BEGIN_INTERFACE + + HRESULT ( STDMETHODCALLTYPE *QueryInterface )( + IDeckLinkAPIInformation * This, + /* [in] */ REFIID riid, + /* [iid_is][out] */ + __RPC__deref_out void **ppvObject); + + ULONG ( STDMETHODCALLTYPE *AddRef )( + IDeckLinkAPIInformation * This); + + ULONG ( STDMETHODCALLTYPE *Release )( + IDeckLinkAPIInformation * This); + + HRESULT ( STDMETHODCALLTYPE *GetFlag )( + IDeckLinkAPIInformation * This, + /* [in] */ BMDDeckLinkAPIInformationID cfgID, + /* [out] */ BOOL *value); + + HRESULT ( STDMETHODCALLTYPE *GetInt )( + IDeckLinkAPIInformation * This, + /* [in] */ BMDDeckLinkAPIInformationID cfgID, + /* [out] */ LONGLONG *value); + + HRESULT ( STDMETHODCALLTYPE *GetFloat )( + IDeckLinkAPIInformation * This, + /* [in] */ BMDDeckLinkAPIInformationID cfgID, + /* [out] */ double *value); + + HRESULT ( STDMETHODCALLTYPE *GetString )( + IDeckLinkAPIInformation * This, + /* [in] */ BMDDeckLinkAPIInformationID cfgID, + /* [out] */ BSTR *value); + + END_INTERFACE + } IDeckLinkAPIInformationVtbl; + + interface IDeckLinkAPIInformation + { + CONST_VTBL struct IDeckLinkAPIInformationVtbl *lpVtbl; + }; + + + +#ifdef COBJMACROS + + +#define IDeckLinkAPIInformation_QueryInterface(This,riid,ppvObject) \ + ( (This)->lpVtbl -> QueryInterface(This,riid,ppvObject) ) + +#define IDeckLinkAPIInformation_AddRef(This) \ + ( (This)->lpVtbl -> AddRef(This) ) + +#define IDeckLinkAPIInformation_Release(This) \ + ( (This)->lpVtbl -> Release(This) ) + + +#define IDeckLinkAPIInformation_GetFlag(This,cfgID,value) \ + ( (This)->lpVtbl -> GetFlag(This,cfgID,value) ) + +#define IDeckLinkAPIInformation_GetInt(This,cfgID,value) \ + ( (This)->lpVtbl -> GetInt(This,cfgID,value) ) + +#define IDeckLinkAPIInformation_GetFloat(This,cfgID,value) \ + ( (This)->lpVtbl -> GetFloat(This,cfgID,value) ) + +#define IDeckLinkAPIInformation_GetString(This,cfgID,value) \ + ( (This)->lpVtbl -> GetString(This,cfgID,value) ) + +#endif /* COBJMACROS */ + + +#endif /* C style interface */ + + + + +#endif /* __IDeckLinkAPIInformation_INTERFACE_DEFINED__ */ + + +#ifndef __IDeckLinkDisplayModeIterator_INTERFACE_DEFINED__ +#define __IDeckLinkDisplayModeIterator_INTERFACE_DEFINED__ + +/* interface IDeckLinkDisplayModeIterator */ +/* [helpstring][uuid][object] */ + + +EXTERN_C const IID IID_IDeckLinkDisplayModeIterator; + +#if defined(__cplusplus) && !defined(CINTERFACE) + + MIDL_INTERFACE("455D741F-1779-4800-86F5-0B5D13D79751") + IDeckLinkDisplayModeIterator : public IUnknown + { + public: + virtual HRESULT STDMETHODCALLTYPE Next( + /* [out] */ IDeckLinkDisplayMode **deckLinkDisplayMode) = 0; + + }; + +#else /* C style interface */ + + typedef struct IDeckLinkDisplayModeIteratorVtbl + { + BEGIN_INTERFACE + + HRESULT ( STDMETHODCALLTYPE *QueryInterface )( + IDeckLinkDisplayModeIterator * This, + /* [in] */ REFIID riid, + /* [iid_is][out] */ + __RPC__deref_out void **ppvObject); + + ULONG ( STDMETHODCALLTYPE *AddRef )( + IDeckLinkDisplayModeIterator * This); + + ULONG ( STDMETHODCALLTYPE *Release )( + IDeckLinkDisplayModeIterator * This); + + HRESULT ( STDMETHODCALLTYPE *Next )( + IDeckLinkDisplayModeIterator * This, + /* [out] */ IDeckLinkDisplayMode **deckLinkDisplayMode); + + END_INTERFACE + } IDeckLinkDisplayModeIteratorVtbl; + + interface IDeckLinkDisplayModeIterator + { + CONST_VTBL struct IDeckLinkDisplayModeIteratorVtbl *lpVtbl; + }; + + + +#ifdef COBJMACROS + + +#define IDeckLinkDisplayModeIterator_QueryInterface(This,riid,ppvObject) \ + ( (This)->lpVtbl -> QueryInterface(This,riid,ppvObject) ) + +#define IDeckLinkDisplayModeIterator_AddRef(This) \ + ( (This)->lpVtbl -> AddRef(This) ) + +#define IDeckLinkDisplayModeIterator_Release(This) \ + ( (This)->lpVtbl -> Release(This) ) + + +#define IDeckLinkDisplayModeIterator_Next(This,deckLinkDisplayMode) \ + ( (This)->lpVtbl -> Next(This,deckLinkDisplayMode) ) + +#endif /* COBJMACROS */ + + +#endif /* C style interface */ + + + + +#endif /* __IDeckLinkDisplayModeIterator_INTERFACE_DEFINED__ */ + + +#ifndef __IDeckLinkDisplayMode_INTERFACE_DEFINED__ +#define __IDeckLinkDisplayMode_INTERFACE_DEFINED__ + +/* interface IDeckLinkDisplayMode */ +/* [helpstring][uuid][object] */ + + +EXTERN_C const IID IID_IDeckLinkDisplayMode; + +#if defined(__cplusplus) && !defined(CINTERFACE) + + MIDL_INTERFACE("87451E84-2B7E-439E-A629-4393EA4A8550") + IDeckLinkDisplayMode : public IUnknown + { + public: + virtual HRESULT STDMETHODCALLTYPE GetName( + /* [out] */ BSTR *name) = 0; + + virtual BMDDisplayMode STDMETHODCALLTYPE GetDisplayMode( void) = 0; + + virtual long STDMETHODCALLTYPE GetWidth( void) = 0; + + virtual long STDMETHODCALLTYPE GetHeight( void) = 0; + + virtual HRESULT STDMETHODCALLTYPE GetFrameRate( + /* [out] */ BMDTimeValue *frameDuration, + /* [out] */ BMDTimeScale *timeScale) = 0; + + virtual BMDFieldDominance STDMETHODCALLTYPE GetFieldDominance( void) = 0; + + }; + +#else /* C style interface */ + + typedef struct IDeckLinkDisplayModeVtbl + { + BEGIN_INTERFACE + + HRESULT ( STDMETHODCALLTYPE *QueryInterface )( + IDeckLinkDisplayMode * This, + /* [in] */ REFIID riid, + /* [iid_is][out] */ + __RPC__deref_out void **ppvObject); + + ULONG ( STDMETHODCALLTYPE *AddRef )( + IDeckLinkDisplayMode * This); + + ULONG ( STDMETHODCALLTYPE *Release )( + IDeckLinkDisplayMode * This); + + HRESULT ( STDMETHODCALLTYPE *GetName )( + IDeckLinkDisplayMode * This, + /* [out] */ BSTR *name); + + BMDDisplayMode ( STDMETHODCALLTYPE *GetDisplayMode )( + IDeckLinkDisplayMode * This); + + long ( STDMETHODCALLTYPE *GetWidth )( + IDeckLinkDisplayMode * This); + + long ( STDMETHODCALLTYPE *GetHeight )( + IDeckLinkDisplayMode * This); + + HRESULT ( STDMETHODCALLTYPE *GetFrameRate )( + IDeckLinkDisplayMode * This, + /* [out] */ BMDTimeValue *frameDuration, + /* [out] */ BMDTimeScale *timeScale); + + BMDFieldDominance ( STDMETHODCALLTYPE *GetFieldDominance )( + IDeckLinkDisplayMode * This); + + END_INTERFACE + } IDeckLinkDisplayModeVtbl; + + interface IDeckLinkDisplayMode + { + CONST_VTBL struct IDeckLinkDisplayModeVtbl *lpVtbl; + }; + + + +#ifdef COBJMACROS + + +#define IDeckLinkDisplayMode_QueryInterface(This,riid,ppvObject) \ + ( (This)->lpVtbl -> QueryInterface(This,riid,ppvObject) ) + +#define IDeckLinkDisplayMode_AddRef(This) \ + ( (This)->lpVtbl -> AddRef(This) ) + +#define IDeckLinkDisplayMode_Release(This) \ + ( (This)->lpVtbl -> Release(This) ) + + +#define IDeckLinkDisplayMode_GetName(This,name) \ + ( (This)->lpVtbl -> GetName(This,name) ) + +#define IDeckLinkDisplayMode_GetDisplayMode(This) \ + ( (This)->lpVtbl -> GetDisplayMode(This) ) + +#define IDeckLinkDisplayMode_GetWidth(This) \ + ( (This)->lpVtbl -> GetWidth(This) ) + +#define IDeckLinkDisplayMode_GetHeight(This) \ + ( (This)->lpVtbl -> GetHeight(This) ) + +#define IDeckLinkDisplayMode_GetFrameRate(This,frameDuration,timeScale) \ + ( (This)->lpVtbl -> GetFrameRate(This,frameDuration,timeScale) ) + +#define IDeckLinkDisplayMode_GetFieldDominance(This) \ + ( (This)->lpVtbl -> GetFieldDominance(This) ) + +#endif /* COBJMACROS */ + + +#endif /* C style interface */ + + + + +#endif /* __IDeckLinkDisplayMode_INTERFACE_DEFINED__ */ + + +#ifndef __IDeckLink_INTERFACE_DEFINED__ +#define __IDeckLink_INTERFACE_DEFINED__ + +/* interface IDeckLink */ +/* [helpstring][uuid][object] */ + + +EXTERN_C const IID IID_IDeckLink; + +#if defined(__cplusplus) && !defined(CINTERFACE) + + MIDL_INTERFACE("62BFF75D-6569-4E55-8D4D-66AA03829ABC") + IDeckLink : public IUnknown + { + public: + virtual HRESULT STDMETHODCALLTYPE GetModelName( + /* [out] */ BSTR *modelName) = 0; + + }; + +#else /* C style interface */ + + typedef struct IDeckLinkVtbl + { + BEGIN_INTERFACE + + HRESULT ( STDMETHODCALLTYPE *QueryInterface )( + IDeckLink * This, + /* [in] */ REFIID riid, + /* [iid_is][out] */ + __RPC__deref_out void **ppvObject); + + ULONG ( STDMETHODCALLTYPE *AddRef )( + IDeckLink * This); + + ULONG ( STDMETHODCALLTYPE *Release )( + IDeckLink * This); + + HRESULT ( STDMETHODCALLTYPE *GetModelName )( + IDeckLink * This, + /* [out] */ BSTR *modelName); + + END_INTERFACE + } IDeckLinkVtbl; + + interface IDeckLink + { + CONST_VTBL struct IDeckLinkVtbl *lpVtbl; + }; + + + +#ifdef COBJMACROS + + +#define IDeckLink_QueryInterface(This,riid,ppvObject) \ + ( (This)->lpVtbl -> QueryInterface(This,riid,ppvObject) ) + +#define IDeckLink_AddRef(This) \ + ( (This)->lpVtbl -> AddRef(This) ) + +#define IDeckLink_Release(This) \ + ( (This)->lpVtbl -> Release(This) ) + + +#define IDeckLink_GetModelName(This,modelName) \ + ( (This)->lpVtbl -> GetModelName(This,modelName) ) + +#endif /* COBJMACROS */ + + +#endif /* C style interface */ + + + + +#endif /* __IDeckLink_INTERFACE_DEFINED__ */ + + +#ifndef __IDeckLinkOutput_INTERFACE_DEFINED__ +#define __IDeckLinkOutput_INTERFACE_DEFINED__ + +/* interface IDeckLinkOutput */ +/* [helpstring][local][uuid][object] */ + + +EXTERN_C const IID IID_IDeckLinkOutput; + +#if defined(__cplusplus) && !defined(CINTERFACE) + + MIDL_INTERFACE("29228142-EB8C-4141-A621-F74026450955") + IDeckLinkOutput : public IUnknown + { + public: + virtual HRESULT STDMETHODCALLTYPE DoesSupportVideoMode( + BMDDisplayMode displayMode, + BMDPixelFormat pixelFormat, + /* [out] */ BMDDisplayModeSupport *result) = 0; + + virtual HRESULT STDMETHODCALLTYPE GetDisplayModeIterator( + /* [out] */ IDeckLinkDisplayModeIterator **iterator) = 0; + + virtual HRESULT STDMETHODCALLTYPE SetScreenPreviewCallback( + /* [in] */ IDeckLinkScreenPreviewCallback *previewCallback) = 0; + + virtual HRESULT STDMETHODCALLTYPE EnableVideoOutput( + BMDDisplayMode displayMode, + BMDVideoOutputFlags flags) = 0; + + virtual HRESULT STDMETHODCALLTYPE DisableVideoOutput( void) = 0; + + virtual HRESULT STDMETHODCALLTYPE SetVideoOutputFrameMemoryAllocator( + /* [in] */ IDeckLinkMemoryAllocator *theAllocator) = 0; + + virtual HRESULT STDMETHODCALLTYPE CreateVideoFrame( + long width, + long height, + long rowBytes, + BMDPixelFormat pixelFormat, + BMDFrameFlags flags, + /* [out] */ IDeckLinkMutableVideoFrame **outFrame) = 0; + + virtual HRESULT STDMETHODCALLTYPE CreateAncillaryData( + BMDDisplayMode displayMode, + BMDPixelFormat pixelFormat, + /* [out] */ IDeckLinkVideoFrameAncillary **outBuffer) = 0; + + virtual HRESULT STDMETHODCALLTYPE DisplayVideoFrameSync( + /* [in] */ IDeckLinkVideoFrame *theFrame) = 0; + + virtual HRESULT STDMETHODCALLTYPE ScheduleVideoFrame( + /* [in] */ IDeckLinkVideoFrame *theFrame, + BMDTimeValue displayTime, + BMDTimeValue displayDuration, + BMDTimeScale timeScale) = 0; + + virtual HRESULT STDMETHODCALLTYPE SetScheduledFrameCompletionCallback( + /* [in] */ IDeckLinkVideoOutputCallback *theCallback) = 0; + + virtual HRESULT STDMETHODCALLTYPE GetBufferedVideoFrameCount( + /* [out] */ unsigned long *bufferedFrameCount) = 0; + + virtual HRESULT STDMETHODCALLTYPE EnableAudioOutput( + BMDAudioSampleRate sampleRate, + BMDAudioSampleType sampleType, + unsigned long channelCount, + BMDAudioOutputStreamType streamType) = 0; + + virtual HRESULT STDMETHODCALLTYPE DisableAudioOutput( void) = 0; + + virtual HRESULT STDMETHODCALLTYPE WriteAudioSamplesSync( + /* [in] */ void *buffer, + unsigned long sampleFrameCount, + /* [out] */ unsigned long *sampleFramesWritten) = 0; + + virtual HRESULT STDMETHODCALLTYPE BeginAudioPreroll( void) = 0; + + virtual HRESULT STDMETHODCALLTYPE EndAudioPreroll( void) = 0; + + virtual HRESULT STDMETHODCALLTYPE ScheduleAudioSamples( + /* [in] */ void *buffer, + unsigned long sampleFrameCount, + BMDTimeValue streamTime, + BMDTimeScale timeScale, + /* [out] */ unsigned long *sampleFramesWritten) = 0; + + virtual HRESULT STDMETHODCALLTYPE GetBufferedAudioSampleFrameCount( + /* [out] */ unsigned long *bufferedSampleFrameCount) = 0; + + virtual HRESULT STDMETHODCALLTYPE FlushBufferedAudioSamples( void) = 0; + + virtual HRESULT STDMETHODCALLTYPE SetAudioCallback( + /* [in] */ IDeckLinkAudioOutputCallback *theCallback) = 0; + + virtual HRESULT STDMETHODCALLTYPE StartScheduledPlayback( + BMDTimeValue playbackStartTime, + BMDTimeScale timeScale, + double playbackSpeed) = 0; + + virtual HRESULT STDMETHODCALLTYPE StopScheduledPlayback( + BMDTimeValue stopPlaybackAtTime, + /* [out] */ BMDTimeValue *actualStopTime, + BMDTimeScale timeScale) = 0; + + virtual HRESULT STDMETHODCALLTYPE IsScheduledPlaybackRunning( + /* [out] */ BOOL *active) = 0; + + virtual HRESULT STDMETHODCALLTYPE GetScheduledStreamTime( + BMDTimeScale desiredTimeScale, + /* [out] */ BMDTimeValue *streamTime, + /* [out] */ double *playbackSpeed) = 0; + + virtual HRESULT STDMETHODCALLTYPE GetHardwareReferenceClock( + BMDTimeScale desiredTimeScale, + /* [out] */ BMDTimeValue *hardwareTime, + /* [out] */ BMDTimeValue *timeInFrame, + /* [out] */ BMDTimeValue *ticksPerFrame) = 0; + + }; + +#else /* C style interface */ + + typedef struct IDeckLinkOutputVtbl + { + BEGIN_INTERFACE + + HRESULT ( STDMETHODCALLTYPE *QueryInterface )( + IDeckLinkOutput * This, + /* [in] */ REFIID riid, + /* [iid_is][out] */ + __RPC__deref_out void **ppvObject); + + ULONG ( STDMETHODCALLTYPE *AddRef )( + IDeckLinkOutput * This); + + ULONG ( STDMETHODCALLTYPE *Release )( + IDeckLinkOutput * This); + + HRESULT ( STDMETHODCALLTYPE *DoesSupportVideoMode )( + IDeckLinkOutput * This, + BMDDisplayMode displayMode, + BMDPixelFormat pixelFormat, + /* [out] */ BMDDisplayModeSupport *result); + + HRESULT ( STDMETHODCALLTYPE *GetDisplayModeIterator )( + IDeckLinkOutput * This, + /* [out] */ IDeckLinkDisplayModeIterator **iterator); + + HRESULT ( STDMETHODCALLTYPE *SetScreenPreviewCallback )( + IDeckLinkOutput * This, + /* [in] */ IDeckLinkScreenPreviewCallback *previewCallback); + + HRESULT ( STDMETHODCALLTYPE *EnableVideoOutput )( + IDeckLinkOutput * This, + BMDDisplayMode displayMode, + BMDVideoOutputFlags flags); + + HRESULT ( STDMETHODCALLTYPE *DisableVideoOutput )( + IDeckLinkOutput * This); + + HRESULT ( STDMETHODCALLTYPE *SetVideoOutputFrameMemoryAllocator )( + IDeckLinkOutput * This, + /* [in] */ IDeckLinkMemoryAllocator *theAllocator); + + HRESULT ( STDMETHODCALLTYPE *CreateVideoFrame )( + IDeckLinkOutput * This, + long width, + long height, + long rowBytes, + BMDPixelFormat pixelFormat, + BMDFrameFlags flags, + /* [out] */ IDeckLinkMutableVideoFrame **outFrame); + + HRESULT ( STDMETHODCALLTYPE *CreateAncillaryData )( + IDeckLinkOutput * This, + BMDDisplayMode displayMode, + BMDPixelFormat pixelFormat, + /* [out] */ IDeckLinkVideoFrameAncillary **outBuffer); + + HRESULT ( STDMETHODCALLTYPE *DisplayVideoFrameSync )( + IDeckLinkOutput * This, + /* [in] */ IDeckLinkVideoFrame *theFrame); + + HRESULT ( STDMETHODCALLTYPE *ScheduleVideoFrame )( + IDeckLinkOutput * This, + /* [in] */ IDeckLinkVideoFrame *theFrame, + BMDTimeValue displayTime, + BMDTimeValue displayDuration, + BMDTimeScale timeScale); + + HRESULT ( STDMETHODCALLTYPE *SetScheduledFrameCompletionCallback )( + IDeckLinkOutput * This, + /* [in] */ IDeckLinkVideoOutputCallback *theCallback); + + HRESULT ( STDMETHODCALLTYPE *GetBufferedVideoFrameCount )( + IDeckLinkOutput * This, + /* [out] */ unsigned long *bufferedFrameCount); + + HRESULT ( STDMETHODCALLTYPE *EnableAudioOutput )( + IDeckLinkOutput * This, + BMDAudioSampleRate sampleRate, + BMDAudioSampleType sampleType, + unsigned long channelCount, + BMDAudioOutputStreamType streamType); + + HRESULT ( STDMETHODCALLTYPE *DisableAudioOutput )( + IDeckLinkOutput * This); + + HRESULT ( STDMETHODCALLTYPE *WriteAudioSamplesSync )( + IDeckLinkOutput * This, + /* [in] */ void *buffer, + unsigned long sampleFrameCount, + /* [out] */ unsigned long *sampleFramesWritten); + + HRESULT ( STDMETHODCALLTYPE *BeginAudioPreroll )( + IDeckLinkOutput * This); + + HRESULT ( STDMETHODCALLTYPE *EndAudioPreroll )( + IDeckLinkOutput * This); + + HRESULT ( STDMETHODCALLTYPE *ScheduleAudioSamples )( + IDeckLinkOutput * This, + /* [in] */ void *buffer, + unsigned long sampleFrameCount, + BMDTimeValue streamTime, + BMDTimeScale timeScale, + /* [out] */ unsigned long *sampleFramesWritten); + + HRESULT ( STDMETHODCALLTYPE *GetBufferedAudioSampleFrameCount )( + IDeckLinkOutput * This, + /* [out] */ unsigned long *bufferedSampleFrameCount); + + HRESULT ( STDMETHODCALLTYPE *FlushBufferedAudioSamples )( + IDeckLinkOutput * This); + + HRESULT ( STDMETHODCALLTYPE *SetAudioCallback )( + IDeckLinkOutput * This, + /* [in] */ IDeckLinkAudioOutputCallback *theCallback); + + HRESULT ( STDMETHODCALLTYPE *StartScheduledPlayback )( + IDeckLinkOutput * This, + BMDTimeValue playbackStartTime, + BMDTimeScale timeScale, + double playbackSpeed); + + HRESULT ( STDMETHODCALLTYPE *StopScheduledPlayback )( + IDeckLinkOutput * This, + BMDTimeValue stopPlaybackAtTime, + /* [out] */ BMDTimeValue *actualStopTime, + BMDTimeScale timeScale); + + HRESULT ( STDMETHODCALLTYPE *IsScheduledPlaybackRunning )( + IDeckLinkOutput * This, + /* [out] */ BOOL *active); + + HRESULT ( STDMETHODCALLTYPE *GetScheduledStreamTime )( + IDeckLinkOutput * This, + BMDTimeScale desiredTimeScale, + /* [out] */ BMDTimeValue *streamTime, + /* [out] */ double *playbackSpeed); + + HRESULT ( STDMETHODCALLTYPE *GetHardwareReferenceClock )( + IDeckLinkOutput * This, + BMDTimeScale desiredTimeScale, + /* [out] */ BMDTimeValue *hardwareTime, + /* [out] */ BMDTimeValue *timeInFrame, + /* [out] */ BMDTimeValue *ticksPerFrame); + + END_INTERFACE + } IDeckLinkOutputVtbl; + + interface IDeckLinkOutput + { + CONST_VTBL struct IDeckLinkOutputVtbl *lpVtbl; + }; + + + +#ifdef COBJMACROS + + +#define IDeckLinkOutput_QueryInterface(This,riid,ppvObject) \ + ( (This)->lpVtbl -> QueryInterface(This,riid,ppvObject) ) + +#define IDeckLinkOutput_AddRef(This) \ + ( (This)->lpVtbl -> AddRef(This) ) + +#define IDeckLinkOutput_Release(This) \ + ( (This)->lpVtbl -> Release(This) ) + + +#define IDeckLinkOutput_DoesSupportVideoMode(This,displayMode,pixelFormat,result) \ + ( (This)->lpVtbl -> DoesSupportVideoMode(This,displayMode,pixelFormat,result) ) + +#define IDeckLinkOutput_GetDisplayModeIterator(This,iterator) \ + ( (This)->lpVtbl -> GetDisplayModeIterator(This,iterator) ) + +#define IDeckLinkOutput_SetScreenPreviewCallback(This,previewCallback) \ + ( (This)->lpVtbl -> SetScreenPreviewCallback(This,previewCallback) ) + +#define IDeckLinkOutput_EnableVideoOutput(This,displayMode,flags) \ + ( (This)->lpVtbl -> EnableVideoOutput(This,displayMode,flags) ) + +#define IDeckLinkOutput_DisableVideoOutput(This) \ + ( (This)->lpVtbl -> DisableVideoOutput(This) ) + +#define IDeckLinkOutput_SetVideoOutputFrameMemoryAllocator(This,theAllocator) \ + ( (This)->lpVtbl -> SetVideoOutputFrameMemoryAllocator(This,theAllocator) ) + +#define IDeckLinkOutput_CreateVideoFrame(This,width,height,rowBytes,pixelFormat,flags,outFrame) \ + ( (This)->lpVtbl -> CreateVideoFrame(This,width,height,rowBytes,pixelFormat,flags,outFrame) ) + +#define IDeckLinkOutput_CreateAncillaryData(This,displayMode,pixelFormat,outBuffer) \ + ( (This)->lpVtbl -> CreateAncillaryData(This,displayMode,pixelFormat,outBuffer) ) + +#define IDeckLinkOutput_DisplayVideoFrameSync(This,theFrame) \ + ( (This)->lpVtbl -> DisplayVideoFrameSync(This,theFrame) ) + +#define IDeckLinkOutput_ScheduleVideoFrame(This,theFrame,displayTime,displayDuration,timeScale) \ + ( (This)->lpVtbl -> ScheduleVideoFrame(This,theFrame,displayTime,displayDuration,timeScale) ) + +#define IDeckLinkOutput_SetScheduledFrameCompletionCallback(This,theCallback) \ + ( (This)->lpVtbl -> SetScheduledFrameCompletionCallback(This,theCallback) ) + +#define IDeckLinkOutput_GetBufferedVideoFrameCount(This,bufferedFrameCount) \ + ( (This)->lpVtbl -> GetBufferedVideoFrameCount(This,bufferedFrameCount) ) + +#define IDeckLinkOutput_EnableAudioOutput(This,sampleRate,sampleType,channelCount,streamType) \ + ( (This)->lpVtbl -> EnableAudioOutput(This,sampleRate,sampleType,channelCount,streamType) ) + +#define IDeckLinkOutput_DisableAudioOutput(This) \ + ( (This)->lpVtbl -> DisableAudioOutput(This) ) + +#define IDeckLinkOutput_WriteAudioSamplesSync(This,buffer,sampleFrameCount,sampleFramesWritten) \ + ( (This)->lpVtbl -> WriteAudioSamplesSync(This,buffer,sampleFrameCount,sampleFramesWritten) ) + +#define IDeckLinkOutput_BeginAudioPreroll(This) \ + ( (This)->lpVtbl -> BeginAudioPreroll(This) ) + +#define IDeckLinkOutput_EndAudioPreroll(This) \ + ( (This)->lpVtbl -> EndAudioPreroll(This) ) + +#define IDeckLinkOutput_ScheduleAudioSamples(This,buffer,sampleFrameCount,streamTime,timeScale,sampleFramesWritten) \ + ( (This)->lpVtbl -> ScheduleAudioSamples(This,buffer,sampleFrameCount,streamTime,timeScale,sampleFramesWritten) ) + +#define IDeckLinkOutput_GetBufferedAudioSampleFrameCount(This,bufferedSampleFrameCount) \ + ( (This)->lpVtbl -> GetBufferedAudioSampleFrameCount(This,bufferedSampleFrameCount) ) + +#define IDeckLinkOutput_FlushBufferedAudioSamples(This) \ + ( (This)->lpVtbl -> FlushBufferedAudioSamples(This) ) + +#define IDeckLinkOutput_SetAudioCallback(This,theCallback) \ + ( (This)->lpVtbl -> SetAudioCallback(This,theCallback) ) + +#define IDeckLinkOutput_StartScheduledPlayback(This,playbackStartTime,timeScale,playbackSpeed) \ + ( (This)->lpVtbl -> StartScheduledPlayback(This,playbackStartTime,timeScale,playbackSpeed) ) + +#define IDeckLinkOutput_StopScheduledPlayback(This,stopPlaybackAtTime,actualStopTime,timeScale) \ + ( (This)->lpVtbl -> StopScheduledPlayback(This,stopPlaybackAtTime,actualStopTime,timeScale) ) + +#define IDeckLinkOutput_IsScheduledPlaybackRunning(This,active) \ + ( (This)->lpVtbl -> IsScheduledPlaybackRunning(This,active) ) + +#define IDeckLinkOutput_GetScheduledStreamTime(This,desiredTimeScale,streamTime,playbackSpeed) \ + ( (This)->lpVtbl -> GetScheduledStreamTime(This,desiredTimeScale,streamTime,playbackSpeed) ) + +#define IDeckLinkOutput_GetHardwareReferenceClock(This,desiredTimeScale,hardwareTime,timeInFrame,ticksPerFrame) \ + ( (This)->lpVtbl -> GetHardwareReferenceClock(This,desiredTimeScale,hardwareTime,timeInFrame,ticksPerFrame) ) + +#endif /* COBJMACROS */ + + +#endif /* C style interface */ + + + + +#endif /* __IDeckLinkOutput_INTERFACE_DEFINED__ */ + + +#ifndef __IDeckLinkInput_INTERFACE_DEFINED__ +#define __IDeckLinkInput_INTERFACE_DEFINED__ + +/* interface IDeckLinkInput */ +/* [helpstring][uuid][object] */ + + +EXTERN_C const IID IID_IDeckLinkInput; + +#if defined(__cplusplus) && !defined(CINTERFACE) + + MIDL_INTERFACE("300C135A-9F43-48E2-9906-6D7911D93CF1") + IDeckLinkInput : public IUnknown + { + public: + virtual HRESULT STDMETHODCALLTYPE DoesSupportVideoMode( + BMDDisplayMode displayMode, + BMDPixelFormat pixelFormat, + /* [out] */ BMDDisplayModeSupport *result) = 0; + + virtual HRESULT STDMETHODCALLTYPE GetDisplayModeIterator( + /* [out] */ IDeckLinkDisplayModeIterator **iterator) = 0; + + virtual HRESULT STDMETHODCALLTYPE SetScreenPreviewCallback( + /* [in] */ IDeckLinkScreenPreviewCallback *previewCallback) = 0; + + virtual HRESULT STDMETHODCALLTYPE EnableVideoInput( + BMDDisplayMode displayMode, + BMDPixelFormat pixelFormat, + BMDVideoInputFlags flags) = 0; + + virtual HRESULT STDMETHODCALLTYPE DisableVideoInput( void) = 0; + + virtual HRESULT STDMETHODCALLTYPE GetAvailableVideoFrameCount( + /* [out] */ unsigned long *availableFrameCount) = 0; + + virtual HRESULT STDMETHODCALLTYPE EnableAudioInput( + BMDAudioSampleRate sampleRate, + BMDAudioSampleType sampleType, + unsigned long channelCount) = 0; + + virtual HRESULT STDMETHODCALLTYPE DisableAudioInput( void) = 0; + + virtual HRESULT STDMETHODCALLTYPE GetAvailableAudioSampleFrameCount( + /* [out] */ unsigned long *availableSampleFrameCount) = 0; + + virtual HRESULT STDMETHODCALLTYPE StartStreams( void) = 0; + + virtual HRESULT STDMETHODCALLTYPE StopStreams( void) = 0; + + virtual HRESULT STDMETHODCALLTYPE PauseStreams( void) = 0; + + virtual HRESULT STDMETHODCALLTYPE FlushStreams( void) = 0; + + virtual HRESULT STDMETHODCALLTYPE SetCallback( + /* [in] */ IDeckLinkInputCallback *theCallback) = 0; + + virtual HRESULT STDMETHODCALLTYPE GetHardwareReferenceClock( + BMDTimeScale desiredTimeScale, + /* [out] */ BMDTimeValue *hardwareTime, + /* [out] */ BMDTimeValue *timeInFrame, + /* [out] */ BMDTimeValue *ticksPerFrame) = 0; + + }; + +#else /* C style interface */ + + typedef struct IDeckLinkInputVtbl + { + BEGIN_INTERFACE + + HRESULT ( STDMETHODCALLTYPE *QueryInterface )( + IDeckLinkInput * This, + /* [in] */ REFIID riid, + /* [iid_is][out] */ + __RPC__deref_out void **ppvObject); + + ULONG ( STDMETHODCALLTYPE *AddRef )( + IDeckLinkInput * This); + + ULONG ( STDMETHODCALLTYPE *Release )( + IDeckLinkInput * This); + + HRESULT ( STDMETHODCALLTYPE *DoesSupportVideoMode )( + IDeckLinkInput * This, + BMDDisplayMode displayMode, + BMDPixelFormat pixelFormat, + /* [out] */ BMDDisplayModeSupport *result); + + HRESULT ( STDMETHODCALLTYPE *GetDisplayModeIterator )( + IDeckLinkInput * This, + /* [out] */ IDeckLinkDisplayModeIterator **iterator); + + HRESULT ( STDMETHODCALLTYPE *SetScreenPreviewCallback )( + IDeckLinkInput * This, + /* [in] */ IDeckLinkScreenPreviewCallback *previewCallback); + + HRESULT ( STDMETHODCALLTYPE *EnableVideoInput )( + IDeckLinkInput * This, + BMDDisplayMode displayMode, + BMDPixelFormat pixelFormat, + BMDVideoInputFlags flags); + + HRESULT ( STDMETHODCALLTYPE *DisableVideoInput )( + IDeckLinkInput * This); + + HRESULT ( STDMETHODCALLTYPE *GetAvailableVideoFrameCount )( + IDeckLinkInput * This, + /* [out] */ unsigned long *availableFrameCount); + + HRESULT ( STDMETHODCALLTYPE *EnableAudioInput )( + IDeckLinkInput * This, + BMDAudioSampleRate sampleRate, + BMDAudioSampleType sampleType, + unsigned long channelCount); + + HRESULT ( STDMETHODCALLTYPE *DisableAudioInput )( + IDeckLinkInput * This); + + HRESULT ( STDMETHODCALLTYPE *GetAvailableAudioSampleFrameCount )( + IDeckLinkInput * This, + /* [out] */ unsigned long *availableSampleFrameCount); + + HRESULT ( STDMETHODCALLTYPE *StartStreams )( + IDeckLinkInput * This); + + HRESULT ( STDMETHODCALLTYPE *StopStreams )( + IDeckLinkInput * This); + + HRESULT ( STDMETHODCALLTYPE *PauseStreams )( + IDeckLinkInput * This); + + HRESULT ( STDMETHODCALLTYPE *FlushStreams )( + IDeckLinkInput * This); + + HRESULT ( STDMETHODCALLTYPE *SetCallback )( + IDeckLinkInput * This, + /* [in] */ IDeckLinkInputCallback *theCallback); + + HRESULT ( STDMETHODCALLTYPE *GetHardwareReferenceClock )( + IDeckLinkInput * This, + BMDTimeScale desiredTimeScale, + /* [out] */ BMDTimeValue *hardwareTime, + /* [out] */ BMDTimeValue *timeInFrame, + /* [out] */ BMDTimeValue *ticksPerFrame); + + END_INTERFACE + } IDeckLinkInputVtbl; + + interface IDeckLinkInput + { + CONST_VTBL struct IDeckLinkInputVtbl *lpVtbl; + }; + + + +#ifdef COBJMACROS + + +#define IDeckLinkInput_QueryInterface(This,riid,ppvObject) \ + ( (This)->lpVtbl -> QueryInterface(This,riid,ppvObject) ) + +#define IDeckLinkInput_AddRef(This) \ + ( (This)->lpVtbl -> AddRef(This) ) + +#define IDeckLinkInput_Release(This) \ + ( (This)->lpVtbl -> Release(This) ) + + +#define IDeckLinkInput_DoesSupportVideoMode(This,displayMode,pixelFormat,result) \ + ( (This)->lpVtbl -> DoesSupportVideoMode(This,displayMode,pixelFormat,result) ) + +#define IDeckLinkInput_GetDisplayModeIterator(This,iterator) \ + ( (This)->lpVtbl -> GetDisplayModeIterator(This,iterator) ) + +#define IDeckLinkInput_SetScreenPreviewCallback(This,previewCallback) \ + ( (This)->lpVtbl -> SetScreenPreviewCallback(This,previewCallback) ) + +#define IDeckLinkInput_EnableVideoInput(This,displayMode,pixelFormat,flags) \ + ( (This)->lpVtbl -> EnableVideoInput(This,displayMode,pixelFormat,flags) ) + +#define IDeckLinkInput_DisableVideoInput(This) \ + ( (This)->lpVtbl -> DisableVideoInput(This) ) + +#define IDeckLinkInput_GetAvailableVideoFrameCount(This,availableFrameCount) \ + ( (This)->lpVtbl -> GetAvailableVideoFrameCount(This,availableFrameCount) ) + +#define IDeckLinkInput_EnableAudioInput(This,sampleRate,sampleType,channelCount) \ + ( (This)->lpVtbl -> EnableAudioInput(This,sampleRate,sampleType,channelCount) ) + +#define IDeckLinkInput_DisableAudioInput(This) \ + ( (This)->lpVtbl -> DisableAudioInput(This) ) + +#define IDeckLinkInput_GetAvailableAudioSampleFrameCount(This,availableSampleFrameCount) \ + ( (This)->lpVtbl -> GetAvailableAudioSampleFrameCount(This,availableSampleFrameCount) ) + +#define IDeckLinkInput_StartStreams(This) \ + ( (This)->lpVtbl -> StartStreams(This) ) + +#define IDeckLinkInput_StopStreams(This) \ + ( (This)->lpVtbl -> StopStreams(This) ) + +#define IDeckLinkInput_PauseStreams(This) \ + ( (This)->lpVtbl -> PauseStreams(This) ) + +#define IDeckLinkInput_FlushStreams(This) \ + ( (This)->lpVtbl -> FlushStreams(This) ) + +#define IDeckLinkInput_SetCallback(This,theCallback) \ + ( (This)->lpVtbl -> SetCallback(This,theCallback) ) + +#define IDeckLinkInput_GetHardwareReferenceClock(This,desiredTimeScale,hardwareTime,timeInFrame,ticksPerFrame) \ + ( (This)->lpVtbl -> GetHardwareReferenceClock(This,desiredTimeScale,hardwareTime,timeInFrame,ticksPerFrame) ) + +#endif /* COBJMACROS */ + + +#endif /* C style interface */ + + + + +#endif /* __IDeckLinkInput_INTERFACE_DEFINED__ */ + + +#ifndef __IDeckLinkTimecode_INTERFACE_DEFINED__ +#define __IDeckLinkTimecode_INTERFACE_DEFINED__ + +/* interface IDeckLinkTimecode */ +/* [helpstring][uuid][object] */ + + +EXTERN_C const IID IID_IDeckLinkTimecode; + +#if defined(__cplusplus) && !defined(CINTERFACE) + + MIDL_INTERFACE("EFB9BCA6-A521-44F7-BD69-2332F24D9EE6") + IDeckLinkTimecode : public IUnknown + { + public: + virtual BMDTimecodeBCD STDMETHODCALLTYPE GetBCD( void) = 0; + + virtual HRESULT STDMETHODCALLTYPE GetComponents( + /* [out] */ unsigned char *hours, + /* [out] */ unsigned char *minutes, + /* [out] */ unsigned char *seconds, + /* [out] */ unsigned char *frames) = 0; + + virtual HRESULT STDMETHODCALLTYPE GetString( + /* [out] */ BSTR *timecode) = 0; + + virtual BMDTimecodeFlags STDMETHODCALLTYPE GetFlags( void) = 0; + + }; + +#else /* C style interface */ + + typedef struct IDeckLinkTimecodeVtbl + { + BEGIN_INTERFACE + + HRESULT ( STDMETHODCALLTYPE *QueryInterface )( + IDeckLinkTimecode * This, + /* [in] */ REFIID riid, + /* [iid_is][out] */ + __RPC__deref_out void **ppvObject); + + ULONG ( STDMETHODCALLTYPE *AddRef )( + IDeckLinkTimecode * This); + + ULONG ( STDMETHODCALLTYPE *Release )( + IDeckLinkTimecode * This); + + BMDTimecodeBCD ( STDMETHODCALLTYPE *GetBCD )( + IDeckLinkTimecode * This); + + HRESULT ( STDMETHODCALLTYPE *GetComponents )( + IDeckLinkTimecode * This, + /* [out] */ unsigned char *hours, + /* [out] */ unsigned char *minutes, + /* [out] */ unsigned char *seconds, + /* [out] */ unsigned char *frames); + + HRESULT ( STDMETHODCALLTYPE *GetString )( + IDeckLinkTimecode * This, + /* [out] */ BSTR *timecode); + + BMDTimecodeFlags ( STDMETHODCALLTYPE *GetFlags )( + IDeckLinkTimecode * This); + + END_INTERFACE + } IDeckLinkTimecodeVtbl; + + interface IDeckLinkTimecode + { + CONST_VTBL struct IDeckLinkTimecodeVtbl *lpVtbl; + }; + + + +#ifdef COBJMACROS + + +#define IDeckLinkTimecode_QueryInterface(This,riid,ppvObject) \ + ( (This)->lpVtbl -> QueryInterface(This,riid,ppvObject) ) + +#define IDeckLinkTimecode_AddRef(This) \ + ( (This)->lpVtbl -> AddRef(This) ) + +#define IDeckLinkTimecode_Release(This) \ + ( (This)->lpVtbl -> Release(This) ) + + +#define IDeckLinkTimecode_GetBCD(This) \ + ( (This)->lpVtbl -> GetBCD(This) ) + +#define IDeckLinkTimecode_GetComponents(This,hours,minutes,seconds,frames) \ + ( (This)->lpVtbl -> GetComponents(This,hours,minutes,seconds,frames) ) + +#define IDeckLinkTimecode_GetString(This,timecode) \ + ( (This)->lpVtbl -> GetString(This,timecode) ) + +#define IDeckLinkTimecode_GetFlags(This) \ + ( (This)->lpVtbl -> GetFlags(This) ) + +#endif /* COBJMACROS */ + + +#endif /* C style interface */ + + + + +#endif /* __IDeckLinkTimecode_INTERFACE_DEFINED__ */ + + +#ifndef __IDeckLinkVideoFrame_INTERFACE_DEFINED__ +#define __IDeckLinkVideoFrame_INTERFACE_DEFINED__ + +/* interface IDeckLinkVideoFrame */ +/* [helpstring][local][uuid][object] */ + + +EXTERN_C const IID IID_IDeckLinkVideoFrame; + +#if defined(__cplusplus) && !defined(CINTERFACE) + + MIDL_INTERFACE("A8D8238E-6B18-4196-99E1-5AF717B83D32") + IDeckLinkVideoFrame : public IUnknown + { + public: + virtual long STDMETHODCALLTYPE GetWidth( void) = 0; + + virtual long STDMETHODCALLTYPE GetHeight( void) = 0; + + virtual long STDMETHODCALLTYPE GetRowBytes( void) = 0; + + virtual BMDPixelFormat STDMETHODCALLTYPE GetPixelFormat( void) = 0; + + virtual BMDFrameFlags STDMETHODCALLTYPE GetFlags( void) = 0; + + virtual HRESULT STDMETHODCALLTYPE GetBytes( + /* [out] */ void **buffer) = 0; + + virtual HRESULT STDMETHODCALLTYPE GetTimecode( + BMDTimecodeFormat format, + /* [out] */ IDeckLinkTimecode **timecode) = 0; + + virtual HRESULT STDMETHODCALLTYPE GetAncillaryData( + /* [out] */ IDeckLinkVideoFrameAncillary **ancillary) = 0; + + }; + +#else /* C style interface */ + + typedef struct IDeckLinkVideoFrameVtbl + { + BEGIN_INTERFACE + + HRESULT ( STDMETHODCALLTYPE *QueryInterface )( + IDeckLinkVideoFrame * This, + /* [in] */ REFIID riid, + /* [iid_is][out] */ + __RPC__deref_out void **ppvObject); + + ULONG ( STDMETHODCALLTYPE *AddRef )( + IDeckLinkVideoFrame * This); + + ULONG ( STDMETHODCALLTYPE *Release )( + IDeckLinkVideoFrame * This); + + long ( STDMETHODCALLTYPE *GetWidth )( + IDeckLinkVideoFrame * This); + + long ( STDMETHODCALLTYPE *GetHeight )( + IDeckLinkVideoFrame * This); + + long ( STDMETHODCALLTYPE *GetRowBytes )( + IDeckLinkVideoFrame * This); + + BMDPixelFormat ( STDMETHODCALLTYPE *GetPixelFormat )( + IDeckLinkVideoFrame * This); + + BMDFrameFlags ( STDMETHODCALLTYPE *GetFlags )( + IDeckLinkVideoFrame * This); + + HRESULT ( STDMETHODCALLTYPE *GetBytes )( + IDeckLinkVideoFrame * This, + /* [out] */ void **buffer); + + HRESULT ( STDMETHODCALLTYPE *GetTimecode )( + IDeckLinkVideoFrame * This, + BMDTimecodeFormat format, + /* [out] */ IDeckLinkTimecode **timecode); + + HRESULT ( STDMETHODCALLTYPE *GetAncillaryData )( + IDeckLinkVideoFrame * This, + /* [out] */ IDeckLinkVideoFrameAncillary **ancillary); + + END_INTERFACE + } IDeckLinkVideoFrameVtbl; + + interface IDeckLinkVideoFrame + { + CONST_VTBL struct IDeckLinkVideoFrameVtbl *lpVtbl; + }; + + + +#ifdef COBJMACROS + + +#define IDeckLinkVideoFrame_QueryInterface(This,riid,ppvObject) \ + ( (This)->lpVtbl -> QueryInterface(This,riid,ppvObject) ) + +#define IDeckLinkVideoFrame_AddRef(This) \ + ( (This)->lpVtbl -> AddRef(This) ) + +#define IDeckLinkVideoFrame_Release(This) \ + ( (This)->lpVtbl -> Release(This) ) + + +#define IDeckLinkVideoFrame_GetWidth(This) \ + ( (This)->lpVtbl -> GetWidth(This) ) + +#define IDeckLinkVideoFrame_GetHeight(This) \ + ( (This)->lpVtbl -> GetHeight(This) ) + +#define IDeckLinkVideoFrame_GetRowBytes(This) \ + ( (This)->lpVtbl -> GetRowBytes(This) ) + +#define IDeckLinkVideoFrame_GetPixelFormat(This) \ + ( (This)->lpVtbl -> GetPixelFormat(This) ) + +#define IDeckLinkVideoFrame_GetFlags(This) \ + ( (This)->lpVtbl -> GetFlags(This) ) + +#define IDeckLinkVideoFrame_GetBytes(This,buffer) \ + ( (This)->lpVtbl -> GetBytes(This,buffer) ) + +#define IDeckLinkVideoFrame_GetTimecode(This,format,timecode) \ + ( (This)->lpVtbl -> GetTimecode(This,format,timecode) ) + +#define IDeckLinkVideoFrame_GetAncillaryData(This,ancillary) \ + ( (This)->lpVtbl -> GetAncillaryData(This,ancillary) ) + +#endif /* COBJMACROS */ + + +#endif /* C style interface */ + + + + +#endif /* __IDeckLinkVideoFrame_INTERFACE_DEFINED__ */ + + +#ifndef __IDeckLinkMutableVideoFrame_INTERFACE_DEFINED__ +#define __IDeckLinkMutableVideoFrame_INTERFACE_DEFINED__ + +/* interface IDeckLinkMutableVideoFrame */ +/* [helpstring][local][uuid][object] */ + + +EXTERN_C const IID IID_IDeckLinkMutableVideoFrame; + +#if defined(__cplusplus) && !defined(CINTERFACE) + + MIDL_INTERFACE("46FCEE00-B4E6-43D0-91C0-023A7FCEB34F") + IDeckLinkMutableVideoFrame : public IDeckLinkVideoFrame + { + public: + virtual HRESULT STDMETHODCALLTYPE SetFlags( + BMDFrameFlags newFlags) = 0; + + virtual HRESULT STDMETHODCALLTYPE SetTimecode( + BMDTimecodeFormat format, + /* [in] */ IDeckLinkTimecode *timecode) = 0; + + virtual HRESULT STDMETHODCALLTYPE SetTimecodeFromComponents( + BMDTimecodeFormat format, + unsigned char hours, + unsigned char minutes, + unsigned char seconds, + unsigned char frames, + BMDTimecodeFlags flags) = 0; + + virtual HRESULT STDMETHODCALLTYPE SetAncillaryData( + /* [in] */ IDeckLinkVideoFrameAncillary *ancillary) = 0; + + }; + +#else /* C style interface */ + + typedef struct IDeckLinkMutableVideoFrameVtbl + { + BEGIN_INTERFACE + + HRESULT ( STDMETHODCALLTYPE *QueryInterface )( + IDeckLinkMutableVideoFrame * This, + /* [in] */ REFIID riid, + /* [iid_is][out] */ + __RPC__deref_out void **ppvObject); + + ULONG ( STDMETHODCALLTYPE *AddRef )( + IDeckLinkMutableVideoFrame * This); + + ULONG ( STDMETHODCALLTYPE *Release )( + IDeckLinkMutableVideoFrame * This); + + long ( STDMETHODCALLTYPE *GetWidth )( + IDeckLinkMutableVideoFrame * This); + + long ( STDMETHODCALLTYPE *GetHeight )( + IDeckLinkMutableVideoFrame * This); + + long ( STDMETHODCALLTYPE *GetRowBytes )( + IDeckLinkMutableVideoFrame * This); + + BMDPixelFormat ( STDMETHODCALLTYPE *GetPixelFormat )( + IDeckLinkMutableVideoFrame * This); + + BMDFrameFlags ( STDMETHODCALLTYPE *GetFlags )( + IDeckLinkMutableVideoFrame * This); + + HRESULT ( STDMETHODCALLTYPE *GetBytes )( + IDeckLinkMutableVideoFrame * This, + /* [out] */ void **buffer); + + HRESULT ( STDMETHODCALLTYPE *GetTimecode )( + IDeckLinkMutableVideoFrame * This, + BMDTimecodeFormat format, + /* [out] */ IDeckLinkTimecode **timecode); + + HRESULT ( STDMETHODCALLTYPE *GetAncillaryData )( + IDeckLinkMutableVideoFrame * This, + /* [out] */ IDeckLinkVideoFrameAncillary **ancillary); + + HRESULT ( STDMETHODCALLTYPE *SetFlags )( + IDeckLinkMutableVideoFrame * This, + BMDFrameFlags newFlags); + + HRESULT ( STDMETHODCALLTYPE *SetTimecode )( + IDeckLinkMutableVideoFrame * This, + BMDTimecodeFormat format, + /* [in] */ IDeckLinkTimecode *timecode); + + HRESULT ( STDMETHODCALLTYPE *SetTimecodeFromComponents )( + IDeckLinkMutableVideoFrame * This, + BMDTimecodeFormat format, + unsigned char hours, + unsigned char minutes, + unsigned char seconds, + unsigned char frames, + BMDTimecodeFlags flags); + + HRESULT ( STDMETHODCALLTYPE *SetAncillaryData )( + IDeckLinkMutableVideoFrame * This, + /* [in] */ IDeckLinkVideoFrameAncillary *ancillary); + + END_INTERFACE + } IDeckLinkMutableVideoFrameVtbl; + + interface IDeckLinkMutableVideoFrame + { + CONST_VTBL struct IDeckLinkMutableVideoFrameVtbl *lpVtbl; + }; + + + +#ifdef COBJMACROS + + +#define IDeckLinkMutableVideoFrame_QueryInterface(This,riid,ppvObject) \ + ( (This)->lpVtbl -> QueryInterface(This,riid,ppvObject) ) + +#define IDeckLinkMutableVideoFrame_AddRef(This) \ + ( (This)->lpVtbl -> AddRef(This) ) + +#define IDeckLinkMutableVideoFrame_Release(This) \ + ( (This)->lpVtbl -> Release(This) ) + + +#define IDeckLinkMutableVideoFrame_GetWidth(This) \ + ( (This)->lpVtbl -> GetWidth(This) ) + +#define IDeckLinkMutableVideoFrame_GetHeight(This) \ + ( (This)->lpVtbl -> GetHeight(This) ) + +#define IDeckLinkMutableVideoFrame_GetRowBytes(This) \ + ( (This)->lpVtbl -> GetRowBytes(This) ) + +#define IDeckLinkMutableVideoFrame_GetPixelFormat(This) \ + ( (This)->lpVtbl -> GetPixelFormat(This) ) + +#define IDeckLinkMutableVideoFrame_GetFlags(This) \ + ( (This)->lpVtbl -> GetFlags(This) ) + +#define IDeckLinkMutableVideoFrame_GetBytes(This,buffer) \ + ( (This)->lpVtbl -> GetBytes(This,buffer) ) + +#define IDeckLinkMutableVideoFrame_GetTimecode(This,format,timecode) \ + ( (This)->lpVtbl -> GetTimecode(This,format,timecode) ) + +#define IDeckLinkMutableVideoFrame_GetAncillaryData(This,ancillary) \ + ( (This)->lpVtbl -> GetAncillaryData(This,ancillary) ) + + +#define IDeckLinkMutableVideoFrame_SetFlags(This,newFlags) \ + ( (This)->lpVtbl -> SetFlags(This,newFlags) ) + +#define IDeckLinkMutableVideoFrame_SetTimecode(This,format,timecode) \ + ( (This)->lpVtbl -> SetTimecode(This,format,timecode) ) + +#define IDeckLinkMutableVideoFrame_SetTimecodeFromComponents(This,format,hours,minutes,seconds,frames,flags) \ + ( (This)->lpVtbl -> SetTimecodeFromComponents(This,format,hours,minutes,seconds,frames,flags) ) + +#define IDeckLinkMutableVideoFrame_SetAncillaryData(This,ancillary) \ + ( (This)->lpVtbl -> SetAncillaryData(This,ancillary) ) + +#endif /* COBJMACROS */ + + +#endif /* C style interface */ + + + + +#endif /* __IDeckLinkMutableVideoFrame_INTERFACE_DEFINED__ */ + + +#ifndef __IDeckLinkVideoInputFrame_INTERFACE_DEFINED__ +#define __IDeckLinkVideoInputFrame_INTERFACE_DEFINED__ + +/* interface IDeckLinkVideoInputFrame */ +/* [helpstring][local][uuid][object] */ + + +EXTERN_C const IID IID_IDeckLinkVideoInputFrame; + +#if defined(__cplusplus) && !defined(CINTERFACE) + + MIDL_INTERFACE("9A74FA41-AE9F-47AC-8CF4-01F42DD59965") + IDeckLinkVideoInputFrame : public IDeckLinkVideoFrame + { + public: + virtual HRESULT STDMETHODCALLTYPE GetStreamTime( + /* [out] */ BMDTimeValue *frameTime, + /* [out] */ BMDTimeValue *frameDuration, + BMDTimeScale timeScale) = 0; + + virtual HRESULT STDMETHODCALLTYPE GetHardwareReferenceTimestamp( + BMDTimeScale timeScale, + /* [out] */ BMDTimeValue *frameTime, + /* [out] */ BMDTimeValue *frameDuration) = 0; + + }; + +#else /* C style interface */ + + typedef struct IDeckLinkVideoInputFrameVtbl + { + BEGIN_INTERFACE + + HRESULT ( STDMETHODCALLTYPE *QueryInterface )( + IDeckLinkVideoInputFrame * This, + /* [in] */ REFIID riid, + /* [iid_is][out] */ + __RPC__deref_out void **ppvObject); + + ULONG ( STDMETHODCALLTYPE *AddRef )( + IDeckLinkVideoInputFrame * This); + + ULONG ( STDMETHODCALLTYPE *Release )( + IDeckLinkVideoInputFrame * This); + + long ( STDMETHODCALLTYPE *GetWidth )( + IDeckLinkVideoInputFrame * This); + + long ( STDMETHODCALLTYPE *GetHeight )( + IDeckLinkVideoInputFrame * This); + + long ( STDMETHODCALLTYPE *GetRowBytes )( + IDeckLinkVideoInputFrame * This); + + BMDPixelFormat ( STDMETHODCALLTYPE *GetPixelFormat )( + IDeckLinkVideoInputFrame * This); + + BMDFrameFlags ( STDMETHODCALLTYPE *GetFlags )( + IDeckLinkVideoInputFrame * This); + + HRESULT ( STDMETHODCALLTYPE *GetBytes )( + IDeckLinkVideoInputFrame * This, + /* [out] */ void **buffer); + + HRESULT ( STDMETHODCALLTYPE *GetTimecode )( + IDeckLinkVideoInputFrame * This, + BMDTimecodeFormat format, + /* [out] */ IDeckLinkTimecode **timecode); + + HRESULT ( STDMETHODCALLTYPE *GetAncillaryData )( + IDeckLinkVideoInputFrame * This, + /* [out] */ IDeckLinkVideoFrameAncillary **ancillary); + + HRESULT ( STDMETHODCALLTYPE *GetStreamTime )( + IDeckLinkVideoInputFrame * This, + /* [out] */ BMDTimeValue *frameTime, + /* [out] */ BMDTimeValue *frameDuration, + BMDTimeScale timeScale); + + HRESULT ( STDMETHODCALLTYPE *GetHardwareReferenceTimestamp )( + IDeckLinkVideoInputFrame * This, + BMDTimeScale timeScale, + /* [out] */ BMDTimeValue *frameTime, + /* [out] */ BMDTimeValue *frameDuration); + + END_INTERFACE + } IDeckLinkVideoInputFrameVtbl; + + interface IDeckLinkVideoInputFrame + { + CONST_VTBL struct IDeckLinkVideoInputFrameVtbl *lpVtbl; + }; + + + +#ifdef COBJMACROS + + +#define IDeckLinkVideoInputFrame_QueryInterface(This,riid,ppvObject) \ + ( (This)->lpVtbl -> QueryInterface(This,riid,ppvObject) ) + +#define IDeckLinkVideoInputFrame_AddRef(This) \ + ( (This)->lpVtbl -> AddRef(This) ) + +#define IDeckLinkVideoInputFrame_Release(This) \ + ( (This)->lpVtbl -> Release(This) ) + + +#define IDeckLinkVideoInputFrame_GetWidth(This) \ + ( (This)->lpVtbl -> GetWidth(This) ) + +#define IDeckLinkVideoInputFrame_GetHeight(This) \ + ( (This)->lpVtbl -> GetHeight(This) ) + +#define IDeckLinkVideoInputFrame_GetRowBytes(This) \ + ( (This)->lpVtbl -> GetRowBytes(This) ) + +#define IDeckLinkVideoInputFrame_GetPixelFormat(This) \ + ( (This)->lpVtbl -> GetPixelFormat(This) ) + +#define IDeckLinkVideoInputFrame_GetFlags(This) \ + ( (This)->lpVtbl -> GetFlags(This) ) + +#define IDeckLinkVideoInputFrame_GetBytes(This,buffer) \ + ( (This)->lpVtbl -> GetBytes(This,buffer) ) + +#define IDeckLinkVideoInputFrame_GetTimecode(This,format,timecode) \ + ( (This)->lpVtbl -> GetTimecode(This,format,timecode) ) + +#define IDeckLinkVideoInputFrame_GetAncillaryData(This,ancillary) \ + ( (This)->lpVtbl -> GetAncillaryData(This,ancillary) ) + + +#define IDeckLinkVideoInputFrame_GetStreamTime(This,frameTime,frameDuration,timeScale) \ + ( (This)->lpVtbl -> GetStreamTime(This,frameTime,frameDuration,timeScale) ) + +#define IDeckLinkVideoInputFrame_GetHardwareReferenceTimestamp(This,timeScale,frameTime,frameDuration) \ + ( (This)->lpVtbl -> GetHardwareReferenceTimestamp(This,timeScale,frameTime,frameDuration) ) + +#endif /* COBJMACROS */ + + +#endif /* C style interface */ + + + + +#endif /* __IDeckLinkVideoInputFrame_INTERFACE_DEFINED__ */ + + +#ifndef __IDeckLinkVideoFrameAncillary_INTERFACE_DEFINED__ +#define __IDeckLinkVideoFrameAncillary_INTERFACE_DEFINED__ + +/* interface IDeckLinkVideoFrameAncillary */ +/* [helpstring][local][uuid][object] */ + + +EXTERN_C const IID IID_IDeckLinkVideoFrameAncillary; + +#if defined(__cplusplus) && !defined(CINTERFACE) + + MIDL_INTERFACE("732E723C-D1A4-4E29-9E8E-4A88797A0004") + IDeckLinkVideoFrameAncillary : public IUnknown + { + public: + virtual HRESULT STDMETHODCALLTYPE GetBufferForVerticalBlankingLine( + unsigned long lineNumber, + /* [out] */ void **buffer) = 0; + + virtual BMDPixelFormat STDMETHODCALLTYPE GetPixelFormat( void) = 0; + + virtual BMDDisplayMode STDMETHODCALLTYPE GetDisplayMode( void) = 0; + + }; + +#else /* C style interface */ + + typedef struct IDeckLinkVideoFrameAncillaryVtbl + { + BEGIN_INTERFACE + + HRESULT ( STDMETHODCALLTYPE *QueryInterface )( + IDeckLinkVideoFrameAncillary * This, + /* [in] */ REFIID riid, + /* [iid_is][out] */ + __RPC__deref_out void **ppvObject); + + ULONG ( STDMETHODCALLTYPE *AddRef )( + IDeckLinkVideoFrameAncillary * This); + + ULONG ( STDMETHODCALLTYPE *Release )( + IDeckLinkVideoFrameAncillary * This); + + HRESULT ( STDMETHODCALLTYPE *GetBufferForVerticalBlankingLine )( + IDeckLinkVideoFrameAncillary * This, + unsigned long lineNumber, + /* [out] */ void **buffer); + + BMDPixelFormat ( STDMETHODCALLTYPE *GetPixelFormat )( + IDeckLinkVideoFrameAncillary * This); + + BMDDisplayMode ( STDMETHODCALLTYPE *GetDisplayMode )( + IDeckLinkVideoFrameAncillary * This); + + END_INTERFACE + } IDeckLinkVideoFrameAncillaryVtbl; + + interface IDeckLinkVideoFrameAncillary + { + CONST_VTBL struct IDeckLinkVideoFrameAncillaryVtbl *lpVtbl; + }; + + + +#ifdef COBJMACROS + + +#define IDeckLinkVideoFrameAncillary_QueryInterface(This,riid,ppvObject) \ + ( (This)->lpVtbl -> QueryInterface(This,riid,ppvObject) ) + +#define IDeckLinkVideoFrameAncillary_AddRef(This) \ + ( (This)->lpVtbl -> AddRef(This) ) + +#define IDeckLinkVideoFrameAncillary_Release(This) \ + ( (This)->lpVtbl -> Release(This) ) + + +#define IDeckLinkVideoFrameAncillary_GetBufferForVerticalBlankingLine(This,lineNumber,buffer) \ + ( (This)->lpVtbl -> GetBufferForVerticalBlankingLine(This,lineNumber,buffer) ) + +#define IDeckLinkVideoFrameAncillary_GetPixelFormat(This) \ + ( (This)->lpVtbl -> GetPixelFormat(This) ) + +#define IDeckLinkVideoFrameAncillary_GetDisplayMode(This) \ + ( (This)->lpVtbl -> GetDisplayMode(This) ) + +#endif /* COBJMACROS */ + + +#endif /* C style interface */ + + + + +#endif /* __IDeckLinkVideoFrameAncillary_INTERFACE_DEFINED__ */ + + +#ifndef __IDeckLinkAudioInputPacket_INTERFACE_DEFINED__ +#define __IDeckLinkAudioInputPacket_INTERFACE_DEFINED__ + +/* interface IDeckLinkAudioInputPacket */ +/* [helpstring][local][uuid][object] */ + + +EXTERN_C const IID IID_IDeckLinkAudioInputPacket; + +#if defined(__cplusplus) && !defined(CINTERFACE) + + MIDL_INTERFACE("E43D5870-2894-11DE-8C30-0800200C9A66") + IDeckLinkAudioInputPacket : public IUnknown + { + public: + virtual long STDMETHODCALLTYPE GetSampleFrameCount( void) = 0; + + virtual HRESULT STDMETHODCALLTYPE GetBytes( + /* [out] */ void **buffer) = 0; + + virtual HRESULT STDMETHODCALLTYPE GetPacketTime( + /* [out] */ BMDTimeValue *packetTime, + BMDTimeScale timeScale) = 0; + + }; + +#else /* C style interface */ + + typedef struct IDeckLinkAudioInputPacketVtbl + { + BEGIN_INTERFACE + + HRESULT ( STDMETHODCALLTYPE *QueryInterface )( + IDeckLinkAudioInputPacket * This, + /* [in] */ REFIID riid, + /* [iid_is][out] */ + __RPC__deref_out void **ppvObject); + + ULONG ( STDMETHODCALLTYPE *AddRef )( + IDeckLinkAudioInputPacket * This); + + ULONG ( STDMETHODCALLTYPE *Release )( + IDeckLinkAudioInputPacket * This); + + long ( STDMETHODCALLTYPE *GetSampleFrameCount )( + IDeckLinkAudioInputPacket * This); + + HRESULT ( STDMETHODCALLTYPE *GetBytes )( + IDeckLinkAudioInputPacket * This, + /* [out] */ void **buffer); + + HRESULT ( STDMETHODCALLTYPE *GetPacketTime )( + IDeckLinkAudioInputPacket * This, + /* [out] */ BMDTimeValue *packetTime, + BMDTimeScale timeScale); + + END_INTERFACE + } IDeckLinkAudioInputPacketVtbl; + + interface IDeckLinkAudioInputPacket + { + CONST_VTBL struct IDeckLinkAudioInputPacketVtbl *lpVtbl; + }; + + + +#ifdef COBJMACROS + + +#define IDeckLinkAudioInputPacket_QueryInterface(This,riid,ppvObject) \ + ( (This)->lpVtbl -> QueryInterface(This,riid,ppvObject) ) + +#define IDeckLinkAudioInputPacket_AddRef(This) \ + ( (This)->lpVtbl -> AddRef(This) ) + +#define IDeckLinkAudioInputPacket_Release(This) \ + ( (This)->lpVtbl -> Release(This) ) + + +#define IDeckLinkAudioInputPacket_GetSampleFrameCount(This) \ + ( (This)->lpVtbl -> GetSampleFrameCount(This) ) + +#define IDeckLinkAudioInputPacket_GetBytes(This,buffer) \ + ( (This)->lpVtbl -> GetBytes(This,buffer) ) + +#define IDeckLinkAudioInputPacket_GetPacketTime(This,packetTime,timeScale) \ + ( (This)->lpVtbl -> GetPacketTime(This,packetTime,timeScale) ) + +#endif /* COBJMACROS */ + + +#endif /* C style interface */ + + + + +#endif /* __IDeckLinkAudioInputPacket_INTERFACE_DEFINED__ */ + + +#ifndef __IDeckLinkScreenPreviewCallback_INTERFACE_DEFINED__ +#define __IDeckLinkScreenPreviewCallback_INTERFACE_DEFINED__ + +/* interface IDeckLinkScreenPreviewCallback */ +/* [helpstring][local][uuid][object] */ + + +EXTERN_C const IID IID_IDeckLinkScreenPreviewCallback; + +#if defined(__cplusplus) && !defined(CINTERFACE) + + MIDL_INTERFACE("373F499D-4B4D-4518-AD22-6354E5A5825E") + IDeckLinkScreenPreviewCallback : public IUnknown + { + public: + virtual HRESULT STDMETHODCALLTYPE DrawFrame( + /* [in] */ IDeckLinkVideoFrame *theFrame) = 0; + + }; + +#else /* C style interface */ + + typedef struct IDeckLinkScreenPreviewCallbackVtbl + { + BEGIN_INTERFACE + + HRESULT ( STDMETHODCALLTYPE *QueryInterface )( + IDeckLinkScreenPreviewCallback * This, + /* [in] */ REFIID riid, + /* [iid_is][out] */ + __RPC__deref_out void **ppvObject); + + ULONG ( STDMETHODCALLTYPE *AddRef )( + IDeckLinkScreenPreviewCallback * This); + + ULONG ( STDMETHODCALLTYPE *Release )( + IDeckLinkScreenPreviewCallback * This); + + HRESULT ( STDMETHODCALLTYPE *DrawFrame )( + IDeckLinkScreenPreviewCallback * This, + /* [in] */ IDeckLinkVideoFrame *theFrame); + + END_INTERFACE + } IDeckLinkScreenPreviewCallbackVtbl; + + interface IDeckLinkScreenPreviewCallback + { + CONST_VTBL struct IDeckLinkScreenPreviewCallbackVtbl *lpVtbl; + }; + + + +#ifdef COBJMACROS + + +#define IDeckLinkScreenPreviewCallback_QueryInterface(This,riid,ppvObject) \ + ( (This)->lpVtbl -> QueryInterface(This,riid,ppvObject) ) + +#define IDeckLinkScreenPreviewCallback_AddRef(This) \ + ( (This)->lpVtbl -> AddRef(This) ) + +#define IDeckLinkScreenPreviewCallback_Release(This) \ + ( (This)->lpVtbl -> Release(This) ) + + +#define IDeckLinkScreenPreviewCallback_DrawFrame(This,theFrame) \ + ( (This)->lpVtbl -> DrawFrame(This,theFrame) ) + +#endif /* COBJMACROS */ + + +#endif /* C style interface */ + + + + +#endif /* __IDeckLinkScreenPreviewCallback_INTERFACE_DEFINED__ */ + + +#ifndef __IDeckLinkGLScreenPreviewHelper_INTERFACE_DEFINED__ +#define __IDeckLinkGLScreenPreviewHelper_INTERFACE_DEFINED__ + +/* interface IDeckLinkGLScreenPreviewHelper */ +/* [helpstring][local][uuid][object] */ + + +EXTERN_C const IID IID_IDeckLinkGLScreenPreviewHelper; + +#if defined(__cplusplus) && !defined(CINTERFACE) + + MIDL_INTERFACE("BA575CD9-A15E-497B-B2C2-F9AFE7BE4EBA") + IDeckLinkGLScreenPreviewHelper : public IUnknown + { + public: + virtual HRESULT STDMETHODCALLTYPE InitializeGL( void) = 0; + + virtual HRESULT STDMETHODCALLTYPE PaintGL( void) = 0; + + virtual HRESULT STDMETHODCALLTYPE SetFrame( + /* [in] */ IDeckLinkVideoFrame *theFrame) = 0; + + }; + +#else /* C style interface */ + + typedef struct IDeckLinkGLScreenPreviewHelperVtbl + { + BEGIN_INTERFACE + + HRESULT ( STDMETHODCALLTYPE *QueryInterface )( + IDeckLinkGLScreenPreviewHelper * This, + /* [in] */ REFIID riid, + /* [iid_is][out] */ + __RPC__deref_out void **ppvObject); + + ULONG ( STDMETHODCALLTYPE *AddRef )( + IDeckLinkGLScreenPreviewHelper * This); + + ULONG ( STDMETHODCALLTYPE *Release )( + IDeckLinkGLScreenPreviewHelper * This); + + HRESULT ( STDMETHODCALLTYPE *InitializeGL )( + IDeckLinkGLScreenPreviewHelper * This); + + HRESULT ( STDMETHODCALLTYPE *PaintGL )( + IDeckLinkGLScreenPreviewHelper * This); + + HRESULT ( STDMETHODCALLTYPE *SetFrame )( + IDeckLinkGLScreenPreviewHelper * This, + /* [in] */ IDeckLinkVideoFrame *theFrame); + + END_INTERFACE + } IDeckLinkGLScreenPreviewHelperVtbl; + + interface IDeckLinkGLScreenPreviewHelper + { + CONST_VTBL struct IDeckLinkGLScreenPreviewHelperVtbl *lpVtbl; + }; + + + +#ifdef COBJMACROS + + +#define IDeckLinkGLScreenPreviewHelper_QueryInterface(This,riid,ppvObject) \ + ( (This)->lpVtbl -> QueryInterface(This,riid,ppvObject) ) + +#define IDeckLinkGLScreenPreviewHelper_AddRef(This) \ + ( (This)->lpVtbl -> AddRef(This) ) + +#define IDeckLinkGLScreenPreviewHelper_Release(This) \ + ( (This)->lpVtbl -> Release(This) ) + + +#define IDeckLinkGLScreenPreviewHelper_InitializeGL(This) \ + ( (This)->lpVtbl -> InitializeGL(This) ) + +#define IDeckLinkGLScreenPreviewHelper_PaintGL(This) \ + ( (This)->lpVtbl -> PaintGL(This) ) + +#define IDeckLinkGLScreenPreviewHelper_SetFrame(This,theFrame) \ + ( (This)->lpVtbl -> SetFrame(This,theFrame) ) + +#endif /* COBJMACROS */ + + +#endif /* C style interface */ + + + + +#endif /* __IDeckLinkGLScreenPreviewHelper_INTERFACE_DEFINED__ */ + + +#ifndef __IDeckLinkConfiguration_INTERFACE_DEFINED__ +#define __IDeckLinkConfiguration_INTERFACE_DEFINED__ + +/* interface IDeckLinkConfiguration */ +/* [helpstring][uuid][object] */ + + +EXTERN_C const IID IID_IDeckLinkConfiguration; + +#if defined(__cplusplus) && !defined(CINTERFACE) + + MIDL_INTERFACE("B8EAD569-B764-47F0-A73F-AE40DF6CBF10") + IDeckLinkConfiguration : public IUnknown + { + public: + virtual HRESULT STDMETHODCALLTYPE GetConfigurationValidator( + /* [out] */ IDeckLinkConfiguration **configObject) = 0; + + virtual HRESULT STDMETHODCALLTYPE WriteConfigurationToPreferences( void) = 0; + + virtual HRESULT STDMETHODCALLTYPE SetVideoOutputFormat( + BMDVideoConnection videoOutputConnection) = 0; + + virtual HRESULT STDMETHODCALLTYPE IsVideoOutputActive( + BMDVideoConnection videoOutputConnection, + /* [out] */ BOOL *active) = 0; + + virtual HRESULT STDMETHODCALLTYPE SetAnalogVideoOutputFlags( + BMDAnalogVideoFlags analogVideoFlags) = 0; + + virtual HRESULT STDMETHODCALLTYPE GetAnalogVideoOutputFlags( + /* [out] */ BMDAnalogVideoFlags *analogVideoFlags) = 0; + + virtual HRESULT STDMETHODCALLTYPE EnableFieldFlickerRemovalWhenPaused( + BOOL enable) = 0; + + virtual HRESULT STDMETHODCALLTYPE IsEnabledFieldFlickerRemovalWhenPaused( + /* [out] */ BOOL *enabled) = 0; + + virtual HRESULT STDMETHODCALLTYPE Set444And3GBpsVideoOutput( + BOOL enable444VideoOutput, + BOOL enable3GbsOutput) = 0; + + virtual HRESULT STDMETHODCALLTYPE Get444And3GBpsVideoOutput( + /* [out] */ BOOL *is444VideoOutputEnabled, + /* [out] */ BOOL *threeGbsOutputEnabled) = 0; + + virtual HRESULT STDMETHODCALLTYPE SetVideoOutputConversionMode( + BMDVideoOutputConversionMode conversionMode) = 0; + + virtual HRESULT STDMETHODCALLTYPE GetVideoOutputConversionMode( + /* [out] */ BMDVideoOutputConversionMode *conversionMode) = 0; + + virtual HRESULT STDMETHODCALLTYPE Set_HD1080p24_to_HD1080i5994_Conversion( + BOOL enable) = 0; + + virtual HRESULT STDMETHODCALLTYPE Get_HD1080p24_to_HD1080i5994_Conversion( + /* [out] */ BOOL *enabled) = 0; + + virtual HRESULT STDMETHODCALLTYPE SetVideoInputFormat( + BMDVideoConnection videoInputFormat) = 0; + + virtual HRESULT STDMETHODCALLTYPE GetVideoInputFormat( + /* [out] */ BMDVideoConnection *videoInputFormat) = 0; + + virtual HRESULT STDMETHODCALLTYPE SetAnalogVideoInputFlags( + BMDAnalogVideoFlags analogVideoFlags) = 0; + + virtual HRESULT STDMETHODCALLTYPE GetAnalogVideoInputFlags( + /* [out] */ BMDAnalogVideoFlags *analogVideoFlags) = 0; + + virtual HRESULT STDMETHODCALLTYPE SetVideoInputConversionMode( + BMDVideoInputConversionMode conversionMode) = 0; + + virtual HRESULT STDMETHODCALLTYPE GetVideoInputConversionMode( + /* [out] */ BMDVideoInputConversionMode *conversionMode) = 0; + + virtual HRESULT STDMETHODCALLTYPE SetBlackVideoOutputDuringCapture( + BOOL blackOutInCapture) = 0; + + virtual HRESULT STDMETHODCALLTYPE GetBlackVideoOutputDuringCapture( + /* [out] */ BOOL *blackOutInCapture) = 0; + + virtual HRESULT STDMETHODCALLTYPE Set32PulldownSequenceInitialTimecodeFrame( + unsigned long aFrameTimecode) = 0; + + virtual HRESULT STDMETHODCALLTYPE Get32PulldownSequenceInitialTimecodeFrame( + /* [out] */ unsigned long *aFrameTimecode) = 0; + + virtual HRESULT STDMETHODCALLTYPE SetVancSourceLineMapping( + unsigned long activeLine1VANCsource, + unsigned long activeLine2VANCsource, + unsigned long activeLine3VANCsource) = 0; + + virtual HRESULT STDMETHODCALLTYPE GetVancSourceLineMapping( + /* [out] */ unsigned long *activeLine1VANCsource, + /* [out] */ unsigned long *activeLine2VANCsource, + /* [out] */ unsigned long *activeLine3VANCsource) = 0; + + virtual HRESULT STDMETHODCALLTYPE SetAudioInputFormat( + BMDAudioConnection audioInputFormat) = 0; + + virtual HRESULT STDMETHODCALLTYPE GetAudioInputFormat( + /* [out] */ BMDAudioConnection *audioInputFormat) = 0; + + }; + +#else /* C style interface */ + + typedef struct IDeckLinkConfigurationVtbl + { + BEGIN_INTERFACE + + HRESULT ( STDMETHODCALLTYPE *QueryInterface )( + IDeckLinkConfiguration * This, + /* [in] */ REFIID riid, + /* [iid_is][out] */ + __RPC__deref_out void **ppvObject); + + ULONG ( STDMETHODCALLTYPE *AddRef )( + IDeckLinkConfiguration * This); + + ULONG ( STDMETHODCALLTYPE *Release )( + IDeckLinkConfiguration * This); + + HRESULT ( STDMETHODCALLTYPE *GetConfigurationValidator )( + IDeckLinkConfiguration * This, + /* [out] */ IDeckLinkConfiguration **configObject); + + HRESULT ( STDMETHODCALLTYPE *WriteConfigurationToPreferences )( + IDeckLinkConfiguration * This); + + HRESULT ( STDMETHODCALLTYPE *SetVideoOutputFormat )( + IDeckLinkConfiguration * This, + BMDVideoConnection videoOutputConnection); + + HRESULT ( STDMETHODCALLTYPE *IsVideoOutputActive )( + IDeckLinkConfiguration * This, + BMDVideoConnection videoOutputConnection, + /* [out] */ BOOL *active); + + HRESULT ( STDMETHODCALLTYPE *SetAnalogVideoOutputFlags )( + IDeckLinkConfiguration * This, + BMDAnalogVideoFlags analogVideoFlags); + + HRESULT ( STDMETHODCALLTYPE *GetAnalogVideoOutputFlags )( + IDeckLinkConfiguration * This, + /* [out] */ BMDAnalogVideoFlags *analogVideoFlags); + + HRESULT ( STDMETHODCALLTYPE *EnableFieldFlickerRemovalWhenPaused )( + IDeckLinkConfiguration * This, + BOOL enable); + + HRESULT ( STDMETHODCALLTYPE *IsEnabledFieldFlickerRemovalWhenPaused )( + IDeckLinkConfiguration * This, + /* [out] */ BOOL *enabled); + + HRESULT ( STDMETHODCALLTYPE *Set444And3GBpsVideoOutput )( + IDeckLinkConfiguration * This, + BOOL enable444VideoOutput, + BOOL enable3GbsOutput); + + HRESULT ( STDMETHODCALLTYPE *Get444And3GBpsVideoOutput )( + IDeckLinkConfiguration * This, + /* [out] */ BOOL *is444VideoOutputEnabled, + /* [out] */ BOOL *threeGbsOutputEnabled); + + HRESULT ( STDMETHODCALLTYPE *SetVideoOutputConversionMode )( + IDeckLinkConfiguration * This, + BMDVideoOutputConversionMode conversionMode); + + HRESULT ( STDMETHODCALLTYPE *GetVideoOutputConversionMode )( + IDeckLinkConfiguration * This, + /* [out] */ BMDVideoOutputConversionMode *conversionMode); + + HRESULT ( STDMETHODCALLTYPE *Set_HD1080p24_to_HD1080i5994_Conversion )( + IDeckLinkConfiguration * This, + BOOL enable); + + HRESULT ( STDMETHODCALLTYPE *Get_HD1080p24_to_HD1080i5994_Conversion )( + IDeckLinkConfiguration * This, + /* [out] */ BOOL *enabled); + + HRESULT ( STDMETHODCALLTYPE *SetVideoInputFormat )( + IDeckLinkConfiguration * This, + BMDVideoConnection videoInputFormat); + + HRESULT ( STDMETHODCALLTYPE *GetVideoInputFormat )( + IDeckLinkConfiguration * This, + /* [out] */ BMDVideoConnection *videoInputFormat); + + HRESULT ( STDMETHODCALLTYPE *SetAnalogVideoInputFlags )( + IDeckLinkConfiguration * This, + BMDAnalogVideoFlags analogVideoFlags); + + HRESULT ( STDMETHODCALLTYPE *GetAnalogVideoInputFlags )( + IDeckLinkConfiguration * This, + /* [out] */ BMDAnalogVideoFlags *analogVideoFlags); + + HRESULT ( STDMETHODCALLTYPE *SetVideoInputConversionMode )( + IDeckLinkConfiguration * This, + BMDVideoInputConversionMode conversionMode); + + HRESULT ( STDMETHODCALLTYPE *GetVideoInputConversionMode )( + IDeckLinkConfiguration * This, + /* [out] */ BMDVideoInputConversionMode *conversionMode); + + HRESULT ( STDMETHODCALLTYPE *SetBlackVideoOutputDuringCapture )( + IDeckLinkConfiguration * This, + BOOL blackOutInCapture); + + HRESULT ( STDMETHODCALLTYPE *GetBlackVideoOutputDuringCapture )( + IDeckLinkConfiguration * This, + /* [out] */ BOOL *blackOutInCapture); + + HRESULT ( STDMETHODCALLTYPE *Set32PulldownSequenceInitialTimecodeFrame )( + IDeckLinkConfiguration * This, + unsigned long aFrameTimecode); + + HRESULT ( STDMETHODCALLTYPE *Get32PulldownSequenceInitialTimecodeFrame )( + IDeckLinkConfiguration * This, + /* [out] */ unsigned long *aFrameTimecode); + + HRESULT ( STDMETHODCALLTYPE *SetVancSourceLineMapping )( + IDeckLinkConfiguration * This, + unsigned long activeLine1VANCsource, + unsigned long activeLine2VANCsource, + unsigned long activeLine3VANCsource); + + HRESULT ( STDMETHODCALLTYPE *GetVancSourceLineMapping )( + IDeckLinkConfiguration * This, + /* [out] */ unsigned long *activeLine1VANCsource, + /* [out] */ unsigned long *activeLine2VANCsource, + /* [out] */ unsigned long *activeLine3VANCsource); + + HRESULT ( STDMETHODCALLTYPE *SetAudioInputFormat )( + IDeckLinkConfiguration * This, + BMDAudioConnection audioInputFormat); + + HRESULT ( STDMETHODCALLTYPE *GetAudioInputFormat )( + IDeckLinkConfiguration * This, + /* [out] */ BMDAudioConnection *audioInputFormat); + + END_INTERFACE + } IDeckLinkConfigurationVtbl; + + interface IDeckLinkConfiguration + { + CONST_VTBL struct IDeckLinkConfigurationVtbl *lpVtbl; + }; + + + +#ifdef COBJMACROS + + +#define IDeckLinkConfiguration_QueryInterface(This,riid,ppvObject) \ + ( (This)->lpVtbl -> QueryInterface(This,riid,ppvObject) ) + +#define IDeckLinkConfiguration_AddRef(This) \ + ( (This)->lpVtbl -> AddRef(This) ) + +#define IDeckLinkConfiguration_Release(This) \ + ( (This)->lpVtbl -> Release(This) ) + + +#define IDeckLinkConfiguration_GetConfigurationValidator(This,configObject) \ + ( (This)->lpVtbl -> GetConfigurationValidator(This,configObject) ) + +#define IDeckLinkConfiguration_WriteConfigurationToPreferences(This) \ + ( (This)->lpVtbl -> WriteConfigurationToPreferences(This) ) + +#define IDeckLinkConfiguration_SetVideoOutputFormat(This,videoOutputConnection) \ + ( (This)->lpVtbl -> SetVideoOutputFormat(This,videoOutputConnection) ) + +#define IDeckLinkConfiguration_IsVideoOutputActive(This,videoOutputConnection,active) \ + ( (This)->lpVtbl -> IsVideoOutputActive(This,videoOutputConnection,active) ) + +#define IDeckLinkConfiguration_SetAnalogVideoOutputFlags(This,analogVideoFlags) \ + ( (This)->lpVtbl -> SetAnalogVideoOutputFlags(This,analogVideoFlags) ) + +#define IDeckLinkConfiguration_GetAnalogVideoOutputFlags(This,analogVideoFlags) \ + ( (This)->lpVtbl -> GetAnalogVideoOutputFlags(This,analogVideoFlags) ) + +#define IDeckLinkConfiguration_EnableFieldFlickerRemovalWhenPaused(This,enable) \ + ( (This)->lpVtbl -> EnableFieldFlickerRemovalWhenPaused(This,enable) ) + +#define IDeckLinkConfiguration_IsEnabledFieldFlickerRemovalWhenPaused(This,enabled) \ + ( (This)->lpVtbl -> IsEnabledFieldFlickerRemovalWhenPaused(This,enabled) ) + +#define IDeckLinkConfiguration_Set444And3GBpsVideoOutput(This,enable444VideoOutput,enable3GbsOutput) \ + ( (This)->lpVtbl -> Set444And3GBpsVideoOutput(This,enable444VideoOutput,enable3GbsOutput) ) + +#define IDeckLinkConfiguration_Get444And3GBpsVideoOutput(This,is444VideoOutputEnabled,threeGbsOutputEnabled) \ + ( (This)->lpVtbl -> Get444And3GBpsVideoOutput(This,is444VideoOutputEnabled,threeGbsOutputEnabled) ) + +#define IDeckLinkConfiguration_SetVideoOutputConversionMode(This,conversionMode) \ + ( (This)->lpVtbl -> SetVideoOutputConversionMode(This,conversionMode) ) + +#define IDeckLinkConfiguration_GetVideoOutputConversionMode(This,conversionMode) \ + ( (This)->lpVtbl -> GetVideoOutputConversionMode(This,conversionMode) ) + +#define IDeckLinkConfiguration_Set_HD1080p24_to_HD1080i5994_Conversion(This,enable) \ + ( (This)->lpVtbl -> Set_HD1080p24_to_HD1080i5994_Conversion(This,enable) ) + +#define IDeckLinkConfiguration_Get_HD1080p24_to_HD1080i5994_Conversion(This,enabled) \ + ( (This)->lpVtbl -> Get_HD1080p24_to_HD1080i5994_Conversion(This,enabled) ) + +#define IDeckLinkConfiguration_SetVideoInputFormat(This,videoInputFormat) \ + ( (This)->lpVtbl -> SetVideoInputFormat(This,videoInputFormat) ) + +#define IDeckLinkConfiguration_GetVideoInputFormat(This,videoInputFormat) \ + ( (This)->lpVtbl -> GetVideoInputFormat(This,videoInputFormat) ) + +#define IDeckLinkConfiguration_SetAnalogVideoInputFlags(This,analogVideoFlags) \ + ( (This)->lpVtbl -> SetAnalogVideoInputFlags(This,analogVideoFlags) ) + +#define IDeckLinkConfiguration_GetAnalogVideoInputFlags(This,analogVideoFlags) \ + ( (This)->lpVtbl -> GetAnalogVideoInputFlags(This,analogVideoFlags) ) + +#define IDeckLinkConfiguration_SetVideoInputConversionMode(This,conversionMode) \ + ( (This)->lpVtbl -> SetVideoInputConversionMode(This,conversionMode) ) + +#define IDeckLinkConfiguration_GetVideoInputConversionMode(This,conversionMode) \ + ( (This)->lpVtbl -> GetVideoInputConversionMode(This,conversionMode) ) + +#define IDeckLinkConfiguration_SetBlackVideoOutputDuringCapture(This,blackOutInCapture) \ + ( (This)->lpVtbl -> SetBlackVideoOutputDuringCapture(This,blackOutInCapture) ) + +#define IDeckLinkConfiguration_GetBlackVideoOutputDuringCapture(This,blackOutInCapture) \ + ( (This)->lpVtbl -> GetBlackVideoOutputDuringCapture(This,blackOutInCapture) ) + +#define IDeckLinkConfiguration_Set32PulldownSequenceInitialTimecodeFrame(This,aFrameTimecode) \ + ( (This)->lpVtbl -> Set32PulldownSequenceInitialTimecodeFrame(This,aFrameTimecode) ) + +#define IDeckLinkConfiguration_Get32PulldownSequenceInitialTimecodeFrame(This,aFrameTimecode) \ + ( (This)->lpVtbl -> Get32PulldownSequenceInitialTimecodeFrame(This,aFrameTimecode) ) + +#define IDeckLinkConfiguration_SetVancSourceLineMapping(This,activeLine1VANCsource,activeLine2VANCsource,activeLine3VANCsource) \ + ( (This)->lpVtbl -> SetVancSourceLineMapping(This,activeLine1VANCsource,activeLine2VANCsource,activeLine3VANCsource) ) + +#define IDeckLinkConfiguration_GetVancSourceLineMapping(This,activeLine1VANCsource,activeLine2VANCsource,activeLine3VANCsource) \ + ( (This)->lpVtbl -> GetVancSourceLineMapping(This,activeLine1VANCsource,activeLine2VANCsource,activeLine3VANCsource) ) + +#define IDeckLinkConfiguration_SetAudioInputFormat(This,audioInputFormat) \ + ( (This)->lpVtbl -> SetAudioInputFormat(This,audioInputFormat) ) + +#define IDeckLinkConfiguration_GetAudioInputFormat(This,audioInputFormat) \ + ( (This)->lpVtbl -> GetAudioInputFormat(This,audioInputFormat) ) + +#endif /* COBJMACROS */ + + +#endif /* C style interface */ + + + + +#endif /* __IDeckLinkConfiguration_INTERFACE_DEFINED__ */ + + +#ifndef __IDeckLinkAttributes_INTERFACE_DEFINED__ +#define __IDeckLinkAttributes_INTERFACE_DEFINED__ + +/* interface IDeckLinkAttributes */ +/* [helpstring][local][uuid][object] */ + + +EXTERN_C const IID IID_IDeckLinkAttributes; + +#if defined(__cplusplus) && !defined(CINTERFACE) + + MIDL_INTERFACE("ABC11843-D966-44CB-96E2-A1CB5D3135C4") + IDeckLinkAttributes : public IUnknown + { + public: + virtual HRESULT STDMETHODCALLTYPE GetFlag( + /* [in] */ BMDDeckLinkAttributeID cfgID, + /* [out] */ BOOL *value) = 0; + + virtual HRESULT STDMETHODCALLTYPE GetInt( + /* [in] */ BMDDeckLinkAttributeID cfgID, + /* [out] */ LONGLONG *value) = 0; + + virtual HRESULT STDMETHODCALLTYPE GetFloat( + /* [in] */ BMDDeckLinkAttributeID cfgID, + /* [out] */ double *value) = 0; + + virtual HRESULT STDMETHODCALLTYPE GetString( + /* [in] */ BMDDeckLinkAttributeID cfgID, + /* [out] */ BSTR *value) = 0; + + }; + +#else /* C style interface */ + + typedef struct IDeckLinkAttributesVtbl + { + BEGIN_INTERFACE + + HRESULT ( STDMETHODCALLTYPE *QueryInterface )( + IDeckLinkAttributes * This, + /* [in] */ REFIID riid, + /* [iid_is][out] */ + __RPC__deref_out void **ppvObject); + + ULONG ( STDMETHODCALLTYPE *AddRef )( + IDeckLinkAttributes * This); + + ULONG ( STDMETHODCALLTYPE *Release )( + IDeckLinkAttributes * This); + + HRESULT ( STDMETHODCALLTYPE *GetFlag )( + IDeckLinkAttributes * This, + /* [in] */ BMDDeckLinkAttributeID cfgID, + /* [out] */ BOOL *value); + + HRESULT ( STDMETHODCALLTYPE *GetInt )( + IDeckLinkAttributes * This, + /* [in] */ BMDDeckLinkAttributeID cfgID, + /* [out] */ LONGLONG *value); + + HRESULT ( STDMETHODCALLTYPE *GetFloat )( + IDeckLinkAttributes * This, + /* [in] */ BMDDeckLinkAttributeID cfgID, + /* [out] */ double *value); + + HRESULT ( STDMETHODCALLTYPE *GetString )( + IDeckLinkAttributes * This, + /* [in] */ BMDDeckLinkAttributeID cfgID, + /* [out] */ BSTR *value); + + END_INTERFACE + } IDeckLinkAttributesVtbl; + + interface IDeckLinkAttributes + { + CONST_VTBL struct IDeckLinkAttributesVtbl *lpVtbl; + }; + + + +#ifdef COBJMACROS + + +#define IDeckLinkAttributes_QueryInterface(This,riid,ppvObject) \ + ( (This)->lpVtbl -> QueryInterface(This,riid,ppvObject) ) + +#define IDeckLinkAttributes_AddRef(This) \ + ( (This)->lpVtbl -> AddRef(This) ) + +#define IDeckLinkAttributes_Release(This) \ + ( (This)->lpVtbl -> Release(This) ) + + +#define IDeckLinkAttributes_GetFlag(This,cfgID,value) \ + ( (This)->lpVtbl -> GetFlag(This,cfgID,value) ) + +#define IDeckLinkAttributes_GetInt(This,cfgID,value) \ + ( (This)->lpVtbl -> GetInt(This,cfgID,value) ) + +#define IDeckLinkAttributes_GetFloat(This,cfgID,value) \ + ( (This)->lpVtbl -> GetFloat(This,cfgID,value) ) + +#define IDeckLinkAttributes_GetString(This,cfgID,value) \ + ( (This)->lpVtbl -> GetString(This,cfgID,value) ) + +#endif /* COBJMACROS */ + + +#endif /* C style interface */ + + + + +#endif /* __IDeckLinkAttributes_INTERFACE_DEFINED__ */ + + +#ifndef __IDeckLinkKeyer_INTERFACE_DEFINED__ +#define __IDeckLinkKeyer_INTERFACE_DEFINED__ + +/* interface IDeckLinkKeyer */ +/* [helpstring][local][uuid][object] */ + + +EXTERN_C const IID IID_IDeckLinkKeyer; + +#if defined(__cplusplus) && !defined(CINTERFACE) + + MIDL_INTERFACE("89AFCAF5-65F8-421E-98F7-96FE5F5BFBA3") + IDeckLinkKeyer : public IUnknown + { + public: + virtual HRESULT STDMETHODCALLTYPE Enable( + /* [in] */ BOOL isExternal) = 0; + + virtual HRESULT STDMETHODCALLTYPE SetLevel( + /* [in] */ unsigned char level) = 0; + + virtual HRESULT STDMETHODCALLTYPE RampUp( + /* [in] */ unsigned long numberOfFrames) = 0; + + virtual HRESULT STDMETHODCALLTYPE RampDown( + /* [in] */ unsigned long numberOfFrames) = 0; + + virtual HRESULT STDMETHODCALLTYPE Disable( void) = 0; + + }; + +#else /* C style interface */ + + typedef struct IDeckLinkKeyerVtbl + { + BEGIN_INTERFACE + + HRESULT ( STDMETHODCALLTYPE *QueryInterface )( + IDeckLinkKeyer * This, + /* [in] */ REFIID riid, + /* [iid_is][out] */ + __RPC__deref_out void **ppvObject); + + ULONG ( STDMETHODCALLTYPE *AddRef )( + IDeckLinkKeyer * This); + + ULONG ( STDMETHODCALLTYPE *Release )( + IDeckLinkKeyer * This); + + HRESULT ( STDMETHODCALLTYPE *Enable )( + IDeckLinkKeyer * This, + /* [in] */ BOOL isExternal); + + HRESULT ( STDMETHODCALLTYPE *SetLevel )( + IDeckLinkKeyer * This, + /* [in] */ unsigned char level); + + HRESULT ( STDMETHODCALLTYPE *RampUp )( + IDeckLinkKeyer * This, + /* [in] */ unsigned long numberOfFrames); + + HRESULT ( STDMETHODCALLTYPE *RampDown )( + IDeckLinkKeyer * This, + /* [in] */ unsigned long numberOfFrames); + + HRESULT ( STDMETHODCALLTYPE *Disable )( + IDeckLinkKeyer * This); + + END_INTERFACE + } IDeckLinkKeyerVtbl; + + interface IDeckLinkKeyer + { + CONST_VTBL struct IDeckLinkKeyerVtbl *lpVtbl; + }; + + + +#ifdef COBJMACROS + + +#define IDeckLinkKeyer_QueryInterface(This,riid,ppvObject) \ + ( (This)->lpVtbl -> QueryInterface(This,riid,ppvObject) ) + +#define IDeckLinkKeyer_AddRef(This) \ + ( (This)->lpVtbl -> AddRef(This) ) + +#define IDeckLinkKeyer_Release(This) \ + ( (This)->lpVtbl -> Release(This) ) + + +#define IDeckLinkKeyer_Enable(This,isExternal) \ + ( (This)->lpVtbl -> Enable(This,isExternal) ) + +#define IDeckLinkKeyer_SetLevel(This,level) \ + ( (This)->lpVtbl -> SetLevel(This,level) ) + +#define IDeckLinkKeyer_RampUp(This,numberOfFrames) \ + ( (This)->lpVtbl -> RampUp(This,numberOfFrames) ) + +#define IDeckLinkKeyer_RampDown(This,numberOfFrames) \ + ( (This)->lpVtbl -> RampDown(This,numberOfFrames) ) + +#define IDeckLinkKeyer_Disable(This) \ + ( (This)->lpVtbl -> Disable(This) ) + +#endif /* COBJMACROS */ + + +#endif /* C style interface */ + + + + +#endif /* __IDeckLinkKeyer_INTERFACE_DEFINED__ */ + + +EXTERN_C const CLSID CLSID_CDeckLinkIterator; + +#ifdef __cplusplus + +class DECLSPEC_UUID("D9EDA3B3-2887-41FA-B724-017CF1EB1D37") +CDeckLinkIterator; +#endif + +EXTERN_C const CLSID CLSID_CDeckLinkGLScreenPreviewHelper; + +#ifdef __cplusplus + +class DECLSPEC_UUID("D398CEE7-4434-4CA3-9BA6-5AE34556B905") +CDeckLinkGLScreenPreviewHelper; +#endif + +#ifndef __IDeckLinkDisplayModeIterator_v7_1_INTERFACE_DEFINED__ +#define __IDeckLinkDisplayModeIterator_v7_1_INTERFACE_DEFINED__ + +/* interface IDeckLinkDisplayModeIterator_v7_1 */ +/* [helpstring][uuid][object] */ + + +EXTERN_C const IID IID_IDeckLinkDisplayModeIterator_v7_1; + +#if defined(__cplusplus) && !defined(CINTERFACE) + + MIDL_INTERFACE("B28131B6-59AC-4857-B5AC-CD75D5883E2F") + IDeckLinkDisplayModeIterator_v7_1 : public IUnknown + { + public: + virtual HRESULT STDMETHODCALLTYPE Next( + /* [out] */ IDeckLinkDisplayMode_v7_1 **deckLinkDisplayMode) = 0; + + }; + +#else /* C style interface */ + + typedef struct IDeckLinkDisplayModeIterator_v7_1Vtbl + { + BEGIN_INTERFACE + + HRESULT ( STDMETHODCALLTYPE *QueryInterface )( + IDeckLinkDisplayModeIterator_v7_1 * This, + /* [in] */ REFIID riid, + /* [iid_is][out] */ + __RPC__deref_out void **ppvObject); + + ULONG ( STDMETHODCALLTYPE *AddRef )( + IDeckLinkDisplayModeIterator_v7_1 * This); + + ULONG ( STDMETHODCALLTYPE *Release )( + IDeckLinkDisplayModeIterator_v7_1 * This); + + HRESULT ( STDMETHODCALLTYPE *Next )( + IDeckLinkDisplayModeIterator_v7_1 * This, + /* [out] */ IDeckLinkDisplayMode_v7_1 **deckLinkDisplayMode); + + END_INTERFACE + } IDeckLinkDisplayModeIterator_v7_1Vtbl; + + interface IDeckLinkDisplayModeIterator_v7_1 + { + CONST_VTBL struct IDeckLinkDisplayModeIterator_v7_1Vtbl *lpVtbl; + }; + + + +#ifdef COBJMACROS + + +#define IDeckLinkDisplayModeIterator_v7_1_QueryInterface(This,riid,ppvObject) \ + ( (This)->lpVtbl -> QueryInterface(This,riid,ppvObject) ) + +#define IDeckLinkDisplayModeIterator_v7_1_AddRef(This) \ + ( (This)->lpVtbl -> AddRef(This) ) + +#define IDeckLinkDisplayModeIterator_v7_1_Release(This) \ + ( (This)->lpVtbl -> Release(This) ) + + +#define IDeckLinkDisplayModeIterator_v7_1_Next(This,deckLinkDisplayMode) \ + ( (This)->lpVtbl -> Next(This,deckLinkDisplayMode) ) + +#endif /* COBJMACROS */ + + +#endif /* C style interface */ + + + + +#endif /* __IDeckLinkDisplayModeIterator_v7_1_INTERFACE_DEFINED__ */ + + +#ifndef __IDeckLinkDisplayMode_v7_1_INTERFACE_DEFINED__ +#define __IDeckLinkDisplayMode_v7_1_INTERFACE_DEFINED__ + +/* interface IDeckLinkDisplayMode_v7_1 */ +/* [helpstring][uuid][object] */ + + +EXTERN_C const IID IID_IDeckLinkDisplayMode_v7_1; + +#if defined(__cplusplus) && !defined(CINTERFACE) + + MIDL_INTERFACE("AF0CD6D5-8376-435E-8433-54F9DD530AC3") + IDeckLinkDisplayMode_v7_1 : public IUnknown + { + public: + virtual HRESULT STDMETHODCALLTYPE GetName( + /* [out] */ BSTR *name) = 0; + + virtual BMDDisplayMode STDMETHODCALLTYPE GetDisplayMode( void) = 0; + + virtual long STDMETHODCALLTYPE GetWidth( void) = 0; + + virtual long STDMETHODCALLTYPE GetHeight( void) = 0; + + virtual HRESULT STDMETHODCALLTYPE GetFrameRate( + /* [out] */ BMDTimeValue *frameDuration, + /* [out] */ BMDTimeScale *timeScale) = 0; + + }; + +#else /* C style interface */ + + typedef struct IDeckLinkDisplayMode_v7_1Vtbl + { + BEGIN_INTERFACE + + HRESULT ( STDMETHODCALLTYPE *QueryInterface )( + IDeckLinkDisplayMode_v7_1 * This, + /* [in] */ REFIID riid, + /* [iid_is][out] */ + __RPC__deref_out void **ppvObject); + + ULONG ( STDMETHODCALLTYPE *AddRef )( + IDeckLinkDisplayMode_v7_1 * This); + + ULONG ( STDMETHODCALLTYPE *Release )( + IDeckLinkDisplayMode_v7_1 * This); + + HRESULT ( STDMETHODCALLTYPE *GetName )( + IDeckLinkDisplayMode_v7_1 * This, + /* [out] */ BSTR *name); + + BMDDisplayMode ( STDMETHODCALLTYPE *GetDisplayMode )( + IDeckLinkDisplayMode_v7_1 * This); + + long ( STDMETHODCALLTYPE *GetWidth )( + IDeckLinkDisplayMode_v7_1 * This); + + long ( STDMETHODCALLTYPE *GetHeight )( + IDeckLinkDisplayMode_v7_1 * This); + + HRESULT ( STDMETHODCALLTYPE *GetFrameRate )( + IDeckLinkDisplayMode_v7_1 * This, + /* [out] */ BMDTimeValue *frameDuration, + /* [out] */ BMDTimeScale *timeScale); + + END_INTERFACE + } IDeckLinkDisplayMode_v7_1Vtbl; + + interface IDeckLinkDisplayMode_v7_1 + { + CONST_VTBL struct IDeckLinkDisplayMode_v7_1Vtbl *lpVtbl; + }; + + + +#ifdef COBJMACROS + + +#define IDeckLinkDisplayMode_v7_1_QueryInterface(This,riid,ppvObject) \ + ( (This)->lpVtbl -> QueryInterface(This,riid,ppvObject) ) + +#define IDeckLinkDisplayMode_v7_1_AddRef(This) \ + ( (This)->lpVtbl -> AddRef(This) ) + +#define IDeckLinkDisplayMode_v7_1_Release(This) \ + ( (This)->lpVtbl -> Release(This) ) + + +#define IDeckLinkDisplayMode_v7_1_GetName(This,name) \ + ( (This)->lpVtbl -> GetName(This,name) ) + +#define IDeckLinkDisplayMode_v7_1_GetDisplayMode(This) \ + ( (This)->lpVtbl -> GetDisplayMode(This) ) + +#define IDeckLinkDisplayMode_v7_1_GetWidth(This) \ + ( (This)->lpVtbl -> GetWidth(This) ) + +#define IDeckLinkDisplayMode_v7_1_GetHeight(This) \ + ( (This)->lpVtbl -> GetHeight(This) ) + +#define IDeckLinkDisplayMode_v7_1_GetFrameRate(This,frameDuration,timeScale) \ + ( (This)->lpVtbl -> GetFrameRate(This,frameDuration,timeScale) ) + +#endif /* COBJMACROS */ + + +#endif /* C style interface */ + + + + +#endif /* __IDeckLinkDisplayMode_v7_1_INTERFACE_DEFINED__ */ + + +#ifndef __IDeckLinkVideoFrame_v7_1_INTERFACE_DEFINED__ +#define __IDeckLinkVideoFrame_v7_1_INTERFACE_DEFINED__ + +/* interface IDeckLinkVideoFrame_v7_1 */ +/* [helpstring][local][uuid][object] */ + + +EXTERN_C const IID IID_IDeckLinkVideoFrame_v7_1; + +#if defined(__cplusplus) && !defined(CINTERFACE) + + MIDL_INTERFACE("333F3A10-8C2D-43CF-B79D-46560FEEA1CE") + IDeckLinkVideoFrame_v7_1 : public IUnknown + { + public: + virtual long STDMETHODCALLTYPE GetWidth( void) = 0; + + virtual long STDMETHODCALLTYPE GetHeight( void) = 0; + + virtual long STDMETHODCALLTYPE GetRowBytes( void) = 0; + + virtual BMDPixelFormat STDMETHODCALLTYPE GetPixelFormat( void) = 0; + + virtual BMDFrameFlags STDMETHODCALLTYPE GetFlags( void) = 0; + + virtual HRESULT STDMETHODCALLTYPE GetBytes( + void **buffer) = 0; + + }; + +#else /* C style interface */ + + typedef struct IDeckLinkVideoFrame_v7_1Vtbl + { + BEGIN_INTERFACE + + HRESULT ( STDMETHODCALLTYPE *QueryInterface )( + IDeckLinkVideoFrame_v7_1 * This, + /* [in] */ REFIID riid, + /* [iid_is][out] */ + __RPC__deref_out void **ppvObject); + + ULONG ( STDMETHODCALLTYPE *AddRef )( + IDeckLinkVideoFrame_v7_1 * This); + + ULONG ( STDMETHODCALLTYPE *Release )( + IDeckLinkVideoFrame_v7_1 * This); + + long ( STDMETHODCALLTYPE *GetWidth )( + IDeckLinkVideoFrame_v7_1 * This); + + long ( STDMETHODCALLTYPE *GetHeight )( + IDeckLinkVideoFrame_v7_1 * This); + + long ( STDMETHODCALLTYPE *GetRowBytes )( + IDeckLinkVideoFrame_v7_1 * This); + + BMDPixelFormat ( STDMETHODCALLTYPE *GetPixelFormat )( + IDeckLinkVideoFrame_v7_1 * This); + + BMDFrameFlags ( STDMETHODCALLTYPE *GetFlags )( + IDeckLinkVideoFrame_v7_1 * This); + + HRESULT ( STDMETHODCALLTYPE *GetBytes )( + IDeckLinkVideoFrame_v7_1 * This, + void **buffer); + + END_INTERFACE + } IDeckLinkVideoFrame_v7_1Vtbl; + + interface IDeckLinkVideoFrame_v7_1 + { + CONST_VTBL struct IDeckLinkVideoFrame_v7_1Vtbl *lpVtbl; + }; + + + +#ifdef COBJMACROS + + +#define IDeckLinkVideoFrame_v7_1_QueryInterface(This,riid,ppvObject) \ + ( (This)->lpVtbl -> QueryInterface(This,riid,ppvObject) ) + +#define IDeckLinkVideoFrame_v7_1_AddRef(This) \ + ( (This)->lpVtbl -> AddRef(This) ) + +#define IDeckLinkVideoFrame_v7_1_Release(This) \ + ( (This)->lpVtbl -> Release(This) ) + + +#define IDeckLinkVideoFrame_v7_1_GetWidth(This) \ + ( (This)->lpVtbl -> GetWidth(This) ) + +#define IDeckLinkVideoFrame_v7_1_GetHeight(This) \ + ( (This)->lpVtbl -> GetHeight(This) ) + +#define IDeckLinkVideoFrame_v7_1_GetRowBytes(This) \ + ( (This)->lpVtbl -> GetRowBytes(This) ) + +#define IDeckLinkVideoFrame_v7_1_GetPixelFormat(This) \ + ( (This)->lpVtbl -> GetPixelFormat(This) ) + +#define IDeckLinkVideoFrame_v7_1_GetFlags(This) \ + ( (This)->lpVtbl -> GetFlags(This) ) + +#define IDeckLinkVideoFrame_v7_1_GetBytes(This,buffer) \ + ( (This)->lpVtbl -> GetBytes(This,buffer) ) + +#endif /* COBJMACROS */ + + +#endif /* C style interface */ + + + + +#endif /* __IDeckLinkVideoFrame_v7_1_INTERFACE_DEFINED__ */ + + +#ifndef __IDeckLinkVideoInputFrame_v7_1_INTERFACE_DEFINED__ +#define __IDeckLinkVideoInputFrame_v7_1_INTERFACE_DEFINED__ + +/* interface IDeckLinkVideoInputFrame_v7_1 */ +/* [helpstring][local][uuid][object] */ + + +EXTERN_C const IID IID_IDeckLinkVideoInputFrame_v7_1; + +#if defined(__cplusplus) && !defined(CINTERFACE) + + MIDL_INTERFACE("C8B41D95-8848-40EE-9B37-6E3417FB114B") + IDeckLinkVideoInputFrame_v7_1 : public IDeckLinkVideoFrame_v7_1 + { + public: + virtual HRESULT STDMETHODCALLTYPE GetFrameTime( + BMDTimeValue *frameTime, + BMDTimeValue *frameDuration, + BMDTimeScale timeScale) = 0; + + }; + +#else /* C style interface */ + + typedef struct IDeckLinkVideoInputFrame_v7_1Vtbl + { + BEGIN_INTERFACE + + HRESULT ( STDMETHODCALLTYPE *QueryInterface )( + IDeckLinkVideoInputFrame_v7_1 * This, + /* [in] */ REFIID riid, + /* [iid_is][out] */ + __RPC__deref_out void **ppvObject); + + ULONG ( STDMETHODCALLTYPE *AddRef )( + IDeckLinkVideoInputFrame_v7_1 * This); + + ULONG ( STDMETHODCALLTYPE *Release )( + IDeckLinkVideoInputFrame_v7_1 * This); + + long ( STDMETHODCALLTYPE *GetWidth )( + IDeckLinkVideoInputFrame_v7_1 * This); + + long ( STDMETHODCALLTYPE *GetHeight )( + IDeckLinkVideoInputFrame_v7_1 * This); + + long ( STDMETHODCALLTYPE *GetRowBytes )( + IDeckLinkVideoInputFrame_v7_1 * This); + + BMDPixelFormat ( STDMETHODCALLTYPE *GetPixelFormat )( + IDeckLinkVideoInputFrame_v7_1 * This); + + BMDFrameFlags ( STDMETHODCALLTYPE *GetFlags )( + IDeckLinkVideoInputFrame_v7_1 * This); + + HRESULT ( STDMETHODCALLTYPE *GetBytes )( + IDeckLinkVideoInputFrame_v7_1 * This, + void **buffer); + + HRESULT ( STDMETHODCALLTYPE *GetFrameTime )( + IDeckLinkVideoInputFrame_v7_1 * This, + BMDTimeValue *frameTime, + BMDTimeValue *frameDuration, + BMDTimeScale timeScale); + + END_INTERFACE + } IDeckLinkVideoInputFrame_v7_1Vtbl; + + interface IDeckLinkVideoInputFrame_v7_1 + { + CONST_VTBL struct IDeckLinkVideoInputFrame_v7_1Vtbl *lpVtbl; + }; + + + +#ifdef COBJMACROS + + +#define IDeckLinkVideoInputFrame_v7_1_QueryInterface(This,riid,ppvObject) \ + ( (This)->lpVtbl -> QueryInterface(This,riid,ppvObject) ) + +#define IDeckLinkVideoInputFrame_v7_1_AddRef(This) \ + ( (This)->lpVtbl -> AddRef(This) ) + +#define IDeckLinkVideoInputFrame_v7_1_Release(This) \ + ( (This)->lpVtbl -> Release(This) ) + + +#define IDeckLinkVideoInputFrame_v7_1_GetWidth(This) \ + ( (This)->lpVtbl -> GetWidth(This) ) + +#define IDeckLinkVideoInputFrame_v7_1_GetHeight(This) \ + ( (This)->lpVtbl -> GetHeight(This) ) + +#define IDeckLinkVideoInputFrame_v7_1_GetRowBytes(This) \ + ( (This)->lpVtbl -> GetRowBytes(This) ) + +#define IDeckLinkVideoInputFrame_v7_1_GetPixelFormat(This) \ + ( (This)->lpVtbl -> GetPixelFormat(This) ) + +#define IDeckLinkVideoInputFrame_v7_1_GetFlags(This) \ + ( (This)->lpVtbl -> GetFlags(This) ) + +#define IDeckLinkVideoInputFrame_v7_1_GetBytes(This,buffer) \ + ( (This)->lpVtbl -> GetBytes(This,buffer) ) + + +#define IDeckLinkVideoInputFrame_v7_1_GetFrameTime(This,frameTime,frameDuration,timeScale) \ + ( (This)->lpVtbl -> GetFrameTime(This,frameTime,frameDuration,timeScale) ) + +#endif /* COBJMACROS */ + + +#endif /* C style interface */ + + + + +#endif /* __IDeckLinkVideoInputFrame_v7_1_INTERFACE_DEFINED__ */ + + +#ifndef __IDeckLinkAudioInputPacket_v7_1_INTERFACE_DEFINED__ +#define __IDeckLinkAudioInputPacket_v7_1_INTERFACE_DEFINED__ + +/* interface IDeckLinkAudioInputPacket_v7_1 */ +/* [helpstring][local][uuid][object] */ + + +EXTERN_C const IID IID_IDeckLinkAudioInputPacket_v7_1; + +#if defined(__cplusplus) && !defined(CINTERFACE) + + MIDL_INTERFACE("C86DE4F6-A29F-42E3-AB3A-1363E29F0788") + IDeckLinkAudioInputPacket_v7_1 : public IUnknown + { + public: + virtual long STDMETHODCALLTYPE GetSampleCount( void) = 0; + + virtual HRESULT STDMETHODCALLTYPE GetBytes( + void **buffer) = 0; + + virtual HRESULT STDMETHODCALLTYPE GetAudioPacketTime( + BMDTimeValue *packetTime, + BMDTimeScale timeScale) = 0; + + }; + +#else /* C style interface */ + + typedef struct IDeckLinkAudioInputPacket_v7_1Vtbl + { + BEGIN_INTERFACE + + HRESULT ( STDMETHODCALLTYPE *QueryInterface )( + IDeckLinkAudioInputPacket_v7_1 * This, + /* [in] */ REFIID riid, + /* [iid_is][out] */ + __RPC__deref_out void **ppvObject); + + ULONG ( STDMETHODCALLTYPE *AddRef )( + IDeckLinkAudioInputPacket_v7_1 * This); + + ULONG ( STDMETHODCALLTYPE *Release )( + IDeckLinkAudioInputPacket_v7_1 * This); + + long ( STDMETHODCALLTYPE *GetSampleCount )( + IDeckLinkAudioInputPacket_v7_1 * This); + + HRESULT ( STDMETHODCALLTYPE *GetBytes )( + IDeckLinkAudioInputPacket_v7_1 * This, + void **buffer); + + HRESULT ( STDMETHODCALLTYPE *GetAudioPacketTime )( + IDeckLinkAudioInputPacket_v7_1 * This, + BMDTimeValue *packetTime, + BMDTimeScale timeScale); + + END_INTERFACE + } IDeckLinkAudioInputPacket_v7_1Vtbl; + + interface IDeckLinkAudioInputPacket_v7_1 + { + CONST_VTBL struct IDeckLinkAudioInputPacket_v7_1Vtbl *lpVtbl; + }; + + + +#ifdef COBJMACROS + + +#define IDeckLinkAudioInputPacket_v7_1_QueryInterface(This,riid,ppvObject) \ + ( (This)->lpVtbl -> QueryInterface(This,riid,ppvObject) ) + +#define IDeckLinkAudioInputPacket_v7_1_AddRef(This) \ + ( (This)->lpVtbl -> AddRef(This) ) + +#define IDeckLinkAudioInputPacket_v7_1_Release(This) \ + ( (This)->lpVtbl -> Release(This) ) + + +#define IDeckLinkAudioInputPacket_v7_1_GetSampleCount(This) \ + ( (This)->lpVtbl -> GetSampleCount(This) ) + +#define IDeckLinkAudioInputPacket_v7_1_GetBytes(This,buffer) \ + ( (This)->lpVtbl -> GetBytes(This,buffer) ) + +#define IDeckLinkAudioInputPacket_v7_1_GetAudioPacketTime(This,packetTime,timeScale) \ + ( (This)->lpVtbl -> GetAudioPacketTime(This,packetTime,timeScale) ) + +#endif /* COBJMACROS */ + + +#endif /* C style interface */ + + + + +#endif /* __IDeckLinkAudioInputPacket_v7_1_INTERFACE_DEFINED__ */ + + +#ifndef __IDeckLinkVideoOutputCallback_v7_1_INTERFACE_DEFINED__ +#define __IDeckLinkVideoOutputCallback_v7_1_INTERFACE_DEFINED__ + +/* interface IDeckLinkVideoOutputCallback_v7_1 */ +/* [helpstring][uuid][object] */ + + +EXTERN_C const IID IID_IDeckLinkVideoOutputCallback_v7_1; + +#if defined(__cplusplus) && !defined(CINTERFACE) + + MIDL_INTERFACE("EBD01AFA-E4B0-49C6-A01D-EDB9D1B55FD9") + IDeckLinkVideoOutputCallback_v7_1 : public IUnknown + { + public: + virtual HRESULT STDMETHODCALLTYPE ScheduledFrameCompleted( + /* [in] */ IDeckLinkVideoFrame_v7_1 *completedFrame, + /* [in] */ BMDOutputFrameCompletionResult result) = 0; + + }; + +#else /* C style interface */ + + typedef struct IDeckLinkVideoOutputCallback_v7_1Vtbl + { + BEGIN_INTERFACE + + HRESULT ( STDMETHODCALLTYPE *QueryInterface )( + IDeckLinkVideoOutputCallback_v7_1 * This, + /* [in] */ REFIID riid, + /* [iid_is][out] */ + __RPC__deref_out void **ppvObject); + + ULONG ( STDMETHODCALLTYPE *AddRef )( + IDeckLinkVideoOutputCallback_v7_1 * This); + + ULONG ( STDMETHODCALLTYPE *Release )( + IDeckLinkVideoOutputCallback_v7_1 * This); + + HRESULT ( STDMETHODCALLTYPE *ScheduledFrameCompleted )( + IDeckLinkVideoOutputCallback_v7_1 * This, + /* [in] */ IDeckLinkVideoFrame_v7_1 *completedFrame, + /* [in] */ BMDOutputFrameCompletionResult result); + + END_INTERFACE + } IDeckLinkVideoOutputCallback_v7_1Vtbl; + + interface IDeckLinkVideoOutputCallback_v7_1 + { + CONST_VTBL struct IDeckLinkVideoOutputCallback_v7_1Vtbl *lpVtbl; + }; + + + +#ifdef COBJMACROS + + +#define IDeckLinkVideoOutputCallback_v7_1_QueryInterface(This,riid,ppvObject) \ + ( (This)->lpVtbl -> QueryInterface(This,riid,ppvObject) ) + +#define IDeckLinkVideoOutputCallback_v7_1_AddRef(This) \ + ( (This)->lpVtbl -> AddRef(This) ) + +#define IDeckLinkVideoOutputCallback_v7_1_Release(This) \ + ( (This)->lpVtbl -> Release(This) ) + + +#define IDeckLinkVideoOutputCallback_v7_1_ScheduledFrameCompleted(This,completedFrame,result) \ + ( (This)->lpVtbl -> ScheduledFrameCompleted(This,completedFrame,result) ) + +#endif /* COBJMACROS */ + + +#endif /* C style interface */ + + + + +#endif /* __IDeckLinkVideoOutputCallback_v7_1_INTERFACE_DEFINED__ */ + + +#ifndef __IDeckLinkInputCallback_v7_1_INTERFACE_DEFINED__ +#define __IDeckLinkInputCallback_v7_1_INTERFACE_DEFINED__ + +/* interface IDeckLinkInputCallback_v7_1 */ +/* [helpstring][uuid][object] */ + + +EXTERN_C const IID IID_IDeckLinkInputCallback_v7_1; + +#if defined(__cplusplus) && !defined(CINTERFACE) + + MIDL_INTERFACE("7F94F328-5ED4-4E9F-9729-76A86BDC99CC") + IDeckLinkInputCallback_v7_1 : public IUnknown + { + public: + virtual HRESULT STDMETHODCALLTYPE VideoInputFrameArrived( + /* [in] */ IDeckLinkVideoInputFrame_v7_1 *videoFrame, + /* [in] */ IDeckLinkAudioInputPacket_v7_1 *audioPacket) = 0; + + }; + +#else /* C style interface */ + + typedef struct IDeckLinkInputCallback_v7_1Vtbl + { + BEGIN_INTERFACE + + HRESULT ( STDMETHODCALLTYPE *QueryInterface )( + IDeckLinkInputCallback_v7_1 * This, + /* [in] */ REFIID riid, + /* [iid_is][out] */ + __RPC__deref_out void **ppvObject); + + ULONG ( STDMETHODCALLTYPE *AddRef )( + IDeckLinkInputCallback_v7_1 * This); + + ULONG ( STDMETHODCALLTYPE *Release )( + IDeckLinkInputCallback_v7_1 * This); + + HRESULT ( STDMETHODCALLTYPE *VideoInputFrameArrived )( + IDeckLinkInputCallback_v7_1 * This, + /* [in] */ IDeckLinkVideoInputFrame_v7_1 *videoFrame, + /* [in] */ IDeckLinkAudioInputPacket_v7_1 *audioPacket); + + END_INTERFACE + } IDeckLinkInputCallback_v7_1Vtbl; + + interface IDeckLinkInputCallback_v7_1 + { + CONST_VTBL struct IDeckLinkInputCallback_v7_1Vtbl *lpVtbl; + }; + + + +#ifdef COBJMACROS + + +#define IDeckLinkInputCallback_v7_1_QueryInterface(This,riid,ppvObject) \ + ( (This)->lpVtbl -> QueryInterface(This,riid,ppvObject) ) + +#define IDeckLinkInputCallback_v7_1_AddRef(This) \ + ( (This)->lpVtbl -> AddRef(This) ) + +#define IDeckLinkInputCallback_v7_1_Release(This) \ + ( (This)->lpVtbl -> Release(This) ) + + +#define IDeckLinkInputCallback_v7_1_VideoInputFrameArrived(This,videoFrame,audioPacket) \ + ( (This)->lpVtbl -> VideoInputFrameArrived(This,videoFrame,audioPacket) ) + +#endif /* COBJMACROS */ + + +#endif /* C style interface */ + + + + +#endif /* __IDeckLinkInputCallback_v7_1_INTERFACE_DEFINED__ */ + + +#ifndef __IDeckLinkOutput_v7_1_INTERFACE_DEFINED__ +#define __IDeckLinkOutput_v7_1_INTERFACE_DEFINED__ + +/* interface IDeckLinkOutput_v7_1 */ +/* [helpstring][local][uuid][object] */ + + +EXTERN_C const IID IID_IDeckLinkOutput_v7_1; + +#if defined(__cplusplus) && !defined(CINTERFACE) + + MIDL_INTERFACE("AE5B3E9B-4E1E-4535-B6E8-480FF52F6CE5") + IDeckLinkOutput_v7_1 : public IUnknown + { + public: + virtual HRESULT STDMETHODCALLTYPE DoesSupportVideoMode( + BMDDisplayMode displayMode, + BMDPixelFormat pixelFormat, + /* [out] */ BMDDisplayModeSupport *result) = 0; + + virtual HRESULT STDMETHODCALLTYPE GetDisplayModeIterator( + /* [out] */ IDeckLinkDisplayModeIterator_v7_1 **iterator) = 0; + + virtual HRESULT STDMETHODCALLTYPE EnableVideoOutput( + BMDDisplayMode displayMode) = 0; + + virtual HRESULT STDMETHODCALLTYPE DisableVideoOutput( void) = 0; + + virtual HRESULT STDMETHODCALLTYPE SetVideoOutputFrameMemoryAllocator( + /* [in] */ IDeckLinkMemoryAllocator *theAllocator) = 0; + + virtual HRESULT STDMETHODCALLTYPE CreateVideoFrame( + long width, + long height, + long rowBytes, + BMDPixelFormat pixelFormat, + BMDFrameFlags flags, + IDeckLinkVideoFrame_v7_1 **outFrame) = 0; + + virtual HRESULT STDMETHODCALLTYPE CreateVideoFrameFromBuffer( + void *buffer, + long width, + long height, + long rowBytes, + BMDPixelFormat pixelFormat, + BMDFrameFlags flags, + IDeckLinkVideoFrame_v7_1 **outFrame) = 0; + + virtual HRESULT STDMETHODCALLTYPE DisplayVideoFrameSync( + IDeckLinkVideoFrame_v7_1 *theFrame) = 0; + + virtual HRESULT STDMETHODCALLTYPE ScheduleVideoFrame( + IDeckLinkVideoFrame_v7_1 *theFrame, + BMDTimeValue displayTime, + BMDTimeValue displayDuration, + BMDTimeScale timeScale) = 0; + + virtual HRESULT STDMETHODCALLTYPE SetScheduledFrameCompletionCallback( + /* [in] */ IDeckLinkVideoOutputCallback_v7_1 *theCallback) = 0; + + virtual HRESULT STDMETHODCALLTYPE EnableAudioOutput( + BMDAudioSampleRate sampleRate, + BMDAudioSampleType sampleType, + unsigned long channelCount) = 0; + + virtual HRESULT STDMETHODCALLTYPE DisableAudioOutput( void) = 0; + + virtual HRESULT STDMETHODCALLTYPE WriteAudioSamplesSync( + void *buffer, + unsigned long sampleFrameCount, + /* [out] */ unsigned long *sampleFramesWritten) = 0; + + virtual HRESULT STDMETHODCALLTYPE BeginAudioPreroll( void) = 0; + + virtual HRESULT STDMETHODCALLTYPE EndAudioPreroll( void) = 0; + + virtual HRESULT STDMETHODCALLTYPE ScheduleAudioSamples( + void *buffer, + unsigned long sampleFrameCount, + BMDTimeValue streamTime, + BMDTimeScale timeScale, + /* [out] */ unsigned long *sampleFramesWritten) = 0; + + virtual HRESULT STDMETHODCALLTYPE GetBufferedAudioSampleFrameCount( + /* [out] */ unsigned long *bufferedSampleCount) = 0; + + virtual HRESULT STDMETHODCALLTYPE FlushBufferedAudioSamples( void) = 0; + + virtual HRESULT STDMETHODCALLTYPE SetAudioCallback( + /* [in] */ IDeckLinkAudioOutputCallback *theCallback) = 0; + + virtual HRESULT STDMETHODCALLTYPE StartScheduledPlayback( + BMDTimeValue playbackStartTime, + BMDTimeScale timeScale, + double playbackSpeed) = 0; + + virtual HRESULT STDMETHODCALLTYPE StopScheduledPlayback( + BMDTimeValue stopPlaybackAtTime, + BMDTimeValue *actualStopTime, + BMDTimeScale timeScale) = 0; + + virtual HRESULT STDMETHODCALLTYPE GetHardwareReferenceClock( + BMDTimeScale desiredTimeScale, + BMDTimeValue *elapsedTimeSinceSchedulerBegan) = 0; + + }; + +#else /* C style interface */ + + typedef struct IDeckLinkOutput_v7_1Vtbl + { + BEGIN_INTERFACE + + HRESULT ( STDMETHODCALLTYPE *QueryInterface )( + IDeckLinkOutput_v7_1 * This, + /* [in] */ REFIID riid, + /* [iid_is][out] */ + __RPC__deref_out void **ppvObject); + + ULONG ( STDMETHODCALLTYPE *AddRef )( + IDeckLinkOutput_v7_1 * This); + + ULONG ( STDMETHODCALLTYPE *Release )( + IDeckLinkOutput_v7_1 * This); + + HRESULT ( STDMETHODCALLTYPE *DoesSupportVideoMode )( + IDeckLinkOutput_v7_1 * This, + BMDDisplayMode displayMode, + BMDPixelFormat pixelFormat, + /* [out] */ BMDDisplayModeSupport *result); + + HRESULT ( STDMETHODCALLTYPE *GetDisplayModeIterator )( + IDeckLinkOutput_v7_1 * This, + /* [out] */ IDeckLinkDisplayModeIterator_v7_1 **iterator); + + HRESULT ( STDMETHODCALLTYPE *EnableVideoOutput )( + IDeckLinkOutput_v7_1 * This, + BMDDisplayMode displayMode); + + HRESULT ( STDMETHODCALLTYPE *DisableVideoOutput )( + IDeckLinkOutput_v7_1 * This); + + HRESULT ( STDMETHODCALLTYPE *SetVideoOutputFrameMemoryAllocator )( + IDeckLinkOutput_v7_1 * This, + /* [in] */ IDeckLinkMemoryAllocator *theAllocator); + + HRESULT ( STDMETHODCALLTYPE *CreateVideoFrame )( + IDeckLinkOutput_v7_1 * This, + long width, + long height, + long rowBytes, + BMDPixelFormat pixelFormat, + BMDFrameFlags flags, + IDeckLinkVideoFrame_v7_1 **outFrame); + + HRESULT ( STDMETHODCALLTYPE *CreateVideoFrameFromBuffer )( + IDeckLinkOutput_v7_1 * This, + void *buffer, + long width, + long height, + long rowBytes, + BMDPixelFormat pixelFormat, + BMDFrameFlags flags, + IDeckLinkVideoFrame_v7_1 **outFrame); + + HRESULT ( STDMETHODCALLTYPE *DisplayVideoFrameSync )( + IDeckLinkOutput_v7_1 * This, + IDeckLinkVideoFrame_v7_1 *theFrame); + + HRESULT ( STDMETHODCALLTYPE *ScheduleVideoFrame )( + IDeckLinkOutput_v7_1 * This, + IDeckLinkVideoFrame_v7_1 *theFrame, + BMDTimeValue displayTime, + BMDTimeValue displayDuration, + BMDTimeScale timeScale); + + HRESULT ( STDMETHODCALLTYPE *SetScheduledFrameCompletionCallback )( + IDeckLinkOutput_v7_1 * This, + /* [in] */ IDeckLinkVideoOutputCallback_v7_1 *theCallback); + + HRESULT ( STDMETHODCALLTYPE *EnableAudioOutput )( + IDeckLinkOutput_v7_1 * This, + BMDAudioSampleRate sampleRate, + BMDAudioSampleType sampleType, + unsigned long channelCount); + + HRESULT ( STDMETHODCALLTYPE *DisableAudioOutput )( + IDeckLinkOutput_v7_1 * This); + + HRESULT ( STDMETHODCALLTYPE *WriteAudioSamplesSync )( + IDeckLinkOutput_v7_1 * This, + void *buffer, + unsigned long sampleFrameCount, + /* [out] */ unsigned long *sampleFramesWritten); + + HRESULT ( STDMETHODCALLTYPE *BeginAudioPreroll )( + IDeckLinkOutput_v7_1 * This); + + HRESULT ( STDMETHODCALLTYPE *EndAudioPreroll )( + IDeckLinkOutput_v7_1 * This); + + HRESULT ( STDMETHODCALLTYPE *ScheduleAudioSamples )( + IDeckLinkOutput_v7_1 * This, + void *buffer, + unsigned long sampleFrameCount, + BMDTimeValue streamTime, + BMDTimeScale timeScale, + /* [out] */ unsigned long *sampleFramesWritten); + + HRESULT ( STDMETHODCALLTYPE *GetBufferedAudioSampleFrameCount )( + IDeckLinkOutput_v7_1 * This, + /* [out] */ unsigned long *bufferedSampleCount); + + HRESULT ( STDMETHODCALLTYPE *FlushBufferedAudioSamples )( + IDeckLinkOutput_v7_1 * This); + + HRESULT ( STDMETHODCALLTYPE *SetAudioCallback )( + IDeckLinkOutput_v7_1 * This, + /* [in] */ IDeckLinkAudioOutputCallback *theCallback); + + HRESULT ( STDMETHODCALLTYPE *StartScheduledPlayback )( + IDeckLinkOutput_v7_1 * This, + BMDTimeValue playbackStartTime, + BMDTimeScale timeScale, + double playbackSpeed); + + HRESULT ( STDMETHODCALLTYPE *StopScheduledPlayback )( + IDeckLinkOutput_v7_1 * This, + BMDTimeValue stopPlaybackAtTime, + BMDTimeValue *actualStopTime, + BMDTimeScale timeScale); + + HRESULT ( STDMETHODCALLTYPE *GetHardwareReferenceClock )( + IDeckLinkOutput_v7_1 * This, + BMDTimeScale desiredTimeScale, + BMDTimeValue *elapsedTimeSinceSchedulerBegan); + + END_INTERFACE + } IDeckLinkOutput_v7_1Vtbl; + + interface IDeckLinkOutput_v7_1 + { + CONST_VTBL struct IDeckLinkOutput_v7_1Vtbl *lpVtbl; + }; + + + +#ifdef COBJMACROS + + +#define IDeckLinkOutput_v7_1_QueryInterface(This,riid,ppvObject) \ + ( (This)->lpVtbl -> QueryInterface(This,riid,ppvObject) ) + +#define IDeckLinkOutput_v7_1_AddRef(This) \ + ( (This)->lpVtbl -> AddRef(This) ) + +#define IDeckLinkOutput_v7_1_Release(This) \ + ( (This)->lpVtbl -> Release(This) ) + + +#define IDeckLinkOutput_v7_1_DoesSupportVideoMode(This,displayMode,pixelFormat,result) \ + ( (This)->lpVtbl -> DoesSupportVideoMode(This,displayMode,pixelFormat,result) ) + +#define IDeckLinkOutput_v7_1_GetDisplayModeIterator(This,iterator) \ + ( (This)->lpVtbl -> GetDisplayModeIterator(This,iterator) ) + +#define IDeckLinkOutput_v7_1_EnableVideoOutput(This,displayMode) \ + ( (This)->lpVtbl -> EnableVideoOutput(This,displayMode) ) + +#define IDeckLinkOutput_v7_1_DisableVideoOutput(This) \ + ( (This)->lpVtbl -> DisableVideoOutput(This) ) + +#define IDeckLinkOutput_v7_1_SetVideoOutputFrameMemoryAllocator(This,theAllocator) \ + ( (This)->lpVtbl -> SetVideoOutputFrameMemoryAllocator(This,theAllocator) ) + +#define IDeckLinkOutput_v7_1_CreateVideoFrame(This,width,height,rowBytes,pixelFormat,flags,outFrame) \ + ( (This)->lpVtbl -> CreateVideoFrame(This,width,height,rowBytes,pixelFormat,flags,outFrame) ) + +#define IDeckLinkOutput_v7_1_CreateVideoFrameFromBuffer(This,buffer,width,height,rowBytes,pixelFormat,flags,outFrame) \ + ( (This)->lpVtbl -> CreateVideoFrameFromBuffer(This,buffer,width,height,rowBytes,pixelFormat,flags,outFrame) ) + +#define IDeckLinkOutput_v7_1_DisplayVideoFrameSync(This,theFrame) \ + ( (This)->lpVtbl -> DisplayVideoFrameSync(This,theFrame) ) + +#define IDeckLinkOutput_v7_1_ScheduleVideoFrame(This,theFrame,displayTime,displayDuration,timeScale) \ + ( (This)->lpVtbl -> ScheduleVideoFrame(This,theFrame,displayTime,displayDuration,timeScale) ) + +#define IDeckLinkOutput_v7_1_SetScheduledFrameCompletionCallback(This,theCallback) \ + ( (This)->lpVtbl -> SetScheduledFrameCompletionCallback(This,theCallback) ) + +#define IDeckLinkOutput_v7_1_EnableAudioOutput(This,sampleRate,sampleType,channelCount) \ + ( (This)->lpVtbl -> EnableAudioOutput(This,sampleRate,sampleType,channelCount) ) + +#define IDeckLinkOutput_v7_1_DisableAudioOutput(This) \ + ( (This)->lpVtbl -> DisableAudioOutput(This) ) + +#define IDeckLinkOutput_v7_1_WriteAudioSamplesSync(This,buffer,sampleFrameCount,sampleFramesWritten) \ + ( (This)->lpVtbl -> WriteAudioSamplesSync(This,buffer,sampleFrameCount,sampleFramesWritten) ) + +#define IDeckLinkOutput_v7_1_BeginAudioPreroll(This) \ + ( (This)->lpVtbl -> BeginAudioPreroll(This) ) + +#define IDeckLinkOutput_v7_1_EndAudioPreroll(This) \ + ( (This)->lpVtbl -> EndAudioPreroll(This) ) + +#define IDeckLinkOutput_v7_1_ScheduleAudioSamples(This,buffer,sampleFrameCount,streamTime,timeScale,sampleFramesWritten) \ + ( (This)->lpVtbl -> ScheduleAudioSamples(This,buffer,sampleFrameCount,streamTime,timeScale,sampleFramesWritten) ) + +#define IDeckLinkOutput_v7_1_GetBufferedAudioSampleFrameCount(This,bufferedSampleCount) \ + ( (This)->lpVtbl -> GetBufferedAudioSampleFrameCount(This,bufferedSampleCount) ) + +#define IDeckLinkOutput_v7_1_FlushBufferedAudioSamples(This) \ + ( (This)->lpVtbl -> FlushBufferedAudioSamples(This) ) + +#define IDeckLinkOutput_v7_1_SetAudioCallback(This,theCallback) \ + ( (This)->lpVtbl -> SetAudioCallback(This,theCallback) ) + +#define IDeckLinkOutput_v7_1_StartScheduledPlayback(This,playbackStartTime,timeScale,playbackSpeed) \ + ( (This)->lpVtbl -> StartScheduledPlayback(This,playbackStartTime,timeScale,playbackSpeed) ) + +#define IDeckLinkOutput_v7_1_StopScheduledPlayback(This,stopPlaybackAtTime,actualStopTime,timeScale) \ + ( (This)->lpVtbl -> StopScheduledPlayback(This,stopPlaybackAtTime,actualStopTime,timeScale) ) + +#define IDeckLinkOutput_v7_1_GetHardwareReferenceClock(This,desiredTimeScale,elapsedTimeSinceSchedulerBegan) \ + ( (This)->lpVtbl -> GetHardwareReferenceClock(This,desiredTimeScale,elapsedTimeSinceSchedulerBegan) ) + +#endif /* COBJMACROS */ + + +#endif /* C style interface */ + + + + +#endif /* __IDeckLinkOutput_v7_1_INTERFACE_DEFINED__ */ + + +#ifndef __IDeckLinkInput_v7_1_INTERFACE_DEFINED__ +#define __IDeckLinkInput_v7_1_INTERFACE_DEFINED__ + +/* interface IDeckLinkInput_v7_1 */ +/* [helpstring][uuid][object] */ + + +EXTERN_C const IID IID_IDeckLinkInput_v7_1; + +#if defined(__cplusplus) && !defined(CINTERFACE) + + MIDL_INTERFACE("2B54EDEF-5B32-429F-BA11-BB990596EACD") + IDeckLinkInput_v7_1 : public IUnknown + { + public: + virtual HRESULT STDMETHODCALLTYPE DoesSupportVideoMode( + BMDDisplayMode displayMode, + BMDPixelFormat pixelFormat, + /* [out] */ BMDDisplayModeSupport *result) = 0; + + virtual HRESULT STDMETHODCALLTYPE GetDisplayModeIterator( + /* [out] */ IDeckLinkDisplayModeIterator_v7_1 **iterator) = 0; + + virtual HRESULT STDMETHODCALLTYPE EnableVideoInput( + BMDDisplayMode displayMode, + BMDPixelFormat pixelFormat, + BMDVideoInputFlags flags) = 0; + + virtual HRESULT STDMETHODCALLTYPE DisableVideoInput( void) = 0; + + virtual HRESULT STDMETHODCALLTYPE EnableAudioInput( + BMDAudioSampleRate sampleRate, + BMDAudioSampleType sampleType, + unsigned long channelCount) = 0; + + virtual HRESULT STDMETHODCALLTYPE DisableAudioInput( void) = 0; + + virtual HRESULT STDMETHODCALLTYPE ReadAudioSamples( + void *buffer, + unsigned long sampleFrameCount, + /* [out] */ unsigned long *sampleFramesRead, + /* [out] */ BMDTimeValue *audioPacketTime, + BMDTimeScale timeScale) = 0; + + virtual HRESULT STDMETHODCALLTYPE GetBufferedAudioSampleFrameCount( + /* [out] */ unsigned long *bufferedSampleCount) = 0; + + virtual HRESULT STDMETHODCALLTYPE StartStreams( void) = 0; + + virtual HRESULT STDMETHODCALLTYPE StopStreams( void) = 0; + + virtual HRESULT STDMETHODCALLTYPE PauseStreams( void) = 0; + + virtual HRESULT STDMETHODCALLTYPE SetCallback( + /* [in] */ IDeckLinkInputCallback_v7_1 *theCallback) = 0; + + }; + +#else /* C style interface */ + + typedef struct IDeckLinkInput_v7_1Vtbl + { + BEGIN_INTERFACE + + HRESULT ( STDMETHODCALLTYPE *QueryInterface )( + IDeckLinkInput_v7_1 * This, + /* [in] */ REFIID riid, + /* [iid_is][out] */ + __RPC__deref_out void **ppvObject); + + ULONG ( STDMETHODCALLTYPE *AddRef )( + IDeckLinkInput_v7_1 * This); + + ULONG ( STDMETHODCALLTYPE *Release )( + IDeckLinkInput_v7_1 * This); + + HRESULT ( STDMETHODCALLTYPE *DoesSupportVideoMode )( + IDeckLinkInput_v7_1 * This, + BMDDisplayMode displayMode, + BMDPixelFormat pixelFormat, + /* [out] */ BMDDisplayModeSupport *result); + + HRESULT ( STDMETHODCALLTYPE *GetDisplayModeIterator )( + IDeckLinkInput_v7_1 * This, + /* [out] */ IDeckLinkDisplayModeIterator_v7_1 **iterator); + + HRESULT ( STDMETHODCALLTYPE *EnableVideoInput )( + IDeckLinkInput_v7_1 * This, + BMDDisplayMode displayMode, + BMDPixelFormat pixelFormat, + BMDVideoInputFlags flags); + + HRESULT ( STDMETHODCALLTYPE *DisableVideoInput )( + IDeckLinkInput_v7_1 * This); + + HRESULT ( STDMETHODCALLTYPE *EnableAudioInput )( + IDeckLinkInput_v7_1 * This, + BMDAudioSampleRate sampleRate, + BMDAudioSampleType sampleType, + unsigned long channelCount); + + HRESULT ( STDMETHODCALLTYPE *DisableAudioInput )( + IDeckLinkInput_v7_1 * This); + + HRESULT ( STDMETHODCALLTYPE *ReadAudioSamples )( + IDeckLinkInput_v7_1 * This, + void *buffer, + unsigned long sampleFrameCount, + /* [out] */ unsigned long *sampleFramesRead, + /* [out] */ BMDTimeValue *audioPacketTime, + BMDTimeScale timeScale); + + HRESULT ( STDMETHODCALLTYPE *GetBufferedAudioSampleFrameCount )( + IDeckLinkInput_v7_1 * This, + /* [out] */ unsigned long *bufferedSampleCount); + + HRESULT ( STDMETHODCALLTYPE *StartStreams )( + IDeckLinkInput_v7_1 * This); + + HRESULT ( STDMETHODCALLTYPE *StopStreams )( + IDeckLinkInput_v7_1 * This); + + HRESULT ( STDMETHODCALLTYPE *PauseStreams )( + IDeckLinkInput_v7_1 * This); + + HRESULT ( STDMETHODCALLTYPE *SetCallback )( + IDeckLinkInput_v7_1 * This, + /* [in] */ IDeckLinkInputCallback_v7_1 *theCallback); + + END_INTERFACE + } IDeckLinkInput_v7_1Vtbl; + + interface IDeckLinkInput_v7_1 + { + CONST_VTBL struct IDeckLinkInput_v7_1Vtbl *lpVtbl; + }; + + + +#ifdef COBJMACROS + + +#define IDeckLinkInput_v7_1_QueryInterface(This,riid,ppvObject) \ + ( (This)->lpVtbl -> QueryInterface(This,riid,ppvObject) ) + +#define IDeckLinkInput_v7_1_AddRef(This) \ + ( (This)->lpVtbl -> AddRef(This) ) + +#define IDeckLinkInput_v7_1_Release(This) \ + ( (This)->lpVtbl -> Release(This) ) + + +#define IDeckLinkInput_v7_1_DoesSupportVideoMode(This,displayMode,pixelFormat,result) \ + ( (This)->lpVtbl -> DoesSupportVideoMode(This,displayMode,pixelFormat,result) ) + +#define IDeckLinkInput_v7_1_GetDisplayModeIterator(This,iterator) \ + ( (This)->lpVtbl -> GetDisplayModeIterator(This,iterator) ) + +#define IDeckLinkInput_v7_1_EnableVideoInput(This,displayMode,pixelFormat,flags) \ + ( (This)->lpVtbl -> EnableVideoInput(This,displayMode,pixelFormat,flags) ) + +#define IDeckLinkInput_v7_1_DisableVideoInput(This) \ + ( (This)->lpVtbl -> DisableVideoInput(This) ) + +#define IDeckLinkInput_v7_1_EnableAudioInput(This,sampleRate,sampleType,channelCount) \ + ( (This)->lpVtbl -> EnableAudioInput(This,sampleRate,sampleType,channelCount) ) + +#define IDeckLinkInput_v7_1_DisableAudioInput(This) \ + ( (This)->lpVtbl -> DisableAudioInput(This) ) + +#define IDeckLinkInput_v7_1_ReadAudioSamples(This,buffer,sampleFrameCount,sampleFramesRead,audioPacketTime,timeScale) \ + ( (This)->lpVtbl -> ReadAudioSamples(This,buffer,sampleFrameCount,sampleFramesRead,audioPacketTime,timeScale) ) + +#define IDeckLinkInput_v7_1_GetBufferedAudioSampleFrameCount(This,bufferedSampleCount) \ + ( (This)->lpVtbl -> GetBufferedAudioSampleFrameCount(This,bufferedSampleCount) ) + +#define IDeckLinkInput_v7_1_StartStreams(This) \ + ( (This)->lpVtbl -> StartStreams(This) ) + +#define IDeckLinkInput_v7_1_StopStreams(This) \ + ( (This)->lpVtbl -> StopStreams(This) ) + +#define IDeckLinkInput_v7_1_PauseStreams(This) \ + ( (This)->lpVtbl -> PauseStreams(This) ) + +#define IDeckLinkInput_v7_1_SetCallback(This,theCallback) \ + ( (This)->lpVtbl -> SetCallback(This,theCallback) ) + +#endif /* COBJMACROS */ + + +#endif /* C style interface */ + + + + +#endif /* __IDeckLinkInput_v7_1_INTERFACE_DEFINED__ */ + + +#ifndef __IDeckLinkInputCallback_v7_3_INTERFACE_DEFINED__ +#define __IDeckLinkInputCallback_v7_3_INTERFACE_DEFINED__ + +/* interface IDeckLinkInputCallback_v7_3 */ +/* [helpstring][uuid][object] */ + + +EXTERN_C const IID IID_IDeckLinkInputCallback_v7_3; + +#if defined(__cplusplus) && !defined(CINTERFACE) + + MIDL_INTERFACE("FD6F311D-4D00-444B-9ED4-1F25B5730AD0") + IDeckLinkInputCallback_v7_3 : public IUnknown + { + public: + virtual HRESULT STDMETHODCALLTYPE VideoInputFormatChanged( + /* [in] */ BMDVideoInputFormatChangedEvents notificationEvents, + /* [in] */ IDeckLinkDisplayMode *newDisplayMode, + /* [in] */ BMDDetectedVideoInputFormatFlags detectedSignalFlags) = 0; + + virtual HRESULT STDMETHODCALLTYPE VideoInputFrameArrived( + /* [in] */ IDeckLinkVideoInputFrame_v7_3 *videoFrame, + /* [in] */ IDeckLinkAudioInputPacket *audioPacket) = 0; + + }; + +#else /* C style interface */ + + typedef struct IDeckLinkInputCallback_v7_3Vtbl + { + BEGIN_INTERFACE + + HRESULT ( STDMETHODCALLTYPE *QueryInterface )( + IDeckLinkInputCallback_v7_3 * This, + /* [in] */ REFIID riid, + /* [iid_is][out] */ + __RPC__deref_out void **ppvObject); + + ULONG ( STDMETHODCALLTYPE *AddRef )( + IDeckLinkInputCallback_v7_3 * This); + + ULONG ( STDMETHODCALLTYPE *Release )( + IDeckLinkInputCallback_v7_3 * This); + + HRESULT ( STDMETHODCALLTYPE *VideoInputFormatChanged )( + IDeckLinkInputCallback_v7_3 * This, + /* [in] */ BMDVideoInputFormatChangedEvents notificationEvents, + /* [in] */ IDeckLinkDisplayMode *newDisplayMode, + /* [in] */ BMDDetectedVideoInputFormatFlags detectedSignalFlags); + + HRESULT ( STDMETHODCALLTYPE *VideoInputFrameArrived )( + IDeckLinkInputCallback_v7_3 * This, + /* [in] */ IDeckLinkVideoInputFrame_v7_3 *videoFrame, + /* [in] */ IDeckLinkAudioInputPacket *audioPacket); + + END_INTERFACE + } IDeckLinkInputCallback_v7_3Vtbl; + + interface IDeckLinkInputCallback_v7_3 + { + CONST_VTBL struct IDeckLinkInputCallback_v7_3Vtbl *lpVtbl; + }; + + + +#ifdef COBJMACROS + + +#define IDeckLinkInputCallback_v7_3_QueryInterface(This,riid,ppvObject) \ + ( (This)->lpVtbl -> QueryInterface(This,riid,ppvObject) ) + +#define IDeckLinkInputCallback_v7_3_AddRef(This) \ + ( (This)->lpVtbl -> AddRef(This) ) + +#define IDeckLinkInputCallback_v7_3_Release(This) \ + ( (This)->lpVtbl -> Release(This) ) + + +#define IDeckLinkInputCallback_v7_3_VideoInputFormatChanged(This,notificationEvents,newDisplayMode,detectedSignalFlags) \ + ( (This)->lpVtbl -> VideoInputFormatChanged(This,notificationEvents,newDisplayMode,detectedSignalFlags) ) + +#define IDeckLinkInputCallback_v7_3_VideoInputFrameArrived(This,videoFrame,audioPacket) \ + ( (This)->lpVtbl -> VideoInputFrameArrived(This,videoFrame,audioPacket) ) + +#endif /* COBJMACROS */ + + +#endif /* C style interface */ + + + + +#endif /* __IDeckLinkInputCallback_v7_3_INTERFACE_DEFINED__ */ + + +#ifndef __IDeckLinkOutput_v7_3_INTERFACE_DEFINED__ +#define __IDeckLinkOutput_v7_3_INTERFACE_DEFINED__ + +/* interface IDeckLinkOutput_v7_3 */ +/* [helpstring][local][uuid][object] */ + + +EXTERN_C const IID IID_IDeckLinkOutput_v7_3; + +#if defined(__cplusplus) && !defined(CINTERFACE) + + MIDL_INTERFACE("271C65E3-C323-4344-A30F-D908BCB20AA3") + IDeckLinkOutput_v7_3 : public IUnknown + { + public: + virtual HRESULT STDMETHODCALLTYPE DoesSupportVideoMode( + BMDDisplayMode displayMode, + BMDPixelFormat pixelFormat, + /* [out] */ BMDDisplayModeSupport *result) = 0; + + virtual HRESULT STDMETHODCALLTYPE GetDisplayModeIterator( + /* [out] */ IDeckLinkDisplayModeIterator **iterator) = 0; + + virtual HRESULT STDMETHODCALLTYPE SetScreenPreviewCallback( + /* [in] */ IDeckLinkScreenPreviewCallback *previewCallback) = 0; + + virtual HRESULT STDMETHODCALLTYPE EnableVideoOutput( + BMDDisplayMode displayMode, + BMDVideoOutputFlags flags) = 0; + + virtual HRESULT STDMETHODCALLTYPE DisableVideoOutput( void) = 0; + + virtual HRESULT STDMETHODCALLTYPE SetVideoOutputFrameMemoryAllocator( + /* [in] */ IDeckLinkMemoryAllocator *theAllocator) = 0; + + virtual HRESULT STDMETHODCALLTYPE CreateVideoFrame( + long width, + long height, + long rowBytes, + BMDPixelFormat pixelFormat, + BMDFrameFlags flags, + /* [out] */ IDeckLinkMutableVideoFrame **outFrame) = 0; + + virtual HRESULT STDMETHODCALLTYPE CreateAncillaryData( + BMDDisplayMode displayMode, + BMDPixelFormat pixelFormat, + /* [out] */ IDeckLinkVideoFrameAncillary **outBuffer) = 0; + + virtual HRESULT STDMETHODCALLTYPE DisplayVideoFrameSync( + /* [in] */ IDeckLinkVideoFrame *theFrame) = 0; + + virtual HRESULT STDMETHODCALLTYPE ScheduleVideoFrame( + /* [in] */ IDeckLinkVideoFrame *theFrame, + BMDTimeValue displayTime, + BMDTimeValue displayDuration, + BMDTimeScale timeScale) = 0; + + virtual HRESULT STDMETHODCALLTYPE SetScheduledFrameCompletionCallback( + /* [in] */ IDeckLinkVideoOutputCallback *theCallback) = 0; + + virtual HRESULT STDMETHODCALLTYPE GetBufferedVideoFrameCount( + /* [out] */ unsigned long *bufferedFrameCount) = 0; + + virtual HRESULT STDMETHODCALLTYPE EnableAudioOutput( + BMDAudioSampleRate sampleRate, + BMDAudioSampleType sampleType, + unsigned long channelCount, + BMDAudioOutputStreamType streamType) = 0; + + virtual HRESULT STDMETHODCALLTYPE DisableAudioOutput( void) = 0; + + virtual HRESULT STDMETHODCALLTYPE WriteAudioSamplesSync( + /* [in] */ void *buffer, + unsigned long sampleFrameCount, + /* [out] */ unsigned long *sampleFramesWritten) = 0; + + virtual HRESULT STDMETHODCALLTYPE BeginAudioPreroll( void) = 0; + + virtual HRESULT STDMETHODCALLTYPE EndAudioPreroll( void) = 0; + + virtual HRESULT STDMETHODCALLTYPE ScheduleAudioSamples( + /* [in] */ void *buffer, + unsigned long sampleFrameCount, + BMDTimeValue streamTime, + BMDTimeScale timeScale, + /* [out] */ unsigned long *sampleFramesWritten) = 0; + + virtual HRESULT STDMETHODCALLTYPE GetBufferedAudioSampleFrameCount( + /* [out] */ unsigned long *bufferedSampleFrameCount) = 0; + + virtual HRESULT STDMETHODCALLTYPE FlushBufferedAudioSamples( void) = 0; + + virtual HRESULT STDMETHODCALLTYPE SetAudioCallback( + /* [in] */ IDeckLinkAudioOutputCallback *theCallback) = 0; + + virtual HRESULT STDMETHODCALLTYPE StartScheduledPlayback( + BMDTimeValue playbackStartTime, + BMDTimeScale timeScale, + double playbackSpeed) = 0; + + virtual HRESULT STDMETHODCALLTYPE StopScheduledPlayback( + BMDTimeValue stopPlaybackAtTime, + /* [out] */ BMDTimeValue *actualStopTime, + BMDTimeScale timeScale) = 0; + + virtual HRESULT STDMETHODCALLTYPE IsScheduledPlaybackRunning( + /* [out] */ BOOL *active) = 0; + + virtual HRESULT STDMETHODCALLTYPE GetHardwareReferenceClock( + BMDTimeScale desiredTimeScale, + /* [out] */ BMDTimeValue *elapsedTimeSinceSchedulerBegan) = 0; + + }; + +#else /* C style interface */ + + typedef struct IDeckLinkOutput_v7_3Vtbl + { + BEGIN_INTERFACE + + HRESULT ( STDMETHODCALLTYPE *QueryInterface )( + IDeckLinkOutput_v7_3 * This, + /* [in] */ REFIID riid, + /* [iid_is][out] */ + __RPC__deref_out void **ppvObject); + + ULONG ( STDMETHODCALLTYPE *AddRef )( + IDeckLinkOutput_v7_3 * This); + + ULONG ( STDMETHODCALLTYPE *Release )( + IDeckLinkOutput_v7_3 * This); + + HRESULT ( STDMETHODCALLTYPE *DoesSupportVideoMode )( + IDeckLinkOutput_v7_3 * This, + BMDDisplayMode displayMode, + BMDPixelFormat pixelFormat, + /* [out] */ BMDDisplayModeSupport *result); + + HRESULT ( STDMETHODCALLTYPE *GetDisplayModeIterator )( + IDeckLinkOutput_v7_3 * This, + /* [out] */ IDeckLinkDisplayModeIterator **iterator); + + HRESULT ( STDMETHODCALLTYPE *SetScreenPreviewCallback )( + IDeckLinkOutput_v7_3 * This, + /* [in] */ IDeckLinkScreenPreviewCallback *previewCallback); + + HRESULT ( STDMETHODCALLTYPE *EnableVideoOutput )( + IDeckLinkOutput_v7_3 * This, + BMDDisplayMode displayMode, + BMDVideoOutputFlags flags); + + HRESULT ( STDMETHODCALLTYPE *DisableVideoOutput )( + IDeckLinkOutput_v7_3 * This); + + HRESULT ( STDMETHODCALLTYPE *SetVideoOutputFrameMemoryAllocator )( + IDeckLinkOutput_v7_3 * This, + /* [in] */ IDeckLinkMemoryAllocator *theAllocator); + + HRESULT ( STDMETHODCALLTYPE *CreateVideoFrame )( + IDeckLinkOutput_v7_3 * This, + long width, + long height, + long rowBytes, + BMDPixelFormat pixelFormat, + BMDFrameFlags flags, + /* [out] */ IDeckLinkMutableVideoFrame **outFrame); + + HRESULT ( STDMETHODCALLTYPE *CreateAncillaryData )( + IDeckLinkOutput_v7_3 * This, + BMDDisplayMode displayMode, + BMDPixelFormat pixelFormat, + /* [out] */ IDeckLinkVideoFrameAncillary **outBuffer); + + HRESULT ( STDMETHODCALLTYPE *DisplayVideoFrameSync )( + IDeckLinkOutput_v7_3 * This, + /* [in] */ IDeckLinkVideoFrame *theFrame); + + HRESULT ( STDMETHODCALLTYPE *ScheduleVideoFrame )( + IDeckLinkOutput_v7_3 * This, + /* [in] */ IDeckLinkVideoFrame *theFrame, + BMDTimeValue displayTime, + BMDTimeValue displayDuration, + BMDTimeScale timeScale); + + HRESULT ( STDMETHODCALLTYPE *SetScheduledFrameCompletionCallback )( + IDeckLinkOutput_v7_3 * This, + /* [in] */ IDeckLinkVideoOutputCallback *theCallback); + + HRESULT ( STDMETHODCALLTYPE *GetBufferedVideoFrameCount )( + IDeckLinkOutput_v7_3 * This, + /* [out] */ unsigned long *bufferedFrameCount); + + HRESULT ( STDMETHODCALLTYPE *EnableAudioOutput )( + IDeckLinkOutput_v7_3 * This, + BMDAudioSampleRate sampleRate, + BMDAudioSampleType sampleType, + unsigned long channelCount, + BMDAudioOutputStreamType streamType); + + HRESULT ( STDMETHODCALLTYPE *DisableAudioOutput )( + IDeckLinkOutput_v7_3 * This); + + HRESULT ( STDMETHODCALLTYPE *WriteAudioSamplesSync )( + IDeckLinkOutput_v7_3 * This, + /* [in] */ void *buffer, + unsigned long sampleFrameCount, + /* [out] */ unsigned long *sampleFramesWritten); + + HRESULT ( STDMETHODCALLTYPE *BeginAudioPreroll )( + IDeckLinkOutput_v7_3 * This); + + HRESULT ( STDMETHODCALLTYPE *EndAudioPreroll )( + IDeckLinkOutput_v7_3 * This); + + HRESULT ( STDMETHODCALLTYPE *ScheduleAudioSamples )( + IDeckLinkOutput_v7_3 * This, + /* [in] */ void *buffer, + unsigned long sampleFrameCount, + BMDTimeValue streamTime, + BMDTimeScale timeScale, + /* [out] */ unsigned long *sampleFramesWritten); + + HRESULT ( STDMETHODCALLTYPE *GetBufferedAudioSampleFrameCount )( + IDeckLinkOutput_v7_3 * This, + /* [out] */ unsigned long *bufferedSampleFrameCount); + + HRESULT ( STDMETHODCALLTYPE *FlushBufferedAudioSamples )( + IDeckLinkOutput_v7_3 * This); + + HRESULT ( STDMETHODCALLTYPE *SetAudioCallback )( + IDeckLinkOutput_v7_3 * This, + /* [in] */ IDeckLinkAudioOutputCallback *theCallback); + + HRESULT ( STDMETHODCALLTYPE *StartScheduledPlayback )( + IDeckLinkOutput_v7_3 * This, + BMDTimeValue playbackStartTime, + BMDTimeScale timeScale, + double playbackSpeed); + + HRESULT ( STDMETHODCALLTYPE *StopScheduledPlayback )( + IDeckLinkOutput_v7_3 * This, + BMDTimeValue stopPlaybackAtTime, + /* [out] */ BMDTimeValue *actualStopTime, + BMDTimeScale timeScale); + + HRESULT ( STDMETHODCALLTYPE *IsScheduledPlaybackRunning )( + IDeckLinkOutput_v7_3 * This, + /* [out] */ BOOL *active); + + HRESULT ( STDMETHODCALLTYPE *GetHardwareReferenceClock )( + IDeckLinkOutput_v7_3 * This, + BMDTimeScale desiredTimeScale, + /* [out] */ BMDTimeValue *elapsedTimeSinceSchedulerBegan); + + END_INTERFACE + } IDeckLinkOutput_v7_3Vtbl; + + interface IDeckLinkOutput_v7_3 + { + CONST_VTBL struct IDeckLinkOutput_v7_3Vtbl *lpVtbl; + }; + + + +#ifdef COBJMACROS + + +#define IDeckLinkOutput_v7_3_QueryInterface(This,riid,ppvObject) \ + ( (This)->lpVtbl -> QueryInterface(This,riid,ppvObject) ) + +#define IDeckLinkOutput_v7_3_AddRef(This) \ + ( (This)->lpVtbl -> AddRef(This) ) + +#define IDeckLinkOutput_v7_3_Release(This) \ + ( (This)->lpVtbl -> Release(This) ) + + +#define IDeckLinkOutput_v7_3_DoesSupportVideoMode(This,displayMode,pixelFormat,result) \ + ( (This)->lpVtbl -> DoesSupportVideoMode(This,displayMode,pixelFormat,result) ) + +#define IDeckLinkOutput_v7_3_GetDisplayModeIterator(This,iterator) \ + ( (This)->lpVtbl -> GetDisplayModeIterator(This,iterator) ) + +#define IDeckLinkOutput_v7_3_SetScreenPreviewCallback(This,previewCallback) \ + ( (This)->lpVtbl -> SetScreenPreviewCallback(This,previewCallback) ) + +#define IDeckLinkOutput_v7_3_EnableVideoOutput(This,displayMode,flags) \ + ( (This)->lpVtbl -> EnableVideoOutput(This,displayMode,flags) ) + +#define IDeckLinkOutput_v7_3_DisableVideoOutput(This) \ + ( (This)->lpVtbl -> DisableVideoOutput(This) ) + +#define IDeckLinkOutput_v7_3_SetVideoOutputFrameMemoryAllocator(This,theAllocator) \ + ( (This)->lpVtbl -> SetVideoOutputFrameMemoryAllocator(This,theAllocator) ) + +#define IDeckLinkOutput_v7_3_CreateVideoFrame(This,width,height,rowBytes,pixelFormat,flags,outFrame) \ + ( (This)->lpVtbl -> CreateVideoFrame(This,width,height,rowBytes,pixelFormat,flags,outFrame) ) + +#define IDeckLinkOutput_v7_3_CreateAncillaryData(This,displayMode,pixelFormat,outBuffer) \ + ( (This)->lpVtbl -> CreateAncillaryData(This,displayMode,pixelFormat,outBuffer) ) + +#define IDeckLinkOutput_v7_3_DisplayVideoFrameSync(This,theFrame) \ + ( (This)->lpVtbl -> DisplayVideoFrameSync(This,theFrame) ) + +#define IDeckLinkOutput_v7_3_ScheduleVideoFrame(This,theFrame,displayTime,displayDuration,timeScale) \ + ( (This)->lpVtbl -> ScheduleVideoFrame(This,theFrame,displayTime,displayDuration,timeScale) ) + +#define IDeckLinkOutput_v7_3_SetScheduledFrameCompletionCallback(This,theCallback) \ + ( (This)->lpVtbl -> SetScheduledFrameCompletionCallback(This,theCallback) ) + +#define IDeckLinkOutput_v7_3_GetBufferedVideoFrameCount(This,bufferedFrameCount) \ + ( (This)->lpVtbl -> GetBufferedVideoFrameCount(This,bufferedFrameCount) ) + +#define IDeckLinkOutput_v7_3_EnableAudioOutput(This,sampleRate,sampleType,channelCount,streamType) \ + ( (This)->lpVtbl -> EnableAudioOutput(This,sampleRate,sampleType,channelCount,streamType) ) + +#define IDeckLinkOutput_v7_3_DisableAudioOutput(This) \ + ( (This)->lpVtbl -> DisableAudioOutput(This) ) + +#define IDeckLinkOutput_v7_3_WriteAudioSamplesSync(This,buffer,sampleFrameCount,sampleFramesWritten) \ + ( (This)->lpVtbl -> WriteAudioSamplesSync(This,buffer,sampleFrameCount,sampleFramesWritten) ) + +#define IDeckLinkOutput_v7_3_BeginAudioPreroll(This) \ + ( (This)->lpVtbl -> BeginAudioPreroll(This) ) + +#define IDeckLinkOutput_v7_3_EndAudioPreroll(This) \ + ( (This)->lpVtbl -> EndAudioPreroll(This) ) + +#define IDeckLinkOutput_v7_3_ScheduleAudioSamples(This,buffer,sampleFrameCount,streamTime,timeScale,sampleFramesWritten) \ + ( (This)->lpVtbl -> ScheduleAudioSamples(This,buffer,sampleFrameCount,streamTime,timeScale,sampleFramesWritten) ) + +#define IDeckLinkOutput_v7_3_GetBufferedAudioSampleFrameCount(This,bufferedSampleFrameCount) \ + ( (This)->lpVtbl -> GetBufferedAudioSampleFrameCount(This,bufferedSampleFrameCount) ) + +#define IDeckLinkOutput_v7_3_FlushBufferedAudioSamples(This) \ + ( (This)->lpVtbl -> FlushBufferedAudioSamples(This) ) + +#define IDeckLinkOutput_v7_3_SetAudioCallback(This,theCallback) \ + ( (This)->lpVtbl -> SetAudioCallback(This,theCallback) ) + +#define IDeckLinkOutput_v7_3_StartScheduledPlayback(This,playbackStartTime,timeScale,playbackSpeed) \ + ( (This)->lpVtbl -> StartScheduledPlayback(This,playbackStartTime,timeScale,playbackSpeed) ) + +#define IDeckLinkOutput_v7_3_StopScheduledPlayback(This,stopPlaybackAtTime,actualStopTime,timeScale) \ + ( (This)->lpVtbl -> StopScheduledPlayback(This,stopPlaybackAtTime,actualStopTime,timeScale) ) + +#define IDeckLinkOutput_v7_3_IsScheduledPlaybackRunning(This,active) \ + ( (This)->lpVtbl -> IsScheduledPlaybackRunning(This,active) ) + +#define IDeckLinkOutput_v7_3_GetHardwareReferenceClock(This,desiredTimeScale,elapsedTimeSinceSchedulerBegan) \ + ( (This)->lpVtbl -> GetHardwareReferenceClock(This,desiredTimeScale,elapsedTimeSinceSchedulerBegan) ) + +#endif /* COBJMACROS */ + + +#endif /* C style interface */ + + + + +#endif /* __IDeckLinkOutput_v7_3_INTERFACE_DEFINED__ */ + + +#ifndef __IDeckLinkInput_v7_3_INTERFACE_DEFINED__ +#define __IDeckLinkInput_v7_3_INTERFACE_DEFINED__ + +/* interface IDeckLinkInput_v7_3 */ +/* [helpstring][uuid][object] */ + + +EXTERN_C const IID IID_IDeckLinkInput_v7_3; + +#if defined(__cplusplus) && !defined(CINTERFACE) + + MIDL_INTERFACE("4973F012-9925-458C-871C-18774CDBBECB") + IDeckLinkInput_v7_3 : public IUnknown + { + public: + virtual HRESULT STDMETHODCALLTYPE DoesSupportVideoMode( + BMDDisplayMode displayMode, + BMDPixelFormat pixelFormat, + /* [out] */ BMDDisplayModeSupport *result) = 0; + + virtual HRESULT STDMETHODCALLTYPE GetDisplayModeIterator( + /* [out] */ IDeckLinkDisplayModeIterator **iterator) = 0; + + virtual HRESULT STDMETHODCALLTYPE SetScreenPreviewCallback( + /* [in] */ IDeckLinkScreenPreviewCallback *previewCallback) = 0; + + virtual HRESULT STDMETHODCALLTYPE EnableVideoInput( + BMDDisplayMode displayMode, + BMDPixelFormat pixelFormat, + BMDVideoInputFlags flags) = 0; + + virtual HRESULT STDMETHODCALLTYPE DisableVideoInput( void) = 0; + + virtual HRESULT STDMETHODCALLTYPE GetAvailableVideoFrameCount( + /* [out] */ unsigned long *availableFrameCount) = 0; + + virtual HRESULT STDMETHODCALLTYPE EnableAudioInput( + BMDAudioSampleRate sampleRate, + BMDAudioSampleType sampleType, + unsigned long channelCount) = 0; + + virtual HRESULT STDMETHODCALLTYPE DisableAudioInput( void) = 0; + + virtual HRESULT STDMETHODCALLTYPE GetAvailableAudioSampleFrameCount( + /* [out] */ unsigned long *availableSampleFrameCount) = 0; + + virtual HRESULT STDMETHODCALLTYPE StartStreams( void) = 0; + + virtual HRESULT STDMETHODCALLTYPE StopStreams( void) = 0; + + virtual HRESULT STDMETHODCALLTYPE PauseStreams( void) = 0; + + virtual HRESULT STDMETHODCALLTYPE FlushStreams( void) = 0; + + virtual HRESULT STDMETHODCALLTYPE SetCallback( + /* [in] */ IDeckLinkInputCallback_v7_3 *theCallback) = 0; + + }; + +#else /* C style interface */ + + typedef struct IDeckLinkInput_v7_3Vtbl + { + BEGIN_INTERFACE + + HRESULT ( STDMETHODCALLTYPE *QueryInterface )( + IDeckLinkInput_v7_3 * This, + /* [in] */ REFIID riid, + /* [iid_is][out] */ + __RPC__deref_out void **ppvObject); + + ULONG ( STDMETHODCALLTYPE *AddRef )( + IDeckLinkInput_v7_3 * This); + + ULONG ( STDMETHODCALLTYPE *Release )( + IDeckLinkInput_v7_3 * This); + + HRESULT ( STDMETHODCALLTYPE *DoesSupportVideoMode )( + IDeckLinkInput_v7_3 * This, + BMDDisplayMode displayMode, + BMDPixelFormat pixelFormat, + /* [out] */ BMDDisplayModeSupport *result); + + HRESULT ( STDMETHODCALLTYPE *GetDisplayModeIterator )( + IDeckLinkInput_v7_3 * This, + /* [out] */ IDeckLinkDisplayModeIterator **iterator); + + HRESULT ( STDMETHODCALLTYPE *SetScreenPreviewCallback )( + IDeckLinkInput_v7_3 * This, + /* [in] */ IDeckLinkScreenPreviewCallback *previewCallback); + + HRESULT ( STDMETHODCALLTYPE *EnableVideoInput )( + IDeckLinkInput_v7_3 * This, + BMDDisplayMode displayMode, + BMDPixelFormat pixelFormat, + BMDVideoInputFlags flags); + + HRESULT ( STDMETHODCALLTYPE *DisableVideoInput )( + IDeckLinkInput_v7_3 * This); + + HRESULT ( STDMETHODCALLTYPE *GetAvailableVideoFrameCount )( + IDeckLinkInput_v7_3 * This, + /* [out] */ unsigned long *availableFrameCount); + + HRESULT ( STDMETHODCALLTYPE *EnableAudioInput )( + IDeckLinkInput_v7_3 * This, + BMDAudioSampleRate sampleRate, + BMDAudioSampleType sampleType, + unsigned long channelCount); + + HRESULT ( STDMETHODCALLTYPE *DisableAudioInput )( + IDeckLinkInput_v7_3 * This); + + HRESULT ( STDMETHODCALLTYPE *GetAvailableAudioSampleFrameCount )( + IDeckLinkInput_v7_3 * This, + /* [out] */ unsigned long *availableSampleFrameCount); + + HRESULT ( STDMETHODCALLTYPE *StartStreams )( + IDeckLinkInput_v7_3 * This); + + HRESULT ( STDMETHODCALLTYPE *StopStreams )( + IDeckLinkInput_v7_3 * This); + + HRESULT ( STDMETHODCALLTYPE *PauseStreams )( + IDeckLinkInput_v7_3 * This); + + HRESULT ( STDMETHODCALLTYPE *FlushStreams )( + IDeckLinkInput_v7_3 * This); + + HRESULT ( STDMETHODCALLTYPE *SetCallback )( + IDeckLinkInput_v7_3 * This, + /* [in] */ IDeckLinkInputCallback_v7_3 *theCallback); + + END_INTERFACE + } IDeckLinkInput_v7_3Vtbl; + + interface IDeckLinkInput_v7_3 + { + CONST_VTBL struct IDeckLinkInput_v7_3Vtbl *lpVtbl; + }; + + + +#ifdef COBJMACROS + + +#define IDeckLinkInput_v7_3_QueryInterface(This,riid,ppvObject) \ + ( (This)->lpVtbl -> QueryInterface(This,riid,ppvObject) ) + +#define IDeckLinkInput_v7_3_AddRef(This) \ + ( (This)->lpVtbl -> AddRef(This) ) + +#define IDeckLinkInput_v7_3_Release(This) \ + ( (This)->lpVtbl -> Release(This) ) + + +#define IDeckLinkInput_v7_3_DoesSupportVideoMode(This,displayMode,pixelFormat,result) \ + ( (This)->lpVtbl -> DoesSupportVideoMode(This,displayMode,pixelFormat,result) ) + +#define IDeckLinkInput_v7_3_GetDisplayModeIterator(This,iterator) \ + ( (This)->lpVtbl -> GetDisplayModeIterator(This,iterator) ) + +#define IDeckLinkInput_v7_3_SetScreenPreviewCallback(This,previewCallback) \ + ( (This)->lpVtbl -> SetScreenPreviewCallback(This,previewCallback) ) + +#define IDeckLinkInput_v7_3_EnableVideoInput(This,displayMode,pixelFormat,flags) \ + ( (This)->lpVtbl -> EnableVideoInput(This,displayMode,pixelFormat,flags) ) + +#define IDeckLinkInput_v7_3_DisableVideoInput(This) \ + ( (This)->lpVtbl -> DisableVideoInput(This) ) + +#define IDeckLinkInput_v7_3_GetAvailableVideoFrameCount(This,availableFrameCount) \ + ( (This)->lpVtbl -> GetAvailableVideoFrameCount(This,availableFrameCount) ) + +#define IDeckLinkInput_v7_3_EnableAudioInput(This,sampleRate,sampleType,channelCount) \ + ( (This)->lpVtbl -> EnableAudioInput(This,sampleRate,sampleType,channelCount) ) + +#define IDeckLinkInput_v7_3_DisableAudioInput(This) \ + ( (This)->lpVtbl -> DisableAudioInput(This) ) + +#define IDeckLinkInput_v7_3_GetAvailableAudioSampleFrameCount(This,availableSampleFrameCount) \ + ( (This)->lpVtbl -> GetAvailableAudioSampleFrameCount(This,availableSampleFrameCount) ) + +#define IDeckLinkInput_v7_3_StartStreams(This) \ + ( (This)->lpVtbl -> StartStreams(This) ) + +#define IDeckLinkInput_v7_3_StopStreams(This) \ + ( (This)->lpVtbl -> StopStreams(This) ) + +#define IDeckLinkInput_v7_3_PauseStreams(This) \ + ( (This)->lpVtbl -> PauseStreams(This) ) + +#define IDeckLinkInput_v7_3_FlushStreams(This) \ + ( (This)->lpVtbl -> FlushStreams(This) ) + +#define IDeckLinkInput_v7_3_SetCallback(This,theCallback) \ + ( (This)->lpVtbl -> SetCallback(This,theCallback) ) + +#endif /* COBJMACROS */ + + +#endif /* C style interface */ + + + + +#endif /* __IDeckLinkInput_v7_3_INTERFACE_DEFINED__ */ + + +#ifndef __IDeckLinkVideoInputFrame_v7_3_INTERFACE_DEFINED__ +#define __IDeckLinkVideoInputFrame_v7_3_INTERFACE_DEFINED__ + +/* interface IDeckLinkVideoInputFrame_v7_3 */ +/* [helpstring][local][uuid][object] */ + + +EXTERN_C const IID IID_IDeckLinkVideoInputFrame_v7_3; + +#if defined(__cplusplus) && !defined(CINTERFACE) + + MIDL_INTERFACE("CF317790-2894-11DE-8C30-0800200C9A66") + IDeckLinkVideoInputFrame_v7_3 : public IDeckLinkVideoFrame + { + public: + virtual HRESULT STDMETHODCALLTYPE GetStreamTime( + /* [out] */ BMDTimeValue *frameTime, + /* [out] */ BMDTimeValue *frameDuration, + BMDTimeScale timeScale) = 0; + + }; + +#else /* C style interface */ + + typedef struct IDeckLinkVideoInputFrame_v7_3Vtbl + { + BEGIN_INTERFACE + + HRESULT ( STDMETHODCALLTYPE *QueryInterface )( + IDeckLinkVideoInputFrame_v7_3 * This, + /* [in] */ REFIID riid, + /* [iid_is][out] */ + __RPC__deref_out void **ppvObject); + + ULONG ( STDMETHODCALLTYPE *AddRef )( + IDeckLinkVideoInputFrame_v7_3 * This); + + ULONG ( STDMETHODCALLTYPE *Release )( + IDeckLinkVideoInputFrame_v7_3 * This); + + long ( STDMETHODCALLTYPE *GetWidth )( + IDeckLinkVideoInputFrame_v7_3 * This); + + long ( STDMETHODCALLTYPE *GetHeight )( + IDeckLinkVideoInputFrame_v7_3 * This); + + long ( STDMETHODCALLTYPE *GetRowBytes )( + IDeckLinkVideoInputFrame_v7_3 * This); + + BMDPixelFormat ( STDMETHODCALLTYPE *GetPixelFormat )( + IDeckLinkVideoInputFrame_v7_3 * This); + + BMDFrameFlags ( STDMETHODCALLTYPE *GetFlags )( + IDeckLinkVideoInputFrame_v7_3 * This); + + HRESULT ( STDMETHODCALLTYPE *GetBytes )( + IDeckLinkVideoInputFrame_v7_3 * This, + /* [out] */ void **buffer); + + HRESULT ( STDMETHODCALLTYPE *GetTimecode )( + IDeckLinkVideoInputFrame_v7_3 * This, + BMDTimecodeFormat format, + /* [out] */ IDeckLinkTimecode **timecode); + + HRESULT ( STDMETHODCALLTYPE *GetAncillaryData )( + IDeckLinkVideoInputFrame_v7_3 * This, + /* [out] */ IDeckLinkVideoFrameAncillary **ancillary); + + HRESULT ( STDMETHODCALLTYPE *GetStreamTime )( + IDeckLinkVideoInputFrame_v7_3 * This, + /* [out] */ BMDTimeValue *frameTime, + /* [out] */ BMDTimeValue *frameDuration, + BMDTimeScale timeScale); + + END_INTERFACE + } IDeckLinkVideoInputFrame_v7_3Vtbl; + + interface IDeckLinkVideoInputFrame_v7_3 + { + CONST_VTBL struct IDeckLinkVideoInputFrame_v7_3Vtbl *lpVtbl; + }; + + + +#ifdef COBJMACROS + + +#define IDeckLinkVideoInputFrame_v7_3_QueryInterface(This,riid,ppvObject) \ + ( (This)->lpVtbl -> QueryInterface(This,riid,ppvObject) ) + +#define IDeckLinkVideoInputFrame_v7_3_AddRef(This) \ + ( (This)->lpVtbl -> AddRef(This) ) + +#define IDeckLinkVideoInputFrame_v7_3_Release(This) \ + ( (This)->lpVtbl -> Release(This) ) + + +#define IDeckLinkVideoInputFrame_v7_3_GetWidth(This) \ + ( (This)->lpVtbl -> GetWidth(This) ) + +#define IDeckLinkVideoInputFrame_v7_3_GetHeight(This) \ + ( (This)->lpVtbl -> GetHeight(This) ) + +#define IDeckLinkVideoInputFrame_v7_3_GetRowBytes(This) \ + ( (This)->lpVtbl -> GetRowBytes(This) ) + +#define IDeckLinkVideoInputFrame_v7_3_GetPixelFormat(This) \ + ( (This)->lpVtbl -> GetPixelFormat(This) ) + +#define IDeckLinkVideoInputFrame_v7_3_GetFlags(This) \ + ( (This)->lpVtbl -> GetFlags(This) ) + +#define IDeckLinkVideoInputFrame_v7_3_GetBytes(This,buffer) \ + ( (This)->lpVtbl -> GetBytes(This,buffer) ) + +#define IDeckLinkVideoInputFrame_v7_3_GetTimecode(This,format,timecode) \ + ( (This)->lpVtbl -> GetTimecode(This,format,timecode) ) + +#define IDeckLinkVideoInputFrame_v7_3_GetAncillaryData(This,ancillary) \ + ( (This)->lpVtbl -> GetAncillaryData(This,ancillary) ) + + +#define IDeckLinkVideoInputFrame_v7_3_GetStreamTime(This,frameTime,frameDuration,timeScale) \ + ( (This)->lpVtbl -> GetStreamTime(This,frameTime,frameDuration,timeScale) ) + +#endif /* COBJMACROS */ + + +#endif /* C style interface */ + + + + +#endif /* __IDeckLinkVideoInputFrame_v7_3_INTERFACE_DEFINED__ */ + +#endif /* __DeckLinkAPI_LIBRARY_DEFINED__ */ + +/* Additional Prototypes for ALL interfaces */ + +/* end of Additional Prototypes */ + +#ifdef __cplusplus +} +#endif + +#endif + + diff --git a/core/consumer/decklink/DeckLinkAPI_i.c b/core/consumer/decklink/DeckLinkAPI_i.c new file mode 100644 index 000000000..b2e87a93f --- /dev/null +++ b/core/consumer/decklink/DeckLinkAPI_i.c @@ -0,0 +1,190 @@ + + +/* this ALWAYS GENERATED file contains the IIDs and CLSIDs */ + +/* link this file in with the server and any clients */ + + + /* File created by MIDL compiler version 7.00.0500 */ +/* at Wed Jan 13 09:58:01 2010 + */ +/* Compiler settings for .\consumers\declink\DeckLinkAPI.idl: + Oicf, W1, Zp8, env=Win32 (32b run) + protocol : dce , ms_ext, c_ext, robust + error checks: allocation ref bounds_check enum stub_data + VC __declspec() decoration level: + __declspec(uuid()), __declspec(selectany), __declspec(novtable) + DECLSPEC_UUID(), MIDL_INTERFACE() +*/ +//@@MIDL_FILE_HEADING( ) + +#pragma warning( disable: 4049 ) /* more than 64k source lines */ + + +#ifdef __cplusplus +extern "C"{ +#endif + + +#include +#include + +#ifdef _MIDL_USE_GUIDDEF_ + +#ifndef INITGUID +#define INITGUID +#include +#undef INITGUID +#else +#include +#endif + +#define MIDL_DEFINE_GUID(type,name,l,w1,w2,b1,b2,b3,b4,b5,b6,b7,b8) \ + DEFINE_GUID(name,l,w1,w2,b1,b2,b3,b4,b5,b6,b7,b8) + +#else // !_MIDL_USE_GUIDDEF_ + +#ifndef __IID_DEFINED__ +#define __IID_DEFINED__ + +typedef struct _IID +{ + unsigned long x; + unsigned short s1; + unsigned short s2; + unsigned char c[8]; +} IID; + +#endif // __IID_DEFINED__ + +#ifndef CLSID_DEFINED +#define CLSID_DEFINED +typedef IID CLSID; +#endif // CLSID_DEFINED + +#define MIDL_DEFINE_GUID(type,name,l,w1,w2,b1,b2,b3,b4,b5,b6,b7,b8) \ + const type name = {l,w1,w2,{b1,b2,b3,b4,b5,b6,b7,b8}} + +#endif !_MIDL_USE_GUIDDEF_ + +MIDL_DEFINE_GUID(IID, LIBID_DeckLinkAPI,0xD864517A,0xEDD5,0x466D,0x86,0x7D,0xC8,0x19,0xF1,0xC0,0x52,0xBB); + + +MIDL_DEFINE_GUID(IID, IID_IDeckLinkVideoOutputCallback,0xE763A626,0x4A3C,0x49D1,0xBF,0x13,0xE7,0xAD,0x36,0x92,0xAE,0x52); + + +MIDL_DEFINE_GUID(IID, IID_IDeckLinkInputCallback,0x31D28EE7,0x88B6,0x4CB1,0x89,0x7A,0xCD,0xBF,0x79,0xA2,0x64,0x14); + + +MIDL_DEFINE_GUID(IID, IID_IDeckLinkMemoryAllocator,0xB36EB6E7,0x9D29,0x4AA8,0x92,0xEF,0x84,0x3B,0x87,0xA2,0x89,0xE8); + + +MIDL_DEFINE_GUID(IID, IID_IDeckLinkAudioOutputCallback,0x403C681B,0x7F46,0x4A12,0xB9,0x93,0x2B,0xB1,0x27,0x08,0x4E,0xE6); + + +MIDL_DEFINE_GUID(IID, IID_IDeckLinkIterator,0x74E936FC,0xCC28,0x4A67,0x81,0xA0,0x1E,0x94,0xE5,0x2D,0x4E,0x69); + + +MIDL_DEFINE_GUID(IID, IID_IDeckLinkAPIInformation,0x7BEA3C68,0x730D,0x4322,0xAF,0x34,0x8A,0x71,0x52,0xB5,0x32,0xA4); + + +MIDL_DEFINE_GUID(IID, IID_IDeckLinkDisplayModeIterator,0x455D741F,0x1779,0x4800,0x86,0xF5,0x0B,0x5D,0x13,0xD7,0x97,0x51); + + +MIDL_DEFINE_GUID(IID, IID_IDeckLinkDisplayMode,0x87451E84,0x2B7E,0x439E,0xA6,0x29,0x43,0x93,0xEA,0x4A,0x85,0x50); + + +MIDL_DEFINE_GUID(IID, IID_IDeckLink,0x62BFF75D,0x6569,0x4E55,0x8D,0x4D,0x66,0xAA,0x03,0x82,0x9A,0xBC); + + +MIDL_DEFINE_GUID(IID, IID_IDeckLinkOutput,0x29228142,0xEB8C,0x4141,0xA6,0x21,0xF7,0x40,0x26,0x45,0x09,0x55); + + +MIDL_DEFINE_GUID(IID, IID_IDeckLinkInput,0x300C135A,0x9F43,0x48E2,0x99,0x06,0x6D,0x79,0x11,0xD9,0x3C,0xF1); + + +MIDL_DEFINE_GUID(IID, IID_IDeckLinkTimecode,0xEFB9BCA6,0xA521,0x44F7,0xBD,0x69,0x23,0x32,0xF2,0x4D,0x9E,0xE6); + + +MIDL_DEFINE_GUID(IID, IID_IDeckLinkVideoFrame,0xA8D8238E,0x6B18,0x4196,0x99,0xE1,0x5A,0xF7,0x17,0xB8,0x3D,0x32); + + +MIDL_DEFINE_GUID(IID, IID_IDeckLinkMutableVideoFrame,0x46FCEE00,0xB4E6,0x43D0,0x91,0xC0,0x02,0x3A,0x7F,0xCE,0xB3,0x4F); + + +MIDL_DEFINE_GUID(IID, IID_IDeckLinkVideoInputFrame,0x9A74FA41,0xAE9F,0x47AC,0x8C,0xF4,0x01,0xF4,0x2D,0xD5,0x99,0x65); + + +MIDL_DEFINE_GUID(IID, IID_IDeckLinkVideoFrameAncillary,0x732E723C,0xD1A4,0x4E29,0x9E,0x8E,0x4A,0x88,0x79,0x7A,0x00,0x04); + + +MIDL_DEFINE_GUID(IID, IID_IDeckLinkAudioInputPacket,0xE43D5870,0x2894,0x11DE,0x8C,0x30,0x08,0x00,0x20,0x0C,0x9A,0x66); + + +MIDL_DEFINE_GUID(IID, IID_IDeckLinkScreenPreviewCallback,0x373F499D,0x4B4D,0x4518,0xAD,0x22,0x63,0x54,0xE5,0xA5,0x82,0x5E); + + +MIDL_DEFINE_GUID(IID, IID_IDeckLinkGLScreenPreviewHelper,0xBA575CD9,0xA15E,0x497B,0xB2,0xC2,0xF9,0xAF,0xE7,0xBE,0x4E,0xBA); + + +MIDL_DEFINE_GUID(IID, IID_IDeckLinkConfiguration,0xB8EAD569,0xB764,0x47F0,0xA7,0x3F,0xAE,0x40,0xDF,0x6C,0xBF,0x10); + + +MIDL_DEFINE_GUID(IID, IID_IDeckLinkAttributes,0xABC11843,0xD966,0x44CB,0x96,0xE2,0xA1,0xCB,0x5D,0x31,0x35,0xC4); + + +MIDL_DEFINE_GUID(IID, IID_IDeckLinkKeyer,0x89AFCAF5,0x65F8,0x421E,0x98,0xF7,0x96,0xFE,0x5F,0x5B,0xFB,0xA3); + + +MIDL_DEFINE_GUID(CLSID, CLSID_CDeckLinkIterator,0xD9EDA3B3,0x2887,0x41FA,0xB7,0x24,0x01,0x7C,0xF1,0xEB,0x1D,0x37); + + +MIDL_DEFINE_GUID(CLSID, CLSID_CDeckLinkGLScreenPreviewHelper,0xD398CEE7,0x4434,0x4CA3,0x9B,0xA6,0x5A,0xE3,0x45,0x56,0xB9,0x05); + + +MIDL_DEFINE_GUID(IID, IID_IDeckLinkDisplayModeIterator_v7_1,0xB28131B6,0x59AC,0x4857,0xB5,0xAC,0xCD,0x75,0xD5,0x88,0x3E,0x2F); + + +MIDL_DEFINE_GUID(IID, IID_IDeckLinkDisplayMode_v7_1,0xAF0CD6D5,0x8376,0x435E,0x84,0x33,0x54,0xF9,0xDD,0x53,0x0A,0xC3); + + +MIDL_DEFINE_GUID(IID, IID_IDeckLinkVideoFrame_v7_1,0x333F3A10,0x8C2D,0x43CF,0xB7,0x9D,0x46,0x56,0x0F,0xEE,0xA1,0xCE); + + +MIDL_DEFINE_GUID(IID, IID_IDeckLinkVideoInputFrame_v7_1,0xC8B41D95,0x8848,0x40EE,0x9B,0x37,0x6E,0x34,0x17,0xFB,0x11,0x4B); + + +MIDL_DEFINE_GUID(IID, IID_IDeckLinkAudioInputPacket_v7_1,0xC86DE4F6,0xA29F,0x42E3,0xAB,0x3A,0x13,0x63,0xE2,0x9F,0x07,0x88); + + +MIDL_DEFINE_GUID(IID, IID_IDeckLinkVideoOutputCallback_v7_1,0xEBD01AFA,0xE4B0,0x49C6,0xA0,0x1D,0xED,0xB9,0xD1,0xB5,0x5F,0xD9); + + +MIDL_DEFINE_GUID(IID, IID_IDeckLinkInputCallback_v7_1,0x7F94F328,0x5ED4,0x4E9F,0x97,0x29,0x76,0xA8,0x6B,0xDC,0x99,0xCC); + + +MIDL_DEFINE_GUID(IID, IID_IDeckLinkOutput_v7_1,0xAE5B3E9B,0x4E1E,0x4535,0xB6,0xE8,0x48,0x0F,0xF5,0x2F,0x6C,0xE5); + + +MIDL_DEFINE_GUID(IID, IID_IDeckLinkInput_v7_1,0x2B54EDEF,0x5B32,0x429F,0xBA,0x11,0xBB,0x99,0x05,0x96,0xEA,0xCD); + + +MIDL_DEFINE_GUID(IID, IID_IDeckLinkInputCallback_v7_3,0xFD6F311D,0x4D00,0x444B,0x9E,0xD4,0x1F,0x25,0xB5,0x73,0x0A,0xD0); + + +MIDL_DEFINE_GUID(IID, IID_IDeckLinkOutput_v7_3,0x271C65E3,0xC323,0x4344,0xA3,0x0F,0xD9,0x08,0xBC,0xB2,0x0A,0xA3); + + +MIDL_DEFINE_GUID(IID, IID_IDeckLinkInput_v7_3,0x4973F012,0x9925,0x458C,0x87,0x1C,0x18,0x77,0x4C,0xDB,0xBE,0xCB); + + +MIDL_DEFINE_GUID(IID, IID_IDeckLinkVideoInputFrame_v7_3,0xCF317790,0x2894,0x11DE,0x8C,0x30,0x08,0x00,0x20,0x0C,0x9A,0x66); + +#undef MIDL_DEFINE_GUID + +#ifdef __cplusplus +} +#endif + + + diff --git a/core/consumer/decklink/DeckLinkAPI_v7_1.idl b/core/consumer/decklink/DeckLinkAPI_v7_1.idl new file mode 100644 index 000000000..20d4e5ff8 --- /dev/null +++ b/core/consumer/decklink/DeckLinkAPI_v7_1.idl @@ -0,0 +1,160 @@ +/* -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- +*/ +/* DeckLinkAPI_v7_1.idl */ + + interface IDeckLinkDisplayModeIterator_v7_1; + interface IDeckLinkDisplayMode_v7_1; + interface IDeckLinkVideoFrame_v7_1; + interface IDeckLinkVideoInputFrame_v7_1; + interface IDeckLinkAudioInputPacket_v7_1; + + [object, uuid(B28131B6-59AC-4857-B5AC-CD75D5883E2F), + helpstring("IDeckLinkDisplayModeIterator_v7_1 enumerates over supported input/output display modes.")] + interface IDeckLinkDisplayModeIterator_v7_1 : IUnknown + { + HRESULT Next ([out] IDeckLinkDisplayMode_v7_1** deckLinkDisplayMode); + }; + + + [object, uuid(AF0CD6D5-8376-435E-8433-54F9DD530AC3), + helpstring("IDeckLinkDisplayMode_v7_1 represents a display mode")] + interface IDeckLinkDisplayMode_v7_1 : IUnknown + { + HRESULT GetName ([out] BSTR* name); + BMDDisplayMode GetDisplayMode (); + long GetWidth (); + long GetHeight (); + HRESULT GetFrameRate ([out] BMDTimeValue *frameDuration, [out] BMDTimeScale *timeScale); + }; + + [object, uuid(EBD01AFA-E4B0-49C6-A01D-EDB9D1B55FD9), + helpstring("IDeckLinkVideoOutputCallback. Frame completion callback.")] + interface IDeckLinkVideoOutputCallback_v7_1 : IUnknown + { + HRESULT ScheduledFrameCompleted ([in] IDeckLinkVideoFrame_v7_1* completedFrame, [in] BMDOutputFrameCompletionResult result); + }; + + [object, uuid(7F94F328-5ED4-4E9F-9729-76A86BDC99CC), + helpstring("IDeckLinkInputCallback_v7_1. Frame arrival callback.")] + interface IDeckLinkInputCallback_v7_1 : IUnknown + { + HRESULT VideoInputFrameArrived ([in] IDeckLinkVideoInputFrame_v7_1* videoFrame, [in] IDeckLinkAudioInputPacket_v7_1* audioPacket); + }; + + + [object, uuid(AE5B3E9B-4E1E-4535-B6E8-480FF52F6CE5), local, + helpstring("IDeckLinkOutput_v7_1. Created by QueryInterface from IDeckLink.")] + interface IDeckLinkOutput_v7_1 : IUnknown + { + HRESULT DoesSupportVideoMode (BMDDisplayMode displayMode, BMDPixelFormat pixelFormat, [out] BMDDisplayModeSupport *result); + HRESULT GetDisplayModeIterator ([out] IDeckLinkDisplayModeIterator_v7_1 **iterator); + + // Video output + HRESULT EnableVideoOutput (BMDDisplayMode displayMode); + HRESULT DisableVideoOutput (); + + HRESULT SetVideoOutputFrameMemoryAllocator ([in] IDeckLinkMemoryAllocator* theAllocator); + HRESULT CreateVideoFrame (long width, long height, long rowBytes, BMDPixelFormat pixelFormat, BMDFrameFlags flags, IDeckLinkVideoFrame_v7_1** outFrame); + HRESULT CreateVideoFrameFromBuffer (void* buffer, long width, long height, long rowBytes, BMDPixelFormat pixelFormat, BMDFrameFlags flags, IDeckLinkVideoFrame_v7_1** outFrame); + + HRESULT DisplayVideoFrameSync (IDeckLinkVideoFrame_v7_1* theFrame); + HRESULT ScheduleVideoFrame (IDeckLinkVideoFrame_v7_1* theFrame, BMDTimeValue displayTime, BMDTimeValue displayDuration, BMDTimeScale timeScale); + HRESULT SetScheduledFrameCompletionCallback ([in] IDeckLinkVideoOutputCallback_v7_1* theCallback); + + // Audio output + HRESULT EnableAudioOutput (BMDAudioSampleRate sampleRate, BMDAudioSampleType sampleType, unsigned long channelCount); + HRESULT DisableAudioOutput (); + + HRESULT WriteAudioSamplesSync (void* buffer, unsigned long sampleFrameCount, [out] unsigned long *sampleFramesWritten); + + HRESULT BeginAudioPreroll (); + HRESULT EndAudioPreroll (); + HRESULT ScheduleAudioSamples (void* buffer, unsigned long sampleFrameCount, BMDTimeValue streamTime, BMDTimeScale timeScale, [out] unsigned long *sampleFramesWritten); + + HRESULT GetBufferedAudioSampleFrameCount ( [out] unsigned long *bufferedSampleCount); + HRESULT FlushBufferedAudioSamples (); + + HRESULT SetAudioCallback ( [in] IDeckLinkAudioOutputCallback* theCallback); + + // Output control + HRESULT StartScheduledPlayback (BMDTimeValue playbackStartTime, BMDTimeScale timeScale, double playbackSpeed); + HRESULT StopScheduledPlayback (BMDTimeValue stopPlaybackAtTime, BMDTimeValue *actualStopTime, BMDTimeScale timeScale); + HRESULT GetHardwareReferenceClock (BMDTimeScale desiredTimeScale, BMDTimeValue *elapsedTimeSinceSchedulerBegan); + }; + + [object, uuid(2B54EDEF-5B32-429F-BA11-BB990596EACD), + helpstring("IDeckLinkInput_v7_1. Created by QueryInterface from IDeckLink.")] + interface IDeckLinkInput_v7_1 : IUnknown + { + HRESULT DoesSupportVideoMode (BMDDisplayMode displayMode, BMDPixelFormat pixelFormat, [out] BMDDisplayModeSupport *result); + HRESULT GetDisplayModeIterator ([out] IDeckLinkDisplayModeIterator_v7_1 **iterator); + + // Video input + HRESULT EnableVideoInput (BMDDisplayMode displayMode, BMDPixelFormat pixelFormat, BMDVideoInputFlags flags); + HRESULT DisableVideoInput (); + + // Audio input + HRESULT EnableAudioInput (BMDAudioSampleRate sampleRate, BMDAudioSampleType sampleType, unsigned long channelCount); + HRESULT DisableAudioInput (); + HRESULT ReadAudioSamples (void* buffer, unsigned long sampleFrameCount, [out] unsigned long *sampleFramesRead, [out] BMDTimeValue *audioPacketTime, BMDTimeScale timeScale); + HRESULT GetBufferedAudioSampleFrameCount ( [out] unsigned long *bufferedSampleCount); + + // Input control + HRESULT StartStreams (); + HRESULT StopStreams (); + HRESULT PauseStreams (); + HRESULT SetCallback ([in] IDeckLinkInputCallback_v7_1* theCallback); + }; + + [object, uuid(333F3A10-8C2D-43CF-B79D-46560FEEA1CE), local, + helpstring("IDeckLinkVideoFrame_v7_1. Created by IDeckLinkVideoOutput::CreateVideoFrame.")] + interface IDeckLinkVideoFrame_v7_1 : IUnknown + { + long GetWidth (); + long GetHeight (); + long GetRowBytes (); + BMDPixelFormat GetPixelFormat (); + BMDFrameFlags GetFlags (); + HRESULT GetBytes (void* *buffer); + }; + + [object, uuid(C8B41D95-8848-40EE-9B37-6E3417FB114B), local, + helpstring("IDeckLinkVideoInputFrame_v7_1. Provided by the IDeckLinkVideoInput frame arrival callback.")] + interface IDeckLinkVideoInputFrame_v7_1 : IDeckLinkVideoFrame_v7_1 + { + HRESULT GetFrameTime (BMDTimeValue *frameTime, BMDTimeValue *frameDuration, BMDTimeScale timeScale); + }; + + [object, uuid(C86DE4F6-A29F-42E3-AB3A-1363E29F0788), local, + helpstring("IDeckLinkAudioInputPacket_v7_1. Provided by the IDeckLinkInput callback.")] + interface IDeckLinkAudioInputPacket_v7_1 : IUnknown + { + long GetSampleCount (); + HRESULT GetBytes (void* *buffer); + HRESULT GetAudioPacketTime (BMDTimeValue *packetTime, BMDTimeScale timeScale); + }; + diff --git a/core/consumer/decklink/DeckLinkAPI_v7_3.idl b/core/consumer/decklink/DeckLinkAPI_v7_3.idl new file mode 100644 index 000000000..682b2007b --- /dev/null +++ b/core/consumer/decklink/DeckLinkAPI_v7_3.idl @@ -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/core/consumer/decklink/DecklinkVideoConsumer.cpp b/core/consumer/decklink/DecklinkVideoConsumer.cpp new file mode 100644 index 000000000..f13a40f06 --- /dev/null +++ b/core/consumer/decklink/DecklinkVideoConsumer.cpp @@ -0,0 +1,467 @@ +/* +* copyright (c) 2010 Sveriges Television AB +* +* This file is part of CasparCG. +* +* CasparCG is free software: you can redistribute it and/or modify +* it under the terms of the GNU General Public License as published by +* the Free Software Foundation, either version 3 of the License, or +* (at your option) any later version. +* +* CasparCG is distributed in the hope that it will be useful, +* but WITHOUT ANY WARRANTY; without even the implied warranty of +* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +* GNU General Public License for more details. + +* You should have received a copy of the GNU General Public License +* along with CasparCG. If not, see . +* +*/ + +#include "../../stdafx.h" + +#if defined(_MSC_VER) +#pragma warning (push, 1) // TODO: Legacy code, just disable warnings +#pragma warning (disable : 4244) +#endif + +#include "DecklinkVideoConsumer.h" +#include "DeckLinkAPI_h.h" + +#include "../../frame/system_frame.h" +#include "../../frame/frame_format.h" +#include "../../../common/image/image.h" + +#include "../../renderer/render_device.h" + +#include +#include + +#pragma warning(push) +#pragma warning(disable : 4996) + + #include + + #include + #include + +#pragma warning(push) + +namespace caspar{ namespace decklink{ + +struct DecklinkVideoConsumer::Implementation : public IDeckLinkVideoOutputCallback +{ + struct DecklinkFrameManager; + struct DecklinkVideoFrame : public frame + { + explicit DecklinkVideoFrame(DecklinkFrameManager* pFactory) + { + IDeckLinkMutableVideoFrame* frame = NULL; + const caspar::frame_format_desc& format_desc = pFactory->pConsumerImpl_->get_frame_format_desc(); + if(pFactory->pConsumerImpl_->pDecklinkOutput_->CreateVideoFrame(format_desc.width, format_desc.height, format_desc.size/format_desc.height, bmdFormat8BitBGRA, bmdFrameFlagDefault, &frame) != S_OK) + { + throw std::exception("DECKLINK: Failed to create frame"); + } + pDecklinkFrame_ = frame; + frame->Release(); + + if(pDecklinkFrame_->GetBytes((void**)&pBytes_) != S_OK) + throw std::exception("DECKLINK: Failed to get bytes to frame"); + } + + unsigned char* data() + { + return pBytes_; + } + + bool valid() const + { + return true; + } + + unsigned int size() const + { + return pDecklinkFrame_->GetRowBytes() * pDecklinkFrame_->GetHeight(); + } + + IDeckLinkMutableVideoFrame* meta_data() const + { + return pDecklinkFrame_; + } + + void* tag() const + { + return pFactory_; + } + + DecklinkFrameManager* pFactory_; + CComPtr pDecklinkFrame_; + unsigned char* pBytes_; + }; + + struct DecklinkPlaybackStrategy + { + explicit DecklinkPlaybackStrategy(Implementation* pConsumerImpl) : pConsumerImpl_(pConsumerImpl), currentReservedFrameIndex_(0), totalFramesScheduled_(0) + { + for(int i = 0; i<4; ++i) + { + reservedFrames_.push_back(pConsumerImpl_->pFrameManager_->CreateReservedFrame()); + } + } + + std::shared_ptr GetReservedFrame() + { + std::shared_ptr pResult; + if(reservedFrames_.size() > currentReservedFrameIndex_) + { + pResult = reservedFrames_[currentReservedFrameIndex_]; + currentReservedFrameIndex_ = (currentReservedFrameIndex_+1) & 3; + } + return pResult; + } + + void DisplayFrame(const frame_ptr& frame) + { + if(frame != NULL) + { + if(pConsumerImpl_->pFrameManager_.get() == reinterpret_cast(frame->tag())) + { + DoRender(std::static_pointer_cast(frame)); + } + else + { + std::shared_ptr pTempFrame = GetReservedFrame(); + if(pTempFrame && frame->size() == pTempFrame->size()) + { + common::image::copy(pTempFrame->data(), frame->data(), pTempFrame->size()); + DoRender(pTempFrame); + } + else + CASPAR_LOG(error) << "DECKLINK: Failed to get reserved frame"; + } + } + else + { + CASPAR_LOG(error) << "DECKLINK: Tried to render frame with no data"; + } + } + void DoRender(const std::shared_ptr& frame) + { + static DWORD lastTime = 0; + static bool bDoLog = true; + + if(pConsumerImpl_->pDecklinkOutput_->DisplayVideoFrameSync(reinterpret_cast(frame->meta_data())) != S_OK) + { + if(bDoLog) + { + CASPAR_LOG(error) << "DECKLINK: Failed to render frame"; + bDoLog = false; + } + } + else + { + bDoLog = true; + } +// lastFrameID_ = frame->ID(); + } + + int totalFramesScheduled_; + std::vector > reservedFrames_; + unsigned int currentReservedFrameIndex_; + Implementation* pConsumerImpl_; + }; + friend struct DecklinkPlaybackStrategy; + + struct DecklinkFrameManager + { + explicit DecklinkFrameManager(Implementation* pConsumerImpl) : pConsumerImpl_(pConsumerImpl) + { + } + + frame_ptr CreateFrame() { + return std::make_shared(pConsumerImpl_->get_frame_format_desc().size); + } + + std::shared_ptr CreateReservedFrame() { + return std::make_shared(this); + } + + const caspar::frame_format_desc& get_frame_format_desc() const { + return pConsumerImpl_->get_frame_format_desc(); + } + + Implementation* pConsumerImpl_; + }; + + typedef std::tr1::shared_ptr DecklinkFrameManagerPtr; + + bool internalKey_; + CComPtr pDecklink_; + CComQIPtr pDecklinkOutput_; + CComQIPtr pDecklinkKeyer_; + + std::shared_ptr pPlayback_; + DecklinkFrameManagerPtr pFrameManager_; + frame_format currentFormat_; + frame_format_desc format_desc_; + + std::exception_ptr pException_; + boost::thread thread_; + tbb::concurrent_bounded_queue frameBuffer_; + +// IDeckLinkMutableVideoFrame* pNextFrame_; + + explicit Implementation(const caspar::frame_format_desc& format_desc, bool internalKey) + : format_desc_(format_desc), currentFormat_(frame_format::pal), internalKey_(internalKey) + { + + CComPtr pDecklinkIterator; + HRESULT result = pDecklinkIterator.CoCreateInstance(CLSID_CDeckLinkIterator); + if(FAILED(result)) + BOOST_THROW_EXCEPTION(caspar_exception() << msg_info("No Decklink drivers installed")); + + CComPtr pDecklink; + IDeckLink* pTempDecklink = NULL; + while(pDecklinkIterator->Next(&pTempDecklink) == S_OK) + { + if(pDecklink == NULL) + pDecklink = pTempDecklink; + + if(pTempDecklink) + pTempDecklink->Release(); + pTempDecklink = NULL; + } + + if(pDecklink == nullptr) + BOOST_THROW_EXCEPTION(caspar_exception() << msg_info("No Decklink card found")); + + if(!SetupDevice()) + BOOST_THROW_EXCEPTION(caspar_exception() << msg_info("Failed to initialize decklink consumer.")); + + pDecklink_ = pDecklink; + + frameBuffer_.set_capacity(1), + thread_ = boost::thread([=]{Run();}); + } + + ~Implementation() + { + frameBuffer_.push(nullptr); + thread_.join(); + ReleaseDevice(); + } + + void DisplayFrame(const frame_ptr& frame) + { + if(frame == nullptr) + return; + + if(pException_ != nullptr) + std::rethrow_exception(pException_); + + frameBuffer_.push(frame); + } + + void Run() + { + auto period = boost::posix_time::microseconds(get_frame_format_period(format_desc_)*1000000); + auto time = boost::posix_time::microsec_clock::local_time(); + while(true) + { + try + { + frame_ptr frame; + frameBuffer_.pop(frame); + if(frame == nullptr) + return; + + auto remaining = period - (boost::posix_time::microsec_clock::local_time() - time); + if(remaining > boost::posix_time::microseconds(5000)) + boost::this_thread::sleep(remaining - boost::posix_time::microseconds(5000)); + time = boost::posix_time::microsec_clock::local_time(); + + pPlayback_->DisplayFrame(frame); + } + catch(...) + { + pException_ = std::current_exception(); + } + } + } + + bool SetupDevice() + { + if(!pDecklink_) + return false; + + BSTR pModelName; + pDecklink_->GetModelName(&pModelName); + if(pModelName != NULL) + CASPAR_LOG(info) << "DECKLINK: Modelname: " << pModelName; + + pDecklinkOutput_ = pDecklink_; + if(pDecklinkOutput_ == NULL) { + CASPAR_LOG(info) << "DECKLINK: Failed to get IDecklinkOutput interface"; + return false; + } + + unsigned long decklinkVideoFormat = GetDecklinkVideoFormat(format_desc_.format); + if(decklinkVideoFormat == ULONG_MAX) { + CASPAR_LOG(error) << "DECKLINK: Card does not support requested videoformat: " << format_desc_.name; + return false; + } + + currentFormat_ = format_desc_.format; + + BMDDisplayModeSupport displayModeSupport; + if(FAILED(pDecklinkOutput_->DoesSupportVideoMode((BMDDisplayMode)decklinkVideoFormat, bmdFormat8BitBGRA, &displayModeSupport))) { + CASPAR_LOG(error) << "DECKLINK: Card does not support requested videoformat"; + return false; + } + + pDecklinkOutput_->DisableAudioOutput(); + if(FAILED(pDecklinkOutput_->EnableVideoOutput((BMDDisplayMode)decklinkVideoFormat, bmdVideoOutputFlagDefault))) { + CASPAR_LOG(error) << "DECKLINK: Could not enable video output"; + return false; + } + + pFrameManager_.reset(new DecklinkFrameManager(this)); + + if(internalKey_) { + pDecklinkKeyer_ = pDecklink_; + if(pDecklinkKeyer_) { + bool bSuccess = true; + if(FAILED(pDecklinkKeyer_->Enable(FALSE))) { + CASPAR_LOG(error) << "DECKLINK: Failed to enable internal keyer"; + bSuccess = false; + } + if(FAILED(pDecklinkKeyer_->SetLevel(255))) { + CASPAR_LOG(error) << "DECKLINK: Keyer - Failed to set blend-level to max"; + bSuccess = false; + } + + if(bSuccess) + CASPAR_LOG(info) << "DECKLINK: Successfully configured internal keyer"; + } + else { + CASPAR_LOG(error) << "DECKLINK: Failed to get keyer-interface"; + } + } + + pPlayback_ = std::make_shared(this); + + CASPAR_LOG(info) << "DECKLINK: Successfully initialized decklink for " << format_desc_.name; + return true; + } + + bool ReleaseDevice() + { + pPlayback_.reset(); + + if(pDecklinkKeyer_) { + pDecklinkKeyer_.Release(); + } + + if(pDecklinkOutput_) { + BOOL bIsRunning = FALSE; + pDecklinkOutput_->IsScheduledPlaybackRunning(&bIsRunning); + if(bIsRunning) + pDecklinkOutput_->StopScheduledPlayback(0, NULL, 0); + + pDecklinkOutput_->DisableVideoOutput(); + } + + return true; + } + + //void DoScheduleNextFrame() { + // static int frame = 0; + // static bool bLog = true; + // if(pDecklinkOutput_->ScheduleVideoFrame(pNextFrame_, frame++, 1, 25) != S_OK) { + // if(bLog) { + // LOG << TEXT("DECKLINK: Failed to display frame"); + // bLog = false; + // } + // } + // else { + // if(((frame-1) % 25) == 0) + // LOG << TEXT("DECKLINK: Scheduled frame ") << (frame-1); + // bLog = true; + // } + //} + + // IUnknown needs o a dummy implementation + virtual HRESULT STDMETHODCALLTYPE QueryInterface(REFIID iid, LPVOID *ppv) + { + if(ppv != NULL) { + if(iid == IID_IUnknown) { + (*ppv) = this; + return S_OK; + } + if(iid == IID_IDeckLinkVideoOutputCallback_v7_1) { + (*ppv) = (IDeckLinkVideoOutputCallback_v7_1*)this; + return S_OK; + } + if(iid == IID_IDeckLinkVideoOutputCallback) { + (*ppv) = (IDeckLinkVideoOutputCallback*)this; + return S_OK; + } + } + return E_NOINTERFACE; + } + virtual ULONG STDMETHODCALLTYPE AddRef() {return 1;} + virtual ULONG STDMETHODCALLTYPE Release() {return 1;} + + virtual HRESULT STDMETHODCALLTYPE ScheduledFrameCompleted(IDeckLinkVideoFrame* completedFrame, BMDOutputFrameCompletionResult result) { + //DoScheduleNextFrame(); + return S_OK; + } + + virtual HRESULT STDMETHODCALLTYPE ScheduledPlaybackHasStopped() + { + return S_OK; + } + + const caspar::frame_format_desc& get_frame_format_desc() const + { + return frame_format_desc::format_descs[currentFormat_]; + } + + unsigned long GetDecklinkVideoFormat(frame_format fmt) + { + switch(fmt) + { + case frame_format::pal: return bmdModePAL; + case frame_format::ntsc: return bmdModeNTSC; + case frame_format::x576p2500: return ULONG_MAX; //not supported + case frame_format::x720p5000: return bmdModeHD720p50; + case frame_format::x720p5994: return bmdModeHD720p5994; + case frame_format::x720p6000: return bmdModeHD720p60; + case frame_format::x1080p2397: return bmdModeHD1080p2398; + case frame_format::x1080p2400: return bmdModeHD1080p24; + case frame_format::x1080i5000: return bmdModeHD1080i50; + case frame_format::x1080i5994: return bmdModeHD1080i5994; + case frame_format::x1080i6000: return bmdModeHD1080i6000; + case frame_format::x1080p2500: return bmdModeHD1080p25; + case frame_format::x1080p2997: return bmdModeHD1080p2997; + case frame_format::x1080p3000: return bmdModeHD1080p30; + default: return ULONG_MAX; + } + } +}; + +DecklinkVideoConsumer::DecklinkVideoConsumer(const caspar::frame_format_desc& format_desc, bool internalKey) : pImpl_(new Implementation(format_desc, internalKey)) +{} + +void DecklinkVideoConsumer::display(const frame_ptr& frame) +{ + pImpl_->DisplayFrame(frame); +} + +const frame_format_desc& DecklinkVideoConsumer::get_frame_format_desc() const +{ + return pImpl_->format_desc_; +} + +} //namespace decklink +} //namespace caspar \ No newline at end of file diff --git a/core/consumer/decklink/DecklinkVideoConsumer.h b/core/consumer/decklink/DecklinkVideoConsumer.h new file mode 100644 index 000000000..ecdd83fc3 --- /dev/null +++ b/core/consumer/decklink/DecklinkVideoConsumer.h @@ -0,0 +1,40 @@ +/* +* copyright (c) 2010 Sveriges Television AB +* +* This file is part of CasparCG. +* +* CasparCG is free software: you can redistribute it and/or modify +* it under the terms of the GNU General Public License as published by +* the Free Software Foundation, either version 3 of the License, or +* (at your option) any later version. +* +* CasparCG is distributed in the hope that it will be useful, +* but WITHOUT ANY WARRANTY; without even the implied warranty of +* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +* GNU General Public License for more details. + +* You should have received a copy of the GNU General Public License +* along with CasparCG. If not, see . +* +*/ +#pragma once + +#include "../../consumer/frame_consumer.h" + +#include "../../frame/frame_fwd.h" + +namespace caspar { namespace decklink { + +class DecklinkVideoConsumer : public frame_consumer +{ +public: + explicit DecklinkVideoConsumer(const caspar::frame_format_desc& format_desc, bool internalKey = false); + + void display(const frame_ptr&); + const frame_format_desc& get_frame_format_desc() const; +private: + struct Implementation; + std::tr1::shared_ptr pImpl_; +}; + +}} \ No newline at end of file diff --git a/core/consumer/frame_consumer.h b/core/consumer/frame_consumer.h new file mode 100644 index 000000000..daeeae749 --- /dev/null +++ b/core/consumer/frame_consumer.h @@ -0,0 +1,45 @@ +/* +* copyright (c) 2010 Sveriges Television AB +* +* This file is part of CasparCG. +* +* CasparCG is free software: you can redistribute it and/or modify +* it under the terms of the GNU General Public License as published by +* the Free Software Foundation, either version 3 of the License, or +* (at your option) any later version. +* +* CasparCG is distributed in the hope that it will be useful, +* but WITHOUT ANY WARRANTY; without even the implied warranty of +* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +* GNU General Public License for more details. + +* You should have received a copy of the GNU General Public License +* along with CasparCG. If not, see . +* +*/ +#pragma once + +#include "../frame/frame_fwd.h" + +#include + +#include + +namespace caspar { + +class frame_consumer : boost::noncopyable +{ +public: + virtual ~frame_consumer() {} + + virtual const frame_format_desc& get_frame_format_desc() const = 0; + virtual void prepare(const frame_ptr&){}; + virtual void display(const frame_ptr&){}; +}; +typedef std::shared_ptr frame_consumer_ptr; +typedef std::shared_ptr frame_consumer_const_ptr; + +typedef std::unique_ptr frame_consumer_uptr; +typedef std::unique_ptr frame_consumer_const_uptr; + +} \ No newline at end of file diff --git a/core/consumer/oal/oal_frame_consumer.cpp b/core/consumer/oal/oal_frame_consumer.cpp new file mode 100644 index 000000000..a746fc495 --- /dev/null +++ b/core/consumer/oal/oal_frame_consumer.cpp @@ -0,0 +1,159 @@ +/* +* copyright (c) 2010 Sveriges Television AB +* +* This file is part of CasparCG. +* +* CasparCG is free software: you can redistribute it and/or modify +* it under the terms of the GNU General Public License as published by +* the Free Software Foundation, either version 3 of the License, or +* (at your option) any later version. +* +* CasparCG is distributed in the hope that it will be useful, +* but WITHOUT ANY WARRANTY; without even the implied warranty of +* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +* GNU General Public License for more details. + +* You should have received a copy of the GNU General Public License +* along with CasparCG. If not, see . +* +*/ + +#include "../../StdAfx.h" + +#include "oal_frame_consumer.h" + +#include "../../frame/audio_chunk.h" +#include "../../frame/frame.h" +#include "../../frame/frame_format.h" + +#include + +#include +#include + +#include + +namespace caspar{ namespace audio{ + +class sound_channel : public sf::SoundStream +{ +public: + sound_channel() : internal_chunks_(5) + { + external_chunks_.set_capacity(3); + } + + ~sound_channel() + { + external_chunks_.clear(); + external_chunks_.push(nullptr); + Stop(); + } + + void Initialize(const sound_channel_info_ptr& info) + { + sf::SoundStream::Initialize(info->channels_count, info->sample_rate); + assert(info->bits_per_sample/(8*sizeof(char)) == sizeof(sf::Int16)); + } + + void Push(const audio_chunk_ptr& paudio_chunk) + { + if(!external_chunks_.try_push(paudio_chunk)) + { + //CASPAR_LOG(debug) << "Sound Buffer Overrun"; + external_chunks_.push(paudio_chunk); + } + + if(GetStatus() != Playing && external_chunks_.size() >= 3) + Play(); + } + +private: + + bool OnStart() + { + external_chunks_.clear(); + return true; + } + + bool OnGetData(sf::SoundStream::Chunk& data) + { + audio_chunk_ptr pChunk; + if(!external_chunks_.try_pop(pChunk)) + { + CASPAR_LOG(trace) << "Sound Buffer Underrun"; + external_chunks_.pop(pChunk); + } + + if(pChunk == nullptr) + { + external_chunks_.clear(); + return false; + } + + internal_chunks_.push_back(pChunk); + SetVolume(pChunk->volume()); + data.Samples = reinterpret_cast(pChunk->data()); + data.NbSamples = pChunk->size()/sizeof(sf::Int16); + return true; + } + + boost::circular_buffer internal_chunks_; + tbb::concurrent_bounded_queue external_chunks_; +}; +typedef std::shared_ptr sound_channelPtr; + +struct oal_frame_consumer::implementation : boost::noncopyable +{ + implementation(const frame_format_desc& format_desc) : format_desc_(format_desc) + { + for(int n = 0; n < 3; ++n) + channel_pool_.push(std::make_shared()); + } + + void push(const frame_ptr& frame) + { + if(frame == nullptr) + return; + + decltype(channels_) active_channels; + BOOST_FOREACH(const audio_chunk_ptr& pChunk, frame->audio_data()) + { + auto info = pChunk->sound_channel_info(); + auto it = channels_.find(info); + sound_channelPtr channel; + if(it == channels_.end()) + { + if(channel_pool_.size() <= 1) + channel_pool_.push(std::make_shared()); + + sound_channelPtr pNewChannel; + channel_pool_.pop(pNewChannel); + + channel = sound_channelPtr(pNewChannel.get(), [=](sound_channel*) + { + channel_pool_.push(pNewChannel); + pNewChannel->Push(nullptr); + }); + channel->Initialize(info); + } + else + channel = it->second; + + active_channels.insert(std::make_pair(info, channel)); + channel->Push(pChunk); // Could Block + } + + channels_ = std::move(active_channels); + } + + tbb::concurrent_bounded_queue channel_pool_; + std::map channels_; + + caspar::frame_format_desc format_desc_; +}; + +oal_frame_consumer::oal_frame_consumer(const caspar::frame_format_desc& format_desc) : impl_(new implementation(format_desc)){} +const caspar::frame_format_desc& oal_frame_consumer::get_frame_format_desc() const{return impl_->format_desc_;} +void oal_frame_consumer::prepare(const frame_ptr& frame){impl_->push(frame);} +}} diff --git a/core/consumer/oal/oal_frame_consumer.h b/core/consumer/oal/oal_frame_consumer.h new file mode 100644 index 000000000..4a2e3687d --- /dev/null +++ b/core/consumer/oal/oal_frame_consumer.h @@ -0,0 +1,38 @@ +/* +* copyright (c) 2010 Sveriges Television AB +* +* This file is part of CasparCG. +* +* CasparCG is free software: you can redistribute it and/or modify +* it under the terms of the GNU General Public License as published by +* the Free Software Foundation, either version 3 of the License, or +* (at your option) any later version. +* +* CasparCG is distributed in the hope that it will be useful, +* but WITHOUT ANY WARRANTY; without even the implied warranty of +* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +* GNU General Public License for more details. + +* You should have received a copy of the GNU General Public License +* along with CasparCG. If not, see . +* +*/ +#pragma once + +#include "../../consumer/frame_consumer.h" + +namespace caspar { namespace audio { + +class oal_frame_consumer : public frame_consumer +{ +public: + explicit oal_frame_consumer(const frame_format_desc& format_desc); + + const frame_format_desc& get_frame_format_desc() const; + void prepare(const frame_ptr& frame); +private: + struct implementation; + std::shared_ptr impl_; +}; + +}} \ No newline at end of file diff --git a/core/consumer/ogl/ogl_frame_consumer.cpp b/core/consumer/ogl/ogl_frame_consumer.cpp new file mode 100644 index 000000000..126f19d21 --- /dev/null +++ b/core/consumer/ogl/ogl_frame_consumer.cpp @@ -0,0 +1,309 @@ +/* +* copyright (c) 2010 Sveriges Television AB +* +* This file is part of CasparCG. +* +* CasparCG is free software: you can redistribute it and/or modify +* it under the terms of the GNU General Public License as published by +* the Free Software Foundation, either version 3 of the License, or +* (at your option) any later version. +* +* CasparCG is distributed in the hope that it will be useful, +* but WITHOUT ANY WARRANTY; without even the implied warranty of +* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +* GNU General Public License for more details. + +* You should have received a copy of the GNU General Public License +* along with CasparCG. If not, see . +* +*/ + +#include "../../StdAfx.h" + +#if defined(_MSC_VER) +#pragma warning (disable : 4244) +#endif + +#include "ogl_frame_consumer.h" + +#include "../../frame/system_frame.h" +#include "../../frame/frame_format.h" +#include "../../../common/image/image.h" + +#include + +#include +#include + +#include + +namespace caspar{ namespace ogl{ + +void GL_CHECK() +{ + if(glGetError() != GL_NO_ERROR) + BOOST_THROW_EXCEPTION(ogl_error() << msg_info(boost::lexical_cast(glGetError()))); +} + +struct ogl_frame_consumer::implementation : boost::noncopyable +{ + implementation(const frame_format_desc& format_desc, unsigned int screen_index, stretch stretch, bool windowed) + : format_desc_(format_desc), stretch_(stretch), texture_(0), pbo_index_(0), screen_width_(0), screen_height_(0), windowed_(windowed) + { + pbos_[0] = pbos_[1] = 0; + +#ifdef _WIN32 + DISPLAY_DEVICE dDevice; + memset(&dDevice,0,sizeof(dDevice)); + dDevice.cb = sizeof(dDevice); + + std::vector displayDevices; + for(int n = 0; EnumDisplayDevices(NULL, n, &dDevice, NULL); ++n) + { + displayDevices.push_back(dDevice); + memset(&dDevice,0,sizeof(dDevice)); + dDevice.cb = sizeof(dDevice); + } + + if(screen_index >= displayDevices.size()) + BOOST_THROW_EXCEPTION(out_of_range() << arg_name_info("screen_index_")); + + DEVMODE devmode; + memset(&devmode,0,sizeof(devmode)); + + if(!EnumDisplaySettings(displayDevices[screen_index].DeviceName, ENUM_CURRENT_SETTINGS, &devmode)) + BOOST_THROW_EXCEPTION(invalid_operation() << arg_name_info("screen_index") << msg_info("EnumDisplaySettings")); + + screen_width_ = windowed ? format_desc_.width : devmode.dmPelsWidth; + screen_height_ = windowed ? format_desc_.height : devmode.dmPelsHeight; + screenX_ = devmode.dmPosition.x; + screenY_ = devmode.dmPosition.y; +#else + if(!windowed) + BOOST_THROW_EXCEPTION(not_supported() << msg_info("OGLConsumer doesn't support non-Win32 fullscreen")); + + if(screen_index != 0) + CASPAR_LOG(warning) << "OGLConsumer only supports screen_index=0 for non-Win32"; + + screen_width_ = format_desc_.width; + screen_height_ = format_desc_.height; + screenX_ = 0; + screenY_ = 0; +#endif + frame_buffer_.set_capacity(1); + thread_ = boost::thread([=]{run();}); + } + + ~implementation() + { + frame_buffer_.push(nullptr), + thread_.join(); + + if(texture_) + glDeleteTextures(1, &texture_); + if(pbos_[0] && pbos_[1]) + glDeleteBuffers(2, pbos_); + } + + void init() + { + window_.reset(new sf::Window()); + window_->Create(sf::VideoMode(format_desc_.width, format_desc_.height, 32), "CasparCG", windowed_ ? sf::Style::Titlebar : sf::Style::Fullscreen); + window_->ShowMouseCursor(false); + window_->SetPosition(screenX_, screenY_); + window_->SetSize(screen_width_, screen_height_); + window_->SetActive(); + + glClearColor(0.0f, 0.0f, 0.0f, 0.0f); + glEnable(GL_TEXTURE_2D); + + glViewport(0, 0, screen_width_, screen_height_); + + GL_CHECK(); + + std::pair target_ratio = None(); + if(stretch_ == ogl::fill) + target_ratio = Fill(); + else if(stretch_ == ogl::uniform) + target_ratio = Uniform(); + else if(stretch_ == ogl::uniform_to_fill) + target_ratio = UniformToFill(); + + float wSize = target_ratio.first; + float hSize = target_ratio.second; + + dlist_ = glGenLists(1); + GL_CHECK(); + + glNewList(dlist_, GL_COMPILE); + glBegin(GL_QUADS); + glTexCoord2f(0.0f, 1.0f); glVertex2f(-wSize, -hSize); + glTexCoord2f(1.0f, 1.0f); glVertex2f( wSize, -hSize); + glTexCoord2f(1.0f, 0.0f); glVertex2f( wSize, hSize); + glTexCoord2f(0.0f, 0.0f); glVertex2f(-wSize, hSize); + glEnd(); + glEndList(); + GL_CHECK(); + + glGenTextures(1, &texture_); + GL_CHECK(); + + glBindTexture( GL_TEXTURE_2D, texture_); + GL_CHECK(); + + glTexParameterf( GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST ); + glTexParameterf( GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR ); + glTexParameterf( GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP ); + glTexParameterf( GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP ); + + glTexImage2D( GL_TEXTURE_2D, 0, GL_RGBA8, format_desc_.width, format_desc_.height, 0, GL_BGRA, GL_UNSIGNED_BYTE, NULL); + GL_CHECK(); + + glGenBuffersARB(2, pbos_); + GL_CHECK(); + glBindBuffer(GL_PIXEL_PACK_BUFFER, pbos_[0]); + glBufferDataARB(GL_PIXEL_UNPACK_BUFFER_ARB, format_desc_.size, 0, GL_STREAM_DRAW); + glBindBufferARB(GL_PIXEL_UNPACK_BUFFER_ARB, pbos_[1]); + glBufferDataARB(GL_PIXEL_UNPACK_BUFFER_ARB, format_desc_.size, 0, GL_STREAM_DRAW); + + pbo_index_ = 0; + } + + std::pair None() + { + float width = static_cast(format_desc_.width)/static_cast(screen_width_); + float height = static_cast(format_desc_.height)/static_cast(screen_height_); + + return std::make_pair(width, height); + } + + std::pair Uniform() + { + float aspect = static_cast(format_desc_.width)/static_cast(format_desc_.height); + float width = std::min(1.0f, static_cast(screen_height_)*aspect/static_cast(screen_width_)); + float height = static_cast(screen_width_*width)/static_cast(screen_height_*aspect); + + return std::make_pair(width, height); + } + + std::pair Fill() + { + return std::make_pair(1.0f, 1.0f); + } + + std::pair UniformToFill() + { + float wr = static_cast(format_desc_.width)/static_cast(screen_width_); + float hr = static_cast(format_desc_.height)/static_cast(screen_height_); + float r_inv = 1.0f/std::min(wr, hr); + + float width = wr*r_inv; + float height = hr*r_inv; + + return std::make_pair(width, height); + } + + void render(const frame_ptr& frame) + { + // Render + glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); + glClearColor(0.0f, 0.0f, 0.0f, 0.0f); + glLoadIdentity(); + + glBindTexture(GL_TEXTURE_2D, texture_); + glBindBuffer(GL_PIXEL_UNPACK_BUFFER, pbos_[pbo_index_]); + + glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, format_desc_.width, format_desc_.height, GL_BGRA, GL_UNSIGNED_BYTE, 0); + + glCallList(dlist_); + + // Update + int nextPboIndex = pbo_index_ ^ 1; + + glBindBuffer(GL_PIXEL_UNPACK_BUFFER, pbos_[nextPboIndex]); + glBufferData(GL_PIXEL_UNPACK_BUFFER, format_desc_.size, NULL, GL_STREAM_DRAW); + GLubyte* ptr = static_cast(glMapBuffer(GL_PIXEL_UNPACK_BUFFER, GL_WRITE_ONLY)); + + if(ptr != NULL) + { + common::image::copy(ptr, frame->data(), frame->size()); + glUnmapBuffer(GL_PIXEL_UNPACK_BUFFER); + } + + // Swap + pbo_index_ = nextPboIndex; + } + + void display(const frame_ptr& frame) + { + if(frame == nullptr) + return; + + if(exception_ != nullptr) + std::rethrow_exception(exception_); + + frame_buffer_.push(frame); + } + + void run() + { + init(); + + auto period = boost::posix_time::microseconds(static_cast(get_frame_format_period(format_desc_)*1000000.0)); + auto time = boost::posix_time::microsec_clock::local_time(); + + frame_ptr frame; + do + { + try + { + frame_buffer_.pop(frame); + if(frame != nullptr) + { + auto remaining = period - (boost::posix_time::microsec_clock::local_time() - time); + if(remaining > boost::posix_time::microseconds(5000)) + boost::this_thread::sleep(remaining - boost::posix_time::microseconds(5000)); + time = boost::posix_time::microsec_clock::local_time(); + + sf::Event e; + while(window_->GetEvent(e)){} + window_->SetActive(); + render(frame); + window_->Display(); + } + } + catch(...) + { + exception_ = std::current_exception(); + } + } + while(frame != nullptr); + } + + + GLuint dlist_; + GLuint texture_; + + bool windowed_; + unsigned int screen_width_; + unsigned int screen_height_; + unsigned int screenX_; + unsigned int screenY_; + + GLuint pbos_[2]; + int pbo_index_; + + std::unique_ptr window_; + stretch stretch_; + caspar::frame_format_desc format_desc_; + + std::exception_ptr exception_; + boost::thread thread_; + tbb::concurrent_bounded_queue frame_buffer_; +}; + +ogl_frame_consumer::ogl_frame_consumer(const caspar::frame_format_desc& format_desc, unsigned int screen_index, stretch stretch, bool windowed) +: impl_(new implementation(format_desc, screen_index, stretch, windowed)){} +const caspar::frame_format_desc& ogl_frame_consumer::get_frame_format_desc() const{return impl_->format_desc_;} +void ogl_frame_consumer::display(const frame_ptr& frame){impl_->display(frame);} +}} diff --git a/core/consumer/ogl/ogl_frame_consumer.h b/core/consumer/ogl/ogl_frame_consumer.h new file mode 100644 index 000000000..44fe7eab1 --- /dev/null +++ b/core/consumer/ogl/ogl_frame_consumer.h @@ -0,0 +1,48 @@ +/* +* copyright (c) 2010 Sveriges Television AB +* +* This file is part of CasparCG. +* +* CasparCG is free software: you can redistribute it and/or modify +* it under the terms of the GNU General Public License as published by +* the Free Software Foundation, either version 3 of the License, or +* (at your option) any later version. +* +* CasparCG is distributed in the hope that it will be useful, +* but WITHOUT ANY WARRANTY; without even the implied warranty of +* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +* GNU General Public License for more details. + +* You should have received a copy of the GNU General Public License +* along with CasparCG. If not, see . +* +*/ +#pragma once + +#include "../../consumer/frame_consumer.h" + +namespace caspar { namespace ogl { + +struct ogl_error : virtual caspar_exception{}; + +enum stretch +{ + none, + uniform, + fill, + uniform_to_fill +}; + +class ogl_frame_consumer : public frame_consumer +{ +public: + explicit ogl_frame_consumer(const frame_format_desc& format_desc, unsigned int screen_index = 0, stretch stretch = stretch::fill, bool windowed = false); + + const frame_format_desc& get_frame_format_desc() const; + void display(const frame_ptr& frame); +private: + struct implementation; + std::shared_ptr impl_; +}; + +}} \ No newline at end of file diff --git a/core/frame/audio_chunk.cpp b/core/frame/audio_chunk.cpp new file mode 100644 index 000000000..b0c7abe61 --- /dev/null +++ b/core/frame/audio_chunk.cpp @@ -0,0 +1,50 @@ +#include "../StdAfx.h" + +#include "audio_chunk.h" + +#include + +namespace caspar{ + +audio_chunk::audio_chunk(size_t dataSize, const sound_channel_info_ptr& snd_channel_info) + : size_(dataSize), snd_channel_info_(snd_channel_info), data_(static_cast(scalable_aligned_malloc(dataSize, 16))), volume_(100.0f) +{} + +audio_chunk::~audio_chunk() +{ + scalable_aligned_free(data_); +} + +const unsigned char* audio_chunk::data() const +{ + return data_; +} + +unsigned char* audio_chunk::data() +{ + return data_; +} + +size_t audio_chunk::size() const +{ + return size_; +} + +float audio_chunk::volume() const +{ + return volume_; +} + +void audio_chunk::set_volume(float volume) +{ + assert(volume_ > 0.0f); + assert(volume_ < (100.0f + std::numeric_limits::epsilon())); + volume_ = volume; +} + +const sound_channel_info_ptr& audio_chunk::sound_channel_info() const +{ + return snd_channel_info_; +} + +} \ No newline at end of file diff --git a/core/frame/audio_chunk.h b/core/frame/audio_chunk.h new file mode 100644 index 000000000..2dbd19b26 --- /dev/null +++ b/core/frame/audio_chunk.h @@ -0,0 +1,62 @@ +/* +* copyright (c) 2010 Sveriges Television AB +* +* This file is part of CasparCG. +* +* CasparCG is free software: you can redistribute it and/or modify +* it under the terms of the GNU General Public License as published by +* the Free Software Foundation, either version 3 of the License, or +* (at your option) any later version. +* +* CasparCG is distributed in the hope that it will be useful, +* but WITHOUT ANY WARRANTY; without even the implied warranty of +* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +* GNU General Public License for more details. + +* You should have received a copy of the GNU General Public License +* along with CasparCG. If not, see . +* +*/ +#pragma once + +#include + +#include + +namespace caspar{ + +struct sound_channel_info : boost::noncopyable +{ +public: + sound_channel_info(size_t channels_count, size_t bits_per_sample, size_t sample_rate) + : channels_count(channels_count), bits_per_sample(bits_per_sample), sample_rate(sample_rate){} + const size_t channels_count; + const size_t bits_per_sample; + const size_t sample_rate; +}; +typedef std::shared_ptr sound_channel_info_ptr; +typedef std::unique_ptr sound_channel_info_uptr; + +class audio_chunk : boost::noncopyable +{ +public: + audio_chunk(size_t dataSize, const sound_channel_info_ptr& snd_channel_info); + ~audio_chunk(); + + const unsigned char* data() const; + unsigned char* data(); + size_t size() const; + float volume() const; + void set_volume(float volume); + const sound_channel_info_ptr& sound_channel_info() const; + +private: + float volume_; + const sound_channel_info_ptr snd_channel_info_; + unsigned char* const data_; + const int size_; +}; +typedef std::shared_ptr audio_chunk_ptr; +typedef std::unique_ptr audio_chunk_uptr; + +} \ No newline at end of file diff --git a/core/frame/bitmap_frame.cpp b/core/frame/bitmap_frame.cpp new file mode 100644 index 000000000..3c1ca7b5d --- /dev/null +++ b/core/frame/bitmap_frame.cpp @@ -0,0 +1,104 @@ +/* +* copyright (c) 2010 Sveriges Television AB +* +* This file is part of CasparCG. +* +* CasparCG is free software: you can redistribute it and/or modify +* it under the terms of the GNU General Public License as published by +* the Free Software Foundation, either version 3 of the License, or +* (at your option) any later version. +* +* CasparCG is distributed in the hope that it will be useful, +* but WITHOUT ANY WARRANTY; without even the implied warranty of +* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +* GNU General Public License for more details. + +* You should have received a copy of the GNU General Public License +* along with CasparCG. If not, see . +* +*/ + +#include "../StdAfx.h" + +#include "bitmap_frame.h" + +#include + +namespace caspar{ + +class scoped_hdc : boost::noncopyable +{ +public: + scoped_hdc(HDC hdc) : hdc_(hdc){} + void operator=(scoped_hdc&& other) + { + hdc_ = other.hdc_; + other.hdc_ = nullptr; + } + ~scoped_hdc() + { + if(hdc_ != nullptr) + DeleteDC(hdc_); + } + operator HDC() { return hdc_; } +private: + HDC hdc_; +}; + +class scoped_bitmap : boost::noncopyable +{ +public: + scoped_bitmap(HBITMAP bmp) : bmp_(bmp){} + void operator=(scoped_bitmap&& other) + { + bmp_ = other.bmp_; + other.bmp_ = nullptr; + } + ~scoped_bitmap() + { + if(bmp_ != nullptr) + DeleteObject(bmp_); + } + operator HBITMAP() const { return bmp_; } +private: + HBITMAP bmp_; +}; + +struct bitmap_frame::implementation : boost::noncopyable +{ + implementation(size_t width, size_t height) : size_(width*height*4), hdc_(CreateCompatibleDC(nullptr)), bitmap_(nullptr) + { + if(hdc_ == nullptr) + throw std::bad_alloc(); + + BITMAPINFO bitmapInfo; + bitmapInfo.bmiHeader.biBitCount = 32; + bitmapInfo.bmiHeader.biClrImportant = 0; + bitmapInfo.bmiHeader.biClrUsed = 0; + bitmapInfo.bmiHeader.biCompression = BI_RGB; + #pragma warning(disable:4146) + bitmapInfo.bmiHeader.biHeight = -height; + #pragma warning(default:4146) + bitmapInfo.bmiHeader.biPlanes = 1; + bitmapInfo.bmiHeader.biSize = sizeof(BITMAPINFO); + bitmapInfo.bmiHeader.biWidth = width; + bitmapInfo.bmiHeader.biSizeImage = 0; + bitmapInfo.bmiHeader.biXPelsPerMeter = 0; + bitmapInfo.bmiHeader.biYPelsPerMeter = 0; + + bitmap_ = std::move(CreateDIBSection(hdc_, &bitmapInfo, DIB_RGB_COLORS, reinterpret_cast(&bitmap_data_), NULL, 0)); + SelectObject(hdc_, bitmap_); + } + + const size_t size_; + unsigned char* bitmap_data_; + scoped_hdc hdc_; + scoped_bitmap bitmap_; +}; + +bitmap_frame::bitmap_frame(size_t width, size_t height) : impl_(new implementation(width, height)){} +unsigned int bitmap_frame::size() const { return impl_->size_; } +unsigned char* bitmap_frame::data() { return impl_->bitmap_data_; } +HDC bitmap_frame::hdc() { return impl_->hdc_; } + +} \ No newline at end of file diff --git a/core/frame/bitmap_frame.h b/core/frame/bitmap_frame.h new file mode 100644 index 000000000..e6601d107 --- /dev/null +++ b/core/frame/bitmap_frame.h @@ -0,0 +1,44 @@ +/* +* copyright (c) 2010 Sveriges Television AB +* +* This file is part of CasparCG. +* +* CasparCG is free software: you can redistribute it and/or modify +* it under the terms of the GNU General Public License as published by +* the Free Software Foundation, either version 3 of the License, or +* (at your option) any later version. +* +* CasparCG is distributed in the hope that it will be useful, +* but WITHOUT ANY WARRANTY; without even the implied warranty of +* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +* GNU General Public License for more details. + +* You should have received a copy of the GNU General Public License +* along with CasparCG. If not, see . +* +*/ +#pragma once + +#include "frame.h" + +#include + +namespace caspar{ + +class bitmap_frame : public frame +{ +public: + bitmap_frame(size_t width, size_t height); + + unsigned char* data(); + unsigned int size() const; + HDC hdc(); +private: + struct implementation; + std::shared_ptr impl_; +}; +typedef std::shared_ptr bitmap_frame_ptr; +typedef std::unique_ptr bitmap_frame_uptr; + +} + diff --git a/core/frame/frame.h b/core/frame/frame.h new file mode 100644 index 000000000..998792a08 --- /dev/null +++ b/core/frame/frame.h @@ -0,0 +1,163 @@ +/* +* copyright (c) 2010 Sveriges Television AB +* +* This file is part of CasparCG. +* +* CasparCG is free software: you can redistribute it and/or modify +* it under the terms of the GNU General Public License as published by +* the Free Software Foundation, either version 3 of the License, or +* (at your option) any later version. +* +* CasparCG is distributed in the hope that it will be useful, +* but WITHOUT ANY WARRANTY; without even the implied warranty of +* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +* GNU General Public License for more details. + +* You should have received a copy of the GNU General Public License +* along with CasparCG. If not, see . +* +*/ +#pragma once + +#include +#include + +#include "audio_chunk.h" +#include "frame_format.h" + +#include "../../common/image/image.h" + +#include + +#include + +namespace caspar { + +// NOTE: audio data is ALWAYS shallow copy +class frame : boost::noncopyable +{ +public: + virtual ~frame(){} + + virtual const unsigned char* data() const { return const_cast(*this).data(); } + virtual unsigned char* data() = 0; + virtual size_t size() const = 0; + virtual void* tag() const { return nullptr; } + virtual const std::vector& audio_data() const { return audioData_; } + virtual std::vector& audio_data() { return audioData_; } + + static std::shared_ptr null() + { + class null_frame : public frame + { + unsigned char* data() { return nullptr; }; + size_t size() const { return 0; }; + }; + static auto my_null_frame = std::make_shared(); + return my_null_frame; + } +private: + std::vector audioData_; +}; +typedef std::shared_ptr frame_ptr; +typedef std::shared_ptr frame_const_ptr; +typedef std::unique_ptr frame_uptr; +typedef std::unique_ptr frame_const_uptr; + +inline bool operator==(const frame& lhs, const frame& rhs) +{ + return lhs.data() == rhs.data() && (lhs.data() == nullptr || lhs.size() == rhs.size()); +} + +template +frame_ptr_type& set_frame_volume(frame_ptr_type& result_frame, float volume) +{ + assert(result_frame != nullptr); + assert(boost::range::find(result_frame->audio_data(), nullptr) == result_frame->audio_data().end()); + boost::range::for_each(result_frame->audio_data(), std::bind(&audio_chunk::set_volume, std::placeholders::_1, volume)); + return result_frame; +} + +template +frame_ptr_type& clear_frame(frame_ptr_type& result_frame) +{ + assert(result_frame != nullptr); + common::image::clear(result_frame->data(), result_frame->size()); + result_frame->audio_data().clear(); + return result_frame; +} + +template +frame_ptr_type& pre_over_frame(frame_ptr_type& result_frame, const frame_const_ptr& frame1, const frame_const_ptr& frame2) +{ + assert(result_frame != nullptr && frame1 != nullptr && frame2 != nullptr); + assert(result_frame->size() == frame1->size()); + assert(result_frame->size() == frame2->size()); + assert(boost::range::find(frame1->audio_data(), nullptr) == frame1->audio_data().end()); + assert(boost::range::find(frame2->audio_data(), nullptr) == frame2->audio_data().end()); + tbb::parallel_invoke( + [&]{common::image::pre_over(result_frame->data(), frame1->data(), frame2->data(), result_frame->size());}, + [&] + { + if(result_frame != frame1) + boost::range::copy(frame1->audio_data(), std::back_inserter(result_frame->audio_data())); + if(result_frame != frame2) + boost::range::copy(frame2->audio_data(), std::back_inserter(result_frame->audio_data())); + }); + return result_frame; +} + +template +frame_ptr_type& copy_frame(frame_ptr_type& result_frame, const frame_const_ptr& frame) +{ + assert(result_frame != nullptr && frame != nullptr); + assert(result_frame->size() == frame->size()); + if(result_frame == frame) + return result_frame; + tbb::parallel_invoke( + [&]{common::image::copy(result_frame->data(), frame->data(), result_frame->size());}, + [&]{boost::range::copy(frame->audio_data(), std::back_inserter(result_frame->audio_data()));}); + return result_frame; +} + +template +frame_ptr_type& copy_frame(frame_ptr_type& result_frame, const frame_const_ptr& frame, const frame_format_desc& format_desc) +{ + assert(result_frame != nullptr && frame != nullptr); + assert(result_frame->size() == format_desc.size); + assert(frame->size() == format_desc.size); + if(result_frame == frame) + return result_frame; + tbb::parallel_invoke( + [&] + { + if(format_desc.mode == video_mode::progressive) + common::image::copy(result_frame->data(), frame->data(), result_frame->size()); + else + common::image::copy_field(result_frame->data(), frame->data(), format_desc.mode == video_mode::upper ? 1 : 0, format_desc.width, format_desc.height); + }, + [&]{boost::range::copy(frame->audio_data(), std::back_inserter(result_frame->audio_data()));}); + return result_frame; +} + +template +frame_ptr_type& compose_frames(frame_ptr_type& result_frame, const frame_container& frames) +{ + assert(boost::range::find(frames, nullptr) == frames.end()); + assert(boost::range::find_if(frames, [&](const frame_ptr& frame) { return frame->size() != result_frame->size();}) == frames.end()); + if(frames.empty()) + clear_frame(result_frame); + else if(frames.size() == 1) + copy_frame(result_frame, frames[0]); + else if(frames.size() == 2) + pre_over_frame(result_frame, frames[0], frames[1]); + else + { + for(size_t n = 0; n < frames.size() - 2; ++n) + pre_over_frame(frames[0], frames[n], frames[n+1]); + pre_over_frame(result_frame, frames[0], frames[frames.size()-1]); + } + return result_frame; +} + +} \ No newline at end of file diff --git a/core/frame/frame_format.cpp b/core/frame/frame_format.cpp new file mode 100644 index 000000000..20a73e5e5 --- /dev/null +++ b/core/frame/frame_format.cpp @@ -0,0 +1,61 @@ +/* +* copyright (c) 2010 Sveriges Television AB +* +* This file is part of CasparCG. +* +* CasparCG is free software: you can redistribute it and/or modify +* it under the terms of the GNU General Public License as published by +* the Free Software Foundation, either version 3 of the License, or +* (at your option) any later version. +* +* CasparCG is distributed in the hope that it will be useful, +* but WITHOUT ANY WARRANTY; without even the implied warranty of +* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +* GNU General Public License for more details. + +* You should have received a copy of the GNU General Public License +* along with CasparCG. If not, see . +* +*/ + +#include "..\StdAfx.h" + +#include "frame_format.h" + +#include + +#define DEFINE_VIDEOFORMATDESC(w, h, m, f, s, fmt) { (w), (h), (m), (f), (w)*(h)*4, s, (fmt) } + +namespace caspar { + +const frame_format_desc frame_format_desc::format_descs[frame_format::count] = +{ + DEFINE_VIDEOFORMATDESC(720, 576, video_mode::upper, 50, TEXT("PAL"), frame_format::pal), + DEFINE_VIDEOFORMATDESC(720, 486, video_mode::lower, 60/1.001, TEXT("NTSC"), frame_format::ntsc), + DEFINE_VIDEOFORMATDESC(720, 576, video_mode::progressive, 25, TEXT("576p2500"), frame_format::x576p2500), + DEFINE_VIDEOFORMATDESC(1280, 720, video_mode::progressive, 50, TEXT("720p5000"), frame_format::x720p5000), + DEFINE_VIDEOFORMATDESC(1280, 720, video_mode::progressive, 60/1.001, TEXT("720p5994"), frame_format::x720p5994), + DEFINE_VIDEOFORMATDESC(1280, 720, video_mode::progressive, 60, TEXT("720p6000"), frame_format::x720p6000), + DEFINE_VIDEOFORMATDESC(1920, 1080, video_mode::progressive, 24/1.001, TEXT("1080p2397"), frame_format::x1080p2397), + DEFINE_VIDEOFORMATDESC(1920, 1080, video_mode::progressive, 24, TEXT("1080p2400"), frame_format::x1080p2400), + DEFINE_VIDEOFORMATDESC(1920, 1080, video_mode::upper, 50, TEXT("1080i5000"), frame_format::x1080i5000), + DEFINE_VIDEOFORMATDESC(1920, 1080, video_mode::upper, 60/1.001, TEXT("1080i5994"), frame_format::x1080i5994), + DEFINE_VIDEOFORMATDESC(1920, 1080, video_mode::upper, 60, TEXT("1080i6000"), frame_format::x1080i6000), + DEFINE_VIDEOFORMATDESC(1920, 1080, video_mode::progressive, 25, TEXT("1080p2500"), frame_format::x1080p2500), + DEFINE_VIDEOFORMATDESC(1920, 1080, video_mode::progressive, 30/1.001, TEXT("1080p2997"), frame_format::x1080p2997), + DEFINE_VIDEOFORMATDESC(1920, 1080,video_mode:: progressive, 30, TEXT("1080p3000"), frame_format::x1080p3000) +}; + +frame_format get_video_format(const std::wstring& strVideoMode) +{ + for(int n = 0; n < frame_format::count; ++n) + { + if(boost::iequals(frame_format_desc::format_descs[n].name, strVideoMode)) + return static_cast(n); + } + + return frame_format::invalid; +} + +} //namespace caspar + diff --git a/core/frame/frame_format.h b/core/frame/frame_format.h new file mode 100644 index 000000000..9ecf39aef --- /dev/null +++ b/core/frame/frame_format.h @@ -0,0 +1,78 @@ +#pragma once + +#include + +namespace caspar{ + +enum video_mode +{ + progressive, + lower, + upper +}; + +enum frame_format +{ + pal = 0, + ntsc, + x576p2500, + x720p5000, + x720p5994, + x720p6000, + x1080p2397, + x1080p2400, + x1080i5000, + x1080i5994, + x1080i6000, + x1080p2500, + x1080p2997, + x1080p3000, + count, + invalid +}; + +struct frame_format_desc +{ + size_t width; + size_t height; + video_mode mode; + double fps; + size_t size; + std::wstring name; + frame_format format; + + static const frame_format_desc format_descs[frame_format::count]; +}; + +inline bool operator==(const frame_format_desc& rhs, const frame_format_desc& lhs) +{ + return rhs.format == lhs.format; +} + +inline bool operator!=(const frame_format_desc& rhs, const frame_format_desc& lhs) +{ + return !(rhs == lhs); +} + +frame_format get_video_format(const std::wstring& strVideoMode); + +inline frame_format_desc get_video_format_desc(const std::wstring& strVideoMode, frame_format defaultFormat = frame_format::x576p2500) +{ + auto casparVideoFormat = defaultFormat; + if(!strVideoMode.empty()) + casparVideoFormat = caspar::get_video_format(std::wstring(strVideoMode.begin(), strVideoMode.end())); + return frame_format_desc::format_descs[casparVideoFormat]; +} + +inline double get_frame_format_period(const frame_format_desc& format_desc) +{ + return 1.0/(format_desc.mode == video_mode::progressive ? format_desc.fps : format_desc.fps/2.0); +} + +inline std::wostream& operator<<(std::wostream& out, const frame_format_desc& format_desc) +{ + out << format_desc.name.c_str(); + return out; +} + +} \ No newline at end of file diff --git a/core/frame/frame_fwd.h b/core/frame/frame_fwd.h new file mode 100644 index 000000000..fac407c0e --- /dev/null +++ b/core/frame/frame_fwd.h @@ -0,0 +1,23 @@ +#pragma once + +#include + +namespace caspar{ + +class frame; +typedef std::shared_ptr frame_ptr; +typedef std::shared_ptr frame_const_ptr; +typedef std::unique_ptr frame_uptr; +typedef std::unique_ptr frame_const_uptr; + +struct frame_format_desc; + +struct sound_channel_info; +typedef std::shared_ptr sound_channel_info_ptr; +typedef std::unique_ptr sound_channel_info_uptr; + +class audio_chunk; +typedef std::shared_ptr audio_chunk_ptr; +typedef std::unique_ptr audio_chunk_uptr; + +} \ No newline at end of file diff --git a/core/frame/system_frame.cpp b/core/frame/system_frame.cpp new file mode 100644 index 000000000..d9b212399 --- /dev/null +++ b/core/frame/system_frame.cpp @@ -0,0 +1,36 @@ +/* +* copyright (c) 2010 Sveriges Television AB +* +* This file is part of CasparCG. +* +* CasparCG is free software: you can redistribute it and/or modify +* it under the terms of the GNU General Public License as published by +* the Free Software Foundation, either version 3 of the License, or +* (at your option) any later version. +* +* CasparCG is distributed in the hope that it will be useful, +* but WITHOUT ANY WARRANTY; without even the implied warranty of +* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +* GNU General Public License for more details. + +* You should have received a copy of the GNU General Public License +* along with CasparCG. If not, see . +* +*/ + +#include "../stdafx.h" + +#include "system_frame.h" + +#include + +namespace caspar { + +system_frame::system_frame(unsigned int dataSize) + : size_(dataSize), data_(static_cast(scalable_aligned_malloc(dataSize, 16))){} +system_frame::~system_frame(){scalable_aligned_free(data_);} +unsigned char* system_frame::data() {return data_;} +unsigned int system_frame::size() const{return size_;} + +} + diff --git a/core/frame/system_frame.h b/core/frame/system_frame.h new file mode 100644 index 000000000..e63b2e7c7 --- /dev/null +++ b/core/frame/system_frame.h @@ -0,0 +1,41 @@ +/* +* copyright (c) 2010 Sveriges Television AB +* +* This file is part of CasparCG. +* +* CasparCG is free software: you can redistribute it and/or modify +* it under the terms of the GNU General Public License as published by +* the Free Software Foundation, either version 3 of the License, or +* (at your option) any later version. +* +* CasparCG is distributed in the hope that it will be useful, +* but WITHOUT ANY WARRANTY; without even the implied warranty of +* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +* GNU General Public License for more details. + +* You should have received a copy of the GNU General Public License +* along with CasparCG. If not, see . +* +*/ +#pragma once + +#include "frame.h" + +#include + +namespace caspar { + +class system_frame : public frame +{ +public: + explicit system_frame(unsigned int dataSize); + ~system_frame(); + + unsigned char* data(); + unsigned int size() const; +private: + unsigned char* const data_; + const size_t size_; +}; + +} \ No newline at end of file diff --git a/core/main.cpp b/core/main.cpp new file mode 100644 index 000000000..53edc3831 --- /dev/null +++ b/core/main.cpp @@ -0,0 +1,103 @@ +/* +* copyright (c) 2010 Sveriges Television AB +* +* This file is part of CasparCG. +* +* CasparCG is free software: you can redistribute it and/or modify +* it under the terms of the GNU General Public License as published by +* the Free Software Foundation, either version 3 of the License, or +* (at your option) any later version. +* +* CasparCG is distributed in the hope that it will be useful, +* but WITHOUT ANY WARRANTY; without even the implied warranty of +* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +* GNU General Public License for more details. + +* You should have received a copy of the GNU General Public License +* along with CasparCG. If not, see . +* +*/ + +#include "StdAfx.h" + +#include +#include + +#ifdef _DEBUG + #define _CRTDBG_MAP_ALLOC + #include + #include +#endif + +#include + +#include "server.h" +#include "protocol/amcp/AMCPProtocolStrategy.h" + +class win32_handler_tbb_installer : public tbb::task_scheduler_observer +{ +public: + win32_handler_tbb_installer() {observe(true);} + void on_scheduler_entry(bool is_worker) {caspar::win32_exception::install_handler();} +}; + +int _tmain(int argc, _TCHAR* argv[]) +{ + std::wstringstream str; + str << "CasparCG " << CASPAR_VERSION_STR << " " << CASPAR_VERSION_TAG; + SetConsoleTitle(str.str().c_str()); + + EnableMenuItem(GetSystemMenu(GetConsoleWindow(), FALSE), SC_CLOSE , MF_GRAYED); + DrawMenuBar(GetConsoleWindow()); + MoveWindow(GetConsoleWindow(), 800, 0, 800, 1000, true); + +#ifdef _DEBUG + _CrtSetDbgFlag ( _CRTDBG_ALLOC_MEM_DF | _CRTDBG_LEAK_CHECK_DF | _CRTDBG_CHECK_ALWAYS_DF ); + _CrtSetReportMode( _CRT_ERROR, _CRTDBG_MODE_DEBUG ); + _CrtSetReportMode( _CRT_WARN, _CRTDBG_MODE_DEBUG ); + _CrtSetReportMode( _CRT_ASSERT, _CRTDBG_MODE_DEBUG ); + + MessageBox(nullptr, TEXT("Now is the time to connect for remote debugging..."), TEXT("Debug"), MB_OK | MB_TOPMOST); +#endif + + caspar::log::add_file_sink(caspar::server::log_folder()); + + win32_handler_tbb_installer win32_handler_tbb_installer; + caspar::win32_exception::install_handler(); + + std::wcout << L"Starting CasparCG Video Playout Server Ver: " << CASPAR_VERSION_STR << " tag: " << CASPAR_VERSION_TAG << std::endl; + std::wcout << L"Copyright (c) 2010 Sveriges Television AB \n\n" << std::endl; + + CASPAR_LOG(debug) << "Started Main Thread"; + try + { + caspar::server caspar_device; + + auto dummy = std::make_shared(); + caspar::amcp::AMCPProtocolStrategy amcp(caspar_device.get_channels()); + bool is_running = true; + while(is_running) + { + std::wstring wcmd; + std::getline(std::wcin, wcmd); // TODO: It's blocking... + is_running = wcmd != L"exit" && wcmd != L"q"; + if(wcmd == L"1") + wcmd = L"LOADBG 1-1 DV SLIDE 50 LOOP AUTOPLAY"; + else if(wcmd == L"2") + wcmd = L"CG 1-2 ADD 1 BBTELEFONARE 1"; + + wcmd += L"\r\n"; + amcp.Parse(wcmd.c_str(), wcmd.length(), dummy); + } + } + catch(const std::exception&) + { + CASPAR_LOG(fatal) << "UNHANDLED EXCEPTION in main thread."; + CASPAR_LOG_CURRENT_EXCEPTION(); + std::wcout << L"Press Any Key To Exit"; + _getwch(); + } + CASPAR_LOG(debug) << "Ended Main Thread"; + + return 0; +} diff --git a/core/producer/color/color_producer.cpp b/core/producer/color/color_producer.cpp new file mode 100644 index 000000000..0d08b29f2 --- /dev/null +++ b/core/producer/color/color_producer.cpp @@ -0,0 +1,90 @@ +/* +* copyright (c) 2010 Sveriges Television AB +* +* This file is part of CasparCG. +* +* CasparCG is free software: you can redistribute it and/or modify +* it under the terms of the GNU General Public License as published by +* the Free Software Foundation, either version 3 of the License, or +* (at your option) any later version. +* +* CasparCG is distributed in the hope that it will be useful, +* but WITHOUT ANY WARRANTY; without even the implied warranty of +* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +* GNU General Public License for more details. + +* You should have received a copy of the GNU General Public License +* along with CasparCG. If not, see . +* +*/ + +#include "../../stdafx.h" + +#include "color_producer.h" + +#include "../../frame/system_frame.h" +#include "../../frame/frame_format.h" + +#include +#pragma intrinsic(__movsd, __stosd) + +namespace caspar { + +class color_producer : public frame_producer +{ +public: + explicit color_producer(unsigned long color_value, const frame_format_desc& format_desc) : format_desc_(format_desc) + { + frame_ = std::make_shared(format_desc.size); + __stosd(reinterpret_cast(frame_->data()), color_value_, frame_->size() / sizeof(unsigned long)); + } + + frame_ptr get_frame() { return frame_; } + const frame_format_desc& get_frame_format_desc() const { return format_desc_; } + + frame_format_desc format_desc_; + frame_ptr frame_; + unsigned long color_value_; +}; + +union Color +{ + struct Components + { + unsigned char a; + unsigned char r; + unsigned char g; + unsigned char b; + } comp; + + unsigned long value; +}; + +unsigned long get_pixel_color_value(const std::wstring& parameter) +{ + std::wstring color_code; + if(parameter.length() != 9 || parameter[0] != '#') + BOOST_THROW_EXCEPTION(invalid_argument() << arg_name_info("parameter") << arg_value_info(common::narrow(parameter)) << msg_info("Invalid color code")); + + color_code = parameter.substr(1); + + Color color; + color.value = _tcstoul(color_code.c_str(), 0, 16); + unsigned char temp = color.comp.a; + color.comp.a = color.comp.b; + color.comp.b = temp; + temp = color.comp.r; + color.comp.r = color.comp.g; + color.comp.g = temp; + + return color.value; +} + +frame_producer_ptr create_color_producer(const std::vector& params, const frame_format_desc& format_desc) +{ + if(params.empty() || params[0].at(0) != '#') + return nullptr; + return std::make_shared(get_pixel_color_value(params[0]), format_desc); +} + +} \ No newline at end of file diff --git a/core/producer/color/color_producer.h b/core/producer/color/color_producer.h new file mode 100644 index 000000000..397a62421 --- /dev/null +++ b/core/producer/color/color_producer.h @@ -0,0 +1,31 @@ +/* +* copyright (c) 2010 Sveriges Television AB +* +* This file is part of CasparCG. +* +* CasparCG is free software: you can redistribute it and/or modify +* it under the terms of the GNU General Public License as published by +* the Free Software Foundation, either version 3 of the License, or +* (at your option) any later version. +* +* CasparCG is distributed in the hope that it will be useful, +* but WITHOUT ANY WARRANTY; without even the implied warranty of +* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +* GNU General Public License for more details. + +* You should have received a copy of the GNU General Public License +* along with CasparCG. If not, see . +* +*/ +#pragma once + +#include "../frame_producer.h" + +#include +#include + +namespace caspar { + +frame_producer_ptr create_color_producer(const std::vector& params, const frame_format_desc& format_desc); + +} diff --git a/core/producer/ffmpeg/audio/audio_decoder.cpp b/core/producer/ffmpeg/audio/audio_decoder.cpp new file mode 100644 index 000000000..139606c16 --- /dev/null +++ b/core/producer/ffmpeg/audio/audio_decoder.cpp @@ -0,0 +1,86 @@ +#include "../../../stdafx.h" + +#include "audio_decoder.h" + +#include "../../../../common/image/image.h" + +#include + +namespace caspar{ namespace ffmpeg{ + +struct audio_decoder::implementation : boost::noncopyable +{ + implementation(const sound_channel_info_ptr& snd_channel_info) : discard_bytes_(0), current_audio_chunk_offset_(0), snd_channel_info_(snd_channel_info) + { + audio_decomp_buffer_.resize(audio_decoder::AUDIO_DECOMP_BUFFER_SIZE); + int alignment_offset_ = static_cast(audio_decoder::ALIGNMENT - (reinterpret_cast(&audio_decomp_buffer_.front()) % audio_decoder::ALIGNMENT)); + aligned_audio_decomp_addr_ = &audio_decomp_buffer_.front() + alignment_offset_; + } + + audio_packet_ptr execute(const audio_packet_ptr& audio_packet) + { + int max_chunk_length = std::min(audio_packet->audio_frame_size, audio_packet->src_audio_frame_size); + + int written_bytes = audio_decoder::AUDIO_DECOMP_BUFFER_SIZE - audio_decoder::ALIGNMENT; + int result = avcodec_decode_audio2(audio_packet->codec_context, reinterpret_cast(aligned_audio_decomp_addr_), &written_bytes, audio_packet->data, audio_packet->size); + + if(result <= 0) + return audio_packet; + + unsigned char* pDecomp = aligned_audio_decomp_addr_; + + //if there are bytes to discard, do that first + while(written_bytes > 0 && discard_bytes_ != 0) + { + int bytesToDiscard = std::min(written_bytes, static_cast(discard_bytes_)); + pDecomp += bytesToDiscard; + + discard_bytes_ -= bytesToDiscard; + written_bytes -= bytesToDiscard; + } + + while(written_bytes > 0) + { + //if we're starting on a new chunk, allocate it + if(current_chunk_ == nullptr) + { + current_chunk_ = std::make_shared(audio_packet->audio_frame_size, snd_channel_info_); + current_audio_chunk_offset_ = 0; + } + + //either fill what's left of the chunk or copy all written_bytes that are left + int targetLength = std::min((max_chunk_length - current_audio_chunk_offset_), written_bytes); + common::image::copy(current_chunk_->data() + current_audio_chunk_offset_, pDecomp, targetLength); + written_bytes -= targetLength; + + current_audio_chunk_offset_ += targetLength; + pDecomp += targetLength; + + if(current_audio_chunk_offset_ >= max_chunk_length) + { + if(max_chunk_length < static_cast(audio_packet->audio_frame_size)) + common::image::clear(current_chunk_->data() + max_chunk_length, audio_packet->audio_frame_size-max_chunk_length); + else if(audio_packet->audio_frame_size < audio_packet->src_audio_frame_size) + discard_bytes_ = audio_packet->src_audio_frame_size-audio_packet->audio_frame_size; + + audio_packet->audio_chunks.push_back(current_chunk_); + current_chunk_.reset(); + } + } + + return audio_packet; + } + + int discard_bytes_; + + std::vector audio_decomp_buffer_; + unsigned char* aligned_audio_decomp_addr_; + + audio_chunk_ptr current_chunk_; + int current_audio_chunk_offset_; + sound_channel_info_ptr snd_channel_info_; +}; + +audio_decoder::audio_decoder(const sound_channel_info_ptr& snd_channel_info) : impl_(new implementation(snd_channel_info)){} +audio_packet_ptr audio_decoder::execute(const audio_packet_ptr& audio_packet){return impl_->execute(audio_packet);} +}} \ No newline at end of file diff --git a/core/producer/ffmpeg/audio/audio_decoder.h b/core/producer/ffmpeg/audio/audio_decoder.h new file mode 100644 index 000000000..5cda54d97 --- /dev/null +++ b/core/producer/ffmpeg/audio/audio_decoder.h @@ -0,0 +1,27 @@ +#pragma once + +#include "../packet.h" +#include "../../../frame/audio_chunk.h" + +namespace caspar{ namespace ffmpeg { + +class audio_decoder : boost::noncopyable +{ +public: + audio_decoder(const sound_channel_info_ptr& snd_channel_info); + audio_packet_ptr execute(const audio_packet_ptr& audio_packet); + + /// The alignment + /// Four sec of 16 bit stereo 48kHz should be enough + static const int ALIGNMENT = 16 ; + + /// Size of the audio decomp buffer + static const int AUDIO_DECOMP_BUFFER_SIZE = 4*48000*4+ALIGNMENT; +private: + struct implementation; + std::shared_ptr impl_; +}; +typedef std::shared_ptr audio_decoder_ptr; +typedef std::unique_ptr audio_decoder_uptr; + +}} \ No newline at end of file diff --git a/core/producer/ffmpeg/ffmpeg_producer.cpp b/core/producer/ffmpeg/ffmpeg_producer.cpp new file mode 100644 index 000000000..20a0d0398 --- /dev/null +++ b/core/producer/ffmpeg/ffmpeg_producer.cpp @@ -0,0 +1,169 @@ +#include "../../stdafx.h" + +#include "ffmpeg_producer.h" + +#if defined(_MSC_VER) +#pragma warning (push) +#pragma warning (disable : 4244) +#endif + +extern "C" +{ + #define __STDC_CONSTANT_MACROS + #define __STDC_LIMIT_MACROS + #include + #include + #include + #include +} + +#if defined(_MSC_VER) +#pragma warning (pop) +#endif + +#include "input.h" + +#include "audio/audio_decoder.h" +#include "video/video_decoder.h" +#include "video/video_deinterlacer.h" +#include "video/video_scaler.h" + +#include "../../frame/frame_format.h" +#include "../../../common/utility/find_file.h" +#include "../../server.h" +#include "../../../common/image/image.h" +#include "../../../common/utility/scope_exit.h" + +#include +#include +#include + +#include +#include +#include +#include + +using namespace boost::assign; + +namespace caspar{ namespace ffmpeg{ + +struct ffmpeg_producer : public frame_producer +{ +public: + static const size_t MAX_TOKENS = 5; + static const size_t MIN_BUFFER_SIZE = 2; + static const size_t DEFAULT_BUFFER_SIZE = 8; + static const size_t MAX_BUFFER_SIZE = 64; + static const size_t LOAD_TARGET_BUFFER_SIZE = 4; + static const size_t THREAD_TIMEOUT_MS = 1000; + + ffmpeg_producer(const std::wstring& filename, const std::vector& params, const frame_format_desc& format_desc) + : filename_(filename), format_desc_(format_desc) + { + if(!boost::filesystem::exists(filename)) + BOOST_THROW_EXCEPTION(file_not_found() << boost::errinfo_file_name(common::narrow(filename))); + + static boost::once_flag flag = BOOST_ONCE_INIT; + boost::call_once(av_register_all, flag); + + input_.reset(new input(format_desc)); + input_->set_loop(std::find(params.begin(), params.end(), L"LOOP") != params.end()); + input_->load(common::narrow(filename_)); + + sound_channel_info_ptr snd_channel_info = input_->get_audio_codec_context() != nullptr ? + std::make_shared + ( + input_->get_audio_codec_context()->channels, + input_->get_audio_codec_context()->bits_per_coded_sample, + input_->get_audio_codec_context()->sample_rate + ) : nullptr; + + video_decoder_.reset(new video_decoder()); + video_scaler_.reset(new video_scaler()); + audio_decoder_.reset(new audio_decoder(snd_channel_info)); + has_audio_ = input_->get_audio_codec_context() != nullptr; + } + + frame_ptr get_frame() + { + while(ouput_channel_.empty() && !input_->is_eof()) + { + tbb::parallel_invoke( + [&] + { // Video Decoding and Scaling + auto video_packet = input_->get_video_packet(); + if(video_packet) + { + video_packet = video_decoder_->execute(video_packet); + auto frame = video_scaler_->execute(video_packet)->frame; + video_frame_channel_.push_back(std::move(frame)); + } + }, + [&] + { // Audio Decoding + auto audio_packet = input_->get_audio_packet(); + if(audio_packet) + { + auto audio_chunks = audio_decoder_->execute(audio_packet); + audio_chunk_channel_.insert(audio_chunk_channel_.end(), audio_packet->audio_chunks.begin(), audio_packet->audio_chunks.end()); + } + }); + + while(!video_frame_channel_.empty() && (!audio_chunk_channel_.empty() || !has_audio_)) + { + if(has_audio_) + { + video_frame_channel_.front()->audio_data().push_back(audio_chunk_channel_.front()); + audio_chunk_channel_.pop_front(); + } + + frame_ptr frame = video_frame_channel_.front(); + video_frame_channel_.pop_front(); + ouput_channel_.push(std::move(frame)); + } + } + + frame_ptr frame; + if(!ouput_channel_.empty()) + { + frame = ouput_channel_.front(); + ouput_channel_.pop(); + } + return frame; + } + + const frame_format_desc& get_frame_format_desc() const { return format_desc_; } + + bool has_audio_; + + // Filter 1 : Input + input_uptr input_; + + // Filter 2 : Video Decoding and Scaling + video_decoder_uptr video_decoder_; + video_scaler_uptr video_scaler_; + //std::deque videoDecodedPacketChannel_; + std::deque video_frame_channel_; + + // Filter 3 : Audio Decoding + audio_decoder_uptr audio_decoder_; + std::deque audio_chunk_channel_; + + // Filter 4 : Merge Video and Audio + std::queue ouput_channel_; + + std::wstring filename_; + frame_format_desc format_desc_; +}; + +frame_producer_ptr create_ffmpeg_producer(const std::vector& params, const frame_format_desc& format_desc) +{ + std::wstring filename = params[0]; + std::wstring result_filename = common::find_file(server::media_folder() + filename, list_of(L"mpg")(L"avi")(L"mov")(L"dv")(L"wav")(L"mp3")(L"mp4")(L"f4v")(L"flv")); + if(result_filename.empty()) + return nullptr; + + return std::make_shared(result_filename, params, format_desc); +} + +}} \ No newline at end of file diff --git a/core/producer/ffmpeg/ffmpeg_producer.h b/core/producer/ffmpeg/ffmpeg_producer.h new file mode 100644 index 000000000..cbe4b9d9e --- /dev/null +++ b/core/producer/ffmpeg/ffmpeg_producer.h @@ -0,0 +1,12 @@ +#pragma once + +#include "../frame_producer.h" + +#include +#include + +namespace caspar { namespace ffmpeg { + +frame_producer_ptr create_ffmpeg_producer(const std::vector& params, const frame_format_desc& format_desc); + +}} \ No newline at end of file diff --git a/core/producer/ffmpeg/input.cpp b/core/producer/ffmpeg/input.cpp new file mode 100644 index 000000000..48d9a1c8b --- /dev/null +++ b/core/producer/ffmpeg/input.cpp @@ -0,0 +1,230 @@ +#include "..\..\stdafx.h" + +#include "input.h" + +#include "../../frame/system_frame.h" +#include "../../frame/frame_format.h" +#include "../../../common/image/image.h" +#include "../../../common/utility/scope_exit.h" + +#include + +#include + +#include +#include + +#pragma warning(disable : 4482) + +namespace caspar{ namespace ffmpeg{ + +struct input::implementation : boost::noncopyable +{ + implementation(const frame_format_desc& format_desc) + : video_frame_rate_(25.0), video_s_index_(-1), audio_s_index_(-1), video_codec_(nullptr), audio_codec_a(nullptr), format_desc_(format_desc) + { + loop_ = false; + video_packet_buffer_.set_capacity(28); + audio_packet_buffer_.set_capacity(28); + } + + ~implementation() + { + is_running_ = false; + audio_packet_buffer_.clear(); + video_packet_buffer_.clear(); + io_thread_.join(); + } + + void load(const std::string& filename) + { + try + { + int errn; + AVFormatContext* weak_format_context; + if((errn = -av_open_input_file(&weak_format_context, filename.c_str(), nullptr, 0, nullptr)) > 0) + BOOST_THROW_EXCEPTION(ffmpeg_error() << boost::errinfo_errno(errn)); + format_context.reset(weak_format_context, av_close_input_file); + + if((errn = -av_find_stream_info(format_context.get())) > 0) + BOOST_THROW_EXCEPTION(ffmpeg_error() << boost::errinfo_errno(errn)); + + video_codec_context_ = open_video_stream(); + if(!video_codec_context_) + CASPAR_LOG(info) << "No video stream found."; + + audio_codex_context = open_audio_stream(); + if(!audio_codex_context) + CASPAR_LOG(info) << "No audio stream found."; + + if(!video_codec_context_ && !audio_codex_context) + BOOST_THROW_EXCEPTION(caspar_exception() << msg_info("No video or audio codec found.")); + + video_frame_rate_ = static_cast(video_codec_context_->time_base.den) / static_cast(video_codec_context_->time_base.num); + + is_running_ = true; + io_thread_ = boost::thread([=]{this->read_file();}); + } + catch(...) + { + video_codec_context_.reset(); + audio_codex_context.reset(); + format_context.reset(); + video_frame_rate_ = 25.0; + video_s_index_ = -1; + audio_s_index_ = -1; + throw; + } + filename_ = filename; + } + + std::shared_ptr open_video_stream() + { + bool succeeded = false; + + CASPAR_SCOPE_EXIT([&] + { + if(!succeeded) + { + video_s_index_ = -1; + video_codec_ = nullptr; + } + }); + + AVStream** streams_end = format_context->streams+format_context->nb_streams; + AVStream** video_stream = std::find_if(format_context->streams, streams_end, + [](AVStream* stream) { return stream != nullptr && stream->codec->codec_type == CODEC_TYPE_VIDEO ;}); + + video_s_index_ = video_stream != streams_end ? (*video_stream)->index : -1; + if(video_s_index_ == -1) + return nullptr; + + video_codec_ = avcodec_find_decoder((*video_stream)->codec->codec_id); + if(video_codec_ == nullptr) + return nullptr; + + if((-avcodec_open((*video_stream)->codec, video_codec_)) > 0) + return nullptr; + + succeeded = true; + + return std::shared_ptr((*video_stream)->codec, avcodec_close); + } + + std::shared_ptr open_audio_stream() + { + bool succeeded = false; + + CASPAR_SCOPE_EXIT([&] + { + if(!succeeded) + { + audio_s_index_ = -1; + audio_codec_a = nullptr; + } + }); + + AVStream** streams_end = format_context->streams+format_context->nb_streams; + AVStream** audio_stream = std::find_if(format_context->streams, streams_end, + [](AVStream* stream) { return stream != nullptr && stream->codec->codec_type == CODEC_TYPE_AUDIO;}); + + audio_s_index_ = audio_stream != streams_end ? (*audio_stream)->index : -1; + if(audio_s_index_ == -1) + return nullptr; + + audio_codec_a = avcodec_find_decoder((*audio_stream)->codec->codec_id); + if(audio_codec_a == nullptr) + return nullptr; + + if((-avcodec_open((*audio_stream)->codec, audio_codec_a)) > 0) + return nullptr; + + succeeded = true; + + return std::shared_ptr((*audio_stream)->codec, avcodec_close); + } + + void read_file() + { + CASPAR_LOG(info) << "Started ffmpeg_producer::read_file Thread for " << filename_.c_str(); + win32_exception::install_handler(); + + try + { + AVPacket tmp_packet; + while(is_running_) + { + std::shared_ptr packet(&tmp_packet, av_free_packet); + + if (av_read_frame(format_context.get(), packet.get()) >= 0) // NOTE: Packet is only valid until next call of av_read_frame or av_close_input_file + { + if(packet->stream_index == video_s_index_) + video_packet_buffer_.push(std::make_shared(packet, std::make_shared(format_desc_.size), format_desc_, video_codec_context_.get(), video_codec_)); // NOTE: video_packet makes a copy of AVPacket + else if(packet->stream_index == audio_s_index_) + audio_packet_buffer_.push(std::make_shared(packet, audio_codex_context.get(), audio_codec_a, video_frame_rate_)); + } + else if(!loop_ || av_seek_frame(format_context.get(), -1, 0, AVSEEK_FLAG_BACKWARD) < 0) // TODO: av_seek_frame does not work for all formats + is_running_ = false; + } + } + catch(...) + { + CASPAR_LOG_CURRENT_EXCEPTION(); + } + + is_running_ = false; + + CASPAR_LOG(info) << " Ended ffmpeg_producer::read_file Thread for " << filename_.c_str(); + } + + video_packet_ptr get_video_packet() + { + video_packet_ptr video_packet; + video_packet_buffer_.try_pop(video_packet); + return video_packet; + } + + audio_packet_ptr get_audio_packet() + { + audio_packet_ptr audio_packet; + audio_packet_buffer_.try_pop(audio_packet); + return audio_packet; + } + + bool is_eof() const + { + return !is_running_ && video_packet_buffer_.empty() && audio_packet_buffer_.empty(); + } + + std::string filename_; + std::shared_ptr format_context; // Destroy this last + + std::shared_ptr video_codec_context_; + AVCodec* video_codec_; + + std::shared_ptr audio_codex_context; + AVCodec* audio_codec_a; + + tbb::atomic loop_; + int video_s_index_; + int audio_s_index_; + + frame_format_desc format_desc_; + + tbb::concurrent_bounded_queue video_packet_buffer_; + tbb::concurrent_bounded_queue audio_packet_buffer_; + boost::thread io_thread_; + tbb::atomic is_running_; + + double video_frame_rate_; +}; + +input::input(const frame_format_desc& format_desc) : impl_(new implementation(format_desc)){} +void input::load(const std::string& filename){impl_->load(filename);} +void input::set_loop(bool value){impl_->loop_ = value;} +const std::shared_ptr& input::get_video_codec_context() const{return impl_->video_codec_context_;} +const std::shared_ptr& input::get_audio_codec_context() const{return impl_->audio_codex_context;} +bool input::is_eof() const{return impl_->is_eof();} +video_packet_ptr input::get_video_packet(){return impl_->get_video_packet();} +audio_packet_ptr input::get_audio_packet(){return impl_->get_audio_packet();} +}} \ No newline at end of file diff --git a/core/producer/ffmpeg/input.h b/core/producer/ffmpeg/input.h new file mode 100644 index 000000000..19462793e --- /dev/null +++ b/core/producer/ffmpeg/input.h @@ -0,0 +1,32 @@ +#pragma once + +#include "packet.h" + +#include + +namespace caspar{ namespace ffmpeg{ + +typedef std::shared_ptr AVFormatContextPtr; + +class input : boost::noncopyable +{ +public: + input(const frame_format_desc& format_desc); + void load(const std::string& filename); + const std::shared_ptr& get_video_codec_context() const; + const std::shared_ptr& get_audio_codec_context() const; + + video_packet_ptr get_video_packet(); + audio_packet_ptr get_audio_packet(); + + bool is_eof() const; + void set_loop(bool value); +private: + struct implementation; + std::shared_ptr impl_; +}; +typedef std::shared_ptr input_ptr; +typedef std::unique_ptr input_uptr; + + } +} diff --git a/core/producer/ffmpeg/packet.h b/core/producer/ffmpeg/packet.h new file mode 100644 index 000000000..2238a848d --- /dev/null +++ b/core/producer/ffmpeg/packet.h @@ -0,0 +1,94 @@ +#pragma once + +#include "../../frame/audio_chunk.h" +#include "../../frame/frame.h" + +#include +#include + +#if defined(_MSC_VER) +#pragma warning (push) +#pragma warning (disable : 4244) +#endif +extern "C" +{ + #define __STDC_CONSTANT_MACROS + #define __STDC_LIMIT_MACROS + #include +} +#if defined(_MSC_VER) +#pragma warning (pop) +#endif + +namespace caspar{ namespace ffmpeg{ + +typedef std::tr1::shared_ptr AVFramePtr; +typedef std::tr1::shared_ptr AVPacketPtr; + +struct ffmpeg_error: virtual boost::exception, virtual std::exception { }; + +struct video_packet : boost::noncopyable +{ + video_packet(const AVPacketPtr& packet, frame_ptr&& frame, const frame_format_desc& format_desc, AVCodecContext* codec_context, AVCodec* codec) + : size(packet->size), codec_context(codec_context), codec(codec), frame(std::move(frame)), format_desc(format_desc), + data(static_cast(scalable_aligned_malloc(packet->size, 16))) + { + memcpy(const_cast(data), packet->data, packet->size); + } + + ~video_packet() + { + scalable_aligned_free(const_cast(data)); + } + + const size_t size; + const uint8_t* const data; + AVCodecContext* const codec_context; + const AVCodec* const codec; + const frame_ptr frame; + AVFramePtr decoded_frame; + const frame_format_desc& format_desc; +}; +typedef std::shared_ptr video_packet_ptr; + +struct audio_packet : boost::noncopyable +{ + audio_packet(const AVPacketPtr& packet, AVCodecContext* codec_context, AVCodec* codec, double frame_rate = 25.0) + : + size(packet->size), + codec_context(codec_context), + codec(codec), + data(static_cast(scalable_aligned_malloc(packet->size, 16))) + { + memcpy(const_cast(data), packet->data, packet->size); + + size_t bytesPerSec = (codec_context->sample_rate * codec_context->channels * 2); + + audio_frame_size = bytesPerSec / 25; + src_audio_frame_size = static_cast(static_cast(bytesPerSec) / frame_rate); + + //make sure the framesize is a multiple of the samplesize + int sourceSizeMod = src_audio_frame_size % (codec_context->channels * 2); + if(sourceSizeMod != 0) + src_audio_frame_size += (codec_context->channels * 2) - sourceSizeMod; + } + + ~audio_packet() + { + scalable_aligned_free(const_cast(data)); + } + + size_t src_audio_frame_size; + size_t audio_frame_size; + + AVCodecContext* const codec_context; + const AVCodec* const codec; + const size_t size; + const uint8_t* const data; + + std::vector audio_chunks; +}; +typedef std::shared_ptr audio_packet_ptr; + + } +} diff --git a/core/producer/ffmpeg/video/video_decoder.cpp b/core/producer/ffmpeg/video/video_decoder.cpp new file mode 100644 index 000000000..09c0dbc4d --- /dev/null +++ b/core/producer/ffmpeg/video/video_decoder.cpp @@ -0,0 +1,28 @@ +#include "../../../stdafx.h" + +#include "video_decoder.h" + +namespace caspar{ namespace ffmpeg{ + +struct video_decoder::implementation : boost::noncopyable +{ + video_packet_ptr execute(const video_packet_ptr& video_packet) + { + if(video_packet->codec->id == CODEC_ID_RAWVIDEO) // TODO: doesnt sws_scale do this? + common::image::shuffle(video_packet->frame->data(), video_packet->data, video_packet->size, 3, 2, 1, 0); + else + { + video_packet->decoded_frame.reset(avcodec_alloc_frame(), av_free); + + int frame_finished = 0; + if((-avcodec_decode_video(video_packet->codec_context, video_packet->decoded_frame.get(), &frame_finished, video_packet->data, video_packet->size)) > 0) + video_packet->decoded_frame.reset(); + } + + return video_packet; + } +}; + +video_decoder::video_decoder() : impl_(new implementation()){} +video_packet_ptr video_decoder::execute(const video_packet_ptr& video_packet){return impl_->execute(video_packet);} +}} \ No newline at end of file diff --git a/core/producer/ffmpeg/video/video_decoder.h b/core/producer/ffmpeg/video/video_decoder.h new file mode 100644 index 000000000..303a6f512 --- /dev/null +++ b/core/producer/ffmpeg/video/video_decoder.h @@ -0,0 +1,22 @@ +#pragma once + +#include "../packet.h" + +namespace caspar{ namespace ffmpeg{ + +typedef std::tr1::shared_ptr AVCodecContextPtr; + +class video_decoder : boost::noncopyable +{ +public: + video_decoder(); + video_packet_ptr execute(const video_packet_ptr& video_packet); +private: + struct implementation; + std::shared_ptr impl_; +}; +typedef std::shared_ptr video_decoder_ptr; +typedef std::unique_ptr video_decoder_uptr; + + } +} \ No newline at end of file diff --git a/core/producer/ffmpeg/video/video_deinterlacer.cpp b/core/producer/ffmpeg/video/video_deinterlacer.cpp new file mode 100644 index 000000000..e59c6d315 --- /dev/null +++ b/core/producer/ffmpeg/video/video_deinterlacer.cpp @@ -0,0 +1,51 @@ +#include "../../../stdafx.h" + +#include "video_deinterlacer.h" + +#include "../packet.h" + +#include "../../../../common/image/image.h" + +#include +#include +#include +#include + +using namespace std::tr1::placeholders; + +namespace caspar +{ + namespace ffmpeg + { + +//struct VideoPacketDeinterlacerFilter::Implementation +//{ +// void* process(video_packet* pVideoPacket) +// { +// avpicture_deinterlace(reinterpret_cast(pVideoPacket->pDecodedFrame.get()), reinterpret_cast(pVideoPacket->pDecodedFrame.get()), pVideoPacket->codecContext->pix_fmt, pVideoPacket->codecContext->width, pVideoPacket->codecContext->height); +// return pVideoPacket; +// } +// +// bool is_valid(video_packet* pVideoPacket) +// { +// return pVideoPacket->pDecodedFrame != nullptr && pVideoPacket->pDecodedFrame->interlaced_frame; +// } +//}; +// +//VideoPacketDeinterlacerFilter::VideoPacketDeinterlacerFilter() +// : tbb::filter(parallel), pImpl_(new Implementation()) +//{ +//} +// +// +//void* VideoPacketDeinterlacerFilter::operator()(void* item) +//{ +// return (*pImpl_)(item); +//} +// +//void VideoPacketDeinterlacerFilter::finalize(void* item) +//{ +// pImpl_->finalize(item); +//} + } +} \ No newline at end of file diff --git a/core/producer/ffmpeg/video/video_deinterlacer.h b/core/producer/ffmpeg/video/video_deinterlacer.h new file mode 100644 index 000000000..c420c0cbd --- /dev/null +++ b/core/producer/ffmpeg/video/video_deinterlacer.h @@ -0,0 +1,22 @@ +#pragma once + +namespace caspar +{ + namespace ffmpeg + { +//class VideoPacketDeinterlacerFilter : public tbb::filter, private boost::noncopyable +//{ +//public: +// VideoPacketDeinterlacerFilter(); +// void* operator()(void* item); +// void finalize(void* item); +// +//private: +// struct Implementation; +// std::tr1::shared_ptr pImpl_; +//}; +//typedef std::shared_ptr video_scer_ptr; +//typedef std::unique_ptr video_scer_uptr; + + } +} \ No newline at end of file diff --git a/core/producer/ffmpeg/video/video_scaler.cpp b/core/producer/ffmpeg/video/video_scaler.cpp new file mode 100644 index 000000000..0222f59b2 --- /dev/null +++ b/core/producer/ffmpeg/video/video_scaler.cpp @@ -0,0 +1,88 @@ +#include "../../../stdafx.h" + +#include "video_scaler.h" + +#include "../../../frame/frame_format.h" +#include "../../../../common/image/image.h" + +#include +#include +#include +#include +#include + +#if defined(_MSC_VER) +#pragma warning (push) +#pragma warning (disable : 4244) +#endif +extern "C" +{ + #define __STDC_CONSTANT_MACROS + #define __STDC_LIMIT_MACROS + #include +} +#if defined(_MSC_VER) +#pragma warning (pop) +#endif + +namespace caspar{ namespace ffmpeg{ + +typedef std::shared_ptr SwsContextPtr; + +// TODO: Remove and do copy right into frame +struct fill_frame +{ + fill_frame(size_t width, size_t height) + : frame(avcodec_alloc_frame(), av_free), buffer(static_cast(scalable_aligned_malloc(width*height*4, 16)), scalable_aligned_free) + { + avpicture_fill(reinterpret_cast(frame.get()), buffer.get(), PIX_FMT_BGRA, width, height); + } + const AVFramePtr frame; + const std::shared_ptr buffer; +}; +typedef std::shared_ptr fill_frame_ptr; + +struct video_scaler::implementation : boost::noncopyable +{ + video_packet_ptr execute(const video_packet_ptr video_packet) + { + assert(video_packet); + + if(!sws_context_) + { + double param; + sws_context_.reset(sws_getContext(video_packet->codec_context->width, video_packet->codec_context->height, video_packet->codec_context->pix_fmt, video_packet->format_desc.width, video_packet->format_desc.height, + PIX_FMT_BGRA, SWS_BILINEAR, nullptr, nullptr, ¶m), sws_freeContext); + } + + //AVFrame avFrame; + //avcodec_get_frame_defaults(avFrame); + //avpicture_fill(reinterpret_cast(&avFrame), video_packet->frame->data(), PIX_FMT_BGRA, video_packet->frameFormat.width, video_packet->frameFormat.height); + + fill_frame fill_frame(video_packet->format_desc.width, video_packet->format_desc.height); + int result = sws_scale(sws_context_.get(), video_packet->decoded_frame->data, video_packet->decoded_frame->linesize, 0, video_packet->codec_context->height, fill_frame.frame->data, fill_frame.frame->linesize); + video_packet->decoded_frame.reset(); // Free memory + + if(video_packet->codec->id == CODEC_ID_DVVIDEO) // Move up one field + { + size_t size = video_packet->format_desc.width * video_packet->format_desc.height * 4; + size_t linesize = video_packet->format_desc.width * 4; + common::image::copy(video_packet->frame->data(), fill_frame.buffer.get() + linesize, size - linesize); + common::image::clear(video_packet->frame->data() + size - linesize, linesize); + } + else + { + // 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. See line 59-61. + common::image::copy(video_packet->frame->data(), fill_frame.buffer.get(), video_packet->frame->size()); + } + + return video_packet; + } + +private: + SwsContextPtr sws_context_; +}; + +video_scaler::video_scaler() : impl_(new implementation()){} +video_packet_ptr video_scaler::execute(const video_packet_ptr& video_packet){return impl_->execute(video_packet);} +}} \ No newline at end of file diff --git a/core/producer/ffmpeg/video/video_scaler.h b/core/producer/ffmpeg/video/video_scaler.h new file mode 100644 index 000000000..03aa8a785 --- /dev/null +++ b/core/producer/ffmpeg/video/video_scaler.h @@ -0,0 +1,19 @@ +#pragma once + +#include "../packet.h" + +namespace caspar{ namespace ffmpeg{ + +class video_scaler : boost::noncopyable +{ +public: + video_scaler(); + video_packet_ptr execute(const video_packet_ptr& video_packet); +private: + struct implementation; + std::shared_ptr impl_; +}; +typedef std::shared_ptr video_scaler_ptr; +typedef std::unique_ptr video_scaler_uptr; + +}} \ No newline at end of file diff --git a/core/producer/flash/Flash9e.IDL b/core/producer/flash/Flash9e.IDL new file mode 100644 index 000000000..c85a3bb3c --- /dev/null +++ b/core/producer/flash/Flash9e.IDL @@ -0,0 +1,367 @@ +// Generated .IDL file (by the OLE/COM Object Viewer) +// +// typelib filename: Flash9e.ocx + +[ + uuid(D27CDB6B-AE6D-11CF-96B8-444553540000), + version(1.0), + helpstring("Shockwave Flash"), + custom(DE77BA64-517C-11D1-A2DA-0000F8773CE9, 100663662), + custom(DE77BA63-517C-11D1-A2DA-0000F8773CE9, 1180654890) + +] +library ShockwaveFlashObjects +{ + // TLib : // TLib : OLE Automation : {00020430-0000-0000-C000-000000000046} + importlib("stdole2.tlb"); + + // Forward declare all types defined in this typelib + interface IShockwaveFlash; + dispinterface _IShockwaveFlashEvents; + interface IFlashFactory; + interface IFlashObjectInterface; + interface IDispatchEx; + interface IServiceProvider; + + [ + odl, + uuid(D27CDB6C-AE6D-11CF-96B8-444553540000), + helpstring("Shockwave Flash"), + dual, + oleautomation + ] + interface IShockwaveFlash : IDispatch { + [id(0xfffffdf3), propget, helpstring("property ReadyState")] + HRESULT ReadyState([out, retval] long* pVal); + [id(0x0000007c), propget, helpstring("property TotalFrames")] + HRESULT TotalFrames([out, retval] long* pVal); + [id(0x0000007d), propget, helpstring("property Playing")] + HRESULT Playing([out, retval] VARIANT_BOOL* pVal); + [id(0x0000007d), propput, helpstring("property Playing")] + HRESULT Playing([in] VARIANT_BOOL pVal); + [id(0x00000069), propget, helpstring("property Quality")] + HRESULT Quality([out, retval] int* pVal); + [id(0x00000069), propput, helpstring("property Quality")] + HRESULT Quality([in] int pVal); + [id(0x00000078), propget, helpstring("property ScaleMode")] + HRESULT ScaleMode([out, retval] int* pVal); + [id(0x00000078), propput, helpstring("property ScaleMode")] + HRESULT ScaleMode([in] int pVal); + [id(0x00000079), propget, helpstring("property AlignMode")] + HRESULT AlignMode([out, retval] int* pVal); + [id(0x00000079), propput, helpstring("property AlignMode")] + HRESULT AlignMode([in] int pVal); + [id(0x0000007b), propget, helpstring("property BackgroundColor")] + HRESULT BackgroundColor([out, retval] long* pVal); + [id(0x0000007b), propput, helpstring("property BackgroundColor")] + HRESULT BackgroundColor([in] long pVal); + [id(0x0000006a), propget, helpstring("property Loop")] + HRESULT Loop([out, retval] VARIANT_BOOL* pVal); + [id(0x0000006a), propput, helpstring("property Loop")] + HRESULT Loop([in] VARIANT_BOOL pVal); + [id(0x00000066), propget, helpstring("property Movie")] + HRESULT Movie([out, retval] BSTR* pVal); + [id(0x00000066), propput, helpstring("property Movie")] + HRESULT Movie([in] BSTR pVal); + [id(0x0000006b), propget, helpstring("property FrameNum")] + HRESULT FrameNum([out, retval] long* pVal); + [id(0x0000006b), propput, helpstring("property FrameNum")] + HRESULT FrameNum([in] long pVal); + [id(0x0000006d), helpstring("method SetZoomRect")] + HRESULT SetZoomRect( + [in] long left, + [in] long top, + [in] long right, + [in] long bottom); + [id(0x00000076), helpstring("method Zoom")] + HRESULT Zoom([in] int factor); + [id(0x00000077), helpstring("method Pan")] + HRESULT Pan( + [in] long x, + [in] long y, + [in] int mode); + [id(0x00000070), helpstring("method Play")] + HRESULT Play(); + [id(0x00000071), helpstring("method Stop")] + HRESULT Stop(); + [id(0x00000072), helpstring("method Back")] + HRESULT Back(); + [id(0x00000073), helpstring("method Forward")] + HRESULT Forward(); + [id(0x00000074), helpstring("method Rewind")] + HRESULT Rewind(); + [id(0x0000007e), helpstring("method StopPlay")] + HRESULT StopPlay(); + [id(0x0000007f), helpstring("method GotoFrame")] + HRESULT GotoFrame([in] long FrameNum); + [id(0x00000080), helpstring("method CurrentFrame")] + HRESULT CurrentFrame([out, retval] long* FrameNum); + [id(0x00000081), helpstring("method IsPlaying")] + HRESULT IsPlaying([out, retval] VARIANT_BOOL* Playing); + [id(0x00000082), helpstring("method PercentLoaded")] + HRESULT PercentLoaded([out, retval] long* percent); + [id(0x00000083), helpstring("method FrameLoaded")] + HRESULT FrameLoaded( + [in] long FrameNum, + [out, retval] VARIANT_BOOL* loaded); + [id(0x00000084), helpstring("method FlashVersion")] + HRESULT FlashVersion([out, retval] long* version); + [id(0x00000085), propget, helpstring("property WMode")] + HRESULT WMode([out, retval] BSTR* pVal); + [id(0x00000085), propput, helpstring("property WMode")] + HRESULT WMode([in] BSTR pVal); + [id(0x00000086), propget, helpstring("property SAlign")] + HRESULT SAlign([out, retval] BSTR* pVal); + [id(0x00000086), propput, helpstring("property SAlign")] + HRESULT SAlign([in] BSTR pVal); + [id(0x00000087), propget, helpstring("property Menu")] + HRESULT Menu([out, retval] VARIANT_BOOL* pVal); + [id(0x00000087), propput, helpstring("property Menu")] + HRESULT Menu([in] VARIANT_BOOL pVal); + [id(0x00000088), propget, helpstring("property Base")] + HRESULT Base([out, retval] BSTR* pVal); + [id(0x00000088), propput, helpstring("property Base")] + HRESULT Base([in] BSTR pVal); + [id(0x00000089), propget, helpstring("property Scale")] + HRESULT Scale([out, retval] BSTR* pVal); + [id(0x00000089), propput, helpstring("property Scale")] + HRESULT Scale([in] BSTR pVal); + [id(0x0000008a), propget, helpstring("property DeviceFont")] + HRESULT DeviceFont([out, retval] VARIANT_BOOL* pVal); + [id(0x0000008a), propput, helpstring("property DeviceFont")] + HRESULT DeviceFont([in] VARIANT_BOOL pVal); + [id(0x0000008b), propget, helpstring("property EmbedMovie")] + HRESULT EmbedMovie([out, retval] VARIANT_BOOL* pVal); + [id(0x0000008b), propput, helpstring("property EmbedMovie")] + HRESULT EmbedMovie([in] VARIANT_BOOL pVal); + [id(0x0000008c), propget, helpstring("property BGColor")] + HRESULT BGColor([out, retval] BSTR* pVal); + [id(0x0000008c), propput, helpstring("property BGColor")] + HRESULT BGColor([in] BSTR pVal); + [id(0x0000008d), propget, helpstring("property Quality2")] + HRESULT Quality2([out, retval] BSTR* pVal); + [id(0x0000008d), propput, helpstring("property Quality2")] + HRESULT Quality2([in] BSTR pVal); + [id(0x0000008e), helpstring("method LoadMovie")] + HRESULT LoadMovie( + [in] int layer, + [in] BSTR url); + [id(0x0000008f), helpstring("method TGotoFrame")] + HRESULT TGotoFrame( + [in] BSTR target, + [in] long FrameNum); + [id(0x00000090), helpstring("method TGotoLabel")] + HRESULT TGotoLabel( + [in] BSTR target, + [in] BSTR label); + [id(0x00000091), helpstring("method TCurrentFrame")] + HRESULT TCurrentFrame( + [in] BSTR target, + [out, retval] long* FrameNum); + [id(0x00000092), helpstring("method TCurrentLabel")] + HRESULT TCurrentLabel( + [in] BSTR target, + [out, retval] BSTR* pVal); + [id(0x00000093), helpstring("method TPlay")] + HRESULT TPlay([in] BSTR target); + [id(0x00000094), helpstring("method TStopPlay")] + HRESULT TStopPlay([in] BSTR target); + [id(0x00000097), helpstring("method SetVariable")] + HRESULT SetVariable( + [in] BSTR name, + [in] BSTR value); + [id(0x00000098), helpstring("method GetVariable")] + HRESULT GetVariable( + [in] BSTR name, + [out, retval] BSTR* pVal); + [id(0x00000099), helpstring("method TSetProperty")] + HRESULT TSetProperty( + [in] BSTR target, + [in] int property, + [in] BSTR value); + [id(0x0000009a), helpstring("method TGetProperty")] + HRESULT TGetProperty( + [in] BSTR target, + [in] int property, + [out, retval] BSTR* pVal); + [id(0x0000009b), helpstring("method TCallFrame")] + HRESULT TCallFrame( + [in] BSTR target, + [in] int FrameNum); + [id(0x0000009c), helpstring("method TCallLabel")] + HRESULT TCallLabel( + [in] BSTR target, + [in] BSTR label); + [id(0x0000009d), helpstring("method TSetPropertyNum")] + HRESULT TSetPropertyNum( + [in] BSTR target, + [in] int property, + [in] double value); + [id(0x0000009e), helpstring("method TGetPropertyNum")] + HRESULT TGetPropertyNum( + [in] BSTR target, + [in] int property, + [out, retval] double* pVal); + [id(0x000000ac), helpstring("method TGetPropertyAsNumber")] + HRESULT TGetPropertyAsNumber( + [in] BSTR target, + [in] int property, + [out, retval] double* pVal); + [id(0x0000009f), propget, helpstring("property SWRemote")] + HRESULT SWRemote([out, retval] BSTR* pVal); + [id(0x0000009f), propput, helpstring("property SWRemote")] + HRESULT SWRemote([in] BSTR pVal); + [id(0x000000aa), propget, helpstring("property FlashVars")] + HRESULT FlashVars([out, retval] BSTR* pVal); + [id(0x000000aa), propput, helpstring("property FlashVars")] + HRESULT FlashVars([in] BSTR pVal); + [id(0x000000ab), propget, helpstring("property AllowScriptAccess")] + HRESULT AllowScriptAccess([out, retval] BSTR* pVal); + [id(0x000000ab), propput, helpstring("property AllowScriptAccess")] + HRESULT AllowScriptAccess([in] BSTR pVal); + [id(0x000000be), propget, helpstring("property MovieData")] + HRESULT MovieData([out, retval] BSTR* pVal); + [id(0x000000be), propput, helpstring("property MovieData")] + HRESULT MovieData([in] BSTR pVal); + [id(0x000000bf), propget, helpstring("property inline-data")] + HRESULT InlineData([out, retval] IUnknown** ppIUnknown); + [id(0x000000bf), propput, helpstring("property inline-data")] + HRESULT InlineData([in] IUnknown* ppIUnknown); + [id(0x000000c0), propget, helpstring("property SeamlessTabbing")] + HRESULT SeamlessTabbing([out, retval] VARIANT_BOOL* pVal); + [id(0x000000c0), propput, helpstring("property SeamlessTabbing")] + HRESULT SeamlessTabbing([in] VARIANT_BOOL pVal); + [id(0x000000c1), helpstring("method EnforceLocalSecurity")] + HRESULT EnforceLocalSecurity(); + [id(0x000000c2), propget, helpstring("property Profile")] + HRESULT Profile([out, retval] VARIANT_BOOL* pVal); + [id(0x000000c2), propput, helpstring("property Profile")] + HRESULT Profile([in] VARIANT_BOOL pVal); + [id(0x000000c3), propget, helpstring("property ProfileAddress")] + HRESULT ProfileAddress([out, retval] BSTR* pVal); + [id(0x000000c3), propput, helpstring("property ProfileAddress")] + HRESULT ProfileAddress([in] BSTR pVal); + [id(0x000000c4), propget, helpstring("property ProfilePort")] + HRESULT ProfilePort([out, retval] long* pVal); + [id(0x000000c4), propput, helpstring("property ProfilePort")] + HRESULT ProfilePort([in] long pVal); + [id(0x000000c6), helpstring("method Call")] + HRESULT CallFunction( + [in] BSTR request, + [out, retval] BSTR* response); + [id(0x000000c7), helpstring("method SetReturnValue")] + HRESULT SetReturnValue([in] BSTR returnValue); + [id(0x000000c8), helpstring("method DisableLocalSecurity")] + HRESULT DisableLocalSecurity(); + [id(0x000000c9), propget, helpstring("property AllowNetworking")] + HRESULT AllowNetworking([out, retval] BSTR* pVal); + [id(0x000000c9), propput, helpstring("property AllowNetworking")] + HRESULT AllowNetworking([in] BSTR pVal); + [id(0x000000ca), propget, helpstring("property AllowFullScreen")] + HRESULT AllowFullScreen([out, retval] BSTR* pVal); + [id(0x000000ca), propput, helpstring("property AllowFullScreen")] + HRESULT AllowFullScreen([in] BSTR pVal); + }; + + [ + uuid(D27CDB6D-AE6D-11CF-96B8-444553540000), + helpstring("Event interface for Shockwave Flash"), + hidden + ] + dispinterface _IShockwaveFlashEvents { + properties: + methods: + [id(0xfffffd9f)] + void OnReadyStateChange(long newState); + [id(0x000007a6)] + void OnProgress(long percentDone); + [id(0x00000096)] + void FSCommand( + [in] BSTR command, + [in] BSTR args); + [id(0x000000c5)] + void FlashCall([in] BSTR request); + }; + + [ + uuid(D27CDB6E-AE6D-11CF-96B8-444553540000), + helpstring("Shockwave Flash") + ] + coclass ShockwaveFlash { + [default] interface IShockwaveFlash; + [default, source] dispinterface _IShockwaveFlashEvents; + }; + + [ + odl, + uuid(D27CDB70-AE6D-11CF-96B8-444553540000), + helpstring("IFlashFactory Interface") + ] + interface IFlashFactory : IUnknown { + }; + + [ + odl, + uuid(D27CDB72-AE6D-11CF-96B8-444553540000), + helpstring("IFlashObjectInterface Interface") + ] + interface IFlashObjectInterface : IDispatchEx { + }; + + [ + odl, + uuid(A6EF9860-C720-11D0-9337-00A0C90DCAA9) + ] + interface IDispatchEx : IDispatch { + HRESULT _stdcall GetDispID( + [in] BSTR bstrName, + [in] unsigned long grfdex, + [out] long* pid); + HRESULT _stdcall RemoteInvokeEx( + [in] long id, + [in] unsigned long lcid, + [in] unsigned long dwFlags, + [in] DISPPARAMS* pdp, + [out] VARIANT* pvarRes, + [out] EXCEPINFO* pei, + [in] IServiceProvider* pspCaller, + [in] unsigned int cvarRefArg, + [in] unsigned int* rgiRefArg, + [in, out] VARIANT* rgvarRefArg); + HRESULT _stdcall DeleteMemberByName( + [in] BSTR bstrName, + [in] unsigned long grfdex); + HRESULT _stdcall DeleteMemberByDispID([in] long id); + HRESULT _stdcall GetMemberProperties( + [in] long id, + [in] unsigned long grfdexFetch, + [out] unsigned long* pgrfdex); + HRESULT _stdcall GetMemberName( + [in] long id, + [out] BSTR* pbstrName); + HRESULT _stdcall GetNextDispID( + [in] unsigned long grfdex, + [in] long id, + [out] long* pid); + HRESULT _stdcall GetNameSpaceParent([out] IUnknown** ppunk); + }; + + [ + odl, + uuid(6D5140C1-7436-11CE-8034-00AA006009FA) + ] + interface IServiceProvider : IUnknown { + HRESULT _stdcall RemoteQueryService( + [in] GUID* guidService, + [in] GUID* riid, + [out] IUnknown** ppvObject); + }; + + [ + uuid(D27CDB71-AE6D-11CF-96B8-444553540000), + helpstring("IFlashObjectInterface Interface") + ] + coclass FlashObjectInterface { + [default] interface IFlashObjectInterface; + }; +}; diff --git a/core/producer/flash/Flash9e_i.c b/core/producer/flash/Flash9e_i.c new file mode 100644 index 000000000..3cc610ec3 --- /dev/null +++ b/core/producer/flash/Flash9e_i.c @@ -0,0 +1,103 @@ + + +/* this ALWAYS GENERATED file contains the IIDs and CLSIDs */ + +/* link this file in with the server and any clients */ + + + /* File created by MIDL compiler version 6.00.0366 */ +/* at Tue Mar 18 13:05:00 2008 + */ +/* Compiler settings for .\flash\Flash9e.IDL: + Oicf, W4, Zp8, env=Win32 (32b run) + protocol : dce , ms_ext, c_ext, robust + error checks: allocation ref bounds_check enum stub_data + VC __declspec() decoration level: + __declspec(uuid()), __declspec(selectany), __declspec(novtable) + DECLSPEC_UUID(), MIDL_INTERFACE() +*/ +//@@MIDL_FILE_HEADING( ) + +#pragma warning( disable: 4049 ) /* more than 64k source lines */ + + +#ifdef __cplusplus +extern "C"{ +#endif + + +#include +#include + +#ifdef _MIDL_USE_GUIDDEF_ + +#ifndef INITGUID +#define INITGUID +#include +#undef INITGUID +#else +#include +#endif + +#define MIDL_DEFINE_GUID(type,name,l,w1,w2,b1,b2,b3,b4,b5,b6,b7,b8) \ + DEFINE_GUID(name,l,w1,w2,b1,b2,b3,b4,b5,b6,b7,b8) + +#else // !_MIDL_USE_GUIDDEF_ + +#ifndef __IID_DEFINED__ +#define __IID_DEFINED__ + +typedef struct _IID +{ + unsigned long x; + unsigned short s1; + unsigned short s2; + unsigned char c[8]; +} IID; + +#endif // __IID_DEFINED__ + +#ifndef CLSID_DEFINED +#define CLSID_DEFINED +typedef IID CLSID; +#endif // CLSID_DEFINED + +#define MIDL_DEFINE_GUID(type,name,l,w1,w2,b1,b2,b3,b4,b5,b6,b7,b8) \ + const type name = {l,w1,w2,{b1,b2,b3,b4,b5,b6,b7,b8}} + +#endif !_MIDL_USE_GUIDDEF_ + +MIDL_DEFINE_GUID(IID, LIBID_ShockwaveFlashObjects,0xD27CDB6B,0xAE6D,0x11CF,0x96,0xB8,0x44,0x45,0x53,0x54,0x00,0x00); + + +MIDL_DEFINE_GUID(IID, IID_IShockwaveFlash,0xD27CDB6C,0xAE6D,0x11CF,0x96,0xB8,0x44,0x45,0x53,0x54,0x00,0x00); + + +MIDL_DEFINE_GUID(IID, DIID__IShockwaveFlashEvents,0xD27CDB6D,0xAE6D,0x11CF,0x96,0xB8,0x44,0x45,0x53,0x54,0x00,0x00); + + +MIDL_DEFINE_GUID(IID, IID_IFlashFactory,0xD27CDB70,0xAE6D,0x11CF,0x96,0xB8,0x44,0x45,0x53,0x54,0x00,0x00); + + +MIDL_DEFINE_GUID(IID, IID_IDispatchEx,0xA6EF9860,0xC720,0x11D0,0x93,0x37,0x00,0xA0,0xC9,0x0D,0xCA,0xA9); + + +MIDL_DEFINE_GUID(IID, IID_IFlashObjectInterface,0xD27CDB72,0xAE6D,0x11CF,0x96,0xB8,0x44,0x45,0x53,0x54,0x00,0x00); + + +MIDL_DEFINE_GUID(IID, IID_IServiceProvider,0x6D5140C1,0x7436,0x11CE,0x80,0x34,0x00,0xAA,0x00,0x60,0x09,0xFA); + + +MIDL_DEFINE_GUID(CLSID, CLSID_ShockwaveFlash,0xD27CDB6E,0xAE6D,0x11CF,0x96,0xB8,0x44,0x45,0x53,0x54,0x00,0x00); + + +MIDL_DEFINE_GUID(CLSID, CLSID_FlashObjectInterface,0xD27CDB71,0xAE6D,0x11CF,0x96,0xB8,0x44,0x45,0x53,0x54,0x00,0x00); + +#undef MIDL_DEFINE_GUID + +#ifdef __cplusplus +} +#endif + + + diff --git a/core/producer/flash/FlashAxContainer.cpp b/core/producer/flash/FlashAxContainer.cpp new file mode 100644 index 000000000..c8b0bb162 --- /dev/null +++ b/core/producer/flash/FlashAxContainer.cpp @@ -0,0 +1,902 @@ +/* +* copyright (c) 2010 Sveriges Television AB +* +* This file is part of CasparCG. +* +* CasparCG is free software: you can redistribute it and/or modify +* it under the terms of the GNU General Public License as published by +* the Free Software Foundation, either version 3 of the License, or +* (at your option) any later version. +* +* CasparCG is distributed in the hope that it will be useful, +* but WITHOUT ANY WARRANTY; without even the implied warranty of +* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +* GNU General Public License for more details. + +* You should have received a copy of the GNU General Public License +* along with CasparCG. If not, see . +* +*/ + +#include "..\..\stdafx.h" + +#include "FlashAxContainer.h" +#include "..\..\frame\frame_format.h" +#include "..\..\protocol\monitor\Monitor.h" +#include "flash_producer.h" +#include "TimerHelper.h" + +using namespace ATL; + +#if defined(_MSC_VER) +#pragma warning (push, 1) // TODO: Legacy code, just disable warnings +#endif + +namespace caspar { +namespace flash { + +CComBSTR FlashAxContainer::flashGUID_(_T("{D27CDB6E-AE6D-11CF-96B8-444553540000}")); + +_ATL_FUNC_INFO fnInfoFlashCallEvent = { CC_STDCALL, VT_EMPTY, 1, { VT_BSTR } }; +_ATL_FUNC_INFO fnInfoReadyStateChangeEvent = { CC_STDCALL, VT_EMPTY, 1, { VT_I4 } }; + +FlashAxContainer::FlashAxContainer() : pflash_producer_(0), bInPlaceActive_(FALSE), pTimerHelper(0), lastTime_(0) +{ + bInvalidRect_ = false; + bCallSuccessful_ = false; + bReadyToRender_ = false; + bIsEmpty_ = false; + bHasNewTiming_ = false; +} +FlashAxContainer::~FlashAxContainer() +{ +// ReleaseAll(); + if(pTimerHelper != 0) + delete pTimerHelper; + + CASPAR_LOG(info) << "[FlashAxContainer] Destroyed"; +} + + +/////////////////// +// IObjectWithSite +/////////////////// +HRESULT STDMETHODCALLTYPE FlashAxContainer::SetSite(IUnknown* pUnkSite) +{ + ATLTRACE(_T("IObjectWithSite::SetSite\n")); + HRESULT hr = IObjectWithSiteImpl::SetSite(pUnkSite); + + if (SUCCEEDED(hr) && m_spUnkSite) + { + // Look for "outer" IServiceProvider + hr = m_spUnkSite->QueryInterface(__uuidof(IServiceProvider), (void**)&m_spServices); + ATLASSERT( !hr && _T("No ServiceProvider!") ); + } + + if (pUnkSite == NULL) + m_spServices.Release(); + + return hr; +} + +/////////////////// +// IOleClientSite +/////////////////// +HRESULT STDMETHODCALLTYPE FlashAxContainer::SaveObject() +{ + ATLTRACENOTIMPL(_T("IOleClientSite::SaveObject")); +} + +HRESULT STDMETHODCALLTYPE FlashAxContainer::GetMoniker(DWORD dwAssign, DWORD dwWhichMoniker, IMoniker** ppmk) +{ +/* if(*ppmk != NULL) { + if(m_spMyMoniker == NULL) { + ATL::CComObject* pMoniker = NULL; + HRESULT hr = ATL::CComObject::CreateInstance(&pMoniker); + if(SUCCEEDED(hr)) + m_spMyMoniker = pMoniker; + } + + if(m_spMyMoniker != NULL) { + *ppmk = m_spMyMoniker; + (*ppmk)->AddRef(); + return S_OK; + } + } +*/ if(ppmk != NULL) + *ppmk = NULL; + return E_FAIL; +} + +HRESULT STDMETHODCALLTYPE FlashAxContainer::GetContainer(IOleContainer** ppContainer) +{ + ATLTRACE(_T("IOleClientSite::GetContainer\n")); + (*ppContainer) = NULL; + return E_NOINTERFACE; +} + +HRESULT STDMETHODCALLTYPE FlashAxContainer::ShowObject() +{ + ATLTRACE(_T("IOleClientSite::ShowObject\n")); + return S_OK; +} + +HRESULT STDMETHODCALLTYPE FlashAxContainer::OnShowWindow(BOOL fShow) +{ + ATLTRACE(_T("IOleClientSite::OnShowWindow")); + return S_OK; +} + +HRESULT STDMETHODCALLTYPE FlashAxContainer::RequestNewObjectLayout() +{ + ATLTRACE(_T("IOleClientSite::RequestNewObjectLayout")); + return S_OK; +} + +/////////////////// +// IOleInPlaceSite +/////////////////// +HRESULT STDMETHODCALLTYPE FlashAxContainer::GetWindow(HWND* pHwnd) +{ + ATLTRACE(_T("IOleInPlaceSite::GetWindow\n")); + (*pHwnd) = NULL;//GetApplication()->GetMainWindow()->getHwnd(); + return E_FAIL; +} +HRESULT STDMETHODCALLTYPE FlashAxContainer::ContextSensitiveHelp(BOOL fEnterMode) +{ + ATLTRACE(_T("IOleInPlaceSite::ContextSensitiveHelp")); + return S_OK; +} + +HRESULT STDMETHODCALLTYPE FlashAxContainer::CanInPlaceActivate() +{ + ATLTRACE(_T("IOleInPlaceSite::CanInPlaceActivate\n")); + return S_OK; +} + +HRESULT STDMETHODCALLTYPE FlashAxContainer::OnInPlaceActivate() +{ + ATLTRACE(_T("IOleInPlaceSite::OnInPlaceActivate")); + return S_OK; +} + +HRESULT STDMETHODCALLTYPE FlashAxContainer::OnUIActivate() +{ + ATLTRACE(_T("IOleInPlaceSite::OnUIActivate\n")); + bUIActive_ = TRUE; + return S_OK; +} + +HRESULT STDMETHODCALLTYPE FlashAxContainer::GetWindowContext(IOleInPlaceFrame** ppFrame, IOleInPlaceUIWindow** ppDoc, LPRECT lprcPosRect, LPRECT lprcClipRect, LPOLEINPLACEFRAMEINFO pFrameInfo) +{ + ATLTRACE(_T("IOleInPlaceSite::GetWindowContext\n")); + if (ppFrame != NULL) + *ppFrame = NULL; + if (ppDoc != NULL) + *ppDoc = NULL; + + if (ppFrame == NULL || ppDoc == NULL || lprcPosRect == NULL || lprcClipRect == NULL) + return E_POINTER; + + pFrameInfo->fMDIApp = FALSE; + pFrameInfo->haccel = NULL; + pFrameInfo->cAccelEntries = 0; + pFrameInfo->hwndFrame = NULL; + + lprcPosRect->top = m_rcPos.top; + lprcPosRect->left = m_rcPos.left; + lprcPosRect->right = m_rcPos.right; + lprcPosRect->bottom = m_rcPos.bottom; + + lprcClipRect->top = m_rcPos.top; + lprcClipRect->left = m_rcPos.left; + lprcClipRect->right = m_rcPos.right; + lprcClipRect->bottom = m_rcPos.bottom; + + return S_OK; +} + +HRESULT STDMETHODCALLTYPE FlashAxContainer::Scroll(SIZE scrollExtant) +{ + ATLTRACE(_T("IOleInPlaceSite::Scroll")); + return S_OK; +} + +HRESULT STDMETHODCALLTYPE FlashAxContainer::OnUIDeactivate(BOOL fUndoable) +{ + ATLTRACE(_T("IOleInPlaceSite::OnUIDeactivate\n")); + bUIActive_ = FALSE; + return S_OK; +} + +HRESULT STDMETHODCALLTYPE FlashAxContainer::OnInPlaceDeactivate() +{ + ATLTRACE(_T("IOleInPlaceSite::OnInPlaceDeactivate\n")); + bInPlaceActive_ = FALSE; + m_spInPlaceObjectWindowless.Release(); + return S_OK; +} + +HRESULT STDMETHODCALLTYPE FlashAxContainer::DiscardUndoState() +{ + ATLTRACE(_T("IOleInPlaceSite::DiscardUndoState")); + return S_OK; +} + +HRESULT STDMETHODCALLTYPE FlashAxContainer::DeactivateAndUndo() +{ + ATLTRACE(_T("IOleInPlaceSite::DeactivateAndUndo")); + return S_OK; +} + +HRESULT STDMETHODCALLTYPE FlashAxContainer::OnPosRectChange(LPCRECT lprcPosRect) +{ + ATLTRACE(_T("IOleInPlaceSite::OnPosRectChange")); + return S_OK; +} + + +///////////////////// +// IOleInPlaceSiteEx +///////////////////// +HRESULT STDMETHODCALLTYPE FlashAxContainer::OnInPlaceActivateEx(BOOL* pfNoRedraw, DWORD dwFlags) +{ + // should only be called once the first time control is inplace-activated + ATLTRACE(_T("IOleInPlaceSiteEx::OnInPlaceActivateEx\n")); + ATLASSERT(bInPlaceActive_ == FALSE); + ATLASSERT(m_spInPlaceObjectWindowless == NULL); + + bInPlaceActive_ = TRUE; + OleLockRunning(m_spOleObject, TRUE, FALSE); + HRESULT hr = E_FAIL; + if (dwFlags & ACTIVATE_WINDOWLESS) + { + hr = m_spOleObject->QueryInterface(__uuidof(IOleInPlaceObjectWindowless), (void**) &m_spInPlaceObjectWindowless); + + if (m_spInPlaceObjectWindowless != NULL) + m_spInPlaceObjectWindowless->SetObjectRects(&m_rcPos, &m_rcPos); + } + + return (m_spInPlaceObjectWindowless != NULL) ? S_OK : E_FAIL; +} + +HRESULT STDMETHODCALLTYPE FlashAxContainer::OnInPlaceDeactivateEx(BOOL fNoRedraw) +{ + ATLTRACE(_T("IOleInPlaceSiteEx::OnInPlaceDeactivateEx\n")); + bInPlaceActive_ = FALSE; + m_spInPlaceObjectWindowless.Release(); + return S_OK; +} + +HRESULT STDMETHODCALLTYPE FlashAxContainer::RequestUIActivate() +{ + ATLTRACE(_T("IOleInPlaceSiteEx::RequestUIActivate\n")); + return S_OK; +} + + +///////////////////////////// +// IOleInPlaceSiteWindowless +///////////////////////////// +HRESULT STDMETHODCALLTYPE FlashAxContainer::CanWindowlessActivate() +{ + ATLTRACE(_T("IOleInPlaceSiteWindowless::CanWindowlessActivate\n")); + return S_OK; +// return S_FALSE; +} + +HRESULT STDMETHODCALLTYPE FlashAxContainer::GetCapture() +{ + ATLTRACE(_T("IOleInPlaceSiteWindowless::GetCapture\n")); + return bCapture_ ? S_OK : S_FALSE; +} + +HRESULT STDMETHODCALLTYPE FlashAxContainer::SetCapture(BOOL fCapture) +{ + ATLTRACE(_T("IOleInPlaceSiteWindowless::SetCapture\n")); + bCapture_ = fCapture; + return S_OK; +} + +HRESULT STDMETHODCALLTYPE FlashAxContainer::GetFocus() +{ + ATLTRACE(_T("IOleInPlaceSiteWindowless::GetFocus\n")); + return bHaveFocus_ ? S_OK : S_FALSE; +} + +HRESULT STDMETHODCALLTYPE FlashAxContainer::SetFocus(BOOL fGotFocus) +{ + ATLTRACE(_T("IOleInPlaceSiteWindowless::SetFocus\n")); + bHaveFocus_ = fGotFocus; + return S_OK; +} + +HRESULT STDMETHODCALLTYPE FlashAxContainer::GetDC(LPCRECT pRect, DWORD grfFlags, HDC* phDC) +{ + ATLTRACE(_T("IOleInPlaceSiteWindowless::GetDC")); + return S_OK; +} + +HRESULT STDMETHODCALLTYPE FlashAxContainer::ReleaseDC(HDC hDC) +{ + ATLTRACE(_T("IOleInPlaceSiteWindowless::ReleaseDC")); + return S_OK; +} + +HRESULT STDMETHODCALLTYPE FlashAxContainer::InvalidateRect(LPCRECT pRect, BOOL fErase) +{ +// ATLTRACE(_T("IOleInPlaceSiteWindowless::InvalidateRect\n")); + + bInvalidRect_ = true; + +/* //Keep a list of dirty rectangles in order to be able to redraw only them + if(pRect != NULL) { + bDirtyRects_.push_back(DirtyRect(*pRect, fErase != 0)); + } + else { + bDirtyRects_.push_back(DirtyRect(true)); + } +*/ return S_OK; +} + +HRESULT STDMETHODCALLTYPE FlashAxContainer::InvalidateRgn(HRGN hRGN, BOOL fErase) +{ + ATLTRACE(_T("IOleInPlaceSiteWindowless::InvalidateRng\n")); + return S_OK; +} + +HRESULT STDMETHODCALLTYPE FlashAxContainer::ScrollRect(INT dx, INT dy, LPCRECT pRectScroll, LPCRECT pRectClip) +{ + ATLTRACE(_T("IOleInPlaceSiteWindowless::ScrollRect")); + return S_OK; +} + +HRESULT STDMETHODCALLTYPE FlashAxContainer::AdjustRect(LPRECT prc) +{ + ATLTRACE(_T("IOleInPlaceSiteWindowless::AdjustRect")); + return S_OK; +} + +HRESULT STDMETHODCALLTYPE FlashAxContainer::OnDefWindowMessage(UINT msg, WPARAM wParam, LPARAM lParam, LRESULT* plResult) +{ + ATLTRACE(_T("IOleInPlaceSiteWindowless::OnDefWindowMessage")); + return S_OK; +} + +/////////////////// +// IOleControlSite +/////////////////// +HRESULT STDMETHODCALLTYPE FlashAxContainer::OnControlInfoChanged() +{ + ATLTRACE(_T("IOleControlSite::OnControlInfoChanged")); + return S_OK; +} + +HRESULT STDMETHODCALLTYPE FlashAxContainer::LockInPlaceActive(BOOL fLock) +{ + ATLTRACE(_T("IOleControlSite::LockInPlaceActive")); + return S_OK; +} + +HRESULT STDMETHODCALLTYPE FlashAxContainer::GetExtendedControl(IDispatch** ppDisp) +{ + ATLTRACE(_T("IOleControlSite::GetExtendedControl")); + + if (ppDisp == NULL) + return E_POINTER; + return m_spOleObject.QueryInterface(ppDisp); +} + +HRESULT STDMETHODCALLTYPE FlashAxContainer::TransformCoords(POINTL* pPtlHimetric, POINTF* pPtfContainer, DWORD dwFlags) +{ + ATLTRACE(_T("IOleControlSite::TransformCoords")); + return S_OK; +} + +HRESULT STDMETHODCALLTYPE FlashAxContainer::TranslateAccelerator(LPMSG lpMsg, DWORD grfModifiers) +{ + ATLTRACE(_T("IOleControlSite::TranslateAccelerator")); + return S_FALSE; +} + +HRESULT STDMETHODCALLTYPE FlashAxContainer::OnFocus(BOOL fGotFocus) +{ + bHaveFocus_ = fGotFocus; + return S_OK; +} + +HRESULT STDMETHODCALLTYPE FlashAxContainer::ShowPropertyFrame() +{ + ATLTRACE(_T("IOleControlSite::ShowPropertyFrame")); + return S_OK; +} + + +/////////////////// +// IAdviseSink +/////////////////// +void STDMETHODCALLTYPE FlashAxContainer::OnDataChange(FORMATETC* pFormatetc, STGMEDIUM* pStgmed) +{ + ATLTRACE(_T("IAdviseSink::OnDataChange\n")); +} + +void STDMETHODCALLTYPE FlashAxContainer::OnViewChange(DWORD dwAspect, LONG lindex) +{ + ATLTRACE(_T("IAdviseSink::OnViewChange\n")); +} + +void STDMETHODCALLTYPE FlashAxContainer::OnRename(IMoniker* pmk) +{ + ATLTRACE(_T("IAdviseSink::OnRename\n")); +} + +void STDMETHODCALLTYPE FlashAxContainer::OnSave() +{ + ATLTRACE(_T("IAdviseSink::OnSave\n")); +} + +void STDMETHODCALLTYPE FlashAxContainer::OnClose() +{ + ATLTRACE(_T("IAdviseSink::OnClose\n")); +} + + +/////////////////// +// IServiceProvider +/////////////////// +HRESULT STDMETHODCALLTYPE FlashAxContainer::QueryService( REFGUID rsid, REFIID riid, void** ppvObj) +{ +// ATLTRACE(_T("IServiceProvider::QueryService\n")); + //the flashcontrol asks for an interface {618F8AD4-8B7A-11D0-8FCC-00C04FD9189D}, this is IID for a DirectDraw3 object + + ATLASSERT(ppvObj != NULL); + if (ppvObj == NULL) + return E_POINTER; + *ppvObj = NULL; + + //TODO: The fullscreen-consumer requires that ths does NOT return an ITimerService + HRESULT hr = QueryInterface(riid, ppvObj);//E_NOINTERFACE; + + return hr; +} + + +/////////////////// +// ITimerService +/////////////////// +HRESULT STDMETHODCALLTYPE FlashAxContainer::CreateTimer(ITimer *pReferenceTimer, ITimer **ppNewTimer) +{ + ATLTRACE(_T("ITimerService::CreateTimer\n")); + if(pTimerHelper != 0) + { + delete pTimerHelper; + pTimerHelper = 0; + } + pTimerHelper = new TimerHelper(); + return QueryInterface(__uuidof(ITimer), (void**) ppNewTimer); +} + +HRESULT STDMETHODCALLTYPE FlashAxContainer::GetNamedTimer(REFGUID rguidName, ITimer **ppTimer) +{ + ATLTRACE(_T("ITimerService::GetNamedTimer")); + if(ppTimer == NULL) + return E_POINTER; + else + *ppTimer = NULL; + + return E_FAIL; +} + +HRESULT STDMETHODCALLTYPE FlashAxContainer::SetNamedTimerReference(REFGUID rguidName, ITimer *pReferenceTimer) +{ + ATLTRACE(_T("ITimerService::SetNamedTimerReference")); + return S_OK; +} + +/////////// +// ITimer +/////////// +HRESULT STDMETHODCALLTYPE FlashAxContainer::Advise(VARIANT vtimeMin, VARIANT vtimeMax, VARIANT vtimeInterval, DWORD dwFlags, ITimerSink *pTimerSink, DWORD *pdwCookie) +{ + ATLTRACE(_T("Timer::Advise\n")); + if(pdwCookie == 0) + return E_POINTER; + + if(pTimerHelper != 0) + { + pTimerHelper->Setup(vtimeMin.ulVal, vtimeInterval.ulVal, pTimerSink); + *pdwCookie = pTimerHelper->ID; + bHasNewTiming_ = true; + + return S_OK; + } + else + return E_OUTOFMEMORY; +} + +HRESULT STDMETHODCALLTYPE FlashAxContainer::Unadvise(/* [in] */ DWORD dwCookie) +{ + ATLTRACE(_T("Timer::Unadvice\n")); + if(pTimerHelper != 0) + { + pTimerHelper->pTimerSink = 0; + return S_OK; + } + else + return E_FAIL; +} + +HRESULT STDMETHODCALLTYPE FlashAxContainer::Freeze(/* [in] */ BOOL fFreeze) +{ + ATLTRACE(_T("Timer::Freeze\n")); + return S_OK; +} + +HRESULT STDMETHODCALLTYPE FlashAxContainer::GetTime(/* [out] */ VARIANT *pvtime) +{ + ATLTRACE(_T("Timer::GetTime\n")); + if(pvtime == 0) + return E_POINTER; + +// return E_NOTIMPL; + pvtime->lVal = 0; + return S_OK; +} + +int FlashAxContainer::GetFPS() { + if(pTimerHelper != 0 && pTimerHelper->interval > 0) + return (1000 / pTimerHelper->interval); + + return 0; +} + +bool FlashAxContainer::IsReadyToRender() const { + return bReadyToRender_; +} + +void FlashAxContainer::EnterFullscreen() +{ + if(m_spInPlaceObjectWindowless != 0) + { + HRESULT result; + m_spInPlaceObjectWindowless->OnWindowMessage(WM_LBUTTONDOWN, 0, MAKELPARAM(1, 1), &result); + m_spInPlaceObjectWindowless->OnWindowMessage(WM_LBUTTONUP, 0, MAKELPARAM(1, 1), &result); + } +} + +void STDMETHODCALLTYPE FlashAxContainer::OnFlashCall(BSTR request) +{ + std::wstring str(request); + if(str.find(TEXT("DisplayedTemplate")) != std::wstring::npos) + { + ATLTRACE(_T("ShockwaveFlash::DisplayedTemplate\n")); + bReadyToRender_ = true; + } + else if(str.find(TEXT("OnCommand")) != std::wstring::npos) { + //this is how templatehost 1.8 reports that a command has been received + CASPAR_LOG(info) << "TEMPLATEHOST: " << str; + bCallSuccessful_ = true; + } + else if(str.find(TEXT("Activity")) != std::wstring::npos) + { + CASPAR_LOG(info) << "TEMPLATEHOST: " << str; + + //this is how templatehost 1.7 reports that a command has been received + if(str.find(TEXT("Command recieved")) != std::wstring::npos) + bCallSuccessful_ = true; + + /*if(pflash_producer_ != 0 && pflash_producer_->pMonitor_) { + std::wstring::size_type pos = str.find(TEXT('@')); + if(pos != std::wstring::npos) + pflash_producer_->GetMonitor()->Inform(str.substr(pos, str.find(TEXT('<'), pos)-pos)); + }*/ + } + else if(str.find(TEXT("OnNotify")) != std::wstring::npos) + { + CASPAR_LOG(info) << "TEMPLATEHOST: " << str; + + //if(pflash_producer_ != 0 && pflash_producer_->pMonitor_) { + // std::wstring::size_type pos = str.find(TEXT('@')); + // if(pos != std::wstring::npos) + // pflash_producer_->pMonitor_->Inform(str.substr(pos, str.find(TEXT('<'), pos)-pos)); + //} + } + else if(str.find(TEXT("IsEmpty")) != std::wstring::npos) + { + ATLTRACE(_T("ShockwaveFlash::IsEmpty\n")); + bIsEmpty_ = true; + } + else if(str.find(TEXT("OnError")) != std::wstring::npos) + { + CASPAR_LOG(error) << "FLASHERROR: " << str; + } + + CComPtr spFlash; + HRESULT hr = m_spOleObject->QueryInterface(__uuidof(IShockwaveFlash), (void**) &spFlash); + if(hr == S_OK && spFlash) + { + hr = spFlash->SetReturnValue(TEXT("")); + } +} + +void STDMETHODCALLTYPE FlashAxContainer::OnReadyStateChange(long newState) +{ + if(newState == 4) + { + bReadyToRender_ = true; + } + else + bReadyToRender_ = false; +} + +void FlashAxContainer::DestroyAxControl() +{ + GetControllingUnknown()->AddRef(); + + if ((!m_spViewObject) == false) + m_spViewObject->SetAdvise(DVASPECT_CONTENT, 0, NULL); + + if ((!m_spOleObject) == false) + { + DispEventUnadvise(m_spOleObject, &DIID__IShockwaveFlashEvents); + m_spOleObject->Unadvise(m_dwOleObject); + m_spOleObject->Close(OLECLOSE_NOSAVE); + m_spOleObject->SetClientSite(NULL); + } + + if ((!m_spUnknown) == false) + { + CComPtr spSite; + m_spUnknown->QueryInterface(__uuidof(IObjectWithSite), (void**)&spSite); + if (spSite != NULL) + spSite->SetSite(NULL); + } + + if ((!m_spViewObject) == false) + m_spViewObject.Release(); + + if ((!m_spInPlaceObjectWindowless) == false) + m_spInPlaceObjectWindowless.Release(); + + if ((!m_spOleObject) == false) + m_spOleObject.Release(); + + if ((!m_spUnknown) == false) + m_spUnknown.Release(); +} + +bool FlashAxContainer::CheckForFlashSupport() +{ + CLSID clsid; + return SUCCEEDED(CLSIDFromString((LPOLESTR)flashGUID_, &clsid)); +} + +HRESULT FlashAxContainer::CreateAxControl() +{ + CLSID clsid; + HRESULT hr = CLSIDFromString((LPOLESTR)flashGUID_, &clsid); + if(SUCCEEDED(hr)) + hr = CoCreateInstance(clsid, NULL, CLSCTX_INPROC_SERVER, __uuidof(IUnknown), (void**)&m_spUnknown); + +//Start ActivateAx + if(SUCCEEDED(hr)) + { + m_spUnknown->QueryInterface(__uuidof(IOleObject), (void**)&m_spOleObject); + if(m_spOleObject) + { + m_spOleObject->GetMiscStatus(DVASPECT_CONTENT, &m_dwMiscStatus); + if (m_dwMiscStatus & OLEMISC_SETCLIENTSITEFIRST) + { + CComQIPtr spClientSite(GetControllingUnknown()); + m_spOleObject->SetClientSite(spClientSite); + } + + //Initialize control + CComQIPtr spPSI(m_spOleObject); + if (spPSI) + hr = spPSI->InitNew(); + + if (FAILED(hr)) // If the initialization of the control failed... + { + // Clean up and return + if (m_dwMiscStatus & OLEMISC_SETCLIENTSITEFIRST) + m_spOleObject->SetClientSite(NULL); + + m_dwMiscStatus = 0; + m_spOleObject.Release(); + m_spUnknown.Release(); + + return hr; + } + //end Initialize object + + if (0 == (m_dwMiscStatus & OLEMISC_SETCLIENTSITEFIRST)) + { + CComQIPtr spClientSite(GetControllingUnknown()); + m_spOleObject->SetClientSite(spClientSite); + } + + CComPtr spFlash; + HRESULT hResultQuality; + HRESULT hr2 = m_spOleObject->QueryInterface(__uuidof(IShockwaveFlash), (void**) &spFlash); + if(hr2 == S_OK && spFlash) + { + spFlash->put_WMode(TEXT("Transparent")); + //spFlash->put_WMode(TEXT("GPU")); + hResultQuality = spFlash->put_Quality2(TEXT("Best")); + } + if(SUCCEEDED(DispEventAdvise(spFlash, &DIID__IShockwaveFlashEvents))) + { + } + + HRESULT hrView = m_spOleObject->QueryInterface(__uuidof(IViewObjectEx), (void**) &m_spViewObject); + + CComQIPtr spAdviseSink(GetControllingUnknown()); + m_spOleObject->Advise(spAdviseSink, &m_dwOleObject); + if (m_spViewObject) + m_spViewObject->SetAdvise(DVASPECT_CONTENT, 0, spAdviseSink); + + if ((m_dwMiscStatus & OLEMISC_INVISIBLEATRUNTIME) == 0) + { + //Initialize window to some dummy size + m_rcPos.top = 0; + m_rcPos.left = 0; + m_rcPos.right = 720; + m_rcPos.bottom = 576; + + m_pxSize.cx = m_rcPos.right - m_rcPos.left; + m_pxSize.cy = m_rcPos.bottom - m_rcPos.top; + AtlPixelToHiMetric(&m_pxSize, &m_hmSize); + m_spOleObject->SetExtent(DVASPECT_CONTENT, &m_hmSize); + m_spOleObject->GetExtent(DVASPECT_CONTENT, &m_hmSize); + AtlHiMetricToPixel(&m_hmSize, &m_pxSize); + m_rcPos.right = m_rcPos.left + m_pxSize.cx; + m_rcPos.bottom = m_rcPos.top + m_pxSize.cy; + + CComQIPtr spClientSite(GetControllingUnknown()); + hr = m_spOleObject->DoVerb(OLEIVERB_INPLACEACTIVATE, NULL, spClientSite, 0, NULL, &m_rcPos); + } + } + CComPtr spSite; + m_spUnknown->QueryInterface(__uuidof(IObjectWithSite), (void**)&spSite); + if (spSite != NULL) + spSite->SetSite(GetControllingUnknown()); + } +//End ActivateAx + +// hr = E_FAIL; + if (FAILED(hr) || m_spUnknown == NULL) + { + return E_FAIL; + // We don't have a control or something failed so release +// ReleaseAll(); + } + + return S_OK; +} + +HRESULT FlashAxContainer::SetFormat(const caspar::frame_format_desc& format_desc) +{ + if(m_spInPlaceObjectWindowless == nullptr) + return E_FAIL; + + if(m_rcPos.right != format_desc.width || m_rcPos.bottom != format_desc.height) + { + RECT oldRcPos = m_rcPos; + m_rcPos.top = 0; + m_rcPos.left = 0; + m_rcPos.right = format_desc.width; + m_rcPos.bottom = format_desc.height; + + m_pxSize.cx = m_rcPos.right - m_rcPos.left; + m_pxSize.cy = m_rcPos.bottom - m_rcPos.top; + AtlPixelToHiMetric(&m_pxSize, &m_hmSize); + m_spOleObject->SetExtent(DVASPECT_CONTENT, &m_hmSize); + m_spOleObject->GetExtent(DVASPECT_CONTENT, &m_hmSize); + AtlHiMetricToPixel(&m_hmSize, &m_pxSize); + m_rcPos.right = m_rcPos.left + m_pxSize.cx; + m_rcPos.bottom = m_rcPos.top + m_pxSize.cy; + + HRESULT result = m_spInPlaceObjectWindowless->SetObjectRects(&m_rcPos, &m_rcPos); + bInvalidRect_ = true; + if(FAILED(result)) + m_spInPlaceObjectWindowless->SetObjectRects(&oldRcPos, &oldRcPos); + + return result; + } + + return S_OK; +} + +HRESULT FlashAxContainer::QueryControl(REFIID iid, void** ppUnk) +{ + ATLASSERT(ppUnk != NULL); + if (ppUnk == NULL) + return E_POINTER; + HRESULT hr; + hr = m_spOleObject->QueryInterface(iid, ppUnk); + return hr; +} + +bool FlashAxContainer::DrawControl(HDC targetDC) +{ +// ATLTRACE(_T("FlashAxContainer::DrawControl\n")); + DVASPECTINFO aspectInfo = {sizeof(DVASPECTINFO), DVASPECTINFOFLAG_CANOPTIMIZE}; + HRESULT hr = S_OK; + + hr = m_spViewObject->Draw(DVASPECT_CONTENT, -1, &aspectInfo, NULL, NULL, targetDC, NULL, NULL, NULL, NULL); + assert(SUCCEEDED(hr)); + bInvalidRect_ = false; + +/* const caspar::frame_format_desc& format_desc = caspar::frame_format_desc::format_descs[format_]; + + //Trying to redraw just the dirty rectangles. Doesn't seem to work when the movie uses "filters", such as glow, dropshadow etc. + std::vector::iterator it = bDirtyRects_.begin(); + std::vector::iterator end = bDirtyRects_.end(); + for(; it != end; ++it) { + flash::DirtyRect& dirtyRect = (*it); + if(dirtyRect.bWhole || dirtyRect.rect.right >= format_desc.width || dirtyRect.rect.bottom >= format_desc.height) { + m_spInPlaceObjectWindowless->SetObjectRects(&m_rcPos, &m_rcPos); + hr = m_spViewObject->Draw(DVASPECT_OPAQUE, -1, NULL, NULL, NULL, targetDC, NULL, NULL, NULL, NULL); + break; + } + else { + m_spInPlaceObjectWindowless->SetObjectRects(&m_rcPos, &(dirtyRect.rect)); + hr = m_spViewObject->Draw(DVASPECT_OPAQUE, -1, NULL, NULL, NULL, targetDC, NULL, NULL, NULL, NULL); + } + } + bDirtyRects_.clear(); +*/ + + return (hr == S_OK); +} + +bool FlashAxContainer::InvalidRectangle() const +{ + return bInvalidRect_; +} + +void FlashAxContainer::Tick() +{ + if(pTimerHelper) + { + HRESULT result; + DWORD time = pTimerHelper->Invoke(); // Tick flash + if(time - lastTime_ >= 400) + { + m_spInPlaceObjectWindowless->OnWindowMessage(WM_TIMER, 3, 0, &result); + lastTime_ = time; + } + } +} + +bool FlashAxContainer::CallFunction(const std::wstring& param) +{ + bIsEmpty_ = false; + bCallSuccessful_ = false; + + CComPtr spFlash; + if(SUCCEEDED(QueryControl(&spFlash))) + { + CComBSTR request(param.c_str()); + CComBSTR result; + return SUCCEEDED(spFlash->CallFunction(request, &result)) || bCallSuccessful_; + } + + return false; +} + +bool FlashAxContainer::IsEmpty() const +{ + return bIsEmpty_; +} + +// Receives the following messages: +// 0 0x0000 ? +// 275 0x0113 WM_TIMER +// 536 0x0218 WM_POWERBROADCAST +// 49286 0xC086 ? + + +} //namespace flash +} //namespace caspar \ No newline at end of file diff --git a/core/producer/flash/FlashAxContainer.h b/core/producer/flash/FlashAxContainer.h new file mode 100644 index 000000000..2c1119edc --- /dev/null +++ b/core/producer/flash/FlashAxContainer.h @@ -0,0 +1,294 @@ +/* +* copyright (c) 2010 Sveriges Television AB +* +* This file is part of CasparCG. +* +* CasparCG is free software: you can redistribute it and/or modify +* it under the terms of the GNU General Public License as published by +* the Free Software Foundation, either version 3 of the License, or +* (at your option) any later version. +* +* CasparCG is distributed in the hope that it will be useful, +* but WITHOUT ANY WARRANTY; without even the implied warranty of +* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +* GNU General Public License for more details. + +* You should have received a copy of the GNU General Public License +* along with CasparCG. If not, see . +* +*/ + +#if defined(_MSC_VER) +#pragma once +#endif + +#ifndef _FLASHAXCONTAINER_H__ +#define _FLASHAXCONTAINER_H__ + +#pragma warning(push) +#pragma warning(disable : 4996) + + #include + + #include + #include + +#pragma warning(push) + +#include "..\..\frame\frame.h" + +#include +#include +#include + +#include "axflash.h" +//#import "progid:ShockwaveFlash.ShockwaveFlash.9" no_namespace, named_guids + +namespace caspar { namespace flash { + +class flash_producer; + +class TimerHelper; +struct DirtyRect { + DirtyRect(LONG l, LONG t, LONG r, LONG b, bool e) : bErase(e), bWhole(false) { + rect.left = l; + rect.top = t; + rect.right = r; + rect.bottom = b; + } + DirtyRect(const RECT& rc, bool e) : bErase(e), bWhole(false) { + rect.left = rc.left; + rect.top = rc.top; + rect.right = rc.right; + rect.bottom = rc.bottom; + } + explicit DirtyRect(bool b) : bWhole(b) {} + + RECT rect; + bool bErase; + bool bWhole; +}; + +extern _ATL_FUNC_INFO fnInfoFlashCallEvent; +extern _ATL_FUNC_INFO fnInfoReadyStateChangeEvent; + +class ATL_NO_VTABLE FlashAxContainer : + public ATL::CComCoClass, + public ATL::CComObjectRootEx, + public IOleClientSite, + public IOleContainer, + public IOleControlSite, + public IOleInPlaceSiteWindowless, + public IObjectWithSiteImpl, + public IServiceProvider, + public IAdviseSink, + public ITimerService, + public ITimer, + public IDispatchImpl, + public IDispEventSimpleImpl<0, FlashAxContainer, &DIID__IShockwaveFlashEvents> +{ + +public: + + FlashAxContainer(); + virtual ~FlashAxContainer(); + + DECLARE_NO_REGISTRY() + DECLARE_POLY_AGGREGATABLE(FlashAxContainer) + DECLARE_GET_CONTROLLING_UNKNOWN() + + BEGIN_COM_MAP(FlashAxContainer) + COM_INTERFACE_ENTRY(IDispatch) + COM_INTERFACE_ENTRY(IOleClientSite) + COM_INTERFACE_ENTRY(IObjectWithSite) + COM_INTERFACE_ENTRY(IOleControlSite) + COM_INTERFACE_ENTRY(IOleContainer) + + COM_INTERFACE_ENTRY(IOleInPlaceSiteWindowless) + COM_INTERFACE_ENTRY(IOleInPlaceSiteEx) + COM_INTERFACE_ENTRY(IOleInPlaceSite) + COM_INTERFACE_ENTRY(IOleWindow) + + COM_INTERFACE_ENTRY(IServiceProvider) + + COM_INTERFACE_ENTRY(IAdviseSink) + + COM_INTERFACE_ENTRY(ITimerService) + + COM_INTERFACE_ENTRY(ITimer) + END_COM_MAP() + + BEGIN_SINK_MAP(FlashAxContainer) + SINK_ENTRY_INFO(0, DIID__IShockwaveFlashEvents, 0xc5, OnFlashCall, &fnInfoFlashCallEvent) + SINK_ENTRY_INFO(0, DIID__IShockwaveFlashEvents, 0xfffffd9f, OnReadyStateChange, &fnInfoReadyStateChangeEvent) + END_SINK_MAP() + + void STDMETHODCALLTYPE OnFlashCall(BSTR request); + void STDMETHODCALLTYPE OnReadyStateChange(long newState); + +// IObjectWithSite + STDMETHOD(SetSite)(IUnknown* pUnkSite); + +// IOleClientSite + STDMETHOD(SaveObject)(); + STDMETHOD(GetMoniker)(DWORD dwAssign, DWORD dwWhichMoniker, IMoniker** ppmk); + STDMETHOD(GetContainer)(IOleContainer** ppContainer); + STDMETHOD(ShowObject)(); + STDMETHOD(OnShowWindow)(BOOL fShow); + STDMETHOD(RequestNewObjectLayout)(); + +// IOleInPlaceSite + STDMETHOD(GetWindow)(HWND* pHwnd); + STDMETHOD(ContextSensitiveHelp)(BOOL fEnterMode); + STDMETHOD(CanInPlaceActivate)(); + STDMETHOD(OnInPlaceActivate)(); + STDMETHOD(OnInPlaceDeactivate)(); + STDMETHOD(OnUIActivate)(); + STDMETHOD(OnUIDeactivate)(BOOL fUndoable); + STDMETHOD(GetWindowContext)(IOleInPlaceFrame** ppFrame, IOleInPlaceUIWindow** ppDoc, LPRECT lprcPosRect, LPRECT lprcClipRect, LPOLEINPLACEFRAMEINFO pFrameInfo); + STDMETHOD(Scroll)(SIZE scrollExtant); + STDMETHOD(DiscardUndoState)(); + STDMETHOD(DeactivateAndUndo)(); + STDMETHOD(OnPosRectChange)(LPCRECT lprcPosRect); + +// IOleInPlaceSiteEx + STDMETHOD(OnInPlaceActivateEx)(BOOL* pfNoRedraw, DWORD dwFlags); + STDMETHOD(OnInPlaceDeactivateEx)(BOOL fNoRedraw); + STDMETHOD(RequestUIActivate)(); + +// IOleInPlaceSiteWindowless + STDMETHOD(CanWindowlessActivate)(); + STDMETHOD(GetCapture)(); + STDMETHOD(SetCapture)(BOOL fCapture); + STDMETHOD(GetFocus)(); + STDMETHOD(SetFocus)(BOOL fGotFocus); + STDMETHOD(GetDC)(LPCRECT pRect, DWORD grfFlags, HDC* phDC); + STDMETHOD(ReleaseDC)(HDC hDC); + STDMETHOD(InvalidateRect)(LPCRECT pRect, BOOL fErase); + STDMETHOD(InvalidateRgn)(HRGN hRGN, BOOL fErase); + STDMETHOD(ScrollRect)(INT dx, INT dy, LPCRECT pRectScroll, LPCRECT pRectClip); + STDMETHOD(AdjustRect)(LPRECT prc); + STDMETHOD(OnDefWindowMessage)(UINT msg, WPARAM wParam, LPARAM lParam, LRESULT* plResult); + +// IOleControlSite + STDMETHOD(OnControlInfoChanged)(); + STDMETHOD(LockInPlaceActive)(BOOL fLock); + STDMETHOD(GetExtendedControl)(IDispatch** ppDisp); + STDMETHOD(TransformCoords)(POINTL* pPtlHimetric, POINTF* pPtfContainer, DWORD dwFlags); + STDMETHOD(TranslateAccelerator)(LPMSG lpMsg, DWORD grfModifiers); + STDMETHOD(OnFocus)(BOOL fGotFocus); + STDMETHOD(ShowPropertyFrame)(); + +// IAdviseSink + STDMETHOD_(void, OnDataChange)(FORMATETC* pFormatetc, STGMEDIUM* pStgmed); + STDMETHOD_(void, OnViewChange)(DWORD dwAspect, LONG lindex); + STDMETHOD_(void, OnRename)(IMoniker* pmk); + STDMETHOD_(void, OnSave)(); + STDMETHOD_(void, OnClose)(); + +// IServiceProvider + STDMETHOD(QueryService)( REFGUID rsid, REFIID riid, void** ppvObj); + +// IOleContainer + STDMETHOD(ParseDisplayName)(IBindCtx*, LPOLESTR, ULONG*, IMoniker**) + { + ATLTRACENOTIMPL(_T("IOleContainer::ParseDisplayName")); + } + STDMETHOD(EnumObjects)(DWORD, IEnumUnknown** ppenum) + { + if (ppenum == NULL) + return E_POINTER; + *ppenum = NULL; + typedef CComObject > > enumunk; + enumunk* p = NULL; + ATLTRY(p = new enumunk); + if(p == NULL) + return E_OUTOFMEMORY; + IUnknown* pTemp = m_spUnknown; + // There is always only one object. + HRESULT hRes = p->Init(reinterpret_cast(&pTemp), reinterpret_cast(&pTemp + 1), GetControllingUnknown(), AtlFlagCopy); + if (SUCCEEDED(hRes)) + hRes = p->QueryInterface(__uuidof(IEnumUnknown), (void**)ppenum); + if (FAILED(hRes)) + delete p; + return hRes; + } + STDMETHOD(LockContainer)(BOOL) + { + ATLTRACENOTIMPL(_T("IOleContainer::LockContainer")); + } + +//ITimerService + STDMETHOD(CreateTimer)(ITimer *pReferenceTimer, ITimer **ppNewTimer); + STDMETHOD(GetNamedTimer)(REFGUID rguidName, ITimer **ppTimer); + STDMETHOD(SetNamedTimerReference)(REFGUID rguidName, ITimer *pReferenceTimer); + +//ITimer + STDMETHOD(Advise)(VARIANT vtimeMin, VARIANT vtimeMax, VARIANT vtimeInterval, DWORD dwFlags, ITimerSink *pTimerSink, DWORD *pdwCookie); + STDMETHOD(Unadvise)(DWORD dwCookie); + STDMETHOD(Freeze)(BOOL fFreeze); + STDMETHOD(GetTime)(VARIANT *pvtime); + int GetFPS(); + + HRESULT CreateAxControl(); + void DestroyAxControl(); + HRESULT QueryControl(REFIID iid, void** ppUnk); + + template + HRESULT QueryControl(Q** ppUnk) + { + return QueryControl(__uuidof(Q), (void**)ppUnk); + } + + bool InvalidRectangle() const; + void Tick(); + bool CallFunction(const std::wstring& param); + bool IsEmpty() const; + +// static ATL::CComObject* CreateInstance(); + + bool DrawControl(HDC targetDC); + + TimerHelper* pTimerHelper; + tbb::atomic bInvalidRect_; + tbb::atomic bCallSuccessful_; + tbb::atomic bReadyToRender_; + tbb::atomic bIsEmpty_; + tbb::atomic bHasNewTiming_; + flash::flash_producer* pflash_producer_; + std::vector bDirtyRects_; + + HRESULT SetFormat(const caspar::frame_format_desc&); + bool IsReadyToRender() const; + void EnterFullscreen(); + + static bool CheckForFlashSupport(); +private: + static CComBSTR flashGUID_; + + DWORD lastTime_; +// state + bool bUIActive_; + bool bInPlaceActive_; + unsigned long bHaveFocus_ : 1; + unsigned long bCapture_ : 1; + + DWORD m_dwOleObject; + DWORD m_dwMiscStatus; + SIZEL m_hmSize; + SIZEL m_pxSize; + RECT m_rcPos; + + ATL::CComPtr m_spUnknown; + ATL::CComPtr m_spServices; + ATL::CComPtr m_spOleObject; + ATL::CComPtr m_spViewObject; + ATL::CComPtr m_spInPlaceObjectWindowless; + +// ATL::CComPtr > m_spMyMoniker; +}; + +} //namespace flash +} //namespace caspar + +#endif //_FLASHAXCONTAINER_H__ \ No newline at end of file diff --git a/core/producer/flash/TimerHelper.h b/core/producer/flash/TimerHelper.h new file mode 100644 index 000000000..a0de2b19e --- /dev/null +++ b/core/producer/flash/TimerHelper.h @@ -0,0 +1,77 @@ +/* +* copyright (c) 2010 Sveriges Television AB +* +* This file is part of CasparCG. +* +* CasparCG is free software: you can redistribute it and/or modify +* it under the terms of the GNU General Public License as published by +* the Free Software Foundation, either version 3 of the License, or +* (at your option) any later version. +* +* CasparCG is distributed in the hope that it will be useful, +* but WITHOUT ANY WARRANTY; without even the implied warranty of +* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +* GNU General Public License for more details. + +* You should have received a copy of the GNU General Public License +* along with CasparCG. If not, see . +* +*/ + +#ifndef _TIMER_HELPER_H__ +#define _TIMER_HELPER_H__ + +#include "FlashAxContainer.h" + +namespace caspar { +namespace flash { + + class TimerHelper + { + TimerHelper(const TimerHelper&); + const TimerHelper& operator=(const TimerHelper&); + + public: + TimerHelper() + {} + TimerHelper(DWORD first, DWORD interv, ITimerSink* pTS) : firstTime(first), interval(interv), currentTime(first), pTimerSink(pTS) + { + ID = first; + } + ~TimerHelper() + { + } + void Setup(DWORD first, DWORD interv, ITimerSink* pTS) + { + firstTime = first; + interval = interv; + currentTime = first; + pTimerSink = pTS; + ID = first; + } + + DWORD Invoke() + { + if(pTimerSink != 0) + { + VARIANT value; + value.vt = VT_UI4; + value.ulVal = currentTime; + + pTimerSink->OnTimer(value); + currentTime += interval; + } + return currentTime; + } + + DWORD firstTime; + DWORD interval; + DWORD currentTime; + ATL::CComPtr pTimerSink; + DWORD ID; + }; + +} //namespace flash +} //namespace caspar + +#endif //_TIMER_HELPER_H__ \ No newline at end of file diff --git a/core/producer/flash/axflash.h b/core/producer/flash/axflash.h new file mode 100644 index 000000000..4685f3a28 --- /dev/null +++ b/core/producer/flash/axflash.h @@ -0,0 +1,3156 @@ + + +/* this ALWAYS GENERATED file contains the definitions for the interfaces */ + + + /* File created by MIDL compiler version 6.00.0366 */ +/* at Tue Mar 18 13:05:00 2008 + */ +/* Compiler settings for .\flash\Flash9e.IDL: + Oicf, W4, Zp8, env=Win32 (32b run) + protocol : dce , ms_ext, c_ext, robust + error checks: allocation ref bounds_check enum stub_data + VC __declspec() decoration level: + __declspec(uuid()), __declspec(selectany), __declspec(novtable) + DECLSPEC_UUID(), MIDL_INTERFACE() +*/ +//@@MIDL_FILE_HEADING( ) + +#pragma warning( disable: 4049 ) /* more than 64k source lines */ + + +/* verify that the version is high enough to compile this file*/ +#ifndef __REQUIRED_RPCNDR_H_VERSION__ +#define __REQUIRED_RPCNDR_H_VERSION__ 475 +#endif + +#include "rpc.h" +#include "rpcndr.h" +#include + +#ifndef __RPCNDR_H_VERSION__ +#error this stub requires an updated version of +#endif // __RPCNDR_H_VERSION__ + + +#ifndef __axflash_h__ +#define __axflash_h__ + +#if defined(_MSC_VER) && (_MSC_VER >= 1020) +#pragma once +#endif + +/* Forward Declarations */ + +#ifndef __IShockwaveFlash_FWD_DEFINED__ +#define __IShockwaveFlash_FWD_DEFINED__ +typedef interface IShockwaveFlash IShockwaveFlash; +#endif /* __IShockwaveFlash_FWD_DEFINED__ */ + + +#ifndef ___IShockwaveFlashEvents_FWD_DEFINED__ +#define ___IShockwaveFlashEvents_FWD_DEFINED__ +typedef interface _IShockwaveFlashEvents _IShockwaveFlashEvents; +#endif /* ___IShockwaveFlashEvents_FWD_DEFINED__ */ + + +#ifndef __IFlashFactory_FWD_DEFINED__ +#define __IFlashFactory_FWD_DEFINED__ +typedef interface IFlashFactory IFlashFactory; +#endif /* __IFlashFactory_FWD_DEFINED__ */ + + +#ifndef __IDispatchEx_FWD_DEFINED__ +#define __IDispatchEx_FWD_DEFINED__ +typedef interface IDispatchEx IDispatchEx; +#endif /* __IDispatchEx_FWD_DEFINED__ */ + + +#ifndef __IFlashObjectInterface_FWD_DEFINED__ +#define __IFlashObjectInterface_FWD_DEFINED__ +typedef interface IFlashObjectInterface IFlashObjectInterface; +#endif /* __IFlashObjectInterface_FWD_DEFINED__ */ + + +#ifndef __IServiceProvider_FWD_DEFINED__ +#define __IServiceProvider_FWD_DEFINED__ +typedef interface IServiceProvider IServiceProvider; +#endif /* __IServiceProvider_FWD_DEFINED__ */ + + +#ifndef __ShockwaveFlash_FWD_DEFINED__ +#define __ShockwaveFlash_FWD_DEFINED__ + +#ifdef __cplusplus +typedef class ShockwaveFlash ShockwaveFlash; +#else +typedef struct ShockwaveFlash ShockwaveFlash; +#endif /* __cplusplus */ + +#endif /* __ShockwaveFlash_FWD_DEFINED__ */ + + +#ifndef __FlashObjectInterface_FWD_DEFINED__ +#define __FlashObjectInterface_FWD_DEFINED__ + +#ifdef __cplusplus +typedef class FlashObjectInterface FlashObjectInterface; +#else +typedef struct FlashObjectInterface FlashObjectInterface; +#endif /* __cplusplus */ + +#endif /* __FlashObjectInterface_FWD_DEFINED__ */ + + +#ifdef __cplusplus +extern "C"{ +#endif + +void * __RPC_USER MIDL_user_allocate(size_t); +void __RPC_USER MIDL_user_free( void * ); + + +#ifndef __ShockwaveFlashObjects_LIBRARY_DEFINED__ +#define __ShockwaveFlashObjects_LIBRARY_DEFINED__ + +/* library ShockwaveFlashObjects */ +/* [custom][custom][helpstring][version][uuid] */ + + + + + + + + +EXTERN_C const IID LIBID_ShockwaveFlashObjects; + +#ifndef __IShockwaveFlash_INTERFACE_DEFINED__ +#define __IShockwaveFlash_INTERFACE_DEFINED__ + +/* interface IShockwaveFlash */ +/* [object][oleautomation][dual][helpstring][uuid] */ + + +EXTERN_C const IID IID_IShockwaveFlash; + +#if defined(__cplusplus) && !defined(CINTERFACE) + + MIDL_INTERFACE("D27CDB6C-AE6D-11CF-96B8-444553540000") + IShockwaveFlash : public IDispatch + { + public: + virtual /* [helpstring][propget][id] */ HRESULT STDMETHODCALLTYPE get_ReadyState( + /* [retval][out] */ long *pVal) = 0; + + virtual /* [helpstring][propget][id] */ HRESULT STDMETHODCALLTYPE get_TotalFrames( + /* [retval][out] */ long *pVal) = 0; + + virtual /* [helpstring][propget][id] */ HRESULT STDMETHODCALLTYPE get_Playing( + /* [retval][out] */ VARIANT_BOOL *pVal) = 0; + + virtual /* [helpstring][propput][id] */ HRESULT STDMETHODCALLTYPE put_Playing( + /* [in] */ VARIANT_BOOL pVal) = 0; + + virtual /* [helpstring][propget][id] */ HRESULT STDMETHODCALLTYPE get_Quality( + /* [retval][out] */ int *pVal) = 0; + + virtual /* [helpstring][propput][id] */ HRESULT STDMETHODCALLTYPE put_Quality( + /* [in] */ int pVal) = 0; + + virtual /* [helpstring][propget][id] */ HRESULT STDMETHODCALLTYPE get_ScaleMode( + /* [retval][out] */ int *pVal) = 0; + + virtual /* [helpstring][propput][id] */ HRESULT STDMETHODCALLTYPE put_ScaleMode( + /* [in] */ int pVal) = 0; + + virtual /* [helpstring][propget][id] */ HRESULT STDMETHODCALLTYPE get_AlignMode( + /* [retval][out] */ int *pVal) = 0; + + virtual /* [helpstring][propput][id] */ HRESULT STDMETHODCALLTYPE put_AlignMode( + /* [in] */ int pVal) = 0; + + virtual /* [helpstring][propget][id] */ HRESULT STDMETHODCALLTYPE get_BackgroundColor( + /* [retval][out] */ long *pVal) = 0; + + virtual /* [helpstring][propput][id] */ HRESULT STDMETHODCALLTYPE put_BackgroundColor( + /* [in] */ long pVal) = 0; + + virtual /* [helpstring][propget][id] */ HRESULT STDMETHODCALLTYPE get_Loop( + /* [retval][out] */ VARIANT_BOOL *pVal) = 0; + + virtual /* [helpstring][propput][id] */ HRESULT STDMETHODCALLTYPE put_Loop( + /* [in] */ VARIANT_BOOL pVal) = 0; + + virtual /* [helpstring][propget][id] */ HRESULT STDMETHODCALLTYPE get_Movie( + /* [retval][out] */ BSTR *pVal) = 0; + + virtual /* [helpstring][propput][id] */ HRESULT STDMETHODCALLTYPE put_Movie( + /* [in] */ BSTR pVal) = 0; + + virtual /* [helpstring][propget][id] */ HRESULT STDMETHODCALLTYPE get_FrameNum( + /* [retval][out] */ long *pVal) = 0; + + virtual /* [helpstring][propput][id] */ HRESULT STDMETHODCALLTYPE put_FrameNum( + /* [in] */ long pVal) = 0; + + virtual /* [helpstring][id] */ HRESULT STDMETHODCALLTYPE SetZoomRect( + /* [in] */ long left, + /* [in] */ long top, + /* [in] */ long right, + /* [in] */ long bottom) = 0; + + virtual /* [helpstring][id] */ HRESULT STDMETHODCALLTYPE Zoom( + /* [in] */ int factor) = 0; + + virtual /* [helpstring][id] */ HRESULT STDMETHODCALLTYPE Pan( + /* [in] */ long x, + /* [in] */ long y, + /* [in] */ int mode) = 0; + + virtual /* [helpstring][id] */ HRESULT STDMETHODCALLTYPE Play( void) = 0; + + virtual /* [helpstring][id] */ HRESULT STDMETHODCALLTYPE Stop( void) = 0; + + virtual /* [helpstring][id] */ HRESULT STDMETHODCALLTYPE Back( void) = 0; + + virtual /* [helpstring][id] */ HRESULT STDMETHODCALLTYPE Forward( void) = 0; + + virtual /* [helpstring][id] */ HRESULT STDMETHODCALLTYPE Rewind( void) = 0; + + virtual /* [helpstring][id] */ HRESULT STDMETHODCALLTYPE StopPlay( void) = 0; + + virtual /* [helpstring][id] */ HRESULT STDMETHODCALLTYPE GotoFrame( + /* [in] */ long FrameNum) = 0; + + virtual /* [helpstring][id] */ HRESULT STDMETHODCALLTYPE CurrentFrame( + /* [retval][out] */ long *FrameNum) = 0; + + virtual /* [helpstring][id] */ HRESULT STDMETHODCALLTYPE IsPlaying( + /* [retval][out] */ VARIANT_BOOL *Playing) = 0; + + virtual /* [helpstring][id] */ HRESULT STDMETHODCALLTYPE PercentLoaded( + /* [retval][out] */ long *percent) = 0; + + virtual /* [helpstring][id] */ HRESULT STDMETHODCALLTYPE FrameLoaded( + /* [in] */ long FrameNum, + /* [retval][out] */ VARIANT_BOOL *loaded) = 0; + + virtual /* [helpstring][id] */ HRESULT STDMETHODCALLTYPE FlashVersion( + /* [retval][out] */ long *version) = 0; + + virtual /* [helpstring][propget][id] */ HRESULT STDMETHODCALLTYPE get_WMode( + /* [retval][out] */ BSTR *pVal) = 0; + + virtual /* [helpstring][propput][id] */ HRESULT STDMETHODCALLTYPE put_WMode( + /* [in] */ BSTR pVal) = 0; + + virtual /* [helpstring][propget][id] */ HRESULT STDMETHODCALLTYPE get_SAlign( + /* [retval][out] */ BSTR *pVal) = 0; + + virtual /* [helpstring][propput][id] */ HRESULT STDMETHODCALLTYPE put_SAlign( + /* [in] */ BSTR pVal) = 0; + + virtual /* [helpstring][propget][id] */ HRESULT STDMETHODCALLTYPE get_Menu( + /* [retval][out] */ VARIANT_BOOL *pVal) = 0; + + virtual /* [helpstring][propput][id] */ HRESULT STDMETHODCALLTYPE put_Menu( + /* [in] */ VARIANT_BOOL pVal) = 0; + + virtual /* [helpstring][propget][id] */ HRESULT STDMETHODCALLTYPE get_Base( + /* [retval][out] */ BSTR *pVal) = 0; + + virtual /* [helpstring][propput][id] */ HRESULT STDMETHODCALLTYPE put_Base( + /* [in] */ BSTR pVal) = 0; + + virtual /* [helpstring][propget][id] */ HRESULT STDMETHODCALLTYPE get_Scale( + /* [retval][out] */ BSTR *pVal) = 0; + + virtual /* [helpstring][propput][id] */ HRESULT STDMETHODCALLTYPE put_Scale( + /* [in] */ BSTR pVal) = 0; + + virtual /* [helpstring][propget][id] */ HRESULT STDMETHODCALLTYPE get_DeviceFont( + /* [retval][out] */ VARIANT_BOOL *pVal) = 0; + + virtual /* [helpstring][propput][id] */ HRESULT STDMETHODCALLTYPE put_DeviceFont( + /* [in] */ VARIANT_BOOL pVal) = 0; + + virtual /* [helpstring][propget][id] */ HRESULT STDMETHODCALLTYPE get_EmbedMovie( + /* [retval][out] */ VARIANT_BOOL *pVal) = 0; + + virtual /* [helpstring][propput][id] */ HRESULT STDMETHODCALLTYPE put_EmbedMovie( + /* [in] */ VARIANT_BOOL pVal) = 0; + + virtual /* [helpstring][propget][id] */ HRESULT STDMETHODCALLTYPE get_BGColor( + /* [retval][out] */ BSTR *pVal) = 0; + + virtual /* [helpstring][propput][id] */ HRESULT STDMETHODCALLTYPE put_BGColor( + /* [in] */ BSTR pVal) = 0; + + virtual /* [helpstring][propget][id] */ HRESULT STDMETHODCALLTYPE get_Quality2( + /* [retval][out] */ BSTR *pVal) = 0; + + virtual /* [helpstring][propput][id] */ HRESULT STDMETHODCALLTYPE put_Quality2( + /* [in] */ BSTR pVal) = 0; + + virtual /* [helpstring][id] */ HRESULT STDMETHODCALLTYPE LoadMovie( + /* [in] */ int layer, + /* [in] */ BSTR url) = 0; + + virtual /* [helpstring][id] */ HRESULT STDMETHODCALLTYPE TGotoFrame( + /* [in] */ BSTR target, + /* [in] */ long FrameNum) = 0; + + virtual /* [helpstring][id] */ HRESULT STDMETHODCALLTYPE TGotoLabel( + /* [in] */ BSTR target, + /* [in] */ BSTR label) = 0; + + virtual /* [helpstring][id] */ HRESULT STDMETHODCALLTYPE TCurrentFrame( + /* [in] */ BSTR target, + /* [retval][out] */ long *FrameNum) = 0; + + virtual /* [helpstring][id] */ HRESULT STDMETHODCALLTYPE TCurrentLabel( + /* [in] */ BSTR target, + /* [retval][out] */ BSTR *pVal) = 0; + + virtual /* [helpstring][id] */ HRESULT STDMETHODCALLTYPE TPlay( + /* [in] */ BSTR target) = 0; + + virtual /* [helpstring][id] */ HRESULT STDMETHODCALLTYPE TStopPlay( + /* [in] */ BSTR target) = 0; + + virtual /* [helpstring][id] */ HRESULT STDMETHODCALLTYPE SetVariable( + /* [in] */ BSTR name, + /* [in] */ BSTR value) = 0; + + virtual /* [helpstring][id] */ HRESULT STDMETHODCALLTYPE GetVariable( + /* [in] */ BSTR name, + /* [retval][out] */ BSTR *pVal) = 0; + + virtual /* [helpstring][id] */ HRESULT STDMETHODCALLTYPE TSetProperty( + /* [in] */ BSTR target, + /* [in] */ int property, + /* [in] */ BSTR value) = 0; + + virtual /* [helpstring][id] */ HRESULT STDMETHODCALLTYPE TGetProperty( + /* [in] */ BSTR target, + /* [in] */ int property, + /* [retval][out] */ BSTR *pVal) = 0; + + virtual /* [helpstring][id] */ HRESULT STDMETHODCALLTYPE TCallFrame( + /* [in] */ BSTR target, + /* [in] */ int FrameNum) = 0; + + virtual /* [helpstring][id] */ HRESULT STDMETHODCALLTYPE TCallLabel( + /* [in] */ BSTR target, + /* [in] */ BSTR label) = 0; + + virtual /* [helpstring][id] */ HRESULT STDMETHODCALLTYPE TSetPropertyNum( + /* [in] */ BSTR target, + /* [in] */ int property, + /* [in] */ double value) = 0; + + virtual /* [helpstring][id] */ HRESULT STDMETHODCALLTYPE TGetPropertyNum( + /* [in] */ BSTR target, + /* [in] */ int property, + /* [retval][out] */ double *pVal) = 0; + + virtual /* [helpstring][id] */ HRESULT STDMETHODCALLTYPE TGetPropertyAsNumber( + /* [in] */ BSTR target, + /* [in] */ int property, + /* [retval][out] */ double *pVal) = 0; + + virtual /* [helpstring][propget][id] */ HRESULT STDMETHODCALLTYPE get_SWRemote( + /* [retval][out] */ BSTR *pVal) = 0; + + virtual /* [helpstring][propput][id] */ HRESULT STDMETHODCALLTYPE put_SWRemote( + /* [in] */ BSTR pVal) = 0; + + virtual /* [helpstring][propget][id] */ HRESULT STDMETHODCALLTYPE get_FlashVars( + /* [retval][out] */ BSTR *pVal) = 0; + + virtual /* [helpstring][propput][id] */ HRESULT STDMETHODCALLTYPE put_FlashVars( + /* [in] */ BSTR pVal) = 0; + + virtual /* [helpstring][propget][id] */ HRESULT STDMETHODCALLTYPE get_AllowScriptAccess( + /* [retval][out] */ BSTR *pVal) = 0; + + virtual /* [helpstring][propput][id] */ HRESULT STDMETHODCALLTYPE put_AllowScriptAccess( + /* [in] */ BSTR pVal) = 0; + + virtual /* [helpstring][propget][id] */ HRESULT STDMETHODCALLTYPE get_MovieData( + /* [retval][out] */ BSTR *pVal) = 0; + + virtual /* [helpstring][propput][id] */ HRESULT STDMETHODCALLTYPE put_MovieData( + /* [in] */ BSTR pVal) = 0; + + virtual /* [helpstring][propget][id] */ HRESULT STDMETHODCALLTYPE get_InlineData( + /* [retval][out] */ IUnknown **ppIUnknown) = 0; + + virtual /* [helpstring][propput][id] */ HRESULT STDMETHODCALLTYPE put_InlineData( + /* [in] */ IUnknown *ppIUnknown) = 0; + + virtual /* [helpstring][propget][id] */ HRESULT STDMETHODCALLTYPE get_SeamlessTabbing( + /* [retval][out] */ VARIANT_BOOL *pVal) = 0; + + virtual /* [helpstring][propput][id] */ HRESULT STDMETHODCALLTYPE put_SeamlessTabbing( + /* [in] */ VARIANT_BOOL pVal) = 0; + + virtual /* [helpstring][id] */ HRESULT STDMETHODCALLTYPE EnforceLocalSecurity( void) = 0; + + virtual /* [helpstring][propget][id] */ HRESULT STDMETHODCALLTYPE get_Profile( + /* [retval][out] */ VARIANT_BOOL *pVal) = 0; + + virtual /* [helpstring][propput][id] */ HRESULT STDMETHODCALLTYPE put_Profile( + /* [in] */ VARIANT_BOOL pVal) = 0; + + virtual /* [helpstring][propget][id] */ HRESULT STDMETHODCALLTYPE get_ProfileAddress( + /* [retval][out] */ BSTR *pVal) = 0; + + virtual /* [helpstring][propput][id] */ HRESULT STDMETHODCALLTYPE put_ProfileAddress( + /* [in] */ BSTR pVal) = 0; + + virtual /* [helpstring][propget][id] */ HRESULT STDMETHODCALLTYPE get_ProfilePort( + /* [retval][out] */ long *pVal) = 0; + + virtual /* [helpstring][propput][id] */ HRESULT STDMETHODCALLTYPE put_ProfilePort( + /* [in] */ long pVal) = 0; + + virtual /* [helpstring][id] */ HRESULT STDMETHODCALLTYPE CallFunction( + /* [in] */ BSTR request, + /* [retval][out] */ BSTR *response) = 0; + + virtual /* [helpstring][id] */ HRESULT STDMETHODCALLTYPE SetReturnValue( + /* [in] */ BSTR returnValue) = 0; + + virtual /* [helpstring][id] */ HRESULT STDMETHODCALLTYPE DisableLocalSecurity( void) = 0; + + virtual /* [helpstring][propget][id] */ HRESULT STDMETHODCALLTYPE get_AllowNetworking( + /* [retval][out] */ BSTR *pVal) = 0; + + virtual /* [helpstring][propput][id] */ HRESULT STDMETHODCALLTYPE put_AllowNetworking( + /* [in] */ BSTR pVal) = 0; + + virtual /* [helpstring][propget][id] */ HRESULT STDMETHODCALLTYPE get_AllowFullScreen( + /* [retval][out] */ BSTR *pVal) = 0; + + virtual /* [helpstring][propput][id] */ HRESULT STDMETHODCALLTYPE put_AllowFullScreen( + /* [in] */ BSTR pVal) = 0; + + }; + +#else /* C style interface */ + + typedef struct IShockwaveFlashVtbl + { + BEGIN_INTERFACE + + HRESULT ( STDMETHODCALLTYPE *QueryInterface )( + IShockwaveFlash * This, + /* [in] */ REFIID riid, + /* [iid_is][out] */ void **ppvObject); + + ULONG ( STDMETHODCALLTYPE *AddRef )( + IShockwaveFlash * This); + + ULONG ( STDMETHODCALLTYPE *Release )( + IShockwaveFlash * This); + + HRESULT ( STDMETHODCALLTYPE *GetTypeInfoCount )( + IShockwaveFlash * This, + /* [out] */ UINT *pctinfo); + + HRESULT ( STDMETHODCALLTYPE *GetTypeInfo )( + IShockwaveFlash * This, + /* [in] */ UINT iTInfo, + /* [in] */ LCID lcid, + /* [out] */ ITypeInfo **ppTInfo); + + HRESULT ( STDMETHODCALLTYPE *GetIDsOfNames )( + IShockwaveFlash * This, + /* [in] */ REFIID riid, + /* [size_is][in] */ LPOLESTR *rgszNames, + /* [in] */ UINT cNames, + /* [in] */ LCID lcid, + /* [size_is][out] */ DISPID *rgDispId); + + /* [local] */ HRESULT ( STDMETHODCALLTYPE *Invoke )( + IShockwaveFlash * This, + /* [in] */ DISPID dispIdMember, + /* [in] */ REFIID riid, + /* [in] */ LCID lcid, + /* [in] */ WORD wFlags, + /* [out][in] */ DISPPARAMS *pDispParams, + /* [out] */ VARIANT *pVarResult, + /* [out] */ EXCEPINFO *pExcepInfo, + /* [out] */ UINT *puArgErr); + + /* [helpstring][propget][id] */ HRESULT ( STDMETHODCALLTYPE *get_ReadyState )( + IShockwaveFlash * This, + /* [retval][out] */ long *pVal); + + /* [helpstring][propget][id] */ HRESULT ( STDMETHODCALLTYPE *get_TotalFrames )( + IShockwaveFlash * This, + /* [retval][out] */ long *pVal); + + /* [helpstring][propget][id] */ HRESULT ( STDMETHODCALLTYPE *get_Playing )( + IShockwaveFlash * This, + /* [retval][out] */ VARIANT_BOOL *pVal); + + /* [helpstring][propput][id] */ HRESULT ( STDMETHODCALLTYPE *put_Playing )( + IShockwaveFlash * This, + /* [in] */ VARIANT_BOOL pVal); + + /* [helpstring][propget][id] */ HRESULT ( STDMETHODCALLTYPE *get_Quality )( + IShockwaveFlash * This, + /* [retval][out] */ int *pVal); + + /* [helpstring][propput][id] */ HRESULT ( STDMETHODCALLTYPE *put_Quality )( + IShockwaveFlash * This, + /* [in] */ int pVal); + + /* [helpstring][propget][id] */ HRESULT ( STDMETHODCALLTYPE *get_ScaleMode )( + IShockwaveFlash * This, + /* [retval][out] */ int *pVal); + + /* [helpstring][propput][id] */ HRESULT ( STDMETHODCALLTYPE *put_ScaleMode )( + IShockwaveFlash * This, + /* [in] */ int pVal); + + /* [helpstring][propget][id] */ HRESULT ( STDMETHODCALLTYPE *get_AlignMode )( + IShockwaveFlash * This, + /* [retval][out] */ int *pVal); + + /* [helpstring][propput][id] */ HRESULT ( STDMETHODCALLTYPE *put_AlignMode )( + IShockwaveFlash * This, + /* [in] */ int pVal); + + /* [helpstring][propget][id] */ HRESULT ( STDMETHODCALLTYPE *get_BackgroundColor )( + IShockwaveFlash * This, + /* [retval][out] */ long *pVal); + + /* [helpstring][propput][id] */ HRESULT ( STDMETHODCALLTYPE *put_BackgroundColor )( + IShockwaveFlash * This, + /* [in] */ long pVal); + + /* [helpstring][propget][id] */ HRESULT ( STDMETHODCALLTYPE *get_Loop )( + IShockwaveFlash * This, + /* [retval][out] */ VARIANT_BOOL *pVal); + + /* [helpstring][propput][id] */ HRESULT ( STDMETHODCALLTYPE *put_Loop )( + IShockwaveFlash * This, + /* [in] */ VARIANT_BOOL pVal); + + /* [helpstring][propget][id] */ HRESULT ( STDMETHODCALLTYPE *get_Movie )( + IShockwaveFlash * This, + /* [retval][out] */ BSTR *pVal); + + /* [helpstring][propput][id] */ HRESULT ( STDMETHODCALLTYPE *put_Movie )( + IShockwaveFlash * This, + /* [in] */ BSTR pVal); + + /* [helpstring][propget][id] */ HRESULT ( STDMETHODCALLTYPE *get_FrameNum )( + IShockwaveFlash * This, + /* [retval][out] */ long *pVal); + + /* [helpstring][propput][id] */ HRESULT ( STDMETHODCALLTYPE *put_FrameNum )( + IShockwaveFlash * This, + /* [in] */ long pVal); + + /* [helpstring][id] */ HRESULT ( STDMETHODCALLTYPE *SetZoomRect )( + IShockwaveFlash * This, + /* [in] */ long left, + /* [in] */ long top, + /* [in] */ long right, + /* [in] */ long bottom); + + /* [helpstring][id] */ HRESULT ( STDMETHODCALLTYPE *Zoom )( + IShockwaveFlash * This, + /* [in] */ int factor); + + /* [helpstring][id] */ HRESULT ( STDMETHODCALLTYPE *Pan )( + IShockwaveFlash * This, + /* [in] */ long x, + /* [in] */ long y, + /* [in] */ int mode); + + /* [helpstring][id] */ HRESULT ( STDMETHODCALLTYPE *Play )( + IShockwaveFlash * This); + + /* [helpstring][id] */ HRESULT ( STDMETHODCALLTYPE *Stop )( + IShockwaveFlash * This); + + /* [helpstring][id] */ HRESULT ( STDMETHODCALLTYPE *Back )( + IShockwaveFlash * This); + + /* [helpstring][id] */ HRESULT ( STDMETHODCALLTYPE *Forward )( + IShockwaveFlash * This); + + /* [helpstring][id] */ HRESULT ( STDMETHODCALLTYPE *Rewind )( + IShockwaveFlash * This); + + /* [helpstring][id] */ HRESULT ( STDMETHODCALLTYPE *StopPlay )( + IShockwaveFlash * This); + + /* [helpstring][id] */ HRESULT ( STDMETHODCALLTYPE *GotoFrame )( + IShockwaveFlash * This, + /* [in] */ long FrameNum); + + /* [helpstring][id] */ HRESULT ( STDMETHODCALLTYPE *CurrentFrame )( + IShockwaveFlash * This, + /* [retval][out] */ long *FrameNum); + + /* [helpstring][id] */ HRESULT ( STDMETHODCALLTYPE *IsPlaying )( + IShockwaveFlash * This, + /* [retval][out] */ VARIANT_BOOL *Playing); + + /* [helpstring][id] */ HRESULT ( STDMETHODCALLTYPE *PercentLoaded )( + IShockwaveFlash * This, + /* [retval][out] */ long *percent); + + /* [helpstring][id] */ HRESULT ( STDMETHODCALLTYPE *FrameLoaded )( + IShockwaveFlash * This, + /* [in] */ long FrameNum, + /* [retval][out] */ VARIANT_BOOL *loaded); + + /* [helpstring][id] */ HRESULT ( STDMETHODCALLTYPE *FlashVersion )( + IShockwaveFlash * This, + /* [retval][out] */ long *version); + + /* [helpstring][propget][id] */ HRESULT ( STDMETHODCALLTYPE *get_WMode )( + IShockwaveFlash * This, + /* [retval][out] */ BSTR *pVal); + + /* [helpstring][propput][id] */ HRESULT ( STDMETHODCALLTYPE *put_WMode )( + IShockwaveFlash * This, + /* [in] */ BSTR pVal); + + /* [helpstring][propget][id] */ HRESULT ( STDMETHODCALLTYPE *get_SAlign )( + IShockwaveFlash * This, + /* [retval][out] */ BSTR *pVal); + + /* [helpstring][propput][id] */ HRESULT ( STDMETHODCALLTYPE *put_SAlign )( + IShockwaveFlash * This, + /* [in] */ BSTR pVal); + + /* [helpstring][propget][id] */ HRESULT ( STDMETHODCALLTYPE *get_Menu )( + IShockwaveFlash * This, + /* [retval][out] */ VARIANT_BOOL *pVal); + + /* [helpstring][propput][id] */ HRESULT ( STDMETHODCALLTYPE *put_Menu )( + IShockwaveFlash * This, + /* [in] */ VARIANT_BOOL pVal); + + /* [helpstring][propget][id] */ HRESULT ( STDMETHODCALLTYPE *get_Base )( + IShockwaveFlash * This, + /* [retval][out] */ BSTR *pVal); + + /* [helpstring][propput][id] */ HRESULT ( STDMETHODCALLTYPE *put_Base )( + IShockwaveFlash * This, + /* [in] */ BSTR pVal); + + /* [helpstring][propget][id] */ HRESULT ( STDMETHODCALLTYPE *get_Scale )( + IShockwaveFlash * This, + /* [retval][out] */ BSTR *pVal); + + /* [helpstring][propput][id] */ HRESULT ( STDMETHODCALLTYPE *put_Scale )( + IShockwaveFlash * This, + /* [in] */ BSTR pVal); + + /* [helpstring][propget][id] */ HRESULT ( STDMETHODCALLTYPE *get_DeviceFont )( + IShockwaveFlash * This, + /* [retval][out] */ VARIANT_BOOL *pVal); + + /* [helpstring][propput][id] */ HRESULT ( STDMETHODCALLTYPE *put_DeviceFont )( + IShockwaveFlash * This, + /* [in] */ VARIANT_BOOL pVal); + + /* [helpstring][propget][id] */ HRESULT ( STDMETHODCALLTYPE *get_EmbedMovie )( + IShockwaveFlash * This, + /* [retval][out] */ VARIANT_BOOL *pVal); + + /* [helpstring][propput][id] */ HRESULT ( STDMETHODCALLTYPE *put_EmbedMovie )( + IShockwaveFlash * This, + /* [in] */ VARIANT_BOOL pVal); + + /* [helpstring][propget][id] */ HRESULT ( STDMETHODCALLTYPE *get_BGColor )( + IShockwaveFlash * This, + /* [retval][out] */ BSTR *pVal); + + /* [helpstring][propput][id] */ HRESULT ( STDMETHODCALLTYPE *put_BGColor )( + IShockwaveFlash * This, + /* [in] */ BSTR pVal); + + /* [helpstring][propget][id] */ HRESULT ( STDMETHODCALLTYPE *get_Quality2 )( + IShockwaveFlash * This, + /* [retval][out] */ BSTR *pVal); + + /* [helpstring][propput][id] */ HRESULT ( STDMETHODCALLTYPE *put_Quality2 )( + IShockwaveFlash * This, + /* [in] */ BSTR pVal); + + /* [helpstring][id] */ HRESULT ( STDMETHODCALLTYPE *LoadMovie )( + IShockwaveFlash * This, + /* [in] */ int layer, + /* [in] */ BSTR url); + + /* [helpstring][id] */ HRESULT ( STDMETHODCALLTYPE *TGotoFrame )( + IShockwaveFlash * This, + /* [in] */ BSTR target, + /* [in] */ long FrameNum); + + /* [helpstring][id] */ HRESULT ( STDMETHODCALLTYPE *TGotoLabel )( + IShockwaveFlash * This, + /* [in] */ BSTR target, + /* [in] */ BSTR label); + + /* [helpstring][id] */ HRESULT ( STDMETHODCALLTYPE *TCurrentFrame )( + IShockwaveFlash * This, + /* [in] */ BSTR target, + /* [retval][out] */ long *FrameNum); + + /* [helpstring][id] */ HRESULT ( STDMETHODCALLTYPE *TCurrentLabel )( + IShockwaveFlash * This, + /* [in] */ BSTR target, + /* [retval][out] */ BSTR *pVal); + + /* [helpstring][id] */ HRESULT ( STDMETHODCALLTYPE *TPlay )( + IShockwaveFlash * This, + /* [in] */ BSTR target); + + /* [helpstring][id] */ HRESULT ( STDMETHODCALLTYPE *TStopPlay )( + IShockwaveFlash * This, + /* [in] */ BSTR target); + + /* [helpstring][id] */ HRESULT ( STDMETHODCALLTYPE *SetVariable )( + IShockwaveFlash * This, + /* [in] */ BSTR name, + /* [in] */ BSTR value); + + /* [helpstring][id] */ HRESULT ( STDMETHODCALLTYPE *GetVariable )( + IShockwaveFlash * This, + /* [in] */ BSTR name, + /* [retval][out] */ BSTR *pVal); + + /* [helpstring][id] */ HRESULT ( STDMETHODCALLTYPE *TSetProperty )( + IShockwaveFlash * This, + /* [in] */ BSTR target, + /* [in] */ int property, + /* [in] */ BSTR value); + + /* [helpstring][id] */ HRESULT ( STDMETHODCALLTYPE *TGetProperty )( + IShockwaveFlash * This, + /* [in] */ BSTR target, + /* [in] */ int property, + /* [retval][out] */ BSTR *pVal); + + /* [helpstring][id] */ HRESULT ( STDMETHODCALLTYPE *TCallFrame )( + IShockwaveFlash * This, + /* [in] */ BSTR target, + /* [in] */ int FrameNum); + + /* [helpstring][id] */ HRESULT ( STDMETHODCALLTYPE *TCallLabel )( + IShockwaveFlash * This, + /* [in] */ BSTR target, + /* [in] */ BSTR label); + + /* [helpstring][id] */ HRESULT ( STDMETHODCALLTYPE *TSetPropertyNum )( + IShockwaveFlash * This, + /* [in] */ BSTR target, + /* [in] */ int property, + /* [in] */ double value); + + /* [helpstring][id] */ HRESULT ( STDMETHODCALLTYPE *TGetPropertyNum )( + IShockwaveFlash * This, + /* [in] */ BSTR target, + /* [in] */ int property, + /* [retval][out] */ double *pVal); + + /* [helpstring][id] */ HRESULT ( STDMETHODCALLTYPE *TGetPropertyAsNumber )( + IShockwaveFlash * This, + /* [in] */ BSTR target, + /* [in] */ int property, + /* [retval][out] */ double *pVal); + + /* [helpstring][propget][id] */ HRESULT ( STDMETHODCALLTYPE *get_SWRemote )( + IShockwaveFlash * This, + /* [retval][out] */ BSTR *pVal); + + /* [helpstring][propput][id] */ HRESULT ( STDMETHODCALLTYPE *put_SWRemote )( + IShockwaveFlash * This, + /* [in] */ BSTR pVal); + + /* [helpstring][propget][id] */ HRESULT ( STDMETHODCALLTYPE *get_FlashVars )( + IShockwaveFlash * This, + /* [retval][out] */ BSTR *pVal); + + /* [helpstring][propput][id] */ HRESULT ( STDMETHODCALLTYPE *put_FlashVars )( + IShockwaveFlash * This, + /* [in] */ BSTR pVal); + + /* [helpstring][propget][id] */ HRESULT ( STDMETHODCALLTYPE *get_AllowScriptAccess )( + IShockwaveFlash * This, + /* [retval][out] */ BSTR *pVal); + + /* [helpstring][propput][id] */ HRESULT ( STDMETHODCALLTYPE *put_AllowScriptAccess )( + IShockwaveFlash * This, + /* [in] */ BSTR pVal); + + /* [helpstring][propget][id] */ HRESULT ( STDMETHODCALLTYPE *get_MovieData )( + IShockwaveFlash * This, + /* [retval][out] */ BSTR *pVal); + + /* [helpstring][propput][id] */ HRESULT ( STDMETHODCALLTYPE *put_MovieData )( + IShockwaveFlash * This, + /* [in] */ BSTR pVal); + + /* [helpstring][propget][id] */ HRESULT ( STDMETHODCALLTYPE *get_InlineData )( + IShockwaveFlash * This, + /* [retval][out] */ IUnknown **ppIUnknown); + + /* [helpstring][propput][id] */ HRESULT ( STDMETHODCALLTYPE *put_InlineData )( + IShockwaveFlash * This, + /* [in] */ IUnknown *ppIUnknown); + + /* [helpstring][propget][id] */ HRESULT ( STDMETHODCALLTYPE *get_SeamlessTabbing )( + IShockwaveFlash * This, + /* [retval][out] */ VARIANT_BOOL *pVal); + + /* [helpstring][propput][id] */ HRESULT ( STDMETHODCALLTYPE *put_SeamlessTabbing )( + IShockwaveFlash * This, + /* [in] */ VARIANT_BOOL pVal); + + /* [helpstring][id] */ HRESULT ( STDMETHODCALLTYPE *EnforceLocalSecurity )( + IShockwaveFlash * This); + + /* [helpstring][propget][id] */ HRESULT ( STDMETHODCALLTYPE *get_Profile )( + IShockwaveFlash * This, + /* [retval][out] */ VARIANT_BOOL *pVal); + + /* [helpstring][propput][id] */ HRESULT ( STDMETHODCALLTYPE *put_Profile )( + IShockwaveFlash * This, + /* [in] */ VARIANT_BOOL pVal); + + /* [helpstring][propget][id] */ HRESULT ( STDMETHODCALLTYPE *get_ProfileAddress )( + IShockwaveFlash * This, + /* [retval][out] */ BSTR *pVal); + + /* [helpstring][propput][id] */ HRESULT ( STDMETHODCALLTYPE *put_ProfileAddress )( + IShockwaveFlash * This, + /* [in] */ BSTR pVal); + + /* [helpstring][propget][id] */ HRESULT ( STDMETHODCALLTYPE *get_ProfilePort )( + IShockwaveFlash * This, + /* [retval][out] */ long *pVal); + + /* [helpstring][propput][id] */ HRESULT ( STDMETHODCALLTYPE *put_ProfilePort )( + IShockwaveFlash * This, + /* [in] */ long pVal); + + /* [helpstring][id] */ HRESULT ( STDMETHODCALLTYPE *CallFunction )( + IShockwaveFlash * This, + /* [in] */ BSTR request, + /* [retval][out] */ BSTR *response); + + /* [helpstring][id] */ HRESULT ( STDMETHODCALLTYPE *SetReturnValue )( + IShockwaveFlash * This, + /* [in] */ BSTR returnValue); + + /* [helpstring][id] */ HRESULT ( STDMETHODCALLTYPE *DisableLocalSecurity )( + IShockwaveFlash * This); + + /* [helpstring][propget][id] */ HRESULT ( STDMETHODCALLTYPE *get_AllowNetworking )( + IShockwaveFlash * This, + /* [retval][out] */ BSTR *pVal); + + /* [helpstring][propput][id] */ HRESULT ( STDMETHODCALLTYPE *put_AllowNetworking )( + IShockwaveFlash * This, + /* [in] */ BSTR pVal); + + /* [helpstring][propget][id] */ HRESULT ( STDMETHODCALLTYPE *get_AllowFullScreen )( + IShockwaveFlash * This, + /* [retval][out] */ BSTR *pVal); + + /* [helpstring][propput][id] */ HRESULT ( STDMETHODCALLTYPE *put_AllowFullScreen )( + IShockwaveFlash * This, + /* [in] */ BSTR pVal); + + END_INTERFACE + } IShockwaveFlashVtbl; + + interface IShockwaveFlash + { + CONST_VTBL struct IShockwaveFlashVtbl *lpVtbl; + }; + + + +#ifdef COBJMACROS + + +#define IShockwaveFlash_QueryInterface(This,riid,ppvObject) \ + (This)->lpVtbl -> QueryInterface(This,riid,ppvObject) + +#define IShockwaveFlash_AddRef(This) \ + (This)->lpVtbl -> AddRef(This) + +#define IShockwaveFlash_Release(This) \ + (This)->lpVtbl -> Release(This) + + +#define IShockwaveFlash_GetTypeInfoCount(This,pctinfo) \ + (This)->lpVtbl -> GetTypeInfoCount(This,pctinfo) + +#define IShockwaveFlash_GetTypeInfo(This,iTInfo,lcid,ppTInfo) \ + (This)->lpVtbl -> GetTypeInfo(This,iTInfo,lcid,ppTInfo) + +#define IShockwaveFlash_GetIDsOfNames(This,riid,rgszNames,cNames,lcid,rgDispId) \ + (This)->lpVtbl -> GetIDsOfNames(This,riid,rgszNames,cNames,lcid,rgDispId) + +#define IShockwaveFlash_Invoke(This,dispIdMember,riid,lcid,wFlags,pDispParams,pVarResult,pExcepInfo,puArgErr) \ + (This)->lpVtbl -> Invoke(This,dispIdMember,riid,lcid,wFlags,pDispParams,pVarResult,pExcepInfo,puArgErr) + + +#define IShockwaveFlash_get_ReadyState(This,pVal) \ + (This)->lpVtbl -> get_ReadyState(This,pVal) + +#define IShockwaveFlash_get_TotalFrames(This,pVal) \ + (This)->lpVtbl -> get_TotalFrames(This,pVal) + +#define IShockwaveFlash_get_Playing(This,pVal) \ + (This)->lpVtbl -> get_Playing(This,pVal) + +#define IShockwaveFlash_put_Playing(This,pVal) \ + (This)->lpVtbl -> put_Playing(This,pVal) + +#define IShockwaveFlash_get_Quality(This,pVal) \ + (This)->lpVtbl -> get_Quality(This,pVal) + +#define IShockwaveFlash_put_Quality(This,pVal) \ + (This)->lpVtbl -> put_Quality(This,pVal) + +#define IShockwaveFlash_get_ScaleMode(This,pVal) \ + (This)->lpVtbl -> get_ScaleMode(This,pVal) + +#define IShockwaveFlash_put_ScaleMode(This,pVal) \ + (This)->lpVtbl -> put_ScaleMode(This,pVal) + +#define IShockwaveFlash_get_AlignMode(This,pVal) \ + (This)->lpVtbl -> get_AlignMode(This,pVal) + +#define IShockwaveFlash_put_AlignMode(This,pVal) \ + (This)->lpVtbl -> put_AlignMode(This,pVal) + +#define IShockwaveFlash_get_BackgroundColor(This,pVal) \ + (This)->lpVtbl -> get_BackgroundColor(This,pVal) + +#define IShockwaveFlash_put_BackgroundColor(This,pVal) \ + (This)->lpVtbl -> put_BackgroundColor(This,pVal) + +#define IShockwaveFlash_get_Loop(This,pVal) \ + (This)->lpVtbl -> get_Loop(This,pVal) + +#define IShockwaveFlash_put_Loop(This,pVal) \ + (This)->lpVtbl -> put_Loop(This,pVal) + +#define IShockwaveFlash_get_Movie(This,pVal) \ + (This)->lpVtbl -> get_Movie(This,pVal) + +#define IShockwaveFlash_put_Movie(This,pVal) \ + (This)->lpVtbl -> put_Movie(This,pVal) + +#define IShockwaveFlash_get_FrameNum(This,pVal) \ + (This)->lpVtbl -> get_FrameNum(This,pVal) + +#define IShockwaveFlash_put_FrameNum(This,pVal) \ + (This)->lpVtbl -> put_FrameNum(This,pVal) + +#define IShockwaveFlash_SetZoomRect(This,left,top,right,bottom) \ + (This)->lpVtbl -> SetZoomRect(This,left,top,right,bottom) + +#define IShockwaveFlash_Zoom(This,factor) \ + (This)->lpVtbl -> Zoom(This,factor) + +#define IShockwaveFlash_Pan(This,x,y,mode) \ + (This)->lpVtbl -> Pan(This,x,y,mode) + +#define IShockwaveFlash_Play(This) \ + (This)->lpVtbl -> Play(This) + +#define IShockwaveFlash_Stop(This) \ + (This)->lpVtbl -> Stop(This) + +#define IShockwaveFlash_Back(This) \ + (This)->lpVtbl -> Back(This) + +#define IShockwaveFlash_Forward(This) \ + (This)->lpVtbl -> Forward(This) + +#define IShockwaveFlash_Rewind(This) \ + (This)->lpVtbl -> Rewind(This) + +#define IShockwaveFlash_StopPlay(This) \ + (This)->lpVtbl -> StopPlay(This) + +#define IShockwaveFlash_GotoFrame(This,FrameNum) \ + (This)->lpVtbl -> GotoFrame(This,FrameNum) + +#define IShockwaveFlash_CurrentFrame(This,FrameNum) \ + (This)->lpVtbl -> CurrentFrame(This,FrameNum) + +#define IShockwaveFlash_IsPlaying(This,Playing) \ + (This)->lpVtbl -> IsPlaying(This,Playing) + +#define IShockwaveFlash_PercentLoaded(This,percent) \ + (This)->lpVtbl -> PercentLoaded(This,percent) + +#define IShockwaveFlash_FrameLoaded(This,FrameNum,loaded) \ + (This)->lpVtbl -> FrameLoaded(This,FrameNum,loaded) + +#define IShockwaveFlash_FlashVersion(This,version) \ + (This)->lpVtbl -> FlashVersion(This,version) + +#define IShockwaveFlash_get_WMode(This,pVal) \ + (This)->lpVtbl -> get_WMode(This,pVal) + +#define IShockwaveFlash_put_WMode(This,pVal) \ + (This)->lpVtbl -> put_WMode(This,pVal) + +#define IShockwaveFlash_get_SAlign(This,pVal) \ + (This)->lpVtbl -> get_SAlign(This,pVal) + +#define IShockwaveFlash_put_SAlign(This,pVal) \ + (This)->lpVtbl -> put_SAlign(This,pVal) + +#define IShockwaveFlash_get_Menu(This,pVal) \ + (This)->lpVtbl -> get_Menu(This,pVal) + +#define IShockwaveFlash_put_Menu(This,pVal) \ + (This)->lpVtbl -> put_Menu(This,pVal) + +#define IShockwaveFlash_get_Base(This,pVal) \ + (This)->lpVtbl -> get_Base(This,pVal) + +#define IShockwaveFlash_put_Base(This,pVal) \ + (This)->lpVtbl -> put_Base(This,pVal) + +#define IShockwaveFlash_get_Scale(This,pVal) \ + (This)->lpVtbl -> get_Scale(This,pVal) + +#define IShockwaveFlash_put_Scale(This,pVal) \ + (This)->lpVtbl -> put_Scale(This,pVal) + +#define IShockwaveFlash_get_DeviceFont(This,pVal) \ + (This)->lpVtbl -> get_DeviceFont(This,pVal) + +#define IShockwaveFlash_put_DeviceFont(This,pVal) \ + (This)->lpVtbl -> put_DeviceFont(This,pVal) + +#define IShockwaveFlash_get_EmbedMovie(This,pVal) \ + (This)->lpVtbl -> get_EmbedMovie(This,pVal) + +#define IShockwaveFlash_put_EmbedMovie(This,pVal) \ + (This)->lpVtbl -> put_EmbedMovie(This,pVal) + +#define IShockwaveFlash_get_BGColor(This,pVal) \ + (This)->lpVtbl -> get_BGColor(This,pVal) + +#define IShockwaveFlash_put_BGColor(This,pVal) \ + (This)->lpVtbl -> put_BGColor(This,pVal) + +#define IShockwaveFlash_get_Quality2(This,pVal) \ + (This)->lpVtbl -> get_Quality2(This,pVal) + +#define IShockwaveFlash_put_Quality2(This,pVal) \ + (This)->lpVtbl -> put_Quality2(This,pVal) + +#define IShockwaveFlash_LoadMovie(This,layer,url) \ + (This)->lpVtbl -> LoadMovie(This,layer,url) + +#define IShockwaveFlash_TGotoFrame(This,target,FrameNum) \ + (This)->lpVtbl -> TGotoFrame(This,target,FrameNum) + +#define IShockwaveFlash_TGotoLabel(This,target,label) \ + (This)->lpVtbl -> TGotoLabel(This,target,label) + +#define IShockwaveFlash_TCurrentFrame(This,target,FrameNum) \ + (This)->lpVtbl -> TCurrentFrame(This,target,FrameNum) + +#define IShockwaveFlash_TCurrentLabel(This,target,pVal) \ + (This)->lpVtbl -> TCurrentLabel(This,target,pVal) + +#define IShockwaveFlash_TPlay(This,target) \ + (This)->lpVtbl -> TPlay(This,target) + +#define IShockwaveFlash_TStopPlay(This,target) \ + (This)->lpVtbl -> TStopPlay(This,target) + +#define IShockwaveFlash_SetVariable(This,name,value) \ + (This)->lpVtbl -> SetVariable(This,name,value) + +#define IShockwaveFlash_GetVariable(This,name,pVal) \ + (This)->lpVtbl -> GetVariable(This,name,pVal) + +#define IShockwaveFlash_TSetProperty(This,target,property,value) \ + (This)->lpVtbl -> TSetProperty(This,target,property,value) + +#define IShockwaveFlash_TGetProperty(This,target,property,pVal) \ + (This)->lpVtbl -> TGetProperty(This,target,property,pVal) + +#define IShockwaveFlash_TCallFrame(This,target,FrameNum) \ + (This)->lpVtbl -> TCallFrame(This,target,FrameNum) + +#define IShockwaveFlash_TCallLabel(This,target,label) \ + (This)->lpVtbl -> TCallLabel(This,target,label) + +#define IShockwaveFlash_TSetPropertyNum(This,target,property,value) \ + (This)->lpVtbl -> TSetPropertyNum(This,target,property,value) + +#define IShockwaveFlash_TGetPropertyNum(This,target,property,pVal) \ + (This)->lpVtbl -> TGetPropertyNum(This,target,property,pVal) + +#define IShockwaveFlash_TGetPropertyAsNumber(This,target,property,pVal) \ + (This)->lpVtbl -> TGetPropertyAsNumber(This,target,property,pVal) + +#define IShockwaveFlash_get_SWRemote(This,pVal) \ + (This)->lpVtbl -> get_SWRemote(This,pVal) + +#define IShockwaveFlash_put_SWRemote(This,pVal) \ + (This)->lpVtbl -> put_SWRemote(This,pVal) + +#define IShockwaveFlash_get_FlashVars(This,pVal) \ + (This)->lpVtbl -> get_FlashVars(This,pVal) + +#define IShockwaveFlash_put_FlashVars(This,pVal) \ + (This)->lpVtbl -> put_FlashVars(This,pVal) + +#define IShockwaveFlash_get_AllowScriptAccess(This,pVal) \ + (This)->lpVtbl -> get_AllowScriptAccess(This,pVal) + +#define IShockwaveFlash_put_AllowScriptAccess(This,pVal) \ + (This)->lpVtbl -> put_AllowScriptAccess(This,pVal) + +#define IShockwaveFlash_get_MovieData(This,pVal) \ + (This)->lpVtbl -> get_MovieData(This,pVal) + +#define IShockwaveFlash_put_MovieData(This,pVal) \ + (This)->lpVtbl -> put_MovieData(This,pVal) + +#define IShockwaveFlash_get_InlineData(This,ppIUnknown) \ + (This)->lpVtbl -> get_InlineData(This,ppIUnknown) + +#define IShockwaveFlash_put_InlineData(This,ppIUnknown) \ + (This)->lpVtbl -> put_InlineData(This,ppIUnknown) + +#define IShockwaveFlash_get_SeamlessTabbing(This,pVal) \ + (This)->lpVtbl -> get_SeamlessTabbing(This,pVal) + +#define IShockwaveFlash_put_SeamlessTabbing(This,pVal) \ + (This)->lpVtbl -> put_SeamlessTabbing(This,pVal) + +#define IShockwaveFlash_EnforceLocalSecurity(This) \ + (This)->lpVtbl -> EnforceLocalSecurity(This) + +#define IShockwaveFlash_get_Profile(This,pVal) \ + (This)->lpVtbl -> get_Profile(This,pVal) + +#define IShockwaveFlash_put_Profile(This,pVal) \ + (This)->lpVtbl -> put_Profile(This,pVal) + +#define IShockwaveFlash_get_ProfileAddress(This,pVal) \ + (This)->lpVtbl -> get_ProfileAddress(This,pVal) + +#define IShockwaveFlash_put_ProfileAddress(This,pVal) \ + (This)->lpVtbl -> put_ProfileAddress(This,pVal) + +#define IShockwaveFlash_get_ProfilePort(This,pVal) \ + (This)->lpVtbl -> get_ProfilePort(This,pVal) + +#define IShockwaveFlash_put_ProfilePort(This,pVal) \ + (This)->lpVtbl -> put_ProfilePort(This,pVal) + +#define IShockwaveFlash_CallFunction(This,request,response) \ + (This)->lpVtbl -> CallFunction(This,request,response) + +#define IShockwaveFlash_SetReturnValue(This,returnValue) \ + (This)->lpVtbl -> SetReturnValue(This,returnValue) + +#define IShockwaveFlash_DisableLocalSecurity(This) \ + (This)->lpVtbl -> DisableLocalSecurity(This) + +#define IShockwaveFlash_get_AllowNetworking(This,pVal) \ + (This)->lpVtbl -> get_AllowNetworking(This,pVal) + +#define IShockwaveFlash_put_AllowNetworking(This,pVal) \ + (This)->lpVtbl -> put_AllowNetworking(This,pVal) + +#define IShockwaveFlash_get_AllowFullScreen(This,pVal) \ + (This)->lpVtbl -> get_AllowFullScreen(This,pVal) + +#define IShockwaveFlash_put_AllowFullScreen(This,pVal) \ + (This)->lpVtbl -> put_AllowFullScreen(This,pVal) + +#endif /* COBJMACROS */ + + +#endif /* C style interface */ + + + +/* [helpstring][propget][id] */ HRESULT STDMETHODCALLTYPE IShockwaveFlash_get_ReadyState_Proxy( + IShockwaveFlash * This, + /* [retval][out] */ long *pVal); + + +void __RPC_STUB IShockwaveFlash_get_ReadyState_Stub( + IRpcStubBuffer *This, + IRpcChannelBuffer *_pRpcChannelBuffer, + PRPC_MESSAGE _pRpcMessage, + DWORD *_pdwStubPhase); + + +/* [helpstring][propget][id] */ HRESULT STDMETHODCALLTYPE IShockwaveFlash_get_TotalFrames_Proxy( + IShockwaveFlash * This, + /* [retval][out] */ long *pVal); + + +void __RPC_STUB IShockwaveFlash_get_TotalFrames_Stub( + IRpcStubBuffer *This, + IRpcChannelBuffer *_pRpcChannelBuffer, + PRPC_MESSAGE _pRpcMessage, + DWORD *_pdwStubPhase); + + +/* [helpstring][propget][id] */ HRESULT STDMETHODCALLTYPE IShockwaveFlash_get_Playing_Proxy( + IShockwaveFlash * This, + /* [retval][out] */ VARIANT_BOOL *pVal); + + +void __RPC_STUB IShockwaveFlash_get_Playing_Stub( + IRpcStubBuffer *This, + IRpcChannelBuffer *_pRpcChannelBuffer, + PRPC_MESSAGE _pRpcMessage, + DWORD *_pdwStubPhase); + + +/* [helpstring][propput][id] */ HRESULT STDMETHODCALLTYPE IShockwaveFlash_put_Playing_Proxy( + IShockwaveFlash * This, + /* [in] */ VARIANT_BOOL pVal); + + +void __RPC_STUB IShockwaveFlash_put_Playing_Stub( + IRpcStubBuffer *This, + IRpcChannelBuffer *_pRpcChannelBuffer, + PRPC_MESSAGE _pRpcMessage, + DWORD *_pdwStubPhase); + + +/* [helpstring][propget][id] */ HRESULT STDMETHODCALLTYPE IShockwaveFlash_get_Quality_Proxy( + IShockwaveFlash * This, + /* [retval][out] */ int *pVal); + + +void __RPC_STUB IShockwaveFlash_get_Quality_Stub( + IRpcStubBuffer *This, + IRpcChannelBuffer *_pRpcChannelBuffer, + PRPC_MESSAGE _pRpcMessage, + DWORD *_pdwStubPhase); + + +/* [helpstring][propput][id] */ HRESULT STDMETHODCALLTYPE IShockwaveFlash_put_Quality_Proxy( + IShockwaveFlash * This, + /* [in] */ int pVal); + + +void __RPC_STUB IShockwaveFlash_put_Quality_Stub( + IRpcStubBuffer *This, + IRpcChannelBuffer *_pRpcChannelBuffer, + PRPC_MESSAGE _pRpcMessage, + DWORD *_pdwStubPhase); + + +/* [helpstring][propget][id] */ HRESULT STDMETHODCALLTYPE IShockwaveFlash_get_ScaleMode_Proxy( + IShockwaveFlash * This, + /* [retval][out] */ int *pVal); + + +void __RPC_STUB IShockwaveFlash_get_ScaleMode_Stub( + IRpcStubBuffer *This, + IRpcChannelBuffer *_pRpcChannelBuffer, + PRPC_MESSAGE _pRpcMessage, + DWORD *_pdwStubPhase); + + +/* [helpstring][propput][id] */ HRESULT STDMETHODCALLTYPE IShockwaveFlash_put_ScaleMode_Proxy( + IShockwaveFlash * This, + /* [in] */ int pVal); + + +void __RPC_STUB IShockwaveFlash_put_ScaleMode_Stub( + IRpcStubBuffer *This, + IRpcChannelBuffer *_pRpcChannelBuffer, + PRPC_MESSAGE _pRpcMessage, + DWORD *_pdwStubPhase); + + +/* [helpstring][propget][id] */ HRESULT STDMETHODCALLTYPE IShockwaveFlash_get_AlignMode_Proxy( + IShockwaveFlash * This, + /* [retval][out] */ int *pVal); + + +void __RPC_STUB IShockwaveFlash_get_AlignMode_Stub( + IRpcStubBuffer *This, + IRpcChannelBuffer *_pRpcChannelBuffer, + PRPC_MESSAGE _pRpcMessage, + DWORD *_pdwStubPhase); + + +/* [helpstring][propput][id] */ HRESULT STDMETHODCALLTYPE IShockwaveFlash_put_AlignMode_Proxy( + IShockwaveFlash * This, + /* [in] */ int pVal); + + +void __RPC_STUB IShockwaveFlash_put_AlignMode_Stub( + IRpcStubBuffer *This, + IRpcChannelBuffer *_pRpcChannelBuffer, + PRPC_MESSAGE _pRpcMessage, + DWORD *_pdwStubPhase); + + +/* [helpstring][propget][id] */ HRESULT STDMETHODCALLTYPE IShockwaveFlash_get_BackgroundColor_Proxy( + IShockwaveFlash * This, + /* [retval][out] */ long *pVal); + + +void __RPC_STUB IShockwaveFlash_get_BackgroundColor_Stub( + IRpcStubBuffer *This, + IRpcChannelBuffer *_pRpcChannelBuffer, + PRPC_MESSAGE _pRpcMessage, + DWORD *_pdwStubPhase); + + +/* [helpstring][propput][id] */ HRESULT STDMETHODCALLTYPE IShockwaveFlash_put_BackgroundColor_Proxy( + IShockwaveFlash * This, + /* [in] */ long pVal); + + +void __RPC_STUB IShockwaveFlash_put_BackgroundColor_Stub( + IRpcStubBuffer *This, + IRpcChannelBuffer *_pRpcChannelBuffer, + PRPC_MESSAGE _pRpcMessage, + DWORD *_pdwStubPhase); + + +/* [helpstring][propget][id] */ HRESULT STDMETHODCALLTYPE IShockwaveFlash_get_Loop_Proxy( + IShockwaveFlash * This, + /* [retval][out] */ VARIANT_BOOL *pVal); + + +void __RPC_STUB IShockwaveFlash_get_Loop_Stub( + IRpcStubBuffer *This, + IRpcChannelBuffer *_pRpcChannelBuffer, + PRPC_MESSAGE _pRpcMessage, + DWORD *_pdwStubPhase); + + +/* [helpstring][propput][id] */ HRESULT STDMETHODCALLTYPE IShockwaveFlash_put_Loop_Proxy( + IShockwaveFlash * This, + /* [in] */ VARIANT_BOOL pVal); + + +void __RPC_STUB IShockwaveFlash_put_Loop_Stub( + IRpcStubBuffer *This, + IRpcChannelBuffer *_pRpcChannelBuffer, + PRPC_MESSAGE _pRpcMessage, + DWORD *_pdwStubPhase); + + +/* [helpstring][propget][id] */ HRESULT STDMETHODCALLTYPE IShockwaveFlash_get_Movie_Proxy( + IShockwaveFlash * This, + /* [retval][out] */ BSTR *pVal); + + +void __RPC_STUB IShockwaveFlash_get_Movie_Stub( + IRpcStubBuffer *This, + IRpcChannelBuffer *_pRpcChannelBuffer, + PRPC_MESSAGE _pRpcMessage, + DWORD *_pdwStubPhase); + + +/* [helpstring][propput][id] */ HRESULT STDMETHODCALLTYPE IShockwaveFlash_put_Movie_Proxy( + IShockwaveFlash * This, + /* [in] */ BSTR pVal); + + +void __RPC_STUB IShockwaveFlash_put_Movie_Stub( + IRpcStubBuffer *This, + IRpcChannelBuffer *_pRpcChannelBuffer, + PRPC_MESSAGE _pRpcMessage, + DWORD *_pdwStubPhase); + + +/* [helpstring][propget][id] */ HRESULT STDMETHODCALLTYPE IShockwaveFlash_get_FrameNum_Proxy( + IShockwaveFlash * This, + /* [retval][out] */ long *pVal); + + +void __RPC_STUB IShockwaveFlash_get_FrameNum_Stub( + IRpcStubBuffer *This, + IRpcChannelBuffer *_pRpcChannelBuffer, + PRPC_MESSAGE _pRpcMessage, + DWORD *_pdwStubPhase); + + +/* [helpstring][propput][id] */ HRESULT STDMETHODCALLTYPE IShockwaveFlash_put_FrameNum_Proxy( + IShockwaveFlash * This, + /* [in] */ long pVal); + + +void __RPC_STUB IShockwaveFlash_put_FrameNum_Stub( + IRpcStubBuffer *This, + IRpcChannelBuffer *_pRpcChannelBuffer, + PRPC_MESSAGE _pRpcMessage, + DWORD *_pdwStubPhase); + + +/* [helpstring][id] */ HRESULT STDMETHODCALLTYPE IShockwaveFlash_SetZoomRect_Proxy( + IShockwaveFlash * This, + /* [in] */ long left, + /* [in] */ long top, + /* [in] */ long right, + /* [in] */ long bottom); + + +void __RPC_STUB IShockwaveFlash_SetZoomRect_Stub( + IRpcStubBuffer *This, + IRpcChannelBuffer *_pRpcChannelBuffer, + PRPC_MESSAGE _pRpcMessage, + DWORD *_pdwStubPhase); + + +/* [helpstring][id] */ HRESULT STDMETHODCALLTYPE IShockwaveFlash_Zoom_Proxy( + IShockwaveFlash * This, + /* [in] */ int factor); + + +void __RPC_STUB IShockwaveFlash_Zoom_Stub( + IRpcStubBuffer *This, + IRpcChannelBuffer *_pRpcChannelBuffer, + PRPC_MESSAGE _pRpcMessage, + DWORD *_pdwStubPhase); + + +/* [helpstring][id] */ HRESULT STDMETHODCALLTYPE IShockwaveFlash_Pan_Proxy( + IShockwaveFlash * This, + /* [in] */ long x, + /* [in] */ long y, + /* [in] */ int mode); + + +void __RPC_STUB IShockwaveFlash_Pan_Stub( + IRpcStubBuffer *This, + IRpcChannelBuffer *_pRpcChannelBuffer, + PRPC_MESSAGE _pRpcMessage, + DWORD *_pdwStubPhase); + + +/* [helpstring][id] */ HRESULT STDMETHODCALLTYPE IShockwaveFlash_Play_Proxy( + IShockwaveFlash * This); + + +void __RPC_STUB IShockwaveFlash_Play_Stub( + IRpcStubBuffer *This, + IRpcChannelBuffer *_pRpcChannelBuffer, + PRPC_MESSAGE _pRpcMessage, + DWORD *_pdwStubPhase); + + +/* [helpstring][id] */ HRESULT STDMETHODCALLTYPE IShockwaveFlash_Stop_Proxy( + IShockwaveFlash * This); + + +void __RPC_STUB IShockwaveFlash_Stop_Stub( + IRpcStubBuffer *This, + IRpcChannelBuffer *_pRpcChannelBuffer, + PRPC_MESSAGE _pRpcMessage, + DWORD *_pdwStubPhase); + + +/* [helpstring][id] */ HRESULT STDMETHODCALLTYPE IShockwaveFlash_Back_Proxy( + IShockwaveFlash * This); + + +void __RPC_STUB IShockwaveFlash_Back_Stub( + IRpcStubBuffer *This, + IRpcChannelBuffer *_pRpcChannelBuffer, + PRPC_MESSAGE _pRpcMessage, + DWORD *_pdwStubPhase); + + +/* [helpstring][id] */ HRESULT STDMETHODCALLTYPE IShockwaveFlash_Forward_Proxy( + IShockwaveFlash * This); + + +void __RPC_STUB IShockwaveFlash_Forward_Stub( + IRpcStubBuffer *This, + IRpcChannelBuffer *_pRpcChannelBuffer, + PRPC_MESSAGE _pRpcMessage, + DWORD *_pdwStubPhase); + + +/* [helpstring][id] */ HRESULT STDMETHODCALLTYPE IShockwaveFlash_Rewind_Proxy( + IShockwaveFlash * This); + + +void __RPC_STUB IShockwaveFlash_Rewind_Stub( + IRpcStubBuffer *This, + IRpcChannelBuffer *_pRpcChannelBuffer, + PRPC_MESSAGE _pRpcMessage, + DWORD *_pdwStubPhase); + + +/* [helpstring][id] */ HRESULT STDMETHODCALLTYPE IShockwaveFlash_StopPlay_Proxy( + IShockwaveFlash * This); + + +void __RPC_STUB IShockwaveFlash_StopPlay_Stub( + IRpcStubBuffer *This, + IRpcChannelBuffer *_pRpcChannelBuffer, + PRPC_MESSAGE _pRpcMessage, + DWORD *_pdwStubPhase); + + +/* [helpstring][id] */ HRESULT STDMETHODCALLTYPE IShockwaveFlash_GotoFrame_Proxy( + IShockwaveFlash * This, + /* [in] */ long FrameNum); + + +void __RPC_STUB IShockwaveFlash_GotoFrame_Stub( + IRpcStubBuffer *This, + IRpcChannelBuffer *_pRpcChannelBuffer, + PRPC_MESSAGE _pRpcMessage, + DWORD *_pdwStubPhase); + + +/* [helpstring][id] */ HRESULT STDMETHODCALLTYPE IShockwaveFlash_CurrentFrame_Proxy( + IShockwaveFlash * This, + /* [retval][out] */ long *FrameNum); + + +void __RPC_STUB IShockwaveFlash_CurrentFrame_Stub( + IRpcStubBuffer *This, + IRpcChannelBuffer *_pRpcChannelBuffer, + PRPC_MESSAGE _pRpcMessage, + DWORD *_pdwStubPhase); + + +/* [helpstring][id] */ HRESULT STDMETHODCALLTYPE IShockwaveFlash_IsPlaying_Proxy( + IShockwaveFlash * This, + /* [retval][out] */ VARIANT_BOOL *Playing); + + +void __RPC_STUB IShockwaveFlash_IsPlaying_Stub( + IRpcStubBuffer *This, + IRpcChannelBuffer *_pRpcChannelBuffer, + PRPC_MESSAGE _pRpcMessage, + DWORD *_pdwStubPhase); + + +/* [helpstring][id] */ HRESULT STDMETHODCALLTYPE IShockwaveFlash_PercentLoaded_Proxy( + IShockwaveFlash * This, + /* [retval][out] */ long *percent); + + +void __RPC_STUB IShockwaveFlash_PercentLoaded_Stub( + IRpcStubBuffer *This, + IRpcChannelBuffer *_pRpcChannelBuffer, + PRPC_MESSAGE _pRpcMessage, + DWORD *_pdwStubPhase); + + +/* [helpstring][id] */ HRESULT STDMETHODCALLTYPE IShockwaveFlash_FrameLoaded_Proxy( + IShockwaveFlash * This, + /* [in] */ long FrameNum, + /* [retval][out] */ VARIANT_BOOL *loaded); + + +void __RPC_STUB IShockwaveFlash_FrameLoaded_Stub( + IRpcStubBuffer *This, + IRpcChannelBuffer *_pRpcChannelBuffer, + PRPC_MESSAGE _pRpcMessage, + DWORD *_pdwStubPhase); + + +/* [helpstring][id] */ HRESULT STDMETHODCALLTYPE IShockwaveFlash_FlashVersion_Proxy( + IShockwaveFlash * This, + /* [retval][out] */ long *version); + + +void __RPC_STUB IShockwaveFlash_FlashVersion_Stub( + IRpcStubBuffer *This, + IRpcChannelBuffer *_pRpcChannelBuffer, + PRPC_MESSAGE _pRpcMessage, + DWORD *_pdwStubPhase); + + +/* [helpstring][propget][id] */ HRESULT STDMETHODCALLTYPE IShockwaveFlash_get_WMode_Proxy( + IShockwaveFlash * This, + /* [retval][out] */ BSTR *pVal); + + +void __RPC_STUB IShockwaveFlash_get_WMode_Stub( + IRpcStubBuffer *This, + IRpcChannelBuffer *_pRpcChannelBuffer, + PRPC_MESSAGE _pRpcMessage, + DWORD *_pdwStubPhase); + + +/* [helpstring][propput][id] */ HRESULT STDMETHODCALLTYPE IShockwaveFlash_put_WMode_Proxy( + IShockwaveFlash * This, + /* [in] */ BSTR pVal); + + +void __RPC_STUB IShockwaveFlash_put_WMode_Stub( + IRpcStubBuffer *This, + IRpcChannelBuffer *_pRpcChannelBuffer, + PRPC_MESSAGE _pRpcMessage, + DWORD *_pdwStubPhase); + + +/* [helpstring][propget][id] */ HRESULT STDMETHODCALLTYPE IShockwaveFlash_get_SAlign_Proxy( + IShockwaveFlash * This, + /* [retval][out] */ BSTR *pVal); + + +void __RPC_STUB IShockwaveFlash_get_SAlign_Stub( + IRpcStubBuffer *This, + IRpcChannelBuffer *_pRpcChannelBuffer, + PRPC_MESSAGE _pRpcMessage, + DWORD *_pdwStubPhase); + + +/* [helpstring][propput][id] */ HRESULT STDMETHODCALLTYPE IShockwaveFlash_put_SAlign_Proxy( + IShockwaveFlash * This, + /* [in] */ BSTR pVal); + + +void __RPC_STUB IShockwaveFlash_put_SAlign_Stub( + IRpcStubBuffer *This, + IRpcChannelBuffer *_pRpcChannelBuffer, + PRPC_MESSAGE _pRpcMessage, + DWORD *_pdwStubPhase); + + +/* [helpstring][propget][id] */ HRESULT STDMETHODCALLTYPE IShockwaveFlash_get_Menu_Proxy( + IShockwaveFlash * This, + /* [retval][out] */ VARIANT_BOOL *pVal); + + +void __RPC_STUB IShockwaveFlash_get_Menu_Stub( + IRpcStubBuffer *This, + IRpcChannelBuffer *_pRpcChannelBuffer, + PRPC_MESSAGE _pRpcMessage, + DWORD *_pdwStubPhase); + + +/* [helpstring][propput][id] */ HRESULT STDMETHODCALLTYPE IShockwaveFlash_put_Menu_Proxy( + IShockwaveFlash * This, + /* [in] */ VARIANT_BOOL pVal); + + +void __RPC_STUB IShockwaveFlash_put_Menu_Stub( + IRpcStubBuffer *This, + IRpcChannelBuffer *_pRpcChannelBuffer, + PRPC_MESSAGE _pRpcMessage, + DWORD *_pdwStubPhase); + + +/* [helpstring][propget][id] */ HRESULT STDMETHODCALLTYPE IShockwaveFlash_get_Base_Proxy( + IShockwaveFlash * This, + /* [retval][out] */ BSTR *pVal); + + +void __RPC_STUB IShockwaveFlash_get_Base_Stub( + IRpcStubBuffer *This, + IRpcChannelBuffer *_pRpcChannelBuffer, + PRPC_MESSAGE _pRpcMessage, + DWORD *_pdwStubPhase); + + +/* [helpstring][propput][id] */ HRESULT STDMETHODCALLTYPE IShockwaveFlash_put_Base_Proxy( + IShockwaveFlash * This, + /* [in] */ BSTR pVal); + + +void __RPC_STUB IShockwaveFlash_put_Base_Stub( + IRpcStubBuffer *This, + IRpcChannelBuffer *_pRpcChannelBuffer, + PRPC_MESSAGE _pRpcMessage, + DWORD *_pdwStubPhase); + + +/* [helpstring][propget][id] */ HRESULT STDMETHODCALLTYPE IShockwaveFlash_get_Scale_Proxy( + IShockwaveFlash * This, + /* [retval][out] */ BSTR *pVal); + + +void __RPC_STUB IShockwaveFlash_get_Scale_Stub( + IRpcStubBuffer *This, + IRpcChannelBuffer *_pRpcChannelBuffer, + PRPC_MESSAGE _pRpcMessage, + DWORD *_pdwStubPhase); + + +/* [helpstring][propput][id] */ HRESULT STDMETHODCALLTYPE IShockwaveFlash_put_Scale_Proxy( + IShockwaveFlash * This, + /* [in] */ BSTR pVal); + + +void __RPC_STUB IShockwaveFlash_put_Scale_Stub( + IRpcStubBuffer *This, + IRpcChannelBuffer *_pRpcChannelBuffer, + PRPC_MESSAGE _pRpcMessage, + DWORD *_pdwStubPhase); + + +/* [helpstring][propget][id] */ HRESULT STDMETHODCALLTYPE IShockwaveFlash_get_DeviceFont_Proxy( + IShockwaveFlash * This, + /* [retval][out] */ VARIANT_BOOL *pVal); + + +void __RPC_STUB IShockwaveFlash_get_DeviceFont_Stub( + IRpcStubBuffer *This, + IRpcChannelBuffer *_pRpcChannelBuffer, + PRPC_MESSAGE _pRpcMessage, + DWORD *_pdwStubPhase); + + +/* [helpstring][propput][id] */ HRESULT STDMETHODCALLTYPE IShockwaveFlash_put_DeviceFont_Proxy( + IShockwaveFlash * This, + /* [in] */ VARIANT_BOOL pVal); + + +void __RPC_STUB IShockwaveFlash_put_DeviceFont_Stub( + IRpcStubBuffer *This, + IRpcChannelBuffer *_pRpcChannelBuffer, + PRPC_MESSAGE _pRpcMessage, + DWORD *_pdwStubPhase); + + +/* [helpstring][propget][id] */ HRESULT STDMETHODCALLTYPE IShockwaveFlash_get_EmbedMovie_Proxy( + IShockwaveFlash * This, + /* [retval][out] */ VARIANT_BOOL *pVal); + + +void __RPC_STUB IShockwaveFlash_get_EmbedMovie_Stub( + IRpcStubBuffer *This, + IRpcChannelBuffer *_pRpcChannelBuffer, + PRPC_MESSAGE _pRpcMessage, + DWORD *_pdwStubPhase); + + +/* [helpstring][propput][id] */ HRESULT STDMETHODCALLTYPE IShockwaveFlash_put_EmbedMovie_Proxy( + IShockwaveFlash * This, + /* [in] */ VARIANT_BOOL pVal); + + +void __RPC_STUB IShockwaveFlash_put_EmbedMovie_Stub( + IRpcStubBuffer *This, + IRpcChannelBuffer *_pRpcChannelBuffer, + PRPC_MESSAGE _pRpcMessage, + DWORD *_pdwStubPhase); + + +/* [helpstring][propget][id] */ HRESULT STDMETHODCALLTYPE IShockwaveFlash_get_BGColor_Proxy( + IShockwaveFlash * This, + /* [retval][out] */ BSTR *pVal); + + +void __RPC_STUB IShockwaveFlash_get_BGColor_Stub( + IRpcStubBuffer *This, + IRpcChannelBuffer *_pRpcChannelBuffer, + PRPC_MESSAGE _pRpcMessage, + DWORD *_pdwStubPhase); + + +/* [helpstring][propput][id] */ HRESULT STDMETHODCALLTYPE IShockwaveFlash_put_BGColor_Proxy( + IShockwaveFlash * This, + /* [in] */ BSTR pVal); + + +void __RPC_STUB IShockwaveFlash_put_BGColor_Stub( + IRpcStubBuffer *This, + IRpcChannelBuffer *_pRpcChannelBuffer, + PRPC_MESSAGE _pRpcMessage, + DWORD *_pdwStubPhase); + + +/* [helpstring][propget][id] */ HRESULT STDMETHODCALLTYPE IShockwaveFlash_get_Quality2_Proxy( + IShockwaveFlash * This, + /* [retval][out] */ BSTR *pVal); + + +void __RPC_STUB IShockwaveFlash_get_Quality2_Stub( + IRpcStubBuffer *This, + IRpcChannelBuffer *_pRpcChannelBuffer, + PRPC_MESSAGE _pRpcMessage, + DWORD *_pdwStubPhase); + + +/* [helpstring][propput][id] */ HRESULT STDMETHODCALLTYPE IShockwaveFlash_put_Quality2_Proxy( + IShockwaveFlash * This, + /* [in] */ BSTR pVal); + + +void __RPC_STUB IShockwaveFlash_put_Quality2_Stub( + IRpcStubBuffer *This, + IRpcChannelBuffer *_pRpcChannelBuffer, + PRPC_MESSAGE _pRpcMessage, + DWORD *_pdwStubPhase); + + +/* [helpstring][id] */ HRESULT STDMETHODCALLTYPE IShockwaveFlash_LoadMovie_Proxy( + IShockwaveFlash * This, + /* [in] */ int layer, + /* [in] */ BSTR url); + + +void __RPC_STUB IShockwaveFlash_LoadMovie_Stub( + IRpcStubBuffer *This, + IRpcChannelBuffer *_pRpcChannelBuffer, + PRPC_MESSAGE _pRpcMessage, + DWORD *_pdwStubPhase); + + +/* [helpstring][id] */ HRESULT STDMETHODCALLTYPE IShockwaveFlash_TGotoFrame_Proxy( + IShockwaveFlash * This, + /* [in] */ BSTR target, + /* [in] */ long FrameNum); + + +void __RPC_STUB IShockwaveFlash_TGotoFrame_Stub( + IRpcStubBuffer *This, + IRpcChannelBuffer *_pRpcChannelBuffer, + PRPC_MESSAGE _pRpcMessage, + DWORD *_pdwStubPhase); + + +/* [helpstring][id] */ HRESULT STDMETHODCALLTYPE IShockwaveFlash_TGotoLabel_Proxy( + IShockwaveFlash * This, + /* [in] */ BSTR target, + /* [in] */ BSTR label); + + +void __RPC_STUB IShockwaveFlash_TGotoLabel_Stub( + IRpcStubBuffer *This, + IRpcChannelBuffer *_pRpcChannelBuffer, + PRPC_MESSAGE _pRpcMessage, + DWORD *_pdwStubPhase); + + +/* [helpstring][id] */ HRESULT STDMETHODCALLTYPE IShockwaveFlash_TCurrentFrame_Proxy( + IShockwaveFlash * This, + /* [in] */ BSTR target, + /* [retval][out] */ long *FrameNum); + + +void __RPC_STUB IShockwaveFlash_TCurrentFrame_Stub( + IRpcStubBuffer *This, + IRpcChannelBuffer *_pRpcChannelBuffer, + PRPC_MESSAGE _pRpcMessage, + DWORD *_pdwStubPhase); + + +/* [helpstring][id] */ HRESULT STDMETHODCALLTYPE IShockwaveFlash_TCurrentLabel_Proxy( + IShockwaveFlash * This, + /* [in] */ BSTR target, + /* [retval][out] */ BSTR *pVal); + + +void __RPC_STUB IShockwaveFlash_TCurrentLabel_Stub( + IRpcStubBuffer *This, + IRpcChannelBuffer *_pRpcChannelBuffer, + PRPC_MESSAGE _pRpcMessage, + DWORD *_pdwStubPhase); + + +/* [helpstring][id] */ HRESULT STDMETHODCALLTYPE IShockwaveFlash_TPlay_Proxy( + IShockwaveFlash * This, + /* [in] */ BSTR target); + + +void __RPC_STUB IShockwaveFlash_TPlay_Stub( + IRpcStubBuffer *This, + IRpcChannelBuffer *_pRpcChannelBuffer, + PRPC_MESSAGE _pRpcMessage, + DWORD *_pdwStubPhase); + + +/* [helpstring][id] */ HRESULT STDMETHODCALLTYPE IShockwaveFlash_TStopPlay_Proxy( + IShockwaveFlash * This, + /* [in] */ BSTR target); + + +void __RPC_STUB IShockwaveFlash_TStopPlay_Stub( + IRpcStubBuffer *This, + IRpcChannelBuffer *_pRpcChannelBuffer, + PRPC_MESSAGE _pRpcMessage, + DWORD *_pdwStubPhase); + + +/* [helpstring][id] */ HRESULT STDMETHODCALLTYPE IShockwaveFlash_SetVariable_Proxy( + IShockwaveFlash * This, + /* [in] */ BSTR name, + /* [in] */ BSTR value); + + +void __RPC_STUB IShockwaveFlash_SetVariable_Stub( + IRpcStubBuffer *This, + IRpcChannelBuffer *_pRpcChannelBuffer, + PRPC_MESSAGE _pRpcMessage, + DWORD *_pdwStubPhase); + + +/* [helpstring][id] */ HRESULT STDMETHODCALLTYPE IShockwaveFlash_GetVariable_Proxy( + IShockwaveFlash * This, + /* [in] */ BSTR name, + /* [retval][out] */ BSTR *pVal); + + +void __RPC_STUB IShockwaveFlash_GetVariable_Stub( + IRpcStubBuffer *This, + IRpcChannelBuffer *_pRpcChannelBuffer, + PRPC_MESSAGE _pRpcMessage, + DWORD *_pdwStubPhase); + + +/* [helpstring][id] */ HRESULT STDMETHODCALLTYPE IShockwaveFlash_TSetProperty_Proxy( + IShockwaveFlash * This, + /* [in] */ BSTR target, + /* [in] */ int property, + /* [in] */ BSTR value); + + +void __RPC_STUB IShockwaveFlash_TSetProperty_Stub( + IRpcStubBuffer *This, + IRpcChannelBuffer *_pRpcChannelBuffer, + PRPC_MESSAGE _pRpcMessage, + DWORD *_pdwStubPhase); + + +/* [helpstring][id] */ HRESULT STDMETHODCALLTYPE IShockwaveFlash_TGetProperty_Proxy( + IShockwaveFlash * This, + /* [in] */ BSTR target, + /* [in] */ int property, + /* [retval][out] */ BSTR *pVal); + + +void __RPC_STUB IShockwaveFlash_TGetProperty_Stub( + IRpcStubBuffer *This, + IRpcChannelBuffer *_pRpcChannelBuffer, + PRPC_MESSAGE _pRpcMessage, + DWORD *_pdwStubPhase); + + +/* [helpstring][id] */ HRESULT STDMETHODCALLTYPE IShockwaveFlash_TCallFrame_Proxy( + IShockwaveFlash * This, + /* [in] */ BSTR target, + /* [in] */ int FrameNum); + + +void __RPC_STUB IShockwaveFlash_TCallFrame_Stub( + IRpcStubBuffer *This, + IRpcChannelBuffer *_pRpcChannelBuffer, + PRPC_MESSAGE _pRpcMessage, + DWORD *_pdwStubPhase); + + +/* [helpstring][id] */ HRESULT STDMETHODCALLTYPE IShockwaveFlash_TCallLabel_Proxy( + IShockwaveFlash * This, + /* [in] */ BSTR target, + /* [in] */ BSTR label); + + +void __RPC_STUB IShockwaveFlash_TCallLabel_Stub( + IRpcStubBuffer *This, + IRpcChannelBuffer *_pRpcChannelBuffer, + PRPC_MESSAGE _pRpcMessage, + DWORD *_pdwStubPhase); + + +/* [helpstring][id] */ HRESULT STDMETHODCALLTYPE IShockwaveFlash_TSetPropertyNum_Proxy( + IShockwaveFlash * This, + /* [in] */ BSTR target, + /* [in] */ int property, + /* [in] */ double value); + + +void __RPC_STUB IShockwaveFlash_TSetPropertyNum_Stub( + IRpcStubBuffer *This, + IRpcChannelBuffer *_pRpcChannelBuffer, + PRPC_MESSAGE _pRpcMessage, + DWORD *_pdwStubPhase); + + +/* [helpstring][id] */ HRESULT STDMETHODCALLTYPE IShockwaveFlash_TGetPropertyNum_Proxy( + IShockwaveFlash * This, + /* [in] */ BSTR target, + /* [in] */ int property, + /* [retval][out] */ double *pVal); + + +void __RPC_STUB IShockwaveFlash_TGetPropertyNum_Stub( + IRpcStubBuffer *This, + IRpcChannelBuffer *_pRpcChannelBuffer, + PRPC_MESSAGE _pRpcMessage, + DWORD *_pdwStubPhase); + + +/* [helpstring][id] */ HRESULT STDMETHODCALLTYPE IShockwaveFlash_TGetPropertyAsNumber_Proxy( + IShockwaveFlash * This, + /* [in] */ BSTR target, + /* [in] */ int property, + /* [retval][out] */ double *pVal); + + +void __RPC_STUB IShockwaveFlash_TGetPropertyAsNumber_Stub( + IRpcStubBuffer *This, + IRpcChannelBuffer *_pRpcChannelBuffer, + PRPC_MESSAGE _pRpcMessage, + DWORD *_pdwStubPhase); + + +/* [helpstring][propget][id] */ HRESULT STDMETHODCALLTYPE IShockwaveFlash_get_SWRemote_Proxy( + IShockwaveFlash * This, + /* [retval][out] */ BSTR *pVal); + + +void __RPC_STUB IShockwaveFlash_get_SWRemote_Stub( + IRpcStubBuffer *This, + IRpcChannelBuffer *_pRpcChannelBuffer, + PRPC_MESSAGE _pRpcMessage, + DWORD *_pdwStubPhase); + + +/* [helpstring][propput][id] */ HRESULT STDMETHODCALLTYPE IShockwaveFlash_put_SWRemote_Proxy( + IShockwaveFlash * This, + /* [in] */ BSTR pVal); + + +void __RPC_STUB IShockwaveFlash_put_SWRemote_Stub( + IRpcStubBuffer *This, + IRpcChannelBuffer *_pRpcChannelBuffer, + PRPC_MESSAGE _pRpcMessage, + DWORD *_pdwStubPhase); + + +/* [helpstring][propget][id] */ HRESULT STDMETHODCALLTYPE IShockwaveFlash_get_FlashVars_Proxy( + IShockwaveFlash * This, + /* [retval][out] */ BSTR *pVal); + + +void __RPC_STUB IShockwaveFlash_get_FlashVars_Stub( + IRpcStubBuffer *This, + IRpcChannelBuffer *_pRpcChannelBuffer, + PRPC_MESSAGE _pRpcMessage, + DWORD *_pdwStubPhase); + + +/* [helpstring][propput][id] */ HRESULT STDMETHODCALLTYPE IShockwaveFlash_put_FlashVars_Proxy( + IShockwaveFlash * This, + /* [in] */ BSTR pVal); + + +void __RPC_STUB IShockwaveFlash_put_FlashVars_Stub( + IRpcStubBuffer *This, + IRpcChannelBuffer *_pRpcChannelBuffer, + PRPC_MESSAGE _pRpcMessage, + DWORD *_pdwStubPhase); + + +/* [helpstring][propget][id] */ HRESULT STDMETHODCALLTYPE IShockwaveFlash_get_AllowScriptAccess_Proxy( + IShockwaveFlash * This, + /* [retval][out] */ BSTR *pVal); + + +void __RPC_STUB IShockwaveFlash_get_AllowScriptAccess_Stub( + IRpcStubBuffer *This, + IRpcChannelBuffer *_pRpcChannelBuffer, + PRPC_MESSAGE _pRpcMessage, + DWORD *_pdwStubPhase); + + +/* [helpstring][propput][id] */ HRESULT STDMETHODCALLTYPE IShockwaveFlash_put_AllowScriptAccess_Proxy( + IShockwaveFlash * This, + /* [in] */ BSTR pVal); + + +void __RPC_STUB IShockwaveFlash_put_AllowScriptAccess_Stub( + IRpcStubBuffer *This, + IRpcChannelBuffer *_pRpcChannelBuffer, + PRPC_MESSAGE _pRpcMessage, + DWORD *_pdwStubPhase); + + +/* [helpstring][propget][id] */ HRESULT STDMETHODCALLTYPE IShockwaveFlash_get_MovieData_Proxy( + IShockwaveFlash * This, + /* [retval][out] */ BSTR *pVal); + + +void __RPC_STUB IShockwaveFlash_get_MovieData_Stub( + IRpcStubBuffer *This, + IRpcChannelBuffer *_pRpcChannelBuffer, + PRPC_MESSAGE _pRpcMessage, + DWORD *_pdwStubPhase); + + +/* [helpstring][propput][id] */ HRESULT STDMETHODCALLTYPE IShockwaveFlash_put_MovieData_Proxy( + IShockwaveFlash * This, + /* [in] */ BSTR pVal); + + +void __RPC_STUB IShockwaveFlash_put_MovieData_Stub( + IRpcStubBuffer *This, + IRpcChannelBuffer *_pRpcChannelBuffer, + PRPC_MESSAGE _pRpcMessage, + DWORD *_pdwStubPhase); + + +/* [helpstring][propget][id] */ HRESULT STDMETHODCALLTYPE IShockwaveFlash_get_InlineData_Proxy( + IShockwaveFlash * This, + /* [retval][out] */ IUnknown **ppIUnknown); + + +void __RPC_STUB IShockwaveFlash_get_InlineData_Stub( + IRpcStubBuffer *This, + IRpcChannelBuffer *_pRpcChannelBuffer, + PRPC_MESSAGE _pRpcMessage, + DWORD *_pdwStubPhase); + + +/* [helpstring][propput][id] */ HRESULT STDMETHODCALLTYPE IShockwaveFlash_put_InlineData_Proxy( + IShockwaveFlash * This, + /* [in] */ IUnknown *ppIUnknown); + + +void __RPC_STUB IShockwaveFlash_put_InlineData_Stub( + IRpcStubBuffer *This, + IRpcChannelBuffer *_pRpcChannelBuffer, + PRPC_MESSAGE _pRpcMessage, + DWORD *_pdwStubPhase); + + +/* [helpstring][propget][id] */ HRESULT STDMETHODCALLTYPE IShockwaveFlash_get_SeamlessTabbing_Proxy( + IShockwaveFlash * This, + /* [retval][out] */ VARIANT_BOOL *pVal); + + +void __RPC_STUB IShockwaveFlash_get_SeamlessTabbing_Stub( + IRpcStubBuffer *This, + IRpcChannelBuffer *_pRpcChannelBuffer, + PRPC_MESSAGE _pRpcMessage, + DWORD *_pdwStubPhase); + + +/* [helpstring][propput][id] */ HRESULT STDMETHODCALLTYPE IShockwaveFlash_put_SeamlessTabbing_Proxy( + IShockwaveFlash * This, + /* [in] */ VARIANT_BOOL pVal); + + +void __RPC_STUB IShockwaveFlash_put_SeamlessTabbing_Stub( + IRpcStubBuffer *This, + IRpcChannelBuffer *_pRpcChannelBuffer, + PRPC_MESSAGE _pRpcMessage, + DWORD *_pdwStubPhase); + + +/* [helpstring][id] */ HRESULT STDMETHODCALLTYPE IShockwaveFlash_EnforceLocalSecurity_Proxy( + IShockwaveFlash * This); + + +void __RPC_STUB IShockwaveFlash_EnforceLocalSecurity_Stub( + IRpcStubBuffer *This, + IRpcChannelBuffer *_pRpcChannelBuffer, + PRPC_MESSAGE _pRpcMessage, + DWORD *_pdwStubPhase); + + +/* [helpstring][propget][id] */ HRESULT STDMETHODCALLTYPE IShockwaveFlash_get_Profile_Proxy( + IShockwaveFlash * This, + /* [retval][out] */ VARIANT_BOOL *pVal); + + +void __RPC_STUB IShockwaveFlash_get_Profile_Stub( + IRpcStubBuffer *This, + IRpcChannelBuffer *_pRpcChannelBuffer, + PRPC_MESSAGE _pRpcMessage, + DWORD *_pdwStubPhase); + + +/* [helpstring][propput][id] */ HRESULT STDMETHODCALLTYPE IShockwaveFlash_put_Profile_Proxy( + IShockwaveFlash * This, + /* [in] */ VARIANT_BOOL pVal); + + +void __RPC_STUB IShockwaveFlash_put_Profile_Stub( + IRpcStubBuffer *This, + IRpcChannelBuffer *_pRpcChannelBuffer, + PRPC_MESSAGE _pRpcMessage, + DWORD *_pdwStubPhase); + + +/* [helpstring][propget][id] */ HRESULT STDMETHODCALLTYPE IShockwaveFlash_get_ProfileAddress_Proxy( + IShockwaveFlash * This, + /* [retval][out] */ BSTR *pVal); + + +void __RPC_STUB IShockwaveFlash_get_ProfileAddress_Stub( + IRpcStubBuffer *This, + IRpcChannelBuffer *_pRpcChannelBuffer, + PRPC_MESSAGE _pRpcMessage, + DWORD *_pdwStubPhase); + + +/* [helpstring][propput][id] */ HRESULT STDMETHODCALLTYPE IShockwaveFlash_put_ProfileAddress_Proxy( + IShockwaveFlash * This, + /* [in] */ BSTR pVal); + + +void __RPC_STUB IShockwaveFlash_put_ProfileAddress_Stub( + IRpcStubBuffer *This, + IRpcChannelBuffer *_pRpcChannelBuffer, + PRPC_MESSAGE _pRpcMessage, + DWORD *_pdwStubPhase); + + +/* [helpstring][propget][id] */ HRESULT STDMETHODCALLTYPE IShockwaveFlash_get_ProfilePort_Proxy( + IShockwaveFlash * This, + /* [retval][out] */ long *pVal); + + +void __RPC_STUB IShockwaveFlash_get_ProfilePort_Stub( + IRpcStubBuffer *This, + IRpcChannelBuffer *_pRpcChannelBuffer, + PRPC_MESSAGE _pRpcMessage, + DWORD *_pdwStubPhase); + + +/* [helpstring][propput][id] */ HRESULT STDMETHODCALLTYPE IShockwaveFlash_put_ProfilePort_Proxy( + IShockwaveFlash * This, + /* [in] */ long pVal); + + +void __RPC_STUB IShockwaveFlash_put_ProfilePort_Stub( + IRpcStubBuffer *This, + IRpcChannelBuffer *_pRpcChannelBuffer, + PRPC_MESSAGE _pRpcMessage, + DWORD *_pdwStubPhase); + + +/* [helpstring][id] */ HRESULT STDMETHODCALLTYPE IShockwaveFlash_CallFunction_Proxy( + IShockwaveFlash * This, + /* [in] */ BSTR request, + /* [retval][out] */ BSTR *response); + + +void __RPC_STUB IShockwaveFlash_CallFunction_Stub( + IRpcStubBuffer *This, + IRpcChannelBuffer *_pRpcChannelBuffer, + PRPC_MESSAGE _pRpcMessage, + DWORD *_pdwStubPhase); + + +/* [helpstring][id] */ HRESULT STDMETHODCALLTYPE IShockwaveFlash_SetReturnValue_Proxy( + IShockwaveFlash * This, + /* [in] */ BSTR returnValue); + + +void __RPC_STUB IShockwaveFlash_SetReturnValue_Stub( + IRpcStubBuffer *This, + IRpcChannelBuffer *_pRpcChannelBuffer, + PRPC_MESSAGE _pRpcMessage, + DWORD *_pdwStubPhase); + + +/* [helpstring][id] */ HRESULT STDMETHODCALLTYPE IShockwaveFlash_DisableLocalSecurity_Proxy( + IShockwaveFlash * This); + + +void __RPC_STUB IShockwaveFlash_DisableLocalSecurity_Stub( + IRpcStubBuffer *This, + IRpcChannelBuffer *_pRpcChannelBuffer, + PRPC_MESSAGE _pRpcMessage, + DWORD *_pdwStubPhase); + + +/* [helpstring][propget][id] */ HRESULT STDMETHODCALLTYPE IShockwaveFlash_get_AllowNetworking_Proxy( + IShockwaveFlash * This, + /* [retval][out] */ BSTR *pVal); + + +void __RPC_STUB IShockwaveFlash_get_AllowNetworking_Stub( + IRpcStubBuffer *This, + IRpcChannelBuffer *_pRpcChannelBuffer, + PRPC_MESSAGE _pRpcMessage, + DWORD *_pdwStubPhase); + + +/* [helpstring][propput][id] */ HRESULT STDMETHODCALLTYPE IShockwaveFlash_put_AllowNetworking_Proxy( + IShockwaveFlash * This, + /* [in] */ BSTR pVal); + + +void __RPC_STUB IShockwaveFlash_put_AllowNetworking_Stub( + IRpcStubBuffer *This, + IRpcChannelBuffer *_pRpcChannelBuffer, + PRPC_MESSAGE _pRpcMessage, + DWORD *_pdwStubPhase); + + +/* [helpstring][propget][id] */ HRESULT STDMETHODCALLTYPE IShockwaveFlash_get_AllowFullScreen_Proxy( + IShockwaveFlash * This, + /* [retval][out] */ BSTR *pVal); + + +void __RPC_STUB IShockwaveFlash_get_AllowFullScreen_Stub( + IRpcStubBuffer *This, + IRpcChannelBuffer *_pRpcChannelBuffer, + PRPC_MESSAGE _pRpcMessage, + DWORD *_pdwStubPhase); + + +/* [helpstring][propput][id] */ HRESULT STDMETHODCALLTYPE IShockwaveFlash_put_AllowFullScreen_Proxy( + IShockwaveFlash * This, + /* [in] */ BSTR pVal); + + +void __RPC_STUB IShockwaveFlash_put_AllowFullScreen_Stub( + IRpcStubBuffer *This, + IRpcChannelBuffer *_pRpcChannelBuffer, + PRPC_MESSAGE _pRpcMessage, + DWORD *_pdwStubPhase); + + + +#endif /* __IShockwaveFlash_INTERFACE_DEFINED__ */ + + +#ifndef ___IShockwaveFlashEvents_DISPINTERFACE_DEFINED__ +#define ___IShockwaveFlashEvents_DISPINTERFACE_DEFINED__ + +/* dispinterface _IShockwaveFlashEvents */ +/* [hidden][helpstring][uuid] */ + + +EXTERN_C const IID DIID__IShockwaveFlashEvents; + +#if defined(__cplusplus) && !defined(CINTERFACE) + + MIDL_INTERFACE("D27CDB6D-AE6D-11CF-96B8-444553540000") + _IShockwaveFlashEvents : public IDispatch + { + }; + +#else /* C style interface */ + + typedef struct _IShockwaveFlashEventsVtbl + { + BEGIN_INTERFACE + + HRESULT ( STDMETHODCALLTYPE *QueryInterface )( + _IShockwaveFlashEvents * This, + /* [in] */ REFIID riid, + /* [iid_is][out] */ void **ppvObject); + + ULONG ( STDMETHODCALLTYPE *AddRef )( + _IShockwaveFlashEvents * This); + + ULONG ( STDMETHODCALLTYPE *Release )( + _IShockwaveFlashEvents * This); + + HRESULT ( STDMETHODCALLTYPE *GetTypeInfoCount )( + _IShockwaveFlashEvents * This, + /* [out] */ UINT *pctinfo); + + HRESULT ( STDMETHODCALLTYPE *GetTypeInfo )( + _IShockwaveFlashEvents * This, + /* [in] */ UINT iTInfo, + /* [in] */ LCID lcid, + /* [out] */ ITypeInfo **ppTInfo); + + HRESULT ( STDMETHODCALLTYPE *GetIDsOfNames )( + _IShockwaveFlashEvents * This, + /* [in] */ REFIID riid, + /* [size_is][in] */ LPOLESTR *rgszNames, + /* [in] */ UINT cNames, + /* [in] */ LCID lcid, + /* [size_is][out] */ DISPID *rgDispId); + + /* [local] */ HRESULT ( STDMETHODCALLTYPE *Invoke )( + _IShockwaveFlashEvents * This, + /* [in] */ DISPID dispIdMember, + /* [in] */ REFIID riid, + /* [in] */ LCID lcid, + /* [in] */ WORD wFlags, + /* [out][in] */ DISPPARAMS *pDispParams, + /* [out] */ VARIANT *pVarResult, + /* [out] */ EXCEPINFO *pExcepInfo, + /* [out] */ UINT *puArgErr); + + END_INTERFACE + } _IShockwaveFlashEventsVtbl; + + interface _IShockwaveFlashEvents + { + CONST_VTBL struct _IShockwaveFlashEventsVtbl *lpVtbl; + }; + + + +#ifdef COBJMACROS + + +#define _IShockwaveFlashEvents_QueryInterface(This,riid,ppvObject) \ + (This)->lpVtbl -> QueryInterface(This,riid,ppvObject) + +#define _IShockwaveFlashEvents_AddRef(This) \ + (This)->lpVtbl -> AddRef(This) + +#define _IShockwaveFlashEvents_Release(This) \ + (This)->lpVtbl -> Release(This) + + +#define _IShockwaveFlashEvents_GetTypeInfoCount(This,pctinfo) \ + (This)->lpVtbl -> GetTypeInfoCount(This,pctinfo) + +#define _IShockwaveFlashEvents_GetTypeInfo(This,iTInfo,lcid,ppTInfo) \ + (This)->lpVtbl -> GetTypeInfo(This,iTInfo,lcid,ppTInfo) + +#define _IShockwaveFlashEvents_GetIDsOfNames(This,riid,rgszNames,cNames,lcid,rgDispId) \ + (This)->lpVtbl -> GetIDsOfNames(This,riid,rgszNames,cNames,lcid,rgDispId) + +#define _IShockwaveFlashEvents_Invoke(This,dispIdMember,riid,lcid,wFlags,pDispParams,pVarResult,pExcepInfo,puArgErr) \ + (This)->lpVtbl -> Invoke(This,dispIdMember,riid,lcid,wFlags,pDispParams,pVarResult,pExcepInfo,puArgErr) + +#endif /* COBJMACROS */ + + +#endif /* C style interface */ + + +#endif /* ___IShockwaveFlashEvents_DISPINTERFACE_DEFINED__ */ + + +#ifndef __IFlashFactory_INTERFACE_DEFINED__ +#define __IFlashFactory_INTERFACE_DEFINED__ + +/* interface IFlashFactory */ +/* [object][helpstring][uuid] */ + + +EXTERN_C const IID IID_IFlashFactory; + +#if defined(__cplusplus) && !defined(CINTERFACE) + + MIDL_INTERFACE("D27CDB70-AE6D-11CF-96B8-444553540000") + IFlashFactory : public IUnknown + { + public: + }; + +#else /* C style interface */ + + typedef struct IFlashFactoryVtbl + { + BEGIN_INTERFACE + + HRESULT ( STDMETHODCALLTYPE *QueryInterface )( + IFlashFactory * This, + /* [in] */ REFIID riid, + /* [iid_is][out] */ void **ppvObject); + + ULONG ( STDMETHODCALLTYPE *AddRef )( + IFlashFactory * This); + + ULONG ( STDMETHODCALLTYPE *Release )( + IFlashFactory * This); + + END_INTERFACE + } IFlashFactoryVtbl; + + interface IFlashFactory + { + CONST_VTBL struct IFlashFactoryVtbl *lpVtbl; + }; + + + +#ifdef COBJMACROS + + +#define IFlashFactory_QueryInterface(This,riid,ppvObject) \ + (This)->lpVtbl -> QueryInterface(This,riid,ppvObject) + +#define IFlashFactory_AddRef(This) \ + (This)->lpVtbl -> AddRef(This) + +#define IFlashFactory_Release(This) \ + (This)->lpVtbl -> Release(This) + + +#endif /* COBJMACROS */ + + +#endif /* C style interface */ + + + + +#endif /* __IFlashFactory_INTERFACE_DEFINED__ */ + + +#ifndef __IFlashObjectInterface_INTERFACE_DEFINED__ +#define __IFlashObjectInterface_INTERFACE_DEFINED__ + +/* interface IFlashObjectInterface */ +/* [object][helpstring][uuid] */ + + +EXTERN_C const IID IID_IFlashObjectInterface; + +#if defined(__cplusplus) && !defined(CINTERFACE) + + MIDL_INTERFACE("D27CDB72-AE6D-11CF-96B8-444553540000") + IFlashObjectInterface : public IDispatchEx + { + public: + }; + +#else /* C style interface */ + + typedef struct IFlashObjectInterfaceVtbl + { + BEGIN_INTERFACE + + HRESULT ( STDMETHODCALLTYPE *QueryInterface )( + IFlashObjectInterface * This, + /* [in] */ REFIID riid, + /* [iid_is][out] */ void **ppvObject); + + ULONG ( STDMETHODCALLTYPE *AddRef )( + IFlashObjectInterface * This); + + ULONG ( STDMETHODCALLTYPE *Release )( + IFlashObjectInterface * This); + + HRESULT ( STDMETHODCALLTYPE *GetTypeInfoCount )( + IFlashObjectInterface * This, + /* [out] */ UINT *pctinfo); + + HRESULT ( STDMETHODCALLTYPE *GetTypeInfo )( + IFlashObjectInterface * This, + /* [in] */ UINT iTInfo, + /* [in] */ LCID lcid, + /* [out] */ ITypeInfo **ppTInfo); + + HRESULT ( STDMETHODCALLTYPE *GetIDsOfNames )( + IFlashObjectInterface * This, + /* [in] */ REFIID riid, + /* [size_is][in] */ LPOLESTR *rgszNames, + /* [in] */ UINT cNames, + /* [in] */ LCID lcid, + /* [size_is][out] */ DISPID *rgDispId); + + /* [local] */ HRESULT ( STDMETHODCALLTYPE *Invoke )( + IFlashObjectInterface * This, + /* [in] */ DISPID dispIdMember, + /* [in] */ REFIID riid, + /* [in] */ LCID lcid, + /* [in] */ WORD wFlags, + /* [out][in] */ DISPPARAMS *pDispParams, + /* [out] */ VARIANT *pVarResult, + /* [out] */ EXCEPINFO *pExcepInfo, + /* [out] */ UINT *puArgErr); + + HRESULT ( __stdcall *GetDispID )( + IFlashObjectInterface * This, + /* [in] */ BSTR bstrName, + /* [in] */ unsigned long grfdex, + /* [out] */ long *pid); + + HRESULT ( __stdcall *RemoteInvokeEx )( + IFlashObjectInterface * This, + /* [in] */ long id, + /* [in] */ unsigned long lcid, + /* [in] */ unsigned long dwFlags, + /* [in] */ DISPPARAMS *pdp, + /* [out] */ VARIANT *pvarRes, + /* [out] */ EXCEPINFO *pei, + /* [in] */ IServiceProvider *pspCaller, + /* [in] */ unsigned int cvarRefArg, + /* [in] */ unsigned int *rgiRefArg, + /* [out][in] */ VARIANT *rgvarRefArg); + + HRESULT ( __stdcall *DeleteMemberByName )( + IFlashObjectInterface * This, + /* [in] */ BSTR bstrName, + /* [in] */ unsigned long grfdex); + + HRESULT ( __stdcall *DeleteMemberByDispID )( + IFlashObjectInterface * This, + /* [in] */ long id); + + HRESULT ( __stdcall *GetMemberProperties )( + IFlashObjectInterface * This, + /* [in] */ long id, + /* [in] */ unsigned long grfdexFetch, + /* [out] */ unsigned long *pgrfdex); + + HRESULT ( __stdcall *GetMemberName )( + IFlashObjectInterface * This, + /* [in] */ long id, + /* [out] */ BSTR *pbstrName); + + HRESULT ( __stdcall *GetNextDispID )( + IFlashObjectInterface * This, + /* [in] */ unsigned long grfdex, + /* [in] */ long id, + /* [out] */ long *pid); + + HRESULT ( __stdcall *GetNameSpaceParent )( + IFlashObjectInterface * This, + /* [out] */ IUnknown **ppunk); + + END_INTERFACE + } IFlashObjectInterfaceVtbl; + + interface IFlashObjectInterface + { + CONST_VTBL struct IFlashObjectInterfaceVtbl *lpVtbl; + }; + + + +#ifdef COBJMACROS + + +#define IFlashObjectInterface_QueryInterface(This,riid,ppvObject) \ + (This)->lpVtbl -> QueryInterface(This,riid,ppvObject) + +#define IFlashObjectInterface_AddRef(This) \ + (This)->lpVtbl -> AddRef(This) + +#define IFlashObjectInterface_Release(This) \ + (This)->lpVtbl -> Release(This) + + +#define IFlashObjectInterface_GetTypeInfoCount(This,pctinfo) \ + (This)->lpVtbl -> GetTypeInfoCount(This,pctinfo) + +#define IFlashObjectInterface_GetTypeInfo(This,iTInfo,lcid,ppTInfo) \ + (This)->lpVtbl -> GetTypeInfo(This,iTInfo,lcid,ppTInfo) + +#define IFlashObjectInterface_GetIDsOfNames(This,riid,rgszNames,cNames,lcid,rgDispId) \ + (This)->lpVtbl -> GetIDsOfNames(This,riid,rgszNames,cNames,lcid,rgDispId) + +#define IFlashObjectInterface_Invoke(This,dispIdMember,riid,lcid,wFlags,pDispParams,pVarResult,pExcepInfo,puArgErr) \ + (This)->lpVtbl -> Invoke(This,dispIdMember,riid,lcid,wFlags,pDispParams,pVarResult,pExcepInfo,puArgErr) + + +#define IFlashObjectInterface_GetDispID(This,bstrName,grfdex,pid) \ + (This)->lpVtbl -> GetDispID(This,bstrName,grfdex,pid) + +#define IFlashObjectInterface_RemoteInvokeEx(This,id,lcid,dwFlags,pdp,pvarRes,pei,pspCaller,cvarRefArg,rgiRefArg,rgvarRefArg) \ + (This)->lpVtbl -> RemoteInvokeEx(This,id,lcid,dwFlags,pdp,pvarRes,pei,pspCaller,cvarRefArg,rgiRefArg,rgvarRefArg) + +#define IFlashObjectInterface_DeleteMemberByName(This,bstrName,grfdex) \ + (This)->lpVtbl -> DeleteMemberByName(This,bstrName,grfdex) + +#define IFlashObjectInterface_DeleteMemberByDispID(This,id) \ + (This)->lpVtbl -> DeleteMemberByDispID(This,id) + +#define IFlashObjectInterface_GetMemberProperties(This,id,grfdexFetch,pgrfdex) \ + (This)->lpVtbl -> GetMemberProperties(This,id,grfdexFetch,pgrfdex) + +#define IFlashObjectInterface_GetMemberName(This,id,pbstrName) \ + (This)->lpVtbl -> GetMemberName(This,id,pbstrName) + +#define IFlashObjectInterface_GetNextDispID(This,grfdex,id,pid) \ + (This)->lpVtbl -> GetNextDispID(This,grfdex,id,pid) + +#define IFlashObjectInterface_GetNameSpaceParent(This,ppunk) \ + (This)->lpVtbl -> GetNameSpaceParent(This,ppunk) + + +#endif /* COBJMACROS */ + + +#endif /* C style interface */ + + + + +#endif /* __IFlashObjectInterface_INTERFACE_DEFINED__ */ + + +#ifndef __IDispatchEx_INTERFACE_DEFINED__ +#define __IDispatchEx_INTERFACE_DEFINED__ + +/* interface IDispatchEx */ +/* [object][uuid] */ + + +EXTERN_C const IID IID_IDispatchEx; + +#if defined(__cplusplus) && !defined(CINTERFACE) + + MIDL_INTERFACE("A6EF9860-C720-11D0-9337-00A0C90DCAA9") + IDispatchEx : public IDispatch + { + public: + virtual HRESULT __stdcall GetDispID( + /* [in] */ BSTR bstrName, + /* [in] */ unsigned long grfdex, + /* [out] */ long *pid) = 0; + + virtual HRESULT __stdcall RemoteInvokeEx( + /* [in] */ long id, + /* [in] */ unsigned long lcid, + /* [in] */ unsigned long dwFlags, + /* [in] */ DISPPARAMS *pdp, + /* [out] */ VARIANT *pvarRes, + /* [out] */ EXCEPINFO *pei, + /* [in] */ IServiceProvider *pspCaller, + /* [in] */ unsigned int cvarRefArg, + /* [in] */ unsigned int *rgiRefArg, + /* [out][in] */ VARIANT *rgvarRefArg) = 0; + + virtual HRESULT __stdcall DeleteMemberByName( + /* [in] */ BSTR bstrName, + /* [in] */ unsigned long grfdex) = 0; + + virtual HRESULT __stdcall DeleteMemberByDispID( + /* [in] */ long id) = 0; + + virtual HRESULT __stdcall GetMemberProperties( + /* [in] */ long id, + /* [in] */ unsigned long grfdexFetch, + /* [out] */ unsigned long *pgrfdex) = 0; + + virtual HRESULT __stdcall GetMemberName( + /* [in] */ long id, + /* [out] */ BSTR *pbstrName) = 0; + + virtual HRESULT __stdcall GetNextDispID( + /* [in] */ unsigned long grfdex, + /* [in] */ long id, + /* [out] */ long *pid) = 0; + + virtual HRESULT __stdcall GetNameSpaceParent( + /* [out] */ IUnknown **ppunk) = 0; + + }; + +#else /* C style interface */ + + typedef struct IDispatchExVtbl + { + BEGIN_INTERFACE + + HRESULT ( STDMETHODCALLTYPE *QueryInterface )( + IDispatchEx * This, + /* [in] */ REFIID riid, + /* [iid_is][out] */ void **ppvObject); + + ULONG ( STDMETHODCALLTYPE *AddRef )( + IDispatchEx * This); + + ULONG ( STDMETHODCALLTYPE *Release )( + IDispatchEx * This); + + HRESULT ( STDMETHODCALLTYPE *GetTypeInfoCount )( + IDispatchEx * This, + /* [out] */ UINT *pctinfo); + + HRESULT ( STDMETHODCALLTYPE *GetTypeInfo )( + IDispatchEx * This, + /* [in] */ UINT iTInfo, + /* [in] */ LCID lcid, + /* [out] */ ITypeInfo **ppTInfo); + + HRESULT ( STDMETHODCALLTYPE *GetIDsOfNames )( + IDispatchEx * This, + /* [in] */ REFIID riid, + /* [size_is][in] */ LPOLESTR *rgszNames, + /* [in] */ UINT cNames, + /* [in] */ LCID lcid, + /* [size_is][out] */ DISPID *rgDispId); + + /* [local] */ HRESULT ( STDMETHODCALLTYPE *Invoke )( + IDispatchEx * This, + /* [in] */ DISPID dispIdMember, + /* [in] */ REFIID riid, + /* [in] */ LCID lcid, + /* [in] */ WORD wFlags, + /* [out][in] */ DISPPARAMS *pDispParams, + /* [out] */ VARIANT *pVarResult, + /* [out] */ EXCEPINFO *pExcepInfo, + /* [out] */ UINT *puArgErr); + + HRESULT ( __stdcall *GetDispID )( + IDispatchEx * This, + /* [in] */ BSTR bstrName, + /* [in] */ unsigned long grfdex, + /* [out] */ long *pid); + + HRESULT ( __stdcall *RemoteInvokeEx )( + IDispatchEx * This, + /* [in] */ long id, + /* [in] */ unsigned long lcid, + /* [in] */ unsigned long dwFlags, + /* [in] */ DISPPARAMS *pdp, + /* [out] */ VARIANT *pvarRes, + /* [out] */ EXCEPINFO *pei, + /* [in] */ IServiceProvider *pspCaller, + /* [in] */ unsigned int cvarRefArg, + /* [in] */ unsigned int *rgiRefArg, + /* [out][in] */ VARIANT *rgvarRefArg); + + HRESULT ( __stdcall *DeleteMemberByName )( + IDispatchEx * This, + /* [in] */ BSTR bstrName, + /* [in] */ unsigned long grfdex); + + HRESULT ( __stdcall *DeleteMemberByDispID )( + IDispatchEx * This, + /* [in] */ long id); + + HRESULT ( __stdcall *GetMemberProperties )( + IDispatchEx * This, + /* [in] */ long id, + /* [in] */ unsigned long grfdexFetch, + /* [out] */ unsigned long *pgrfdex); + + HRESULT ( __stdcall *GetMemberName )( + IDispatchEx * This, + /* [in] */ long id, + /* [out] */ BSTR *pbstrName); + + HRESULT ( __stdcall *GetNextDispID )( + IDispatchEx * This, + /* [in] */ unsigned long grfdex, + /* [in] */ long id, + /* [out] */ long *pid); + + HRESULT ( __stdcall *GetNameSpaceParent )( + IDispatchEx * This, + /* [out] */ IUnknown **ppunk); + + END_INTERFACE + } IDispatchExVtbl; + + interface IDispatchEx + { + CONST_VTBL struct IDispatchExVtbl *lpVtbl; + }; + + + +#ifdef COBJMACROS + + +#define IDispatchEx_QueryInterface(This,riid,ppvObject) \ + (This)->lpVtbl -> QueryInterface(This,riid,ppvObject) + +#define IDispatchEx_AddRef(This) \ + (This)->lpVtbl -> AddRef(This) + +#define IDispatchEx_Release(This) \ + (This)->lpVtbl -> Release(This) + + +#define IDispatchEx_GetTypeInfoCount(This,pctinfo) \ + (This)->lpVtbl -> GetTypeInfoCount(This,pctinfo) + +#define IDispatchEx_GetTypeInfo(This,iTInfo,lcid,ppTInfo) \ + (This)->lpVtbl -> GetTypeInfo(This,iTInfo,lcid,ppTInfo) + +#define IDispatchEx_GetIDsOfNames(This,riid,rgszNames,cNames,lcid,rgDispId) \ + (This)->lpVtbl -> GetIDsOfNames(This,riid,rgszNames,cNames,lcid,rgDispId) + +#define IDispatchEx_Invoke(This,dispIdMember,riid,lcid,wFlags,pDispParams,pVarResult,pExcepInfo,puArgErr) \ + (This)->lpVtbl -> Invoke(This,dispIdMember,riid,lcid,wFlags,pDispParams,pVarResult,pExcepInfo,puArgErr) + + +#define IDispatchEx_GetDispID(This,bstrName,grfdex,pid) \ + (This)->lpVtbl -> GetDispID(This,bstrName,grfdex,pid) + +#define IDispatchEx_RemoteInvokeEx(This,id,lcid,dwFlags,pdp,pvarRes,pei,pspCaller,cvarRefArg,rgiRefArg,rgvarRefArg) \ + (This)->lpVtbl -> RemoteInvokeEx(This,id,lcid,dwFlags,pdp,pvarRes,pei,pspCaller,cvarRefArg,rgiRefArg,rgvarRefArg) + +#define IDispatchEx_DeleteMemberByName(This,bstrName,grfdex) \ + (This)->lpVtbl -> DeleteMemberByName(This,bstrName,grfdex) + +#define IDispatchEx_DeleteMemberByDispID(This,id) \ + (This)->lpVtbl -> DeleteMemberByDispID(This,id) + +#define IDispatchEx_GetMemberProperties(This,id,grfdexFetch,pgrfdex) \ + (This)->lpVtbl -> GetMemberProperties(This,id,grfdexFetch,pgrfdex) + +#define IDispatchEx_GetMemberName(This,id,pbstrName) \ + (This)->lpVtbl -> GetMemberName(This,id,pbstrName) + +#define IDispatchEx_GetNextDispID(This,grfdex,id,pid) \ + (This)->lpVtbl -> GetNextDispID(This,grfdex,id,pid) + +#define IDispatchEx_GetNameSpaceParent(This,ppunk) \ + (This)->lpVtbl -> GetNameSpaceParent(This,ppunk) + +#endif /* COBJMACROS */ + + +#endif /* C style interface */ + + + +HRESULT __stdcall IDispatchEx_GetDispID_Proxy( + IDispatchEx * This, + /* [in] */ BSTR bstrName, + /* [in] */ unsigned long grfdex, + /* [out] */ long *pid); + + +void __RPC_STUB IDispatchEx_GetDispID_Stub( + IRpcStubBuffer *This, + IRpcChannelBuffer *_pRpcChannelBuffer, + PRPC_MESSAGE _pRpcMessage, + DWORD *_pdwStubPhase); + + +HRESULT __stdcall IDispatchEx_RemoteInvokeEx_Proxy( + IDispatchEx * This, + /* [in] */ long id, + /* [in] */ unsigned long lcid, + /* [in] */ unsigned long dwFlags, + /* [in] */ DISPPARAMS *pdp, + /* [out] */ VARIANT *pvarRes, + /* [out] */ EXCEPINFO *pei, + /* [in] */ IServiceProvider *pspCaller, + /* [in] */ unsigned int cvarRefArg, + /* [in] */ unsigned int *rgiRefArg, + /* [out][in] */ VARIANT *rgvarRefArg); + + +void __RPC_STUB IDispatchEx_RemoteInvokeEx_Stub( + IRpcStubBuffer *This, + IRpcChannelBuffer *_pRpcChannelBuffer, + PRPC_MESSAGE _pRpcMessage, + DWORD *_pdwStubPhase); + + +HRESULT __stdcall IDispatchEx_DeleteMemberByName_Proxy( + IDispatchEx * This, + /* [in] */ BSTR bstrName, + /* [in] */ unsigned long grfdex); + + +void __RPC_STUB IDispatchEx_DeleteMemberByName_Stub( + IRpcStubBuffer *This, + IRpcChannelBuffer *_pRpcChannelBuffer, + PRPC_MESSAGE _pRpcMessage, + DWORD *_pdwStubPhase); + + +HRESULT __stdcall IDispatchEx_DeleteMemberByDispID_Proxy( + IDispatchEx * This, + /* [in] */ long id); + + +void __RPC_STUB IDispatchEx_DeleteMemberByDispID_Stub( + IRpcStubBuffer *This, + IRpcChannelBuffer *_pRpcChannelBuffer, + PRPC_MESSAGE _pRpcMessage, + DWORD *_pdwStubPhase); + + +HRESULT __stdcall IDispatchEx_GetMemberProperties_Proxy( + IDispatchEx * This, + /* [in] */ long id, + /* [in] */ unsigned long grfdexFetch, + /* [out] */ unsigned long *pgrfdex); + + +void __RPC_STUB IDispatchEx_GetMemberProperties_Stub( + IRpcStubBuffer *This, + IRpcChannelBuffer *_pRpcChannelBuffer, + PRPC_MESSAGE _pRpcMessage, + DWORD *_pdwStubPhase); + + +HRESULT __stdcall IDispatchEx_GetMemberName_Proxy( + IDispatchEx * This, + /* [in] */ long id, + /* [out] */ BSTR *pbstrName); + + +void __RPC_STUB IDispatchEx_GetMemberName_Stub( + IRpcStubBuffer *This, + IRpcChannelBuffer *_pRpcChannelBuffer, + PRPC_MESSAGE _pRpcMessage, + DWORD *_pdwStubPhase); + + +HRESULT __stdcall IDispatchEx_GetNextDispID_Proxy( + IDispatchEx * This, + /* [in] */ unsigned long grfdex, + /* [in] */ long id, + /* [out] */ long *pid); + + +void __RPC_STUB IDispatchEx_GetNextDispID_Stub( + IRpcStubBuffer *This, + IRpcChannelBuffer *_pRpcChannelBuffer, + PRPC_MESSAGE _pRpcMessage, + DWORD *_pdwStubPhase); + + +HRESULT __stdcall IDispatchEx_GetNameSpaceParent_Proxy( + IDispatchEx * This, + /* [out] */ IUnknown **ppunk); + + +void __RPC_STUB IDispatchEx_GetNameSpaceParent_Stub( + IRpcStubBuffer *This, + IRpcChannelBuffer *_pRpcChannelBuffer, + PRPC_MESSAGE _pRpcMessage, + DWORD *_pdwStubPhase); + + + +#endif /* __IDispatchEx_INTERFACE_DEFINED__ */ + + +#ifndef __IServiceProvider_INTERFACE_DEFINED__ +#define __IServiceProvider_INTERFACE_DEFINED__ + +/* interface IServiceProvider */ +/* [object][uuid] */ + + +EXTERN_C const IID IID_IServiceProvider; + +#if defined(__cplusplus) && !defined(CINTERFACE) + + MIDL_INTERFACE("6D5140C1-7436-11CE-8034-00AA006009FA") + IServiceProvider : public IUnknown + { + public: + virtual HRESULT __stdcall RemoteQueryService( + /* [in] */ GUID *guidService, + /* [in] */ GUID *riid, + /* [out] */ IUnknown **ppvObject) = 0; + + }; + +#else /* C style interface */ + + typedef struct IServiceProviderVtbl + { + BEGIN_INTERFACE + + HRESULT ( STDMETHODCALLTYPE *QueryInterface )( + IServiceProvider * This, + /* [in] */ REFIID riid, + /* [iid_is][out] */ void **ppvObject); + + ULONG ( STDMETHODCALLTYPE *AddRef )( + IServiceProvider * This); + + ULONG ( STDMETHODCALLTYPE *Release )( + IServiceProvider * This); + + HRESULT ( __stdcall *RemoteQueryService )( + IServiceProvider * This, + /* [in] */ GUID *guidService, + /* [in] */ GUID *riid, + /* [out] */ IUnknown **ppvObject); + + END_INTERFACE + } IServiceProviderVtbl; + + interface IServiceProvider + { + CONST_VTBL struct IServiceProviderVtbl *lpVtbl; + }; + + + +#ifdef COBJMACROS + + +#define IServiceProvider_QueryInterface(This,riid,ppvObject) \ + (This)->lpVtbl -> QueryInterface(This,riid,ppvObject) + +#define IServiceProvider_AddRef(This) \ + (This)->lpVtbl -> AddRef(This) + +#define IServiceProvider_Release(This) \ + (This)->lpVtbl -> Release(This) + + +#define IServiceProvider_RemoteQueryService(This,guidService,riid,ppvObject) \ + (This)->lpVtbl -> RemoteQueryService(This,guidService,riid,ppvObject) + +#endif /* COBJMACROS */ + + +#endif /* C style interface */ + + + +HRESULT __stdcall IServiceProvider_RemoteQueryService_Proxy( + IServiceProvider * This, + /* [in] */ GUID *guidService, + /* [in] */ GUID *riid, + /* [out] */ IUnknown **ppvObject); + + +void __RPC_STUB IServiceProvider_RemoteQueryService_Stub( + IRpcStubBuffer *This, + IRpcChannelBuffer *_pRpcChannelBuffer, + PRPC_MESSAGE _pRpcMessage, + DWORD *_pdwStubPhase); + + + +#endif /* __IServiceProvider_INTERFACE_DEFINED__ */ + + +EXTERN_C const CLSID CLSID_ShockwaveFlash; + +#ifdef __cplusplus + +class DECLSPEC_UUID("D27CDB6E-AE6D-11CF-96B8-444553540000") +ShockwaveFlash; +#endif + +EXTERN_C const CLSID CLSID_FlashObjectInterface; + +#ifdef __cplusplus + +class DECLSPEC_UUID("D27CDB71-AE6D-11CF-96B8-444553540000") +FlashObjectInterface; +#endif +#endif /* __ShockwaveFlashObjects_LIBRARY_DEFINED__ */ + +/* Additional Prototypes for ALL interfaces */ + +/* end of Additional Prototypes */ + +#ifdef __cplusplus +} +#endif + +#endif + + diff --git a/core/producer/flash/cg_producer.cpp b/core/producer/flash/cg_producer.cpp new file mode 100644 index 000000000..94d544d6d --- /dev/null +++ b/core/producer/flash/cg_producer.cpp @@ -0,0 +1,280 @@ +#include "../../StdAfx.h" + +#if defined(_MSC_VER) +#pragma warning (disable : 4714) // marked as __forceinline not inlined +#endif + +#include "cg_producer.h" +#include "flash_producer.h" + +#include "../../renderer/render_device.h" +#include "../../frame/frame_format.h" +#include "../../frame/frame.h" +#include "../../Server.h" + +#include +#include +#include + +namespace caspar{ namespace flash{ + +struct flash_cg_proxy +{ + virtual std::wstring add(int layer, const std::wstring& templateName, bool playOnLoad, const std::wstring& startFromLabel = TEXT(""), const std::wstring& data = TEXT("")) = 0; + virtual std::wstring remove(int layer) = 0; + virtual std::wstring play(int layer) = 0; + virtual std::wstring stop(int layer, unsigned int mixOutDuration) = 0; + virtual std::wstring next(int layer) = 0; + virtual std::wstring update(int layer, const std::wstring& data) = 0; + virtual std::wstring invoke(int layer, const std::wstring& label) = 0; +}; + +struct flash_cg_proxy16 : public flash_cg_proxy +{ + virtual std::wstring add(int layer, const std::wstring& templateName, bool playOnLoad, const std::wstring& label, const std::wstring& data) + { + std::wstringstream flashParam; + std::wstring::size_type pos = templateName.find('.'); + std::wstring filename = (pos != std::wstring::npos) ? templateName.substr(0, pos) : templateName; + flashParam << TEXT("") << layer << TEXT("") << filename << TEXT("0") << (playOnLoad?TEXT(""):TEXT("")) << TEXT("") << label << TEXT(""); + return flashParam.str(); + } + + virtual std::wstring remove(int layer) + { + std::wstringstream flashParam; + flashParam << TEXT("") << layer << TEXT(""); + return flashParam.str(); + } + + virtual std::wstring play(int layer) + { + std::wstringstream flashParam; + flashParam << TEXT("") << layer << TEXT(""); + return flashParam.str(); + } + + virtual std::wstring stop(int layer, unsigned int mixOutDuration) + { + std::wstringstream flashParam; + flashParam << TEXT("") << layer << TEXT("") << mixOutDuration << TEXT(""); + return flashParam.str(); + } + + virtual std::wstring next(int layer) + { + std::wstringstream flashParam; + flashParam << TEXT("") << layer << TEXT(""); + return flashParam.str(); + } + + virtual std::wstring update(int layer, const std::wstring& data) + { + std::wstringstream flashParam; + flashParam << TEXT("") << layer << TEXT(""); + return flashParam.str(); + } + + virtual std::wstring invoke(int layer, const std::wstring& label) + { + std::wstringstream flashParam; + flashParam << TEXT("") << layer << TEXT("") << label << TEXT(""); + return flashParam.str(); + } +}; + +struct flash_cg_proxy17 : public flash_cg_proxy +{ + virtual std::wstring add(int layer, const std::wstring& templateName, bool playOnLoad, const std::wstring& label, const std::wstring& data) + { + std::wstringstream flashParam; + + std::wstring::size_type pos = templateName.find('.'); + std::wstring filename = (pos != std::wstring::npos) ? templateName.substr(0, pos) : templateName; + + flashParam << TEXT("") << layer << TEXT("") << filename << TEXT("") << (playOnLoad?TEXT(""):TEXT("")) << TEXT("") << label << TEXT(""); + return flashParam.str(); + } + + virtual std::wstring remove(int layer) + { + std::wstringstream flashParam; + flashParam << TEXT("") << layer << TEXT(""); + return flashParam.str(); + } + + virtual std::wstring play(int layer) + { + std::wstringstream flashParam; + flashParam << TEXT("") << layer << TEXT(""); + return flashParam.str(); + } + + virtual std::wstring stop(int layer, unsigned int mixOutDuration) + { + std::wstringstream flashParam; + flashParam << TEXT("") << layer << TEXT("") << mixOutDuration << TEXT(""); + return flashParam.str(); + } + + virtual std::wstring next(int layer) + { + std::wstringstream flashParam; + flashParam << TEXT("") << layer << TEXT(""); + return flashParam.str(); + } + + virtual std::wstring update(int layer, const std::wstring& data) + { + std::wstringstream flashParam; + flashParam << TEXT("") << layer << TEXT(""); + return flashParam.str(); + } + + virtual std::wstring invoke(int layer, const std::wstring& label) + { + std::wstringstream flashParam; + flashParam << TEXT("") << layer << TEXT("") << label << TEXT(""); + return flashParam.str(); + } +}; + +struct flash_cg_proxy18 : public flash_cg_proxy17 +{ + virtual std::wstring add(int layer, const std::wstring& templateName, bool playOnLoad, const std::wstring& label, const std::wstring& data) + { + std::wstringstream flashParam; + flashParam << TEXT("") << layer << TEXT("") << templateName << TEXT("") << (playOnLoad?TEXT(""):TEXT("")) << TEXT("") << label << TEXT(""); + return flashParam.str(); + } +}; + +struct cg_producer::implementation : boost::noncopyable +{ +public: + + implementation(const frame_format_desc& fmtDesc, Monitor* pMonitor) : format_desc_(fmtDesc) + { + if(boost::filesystem::exists(server::template_folder()+TEXT("cg.fth.18"))) + { + flash_producer_ = std::make_shared(server::template_folder()+TEXT("cg.fth.18"), fmtDesc, pMonitor); + proxy_.reset(new flash_cg_proxy18()); + CASPAR_LOG(info) << L"Running version 1.8 template graphics."; + } + else if(boost::filesystem::exists(server::template_folder()+TEXT("cg.fth.17"))) + { + flash_producer_ = std::make_shared(server::template_folder()+TEXT("cg.fth.17"), fmtDesc, pMonitor); + proxy_.reset(new flash_cg_proxy17()); + CASPAR_LOG(info) << L"Running version 1.7 template graphics."; + } + else if(boost::filesystem::exists(server::template_folder()+TEXT("cg.fth"))) + { + flash_producer_ = std::make_shared(server::template_folder()+TEXT("cg.fth"), fmtDesc, pMonitor); + proxy_.reset(new flash_cg_proxy16()); + CASPAR_LOG(info) << L"Running version 1.6 template graphics."; + } + else + CASPAR_LOG(info) << L"No templatehost found. Template graphics will be disabled"; + + } + + void clear() + { + flash_producer_.reset(); + } + + void add(int layer, const std::wstring& templateName, bool playOnLoad, const std::wstring& startFromLabel, const std::wstring& data) + { + if(flash_producer_ == nullptr) + return; + CASPAR_LOG(info) << "Invoking add-command"; + flash_producer_->param(proxy_->add(layer, templateName, playOnLoad, startFromLabel, data)); + } + + void remove(int layer) + { + if(flash_producer_ == nullptr) + return; + CASPAR_LOG(info) << "Invoking remove-command"; + flash_producer_->param(proxy_->remove(layer)); + } + + void play(int layer) + { + if(flash_producer_ == nullptr) + return; + CASPAR_LOG(info) << "Invoking play-command"; + flash_producer_->param(proxy_->play(layer)); + } + + void stop(int layer, unsigned int mixOutDuration) + { + if(flash_producer_ == nullptr) + return; + CASPAR_LOG(info) << "Invoking stop-command"; + flash_producer_->param(proxy_->stop(layer, mixOutDuration)); + } + + void next(int layer) + { + if(flash_producer_ == nullptr) + return; + CASPAR_LOG(info) << "Invoking next-command"; + flash_producer_->param(proxy_->next(layer)); + } + + void update(int layer, const std::wstring& data) + { + if(flash_producer_ == nullptr) + return; + CASPAR_LOG(info) << "Invoking update-command"; + flash_producer_->param(proxy_->update(layer, data)); + } + + void invoke(int layer, const std::wstring& label) + { + if(flash_producer_ == nullptr) + return; + CASPAR_LOG(info) << "Invoking invoke-command"; + flash_producer_->param(proxy_->invoke(layer, label)); + } + + frame_ptr get_frame() + { + return flash_producer_ ? flash_producer_->get_frame() : nullptr; + } + + frame_format_desc format_desc_; + flash_producer_ptr flash_producer_; + std::unique_ptr proxy_; +}; + + +// This is somewhat a hack... needs redesign +cg_producer_ptr get_default_cg_producer(const renderer::render_device_ptr& prender_device, unsigned int exLayer) +{ + if(!prender_device) + BOOST_THROW_EXCEPTION(null_argument() << msg_info("prender_device")); + + auto pProducer = std::dynamic_pointer_cast(prender_device->active(exLayer)); + if(!pProducer) + { + pProducer = std::make_shared(prender_device->frame_format_desc(), &prender_device->monitor()); + prender_device->load(exLayer, pProducer, renderer::load_option::auto_play); + } + + return pProducer; +} + +cg_producer::cg_producer(const frame_format_desc& fmtDesc, Monitor* pMonitor) : impl_(new implementation(fmtDesc, pMonitor)){} +frame_ptr cg_producer::get_frame(){return impl_->get_frame();} +void cg_producer::clear(){impl_->clear();} +void cg_producer::add(int layer, const std::wstring& templateName, bool playOnLoad, const std::wstring& startFromLabel, const std::wstring& data){impl_->add(layer, templateName, playOnLoad, startFromLabel, data);} +void cg_producer::remove(int layer){impl_->remove(layer);} +void cg_producer::play(int layer){impl_->play(layer);} +void cg_producer::stop(int layer, unsigned int mixOutDuration){impl_->stop(layer, mixOutDuration);} +void cg_producer::next(int layer){impl_->next(layer);} +void cg_producer::update(int layer, const std::wstring& data){impl_->update(layer, data);} +void cg_producer::invoke(int layer, const std::wstring& label){impl_->invoke(layer, label);} +const frame_format_desc& cg_producer::get_frame_format_desc() const { return impl_->format_desc_; } +}} \ No newline at end of file diff --git a/core/producer/flash/cg_producer.h b/core/producer/flash/cg_producer.h new file mode 100644 index 000000000..857181b67 --- /dev/null +++ b/core/producer/flash/cg_producer.h @@ -0,0 +1,36 @@ +#pragma once + +#include "../frame_producer.h" +#include "../../frame/frame_fwd.h" +#include "../../renderer/render_device.h" + +namespace caspar{ namespace flash{ + +class cg_producer : public frame_producer +{ +public: + cg_producer(const frame_format_desc& format_desc, Monitor* pMonitor); + + frame_ptr get_frame(); + + void clear(); + void add(int layer, const std::wstring& template_name, bool play_on_load, const std::wstring& start_from_label = TEXT(""), const std::wstring& data = TEXT("")); + void remove(int layer); + void play(int layer); + void stop(int layer, unsigned int mix_out_duration); + void next(int layer); + void update(int layer, const std::wstring& data); + void invoke(int layer, const std::wstring& label); + + const frame_format_desc& get_frame_format_desc() const; +private: + struct implementation; + std::shared_ptr impl_; +}; +typedef std::shared_ptr cg_producer_ptr; + +static const unsigned int CG_DEFAULT_LAYER = 5000; + +cg_producer_ptr get_default_cg_producer(const renderer::render_device_ptr& render_device, unsigned int layer_index = CG_DEFAULT_LAYER); + +}} \ No newline at end of file diff --git a/core/producer/flash/ct_producer.cpp b/core/producer/flash/ct_producer.cpp new file mode 100644 index 000000000..b7c519360 --- /dev/null +++ b/core/producer/flash/ct_producer.cpp @@ -0,0 +1,56 @@ +/* +* copyright (c) 2010 Sveriges Television AB +* +* This file is part of CasparCG. +* +* CasparCG is free software: you can redistribute it and/or modify +* it under the terms of the GNU General Public License as published by +* the Free Software Foundation, either version 3 of the License, or +* (at your option) any later version. +* +* CasparCG is distributed in the hope that it will be useful, +* but WITHOUT ANY WARRANTY; without even the implied warranty of +* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +* GNU General Public License for more details. + +* You should have received a copy of the GNU General Public License +* along with CasparCG. If not, see . +* +*/ + +#include "../../stdafx.h" + +#include "ct_producer.h" + +#include "cg_producer.h" + +#include "../../../common/utility/find_file.h" +#include "../../frame/frame.h" +#include "../../server.h" + +#include + +using namespace boost::assign; + +namespace caspar { namespace flash { + +frame_producer_ptr create_ct_producer(const std::vector& params, const frame_format_desc& format_desc) +{ + std::wstring filename = params[0]; + std::wstring result_filename = common::find_file(server::media_folder() + filename, list_of(L"ct")); + if(result_filename.empty()) + return nullptr; + + std::wstring fixed_filename = result_filename; + std::wstring::size_type pos = 0; + while((pos = fixed_filename.find(TEXT('\\'), pos)) != std::wstring::npos) + fixed_filename[pos] = TEXT('/'); + + cg_producer_ptr cg_producer(new cg_producer(format_desc, nullptr)); + cg_producer->add(0, filename, 1); + return cg_producer; +} + +} + +} //namespace caspar \ No newline at end of file diff --git a/core/producer/flash/ct_producer.h b/core/producer/flash/ct_producer.h new file mode 100644 index 000000000..581edf547 --- /dev/null +++ b/core/producer/flash/ct_producer.h @@ -0,0 +1,28 @@ +/* +* copyright (c) 2010 Sveriges Television AB +* +* This file is part of CasparCG. +* +* CasparCG is free software: you can redistribute it and/or modify +* it under the terms of the GNU General Public License as published by +* the Free Software Foundation, either version 3 of the License, or +* (at your option) any later version. +* +* CasparCG is distributed in the hope that it will be useful, +* but WITHOUT ANY WARRANTY; without even the implied warranty of +* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +* GNU General Public License for more details. + +* You should have received a copy of the GNU General Public License +* along with CasparCG. If not, see . +* +*/ +#pragma once + +#include "../frame_producer.h" + +namespace caspar{ namespace flash{ + +caspar::frame_producer_ptr create_ct_producer(const std::vector& params, const frame_format_desc& format_desc); + +}} \ No newline at end of file diff --git a/core/producer/flash/flash_producer.cpp b/core/producer/flash/flash_producer.cpp new file mode 100644 index 000000000..6b6ef3e67 --- /dev/null +++ b/core/producer/flash/flash_producer.cpp @@ -0,0 +1,312 @@ +/* +* copyright (c) 2010 Sveriges Television AB +* +* This file is part of CasparCG. +* +* CasparCG is free software: you can redistribute it and/or modify +* it under the terms of the GNU General Public License as published by +* the Free Software Foundation, either version 3 of the License, or +* (at your option) any later version. +* +* CasparCG is distributed in the hope that it will be useful, +* but WITHOUT ANY WARRANTY; without even the implied warranty of +* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +* GNU General Public License for more details. + +* You should have received a copy of the GNU General Public License +* along with CasparCG. If not, see . +* +*/ + +#include "..\..\stdafx.h" + +#if defined(_MSC_VER) +#pragma warning (disable : 4714) // marked as __forceinline not inlined +#endif + +#include "flash_producer.h" +#include "FlashAxContainer.h" +#include "TimerHelper.h" + +#include "../../frame/bitmap_frame.h" +#include "../../frame/frame_format.h" +#include "../../frame/system_frame.h" +#include "../../../common/utility/find_file.h" +#include "../../server.h" +#include "../../../common/concurrency/executor.h" +#include "../../../common/concurrency/function_task.h" +#include "../../../common/image/image.h" +#include "../../../common/utility/scope_exit.h" + +#include +#include +#include + +#include +#include + +#include + +namespace caspar { namespace flash { + +using namespace boost::assign; + +// This is needed in order to make CComObject work since this is not a real ATL project +CComModule _AtlModule; +extern __declspec(selectany) CAtlModule* _pAtlModule = &_AtlModule; + +struct flash_producer::implementation +{ + implementation(flash_producer* self, const std::wstring& filename, const frame_format_desc& format_desc, Monitor* monitor) + : flashax_container_(nullptr), filename_(filename), self_(self), format_desc_(format_desc), monitor_(monitor), + bitmap_pool_(new bitmap_pool), executor_([=]{run();}), invalid_count_(0) + { + if(!boost::filesystem::exists(filename)) + BOOST_THROW_EXCEPTION(file_not_found() << boost::errinfo_file_name(common::narrow(filename))); + + frame_buffer_.set_capacity(flash_producer::DEFAULT_BUFFER_SIZE); + last_frame_ = std::make_shared(format_desc_.width, format_desc_.height); + + start(); + } + + ~implementation() + { + stop(); + } + + void start() + { + try + { + is_empty_ = true; + executor_.stop(); // Restart if running + executor_.start(); + executor_.invoke([=]() + { + if(FAILED(CComObject::CreateInstance(&flashax_container_)) || + flashax_container_ == nullptr) + BOOST_THROW_EXCEPTION(caspar_exception() << msg_info("Failed to create FlashAxContainer")); + + flashax_container_->pflash_producer_ = self_; + CComPtr spFlash; + + if(FAILED(flashax_container_->CreateAxControl())) + BOOST_THROW_EXCEPTION(caspar_exception() << msg_info("Failed to Create FlashAxControl")); + + if(FAILED(flashax_container_->QueryControl(&spFlash))) + BOOST_THROW_EXCEPTION(caspar_exception() << msg_info("Failed to Query FlashAxControl")); + + if(FAILED(spFlash->put_Playing(true)) ) + BOOST_THROW_EXCEPTION(caspar_exception() << msg_info("Failed to start playing Flash")); + + if(FAILED(spFlash->put_Movie(CComBSTR(filename_.c_str())))) + BOOST_THROW_EXCEPTION(caspar_exception() << msg_info("Failed to Load Template Host")); + + //Exact fit. Scale without respect to the aspect ratio. + if(FAILED(spFlash->put_ScaleMode(2))) + BOOST_THROW_EXCEPTION(caspar_exception() << msg_info("Failed to Set Scale Mode")); + + // stop if failed + if(FAILED(flashax_container_->SetFormat(format_desc_))) + BOOST_THROW_EXCEPTION(caspar_exception() << msg_info("Failed to Set Format")); + + current_frame_ = nullptr; // Force re-render of current frame + }); + } + catch(...) + { + stop(); + CASPAR_LOG_CURRENT_EXCEPTION(); + throw; + } + } + + void stop() + { + is_empty_ = true; + if(executor_.is_running()) + { + frame_buffer_.clear(); + executor_.stop(); + } + } + + void param(const std::wstring& param) + { + if(!executor_.is_running()) + { + try + { + start(); + } + catch(caspar_exception& e) + { + e << msg_info("Flashproducer failed to recover from failure."); + throw e; + } + } + + executor_.invoke([&]() + { + for(size_t retries = 0; !flashax_container_->CallFunction(param); ++retries) + { + CASPAR_LOG(debug) << "Retrying. Count: " << retries; + if(retries > 3) + BOOST_THROW_EXCEPTION(operation_failed() << warg_name_info(L"param") << warg_value_info(param)); + } + is_empty_ = false; + }); + } + + void run() + { + win32_exception::install_handler(); + CASPAR_LOG(info) << L"started flash_producer Thread"; + + try + { + ::OleInitialize(nullptr); + CASPAR_SCOPE_EXIT(::OleUninitialize); + + CASPAR_SCOPE_EXIT([=] + { + if(flashax_container_ != nullptr) + { + flashax_container_->DestroyAxControl(); + flashax_container_->Release(); + flashax_container_ = nullptr; + } + }); + + CASPAR_SCOPE_EXIT([=] + { + stop(); + + frame_buffer_.clear(); + frame_buffer_.try_push(nullptr); // EOF + + current_frame_ = nullptr; + }); + + while(executor_.is_running()) + { + if(!is_empty_) + { + render(); + while(executor_.try_execute()){} + } + else + { + executor_.execute(); + while(executor_.try_execute()){} + } + } + } + catch(...) + { + CASPAR_LOG_CURRENT_EXCEPTION(); + } + + CASPAR_LOG(info) << L"Ended flash_producer Thread"; + } + + void render() + { + assert(flashax_container_); + + if(!is_empty_ || current_frame_ == nullptr) + { + if(!flashax_container_->IsReadyToRender()) + { + CASPAR_LOG(trace) << "Flash Producer Underflow"; + boost::thread::yield(); + return; + } + + bool isProgressive = format_desc_.mode == video_mode::progressive || (flashax_container_->GetFPS() - format_desc_.fps/2 == 0); + frame_buffer_.push(isProgressive ? render_frame() : render_interlace_frame()); + is_empty_ = flashax_container_->IsEmpty(); + } + } + + frame_ptr render_interlace_frame() + { + return copy_frame(render_frame(), render_frame(), format_desc_); + } + + frame_ptr render_frame() + { + flashax_container_->Tick(); + invalid_count_ = !flashax_container_->InvalidRectangle() ? std::min(2, invalid_count_+1) : 0; + if(current_frame_ == nullptr || invalid_count_ < 2) + { + bitmap_frame_ptr frame; + if(!bitmap_pool_->try_pop(frame)) + { + CASPAR_LOG(trace) << "Allocated bitmap_frame"; + frame = clear_frame(std::make_shared(format_desc_.width, format_desc_.height)); + } + flashax_container_->DrawControl(frame->hdc()); + + auto pool = bitmap_pool_; + current_frame_.reset(frame.get(), [=](bitmap_frame*) + { + common::function_task::enqueue([=]{pool->try_push(clear_frame(frame));}); + }); + } + return current_frame_; + } + + frame_ptr get_frame() + { + return frame_buffer_.try_pop(last_frame_) || !is_empty_ ? last_frame_ : frame::null(); + } + + typedef tbb::concurrent_bounded_queue bitmap_pool; + std::shared_ptr bitmap_pool_; + frame_format_desc format_desc_; + + CComObject* flashax_container_; + + tbb::concurrent_bounded_queue frame_buffer_; + frame_ptr last_frame_; + frame_ptr current_frame_; + + std::wstring filename_; + flash_producer* self_; + Monitor* monitor_; + + tbb::atomic is_empty_; + common::executor executor_; + int invalid_count_; +}; + +flash_producer::flash_producer(const std::wstring& filename, const frame_format_desc& format_desc, Monitor* monitor) : impl_(new implementation(this, filename, format_desc, monitor)){} +frame_ptr flash_producer::get_frame(){return impl_->get_frame();} +Monitor* flash_producer::get_monitor(){return impl_->monitor_; } +void flash_producer::param(const std::wstring& param){impl_->param(param);} +const frame_format_desc& flash_producer::get_frame_format_desc() const { return impl_->format_desc_; } + +std::wstring flash_producer::find_template(const std::wstring& template_name) +{ + if(boost::filesystem::exists(template_name + TEXT(".ft"))) + return template_name + TEXT(".ft"); + + if(boost::filesystem::exists(template_name + TEXT(".ct"))) + return template_name + TEXT(".ct"); + + return TEXT(""); +} + +flash_producer_ptr create_flash_producer(const std::vector& params, const frame_format_desc& format_desc) +{ + // TODO: Check for flash support + auto filename = params[0]; + std::wstring result_filename = common::find_file(server::media_folder() + filename, + list_of(L"swf")); + + return result_filename.empty() ? nullptr : std::make_shared(result_filename, format_desc); +} + +}} \ No newline at end of file diff --git a/core/producer/flash/flash_producer.h b/core/producer/flash/flash_producer.h new file mode 100644 index 000000000..0a815af5c --- /dev/null +++ b/core/producer/flash/flash_producer.h @@ -0,0 +1,67 @@ +/* +* copyright (c) 2010 Sveriges Television AB +* +* This file is part of CasparCG. +* +* CasparCG is free software: you can redistribute it and/or modify +* it under the terms of the GNU General Public License as published by +* the Free Software Foundation, either version 3 of the License, or +* (at your option) any later version. +* +* CasparCG is distributed in the hope that it will be useful, +* but WITHOUT ANY WARRANTY; without even the implied warranty of +* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +* GNU General Public License for more details. + +* You should have received a copy of the GNU General Public License +* along with CasparCG. If not, see . +* +*/ +#pragma once + +#include "../frame_producer.h" + +namespace caspar { + +class Monitor; + +namespace flash { + +class FlashAxContainer; + +///================================================================================================= +/// Flash Producer. +///================================================================================================= +class flash_producer : public frame_producer +{ +public: + /// Default frame buffer size. + static const int DEFAULT_BUFFER_SIZE = 2; + /// The maximum number of retries when trying to invoce a flash method. + static const int MAX_PARAM_RETRIES = 5; + /// Timeout for blocking while trying to stop the producer. + static const int STOP_TIMEOUT = 2000; + + flash_producer(const std::wstring& filename, const frame_format_desc& format_desc, Monitor* monitor = nullptr); + frame_ptr get_frame(); + const frame_format_desc& get_frame_format_desc() const; + + void param(const std::wstring& param); + + static std::wstring find_template(const std::wstring& templateName); + +private: + friend class flash::FlashAxContainer; + + Monitor* get_monitor(); + + struct implementation; + std::shared_ptr impl_; + +}; + +typedef std::tr1::shared_ptr flash_producer_ptr; + +flash_producer_ptr create_flash_producer(const std::vector& params, const frame_format_desc& format_desc); + +}} \ No newline at end of file diff --git a/core/producer/frame_producer.h b/core/producer/frame_producer.h new file mode 100644 index 000000000..bdd4cc12b --- /dev/null +++ b/core/producer/frame_producer.h @@ -0,0 +1,43 @@ +/* +* copyright (c) 2010 Sveriges Television AB +* +* This file is part of CasparCG. +* +* CasparCG is free software: you can redistribute it and/or modify +* it under the terms of the GNU General Public License as published by +* the Free Software Foundation, either version 3 of the License, or +* (at your option) any later version. +* +* CasparCG is distributed in the hope that it will be useful, +* but WITHOUT ANY WARRANTY; without even the implied warranty of +* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +* GNU General Public License for more details. + +* You should have received a copy of the GNU General Public License +* along with CasparCG. If not, see . +* +*/ +#pragma once + +#include "../frame/frame_fwd.h" + +#include + +#include + +namespace caspar { + +class Monitor; + +class frame_producer : boost::noncopyable +{ +public: + virtual ~frame_producer(){} + virtual frame_ptr get_frame() = 0; + virtual std::shared_ptr get_following_producer() const { return nullptr; } + virtual void set_leading_producer(const std::shared_ptr&) {} + virtual const frame_format_desc& get_frame_format_desc() const = 0; +}; +typedef std::shared_ptr frame_producer_ptr; + +} \ No newline at end of file diff --git a/core/producer/image/image_loader.cpp b/core/producer/image/image_loader.cpp new file mode 100644 index 000000000..9513186ab --- /dev/null +++ b/core/producer/image/image_loader.cpp @@ -0,0 +1,51 @@ +#include "..\..\StdAfx.h" + +#include "image_loader.h" + +#include "../../../common/exception/Exceptions.h" + +#include "../../frame/frame.h" +#include "../../frame/system_frame.h" +#include "../../../common/image/image.h" + +#if defined(_MSC_VER) +#pragma warning (disable : 4714) // marked as __forceinline not inlined +#endif + +#include +#include + +namespace caspar{ namespace image{ + +std::shared_ptr load_image(const std::string& filename) +{ + if(!boost::filesystem::exists(filename)) + BOOST_THROW_EXCEPTION(file_not_found() << boost::errinfo_file_name(filename)); + + FREE_IMAGE_FORMAT fif = FIF_UNKNOWN; + fif = FreeImage_GetFileType(filename.c_str(), 0); + if(fif == FIF_UNKNOWN) + fif = FreeImage_GetFIFFromFilename(filename.c_str()); + + if(fif == FIF_UNKNOWN || !FreeImage_FIFSupportsReading(fif)) + BOOST_THROW_EXCEPTION(invalid_argument() << msg_info("Unsupported image format.")); + + auto bitmap = std::shared_ptr(FreeImage_Load(fif, filename.c_str(), 0), FreeImage_Unload); + //FREE_IMAGE_TYPE ImageType = FreeImage_GetImageType(bitmap.get()); + + if(FreeImage_GetBPP(bitmap.get()) != 32) + { + bitmap = std::shared_ptr(FreeImage_ConvertTo32Bits(bitmap.get()), FreeImage_Unload); + if(!bitmap) + BOOST_THROW_EXCEPTION(invalid_argument() << msg_info("Unsupported image format.")); + } + + return bitmap; +} + +std::shared_ptr load_image(const std::wstring& filename) +{ + return load_image(common::narrow(filename)); +} + +}} \ No newline at end of file diff --git a/core/producer/image/image_loader.h b/core/producer/image/image_loader.h new file mode 100644 index 000000000..53cfec392 --- /dev/null +++ b/core/producer/image/image_loader.h @@ -0,0 +1,13 @@ +#pragma once + +#include + +#include +#include + +namespace caspar{ namespace image{ + +std::shared_ptr load_image(const std::string& filename); +std::shared_ptr load_image(const std::wstring& filename); + +}} diff --git a/core/producer/image/image_producer.cpp b/core/producer/image/image_producer.cpp new file mode 100644 index 000000000..17acabe89 --- /dev/null +++ b/core/producer/image/image_producer.cpp @@ -0,0 +1,58 @@ +#include "../../StdAfx.h" + +#include "image_producer.h" +#include "image_loader.h" + +#include "../../frame/system_frame.h" +#include "../../frame/frame_format.h" +#include "../../server.h" +#include "../../../common/utility/find_file.h" +#include "../../../common/image/image.h" + +#include + +using namespace boost::assign; + +namespace caspar{ namespace image{ + +struct image_producer : public frame_producer +{ + image_producer(const std::wstring& filename, const frame_format_desc& format_desc) : format_desc_(format_desc) + { + auto bitmap = load_image(filename); + + if(FreeImage_GetWidth(bitmap.get()) != format_desc.width || FreeImage_GetHeight(bitmap.get()) == format_desc.height) + { + bitmap = std::shared_ptr(FreeImage_Rescale(bitmap.get(), format_desc.width, format_desc.width, FILTER_BICUBIC), FreeImage_Unload); + if(!bitmap) + BOOST_THROW_EXCEPTION(invalid_argument() << msg_info("Unsupported image format.")); + } + + FreeImage_FlipVertical(bitmap.get()); + + frame_ = std::make_shared(format_desc.size); + common::image::copy(frame_->data(), FreeImage_GetBits(bitmap.get()), frame_->size()); + } + + frame_ptr get_frame() + { + return frame_; + } + + const frame_format_desc& get_frame_format_desc() const { return format_desc_; } + + frame_format_desc format_desc_; + frame_ptr frame_; +}; + +frame_producer_ptr create_image_producer(const std::vector& params, const frame_format_desc& format_desc) +{ + std::wstring filename = params[0]; + std::wstring resultFilename = common::find_file(server::media_folder() + filename, list_of(L"png")(L"tga")(L"bmp")(L"jpg")(L"jpeg")); + if(!resultFilename.empty()) + return std::make_shared(resultFilename, format_desc); + + return nullptr; +} + +}} \ No newline at end of file diff --git a/core/producer/image/image_producer.h b/core/producer/image/image_producer.h new file mode 100644 index 000000000..54df972d6 --- /dev/null +++ b/core/producer/image/image_producer.h @@ -0,0 +1,12 @@ +#pragma once + +#include "../frame_producer.h" + +#include +#include + +namespace caspar { namespace image { + +frame_producer_ptr create_image_producer(const std::vector& params, const frame_format_desc& format_desc); + +}} \ No newline at end of file diff --git a/core/producer/image/image_scroll_producer.cpp b/core/producer/image/image_scroll_producer.cpp new file mode 100644 index 000000000..764432c2a --- /dev/null +++ b/core/producer/image/image_scroll_producer.cpp @@ -0,0 +1,166 @@ +#include "../../StdAfx.h" + +#include "image_scroll_producer.h" + +#include "image_loader.h" + +#include "../../frame/frame_format.h" +#include "../../frame/system_frame.h" +#include "../../server.h" +#include "../../../common/utility/find_file.h" +#include "../../../common/image/image.h" + +#include +#include +#include + +#include +#include + +using namespace boost::assign; + +namespace caspar{ namespace image{ + +enum direction +{ + Up, Down, Left, Right +}; + +struct image_scroll_producer : public frame_producer +{ + static const int DEFAULT_SCROLL_SPEED = 50; + + image_scroll_producer(const std::wstring& filename, const std::vector& params, const frame_format_desc& format_desc) + : format_desc_(format_desc), speed_(image_scroll_producer::DEFAULT_SCROLL_SPEED), direction_(direction::Up), offset_(0) + { + load_and_pad_image(filename); + + auto pos = filename.find_last_of(L'_'); + if(pos != std::wstring::npos && pos + 1 < filename.size()) + { + std::wstring speedStr = filename.substr(pos + 1); + pos = speedStr.find_first_of(L'.'); + if(pos != std::wstring::npos) + { + speedStr = speedStr.substr(0, pos); + speed_ = common::lexical_cast_or_default(speedStr, image_scroll_producer::DEFAULT_SCROLL_SPEED); + } + } + + loop_ = std::find(params.begin(), params.end(), L"LOOP") != params.end(); + + if(image_width_ - format_desc.width > image_height_ - format_desc_.height) + direction_ = speed_ < 0 ? direction::Right : direction::Left; + else + direction_ = speed_ < 0 ? direction::Down : direction::Up; + + if (direction_ == direction::Down) + offset_ = image_height_ - format_desc_.height; + else if (direction_ == direction::Right) + offset_ = image_width_ - format_desc_.width; + + speed_ = static_cast(abs(static_cast(speed_) / format_desc.fps)); + } + + void load_and_pad_image(const std::wstring& filename) + { + auto pBitmap = load_image(filename); + + size_t width = FreeImage_GetWidth(pBitmap.get()); + size_t height = FreeImage_GetHeight(pBitmap.get()); + + image_width_ = std::max(width, format_desc_.width); + image_height_ = std::max(height, format_desc_.height); + + image_ = std::shared_ptr(static_cast(scalable_aligned_malloc(image_width_*image_height_*4, 16))); + common::image::clear(image_.get(), image_width_*image_height_*4); + + unsigned char* pBits = FreeImage_GetBits(pBitmap.get()); + + for (size_t i = 0; i < height; ++i) + common::image::copy(&image_.get()[i * image_width_ * 4], &pBits[i* width * 4], width * 4); + } + + frame_ptr render_frame() + { + frame_ptr frame = std::make_shared(format_desc_.size); + common::image::clear(frame->data(), frame->size()); + + const int delta_x = direction_ == direction::Left ? speed_ : -speed_; + const int delta_y = direction_ == direction::Up ? speed_ : -speed_; + + unsigned char* frame_data = frame->data(); + unsigned char* image_data = image_.get(); + + if (direction_ == direction::Up || direction_ == direction::Down) + { + tbb::parallel_for(static_cast(0), format_desc_.height, static_cast(1), [&](size_t i) + { + int srcRow = i + offset_; + int dstInxex = i * format_desc_.width * 4; + int srcIndex = srcRow * format_desc_.width * 4; + int size = format_desc_.width * 4; + + memcpy(&frame_data[dstInxex], &image_data[srcIndex], size); + }); + + offset_ += delta_y; + } + else + { + tbb::parallel_for(static_cast(0), format_desc_.height, static_cast(1), [&](size_t i) + { + int correctOffset = offset_; + int dstIndex = i * format_desc_.width * 4; + int srcIndex = (i * image_width_ + correctOffset) * 4; + + int stopOffset = std::min(correctOffset + format_desc_ .width, image_width_); + int size = (stopOffset - correctOffset) * 4; + + memcpy(&frame_data[dstIndex], &image_data[srcIndex], size); + }); + + offset_ += delta_x; + } + + return frame; + } + + frame_ptr render_interlaced_frame() + { + frame_ptr next_frame1; + frame_ptr next_frame2; + tbb::parallel_invoke([&]{ next_frame1 = render_frame(); }, [&]{ next_frame2 = render_frame(); }); + + return copy_frame(next_frame1, next_frame2, format_desc_); + } + + frame_ptr get_frame() + { + return format_desc_.mode == video_mode::progressive ? render_frame() : render_interlaced_frame(); + } + + const frame_format_desc& get_frame_format_desc() const { return format_desc_; } + + int image_width_; + int image_height_; + int speed_; + int offset_; + direction direction_; + + tbb::atomic loop_; + std::shared_ptr image_; + frame_format_desc format_desc_; +}; + +frame_producer_ptr create_image_scroll_producer(const std::vector& params, const frame_format_desc& format_desc) +{ + std::wstring filename = params[0]; + auto result_filename = common::find_file(server::media_folder() + filename, list_of(L"spng")(L"stga")(L"sbmp")(L"sjpg")(L"sjpeg")); + if(!result_filename.empty()) + return std::make_shared(result_filename, params, format_desc); + + return nullptr; +} + +}} \ No newline at end of file diff --git a/core/producer/image/image_scroll_producer.h b/core/producer/image/image_scroll_producer.h new file mode 100644 index 000000000..99d10feca --- /dev/null +++ b/core/producer/image/image_scroll_producer.h @@ -0,0 +1,12 @@ +#pragma once + +#include "../frame_producer.h" + +#include +#include + +namespace caspar { namespace image { + +frame_producer_ptr create_image_scroll_producer(const std::vector& params, const frame_format_desc& format_desc); + +}} \ No newline at end of file diff --git a/core/producer/transition/transition_producer.cpp b/core/producer/transition/transition_producer.cpp new file mode 100644 index 000000000..5ecb7b2e3 --- /dev/null +++ b/core/producer/transition/transition_producer.cpp @@ -0,0 +1,269 @@ +/* +* copyright (c) 2010 Sveriges Television AB +* +* This file is part of CasparCG. +* +* CasparCG is free software: you can redistribute it and/or modify +* it under the terms of the GNU General Public License as published by +* the Free Software Foundation, either version 3 of the License, or +* (at your option) any later version. +* +* CasparCG is distributed in the hope that it will be useful, +* but WITHOUT ANY WARRANTY; without even the implied warranty of +* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +* GNU General Public License for more details. + +* You should have received a copy of the GNU General Public License +* along with CasparCG. If not, see . +* +*/ +#include "../../stdafx.h" + +#include "transition_producer.h" + +#include "../../frame/frame_format.h" + +#include "../../../common/image/image.h" +#include "../../frame/system_frame.h" +#include "../../frame/audio_chunk.h" +#include "../../renderer/render_device.h" + +#include + +namespace caspar{ + +class empty_producer : public frame_producer +{ +public: + explicit empty_producer(const frame_format_desc& format_desc) + : format_desc_(format_desc), frame_(clear_frame(std::make_shared(format_desc_.size))) + {} + + frame_ptr get_frame() { return frame_; } + const frame_format_desc& get_frame_format_desc() const { return format_desc_; } +private: + frame_format_desc format_desc_; + frame_ptr frame_; +}; + +struct transition_producer::implementation : boost::noncopyable +{ + implementation(const frame_producer_ptr& dest, const transition_info& info, const frame_format_desc& format_desc) + : current_frame_(0), info_(info), border_color_(0), format_desc_(format_desc), + empty_(std::make_shared(format_desc)), source_(empty_), dest_(dest) + { + if(!dest) + BOOST_THROW_EXCEPTION(null_argument() << arg_name_info("dest")); + } + + frame_producer_ptr get_following_producer() const + { + return dest_; + } + + void set_leading_producer(const frame_producer_ptr& producer) + { + source_ = producer != nullptr ? producer : empty_; + } + + frame_ptr get_frame() + { + if(++current_frame_ >= info_.duration) + return nullptr; + + return compose(get_producer_frame(dest_), get_producer_frame(source_)); + } + + frame_ptr get_producer_frame(frame_producer_ptr& producer) + { + assert(producer != nullptr); + + frame_ptr frame; + try + { + frame = producer->get_frame(); + } + catch(...) + { + CASPAR_LOG_CURRENT_EXCEPTION(); + CASPAR_LOG(warning) << "Removed renderer from transition."; + } + + if(frame == nullptr && producer->get_following_producer() != nullptr) + { + auto following = producer->get_following_producer(); + following->set_leading_producer(producer); + producer = following; + return get_producer_frame(producer); + } + return frame; + } + + frame_ptr compose(const frame_ptr& dest_frame, const frame_ptr& src_frame) + { + frame_ptr result_frame = dest_frame; + if(src_frame != nullptr && dest_frame != nullptr) + { + result_frame = std::make_shared(format_desc_.size); + tbb::parallel_invoke( + [&] + { + GenerateFrame(result_frame->data(), src_frame->data(), dest_frame->data()); + }, + [&] + { + float delta = static_cast(current_frame_)/static_cast(info_.duration); + set_frame_volume(dest_frame, delta*100.0f); + set_frame_volume(src_frame, (1.0f-delta)*100.0f); + + boost::range::copy(src_frame->audio_data(), std::back_inserter(result_frame->audio_data())); + boost::range::copy(dest_frame->audio_data(), std::back_inserter(result_frame->audio_data()));; + }); + } + return result_frame; + } + + void GenerateFrame(unsigned char* pResultData, const unsigned char* pSourceData, const unsigned char* pDestData) + { + if(info_.type == transition_type::cut) + { + common::image::copy(pResultData, pSourceData, format_desc_.size); + return; + } + + if(current_frame_ >= info_.duration) + { + common::image::copy(pResultData, pDestData, format_desc_.size); + return; + } + + if(info_.type == transition_type::mix) + { + common::image::lerp(pResultData, pSourceData, pDestData, 1.0f-static_cast(current_frame_)/static_cast(info_.duration), format_desc_.size); + return; + } + + size_t totalWidth = format_desc_.width + info_.border_width; + + float fStep = totalWidth / static_cast(info_.duration); + float fOffset = fStep * static_cast(current_frame_); + + size_t halfStep = static_cast(fStep/2.0); + size_t offset = static_cast(fOffset+0.5f); + + //read source to buffer + for(size_t row = 0, even = 0; row < format_desc_.height; ++row, even ^= 1) + { + size_t fieldCorrectedOffset = offset + (halfStep*even); + if(fieldCorrectedOffset < format_desc_.width) + { + if(info_.direction != transition_direction::from_left) + { + if(info_.type == transition_type::push) + memcpy(&(pResultData[4*row*format_desc_.width]), &(pSourceData[4*(row*format_desc_.width+fieldCorrectedOffset)]), (format_desc_.width-fieldCorrectedOffset)*4); + else //Slide | Wipe + memcpy(&(pResultData[4*row*format_desc_.width]), &(pSourceData[4*row*format_desc_.width]), (format_desc_.width-fieldCorrectedOffset)*4); + } + else // if (direction == LEFT) + { + if(info_.type == transition_type::push) + memcpy(&(pResultData[4*(row*format_desc_.width+fieldCorrectedOffset)]), &(pSourceData[4*(row*format_desc_.width)]), (format_desc_.width-fieldCorrectedOffset)*4); + else //slide eller wipe + memcpy(&(pResultData[4*(row*format_desc_.width+fieldCorrectedOffset)]), &(pSourceData[4*(row*format_desc_.width+fieldCorrectedOffset)]), (format_desc_.width-fieldCorrectedOffset)*4); + } + } + } + + //write border to buffer + if(info_.border_width > 0) + { + for(size_t row = 0, even = 0; row < format_desc_.height; ++row, even ^= 1) + { + size_t fieldCorrectedOffset = offset + (halfStep*even); + size_t length = info_.border_width; + size_t start = 0; + + if(info_.direction != transition_direction::from_left) + { + if(fieldCorrectedOffset > format_desc_.width) + { + length -= fieldCorrectedOffset-format_desc_.width; + start += fieldCorrectedOffset-format_desc_.width; + fieldCorrectedOffset = format_desc_.width; + } + else if(fieldCorrectedOffset < length) + { + length = fieldCorrectedOffset; + } + + for(size_t i = 0; i < length; ++i) + memcpy(&(pResultData[4*(row*format_desc_.width+format_desc_.width-fieldCorrectedOffset+i)]), &border_color_, 4); + + } + else // if (direction == LEFT) + { + if(fieldCorrectedOffset > format_desc_.width) + { + length -= fieldCorrectedOffset-format_desc_.width; + start = 0; + fieldCorrectedOffset -= info_.border_width-length; + } + else if(fieldCorrectedOffset < length) + { + length = fieldCorrectedOffset; + start = info_.border_width-fieldCorrectedOffset; + } + + for(size_t i = 0; i < length; ++i) + memcpy(&(pResultData[4*(row*format_desc_.width+fieldCorrectedOffset-length+i)]), &border_color_, 4); + } + + } + } + + //read dest to buffer + offset -= info_.border_width; + if(offset > 0) + { + for(size_t row = 0, even = 0; row < format_desc_.height; ++row, even ^= 1) + { + int fieldCorrectedOffset = offset + (halfStep*even); + + if(info_.direction != transition_direction::from_left) + { + if(info_.type == transition_type::wipe) + memcpy(&(pResultData[4*(row*format_desc_.width+format_desc_.width-fieldCorrectedOffset)]), &(pDestData[4*(row*format_desc_.width+format_desc_.width-fieldCorrectedOffset)]), fieldCorrectedOffset*4); + else + memcpy(&(pResultData[4*(row*format_desc_.width+format_desc_.width-fieldCorrectedOffset)]), &(pDestData[4*row*format_desc_.width]), fieldCorrectedOffset*4); + } + else // if (direction == LEFT) + { + if(info_.type == transition_type::wipe) + memcpy(&(pResultData[4*(row*format_desc_.width)]), &(pDestData[4*(row*format_desc_.width)]), fieldCorrectedOffset*4); + else + memcpy(&(pResultData[4*(row*format_desc_.width)]), &(pDestData[4*(row*format_desc_.width+format_desc_.width-fieldCorrectedOffset)]), fieldCorrectedOffset*4); + } + } + } + } + + const frame_format_desc format_desc_; + + frame_producer_ptr empty_; + frame_producer_ptr source_; + frame_producer_ptr dest_; + + unsigned short current_frame_; + + const transition_info info_; + const unsigned long border_color_; +}; + +transition_producer::transition_producer(const frame_producer_ptr& dest, const transition_info& info, const frame_format_desc& format_desc) + : impl_(new implementation(dest, info, format_desc)){} +frame_ptr transition_producer::get_frame(){return impl_->get_frame();} +frame_producer_ptr transition_producer::get_following_producer() const{return impl_->get_following_producer();} +void transition_producer::set_leading_producer(const frame_producer_ptr& producer) { impl_->set_leading_producer(producer); } +const frame_format_desc& transition_producer::get_frame_format_desc() const { return impl_->format_desc_; } + +} \ No newline at end of file diff --git a/core/producer/transition/transition_producer.h b/core/producer/transition/transition_producer.h new file mode 100644 index 000000000..6acd3ae7a --- /dev/null +++ b/core/producer/transition/transition_producer.h @@ -0,0 +1,74 @@ +/* +* copyright (c) 2010 Sveriges Television AB +* +* This file is part of CasparCG. +* +* CasparCG is free software: you can redistribute it and/or modify +* it under the terms of the GNU General Public License as published by +* the Free Software Foundation, either version 3 of the License, or +* (at your option) any later version. +* +* CasparCG is distributed in the hope that it will be useful, +* but WITHOUT ANY WARRANTY; without even the implied warranty of +* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +* GNU General Public License for more details. + +* You should have received a copy of the GNU General Public License +* along with CasparCG. If not, see . +* +*/ +#pragma once + +#include "../frame_producer.h" + +#include +#include + +namespace caspar { + +enum transition_type +{ + cut = 1, + mix, + push, + slide, + wipe +}; + +enum transition_direction +{ + from_left = 1, + from_right, + from_top, + from_bottom +}; + +struct transition_info +{ + transition_info() : type(transition_type::cut), duration(0), border_width(0), border_color(TEXT("#00000000")), direction(transition_direction::from_left){} + + unsigned short duration; + unsigned short border_width; + transition_direction direction; + transition_type type; + std::wstring border_color; + std::wstring border_image; +}; + +class transition_producer : public frame_producer +{ +public: + transition_producer(const frame_producer_ptr& destination, const transition_info& info, const frame_format_desc& fmt); + + frame_ptr get_frame(); + + frame_producer_ptr get_following_producer() const; + void set_leading_producer(const frame_producer_ptr& producer); + const frame_format_desc& get_frame_format_desc() const; +private: + struct implementation; + std::shared_ptr impl_; +}; +typedef std::shared_ptr transition_producer_ptr; + +} \ No newline at end of file diff --git a/core/protocol/amcp/AMCPCommand.h b/core/protocol/amcp/AMCPCommand.h new file mode 100644 index 000000000..7e1d914a0 --- /dev/null +++ b/core/protocol/amcp/AMCPCommand.h @@ -0,0 +1,110 @@ +/* +* copyright (c) 2010 Sveriges Television AB +* +* This file is part of CasparCG. +* +* CasparCG is free software: you can redistribute it and/or modify +* it under the terms of the GNU General Public License as published by +* the Free Software Foundation, either version 3 of the License, or +* (at your option) any later version. +* +* CasparCG is distributed in the hope that it will be useful, +* but WITHOUT ANY WARRANTY; without even the implied warranty of +* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +* GNU General Public License for more details. + +* You should have received a copy of the GNU General Public License +* along with CasparCG. If not, see . +* +*/ +#pragma once + +#include "../../../common/io/clientinfo.h" +#include "../../consumer/frame_consumer.h" +#include +#include "../../renderer/render_device.h" + +namespace caspar { +namespace amcp { + + enum AMCPCommandScheduling + { + Default = 0, + AddToQueue, + ImmediatelyAndClear + }; + + class AMCPCommand + { + AMCPCommand(const AMCPCommand&); + AMCPCommand& operator=(const AMCPCommand&); + public: + AMCPCommand(); + virtual ~AMCPCommand() {} + virtual bool Execute() = 0; + + virtual bool NeedChannel() = 0; + virtual AMCPCommandScheduling GetDefaultScheduling() = 0; + virtual int GetMinimumParameters() = 0; + + void SendReply(); + + void AddParameter(const std::wstring& param){_parameters.push_back(param);} + + void SetClientInfo(caspar::IO::ClientInfoPtr& s){pClientInfo_ = s;} + caspar::IO::ClientInfoPtr GetClientInfo(){return pClientInfo_;} + + void SetChannel(const renderer::render_device_ptr& pChannel){pChannel_ = pChannel;} + renderer::render_device_ptr GetChannel(){return pChannel_;} + + void SetChannelIndex(unsigned int channelIndex){channelIndex_ = channelIndex;} + unsigned int GetChannelIndex(){return channelIndex_;} + + void SetLayerIntex(int layerIndex){layerIndex_ = layerIndex;} + int GetLayerIndex(int defaultValue = 0) const{return layerIndex_ != -1 ? layerIndex_ : defaultValue;} + + virtual void Clear(); + + AMCPCommandScheduling GetScheduling() + { + return scheduling_ == Default ? GetDefaultScheduling() : scheduling_; + } + + void SetScheduling(AMCPCommandScheduling s){scheduling_ = s;} + + protected: + void SetReplyString(const std::wstring& str){replyString_ = str;} + std::vector _parameters; + + private: + unsigned int channelIndex_; + int layerIndex_; + caspar::IO::ClientInfoPtr pClientInfo_; + renderer::render_device_ptr pChannel_; + AMCPCommandScheduling scheduling_; + std::wstring replyString_; + }; + + typedef std::tr1::shared_ptr AMCPCommandPtr; + + template + class AMCPCommandBase : public AMCPCommand + { + public: + virtual bool Execute() + { + for(size_t n = 0; n < _parameters.size(); ++n) + _parameters[n] = boost::to_upper_copy(_parameters[n]); + return (TNeedChannel && !GetChannel()) || _parameters.size() < TMinParameters ? false : DoExecute(); + } + + virtual bool NeedChannel(){return TNeedChannel;} + virtual AMCPCommandScheduling GetDefaultScheduling(){return TScheduling;} + virtual int GetMinimumParameters(){return TMinParameters;} + protected: + ~AMCPCommandBase(){} + private: + virtual bool DoExecute() = 0; + }; + +}} diff --git a/core/protocol/amcp/AMCPCommandQueue.cpp b/core/protocol/amcp/AMCPCommandQueue.cpp new file mode 100644 index 000000000..d07d4449a --- /dev/null +++ b/core/protocol/amcp/AMCPCommandQueue.cpp @@ -0,0 +1,134 @@ +/* +* copyright (c) 2010 Sveriges Television AB +* +* This file is part of CasparCG. +* +* CasparCG is free software: you can redistribute it and/or modify +* it under the terms of the GNU General Public License as published by +* the Free Software Foundation, either version 3 of the License, or +* (at your option) any later version. +* +* CasparCG is distributed in the hope that it will be useful, +* but WITHOUT ANY WARRANTY; without even the implied warranty of +* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +* GNU General Public License for more details. + +* You should have received a copy of the GNU General Public License +* along with CasparCG. If not, see . +* +*/ + +#include "..\..\stdafx.h" + +#include "AMCPCommandQueue.h" + +namespace caspar { namespace amcp { + +using namespace common; + +AMCPCommandQueue::AMCPCommandQueue() : newCommandEvent_(FALSE, FALSE) +{} + +AMCPCommandQueue::~AMCPCommandQueue() +{ + Stop(); +} + +bool AMCPCommandQueue::Start() +{ + if(commandPump_.IsRunning()) + return false; + + return commandPump_.Start(this); +} + +void AMCPCommandQueue::Stop() +{ + commandPump_.Stop(); +} + +void AMCPCommandQueue::AddCommand(AMCPCommandPtr pNewCommand) +{ + { + tbb::mutex::scoped_lock lock(mutex_); + + if(pNewCommand->GetScheduling() == ImmediatelyAndClear) { + //Clears the queue, objects are deleted automatically + commands_.clear(); + + commands_.push_back(pNewCommand); + CASPAR_LOG(info) << "Cleared queue and added command"; + } + else { + commands_.push_back(pNewCommand); + CASPAR_LOG(info) << "Added command to end of queue"; + } + } + + SetEvent(newCommandEvent_); +} + +void AMCPCommandQueue::Run(HANDLE stopEvent) +{ + bool logTemporarilyBadState = true; + AMCPCommandPtr pCurrentCommand; + + CASPAR_LOG(info) << "AMCP CommandPump started"; + + while(WaitForSingleObject(stopEvent, 0) != WAIT_OBJECT_0) + { + DWORD waitResult = WaitForSingleObject(newCommandEvent_, 50); + if(waitResult == WAIT_OBJECT_0) + { + tbb::mutex::scoped_lock lock(mutex_); + + if(commands_.size() > 0) + { + CASPAR_LOG(debug) << "Found " << commands_.size() << " commands in queue"; + + AMCPCommandPtr pNextCommand = commands_.front(); + + if(pCurrentCommand == 0 || pNextCommand->GetScheduling() == ImmediatelyAndClear) { + pCurrentCommand = pNextCommand; + commands_.pop_front(); + } + } + } + + if(pCurrentCommand != 0) + { + if(pCurrentCommand->Execute()) + CASPAR_LOG(info) << "Executed command"; + else + CASPAR_LOG(info) << "Failed to executed command"; + + pCurrentCommand->SendReply(); + pCurrentCommand.reset(); + + newCommandEvent_.Set(); + logTemporarilyBadState = true; + + CASPAR_LOG(info) << "Ready for a new command"; + } + } + + CASPAR_LOG(info) << "CommandPump ended"; +} + +bool AMCPCommandQueue::OnUnhandledException(const std::exception& ex) throw() +{ + bool bDoRestart = true; + + try + { + CASPAR_LOG(fatal) << "UNHANDLED EXCEPTION in commandqueue. Message: " << ex.what(); + } + catch(...) + { + bDoRestart = false; + } + + return bDoRestart; +} + +}} \ No newline at end of file diff --git a/core/protocol/amcp/AMCPCommandQueue.h b/core/protocol/amcp/AMCPCommandQueue.h new file mode 100644 index 000000000..4da281baf --- /dev/null +++ b/core/protocol/amcp/AMCPCommandQueue.h @@ -0,0 +1,55 @@ +/* +* copyright (c) 2010 Sveriges Television AB +* +* This file is part of CasparCG. +* +* CasparCG is free software: you can redistribute it and/or modify +* it under the terms of the GNU General Public License as published by +* the Free Software Foundation, either version 3 of the License, or +* (at your option) any later version. +* +* CasparCG is distributed in the hope that it will be useful, +* but WITHOUT ANY WARRANTY; without even the implied warranty of +* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +* GNU General Public License for more details. + +* You should have received a copy of the GNU General Public License +* along with CasparCG. If not, see . +* +*/ +#pragma once + +#include "../../../common/concurrency\thread.h" + +#include "AMCPCommand.h" + +#include + +namespace caspar { namespace amcp { + +class AMCPCommandQueue : public common::IRunnable +{ + AMCPCommandQueue(const AMCPCommandQueue&); + AMCPCommandQueue& operator=(const AMCPCommandQueue&); +public: + AMCPCommandQueue(); + ~AMCPCommandQueue(); + + bool Start(); + void Stop(); + void AddCommand(AMCPCommandPtr pCommand); + +private: + common::Thread commandPump_; + virtual void Run(HANDLE stopEvent); + virtual bool OnUnhandledException(const std::exception& ex) throw(); + + common::Event newCommandEvent_; + + //Needs synro-protection + std::list commands_; + tbb::mutex mutex_; +}; +typedef std::tr1::shared_ptr AMCPCommandQueuePtr; + +}} diff --git a/core/protocol/amcp/AMCPCommandsImpl.cpp b/core/protocol/amcp/AMCPCommandsImpl.cpp new file mode 100644 index 000000000..d95c8dd1c --- /dev/null +++ b/core/protocol/amcp/AMCPCommandsImpl.cpp @@ -0,0 +1,859 @@ +/* +* copyright (c) 2010 Sveriges Television AB +* +* This file is part of CasparCG. +* +* CasparCG is free software: you can redistribute it and/or modify +* it under the terms of the GNU General Public License as published by +* the Free Software Foundation, either version 3 of the License, or +* (at your option) any later version. +* +* CasparCG is distributed in the hope that it will be useful, +* but WITHOUT ANY WARRANTY; without even the implied warranty of +* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +* GNU General Public License for more details. + +* You should have received a copy of the GNU General Public License +* along with CasparCG. If not, see . +* +*/ + +#include "../../StdAfx.h" + +#include "AMCPCommandsImpl.h" +#include "AMCPProtocolStrategy.h" +#include "../../producer/frame_producer.h" +#include "../../Frame/frame_format.h" +#include "../../producer/flash/flash_producer.h" +#include "../../producer/transition/transition_producer.h" +#include +#include "../monitor/Monitor.h" +#include "../../producer/flash/cg_producer.h" +#include "../media.h" +#include "../../Server.h" + +#include +#include +#include +#include +#include + +#include +#include +#include +#include + +#if defined(_MSC_VER) +#pragma warning (push, 1) // TODO: Legacy code, just disable warnings +#endif + +/* Return codes + +100 [action] Information om att något har hänt +101 [action] Information om att något har hänt, en rad data skickas + +202 [kommando] OK Kommandot har utförts +201 [kommando] OK Kommandot har utförts, och en rad data skickas tillbaka +200 [kommando] OK Kommandot har utförts, och flera rader data skickas tillbaka. Avslutas med tomrad + +400 ERROR Kommandot kunde inte förstås +401 [kommando] ERROR Ogiltig kanal +402 [kommando] ERROR Parameter saknas +403 [kommando] ERROR Ogiltig parameter +404 [kommando] ERROR Mediafilen hittades inte + +500 FAILED Internt serverfel +501 [kommando] FAILED Internt serverfel +502 [kommando] FAILED Oläslig mediafil + +600 [kommando] FAILED funktion ej implementerad +*/ + +namespace caspar { + +std::wstring ListMedia() +{ + std::wstringstream replyString; + for (boost::filesystem::wrecursive_directory_iterator itr(server::media_folder()), end; itr != end; ++itr) + { + if(boost::filesystem::is_regular_file(itr->path())) + { + std::wstring clipttype = TEXT(" N/A "); + std::wstring extension = boost::to_upper_copy(itr->path().extension()); + if(extension == TEXT(".TGA") || extension == TEXT(".COL")) + clipttype = TEXT(" STILL "); + else if(extension == TEXT(".SWF") || extension == TEXT(".DV") || extension == TEXT(".MOV") || extension == TEXT(".MPG") || + extension == TEXT(".AVI") || extension == TEXT(".FLV") || extension == TEXT(".F4V") || extension == TEXT(".MP4")) + clipttype = TEXT(" MOVIE "); + else if(extension == TEXT(".WAV") || extension == TEXT(".MP3")) + clipttype = TEXT(" STILL "); + + if(clipttype != TEXT(" N/A ")) + { + auto is_not_digit = [](char c){ return std::isdigit(c) == 0; }; + + auto relativePath = boost::filesystem::wpath(itr->path().file_string().substr(server::media_folder().size()-1, itr->path().file_string().size())); + + auto writeTimeStr = boost::posix_time::to_iso_string(boost::posix_time::from_time_t(boost::filesystem::last_write_time(itr->path()))); + writeTimeStr.erase(std::remove_if(writeTimeStr.begin(), writeTimeStr.end(), is_not_digit), writeTimeStr.end()); + auto writeTimeWStr = std::wstring(writeTimeStr.begin(), writeTimeStr.end()); + + auto sizeStr = boost::lexical_cast(boost::filesystem::file_size(itr->path())); + sizeStr.erase(std::remove_if(sizeStr.begin(), sizeStr.end(), is_not_digit), sizeStr.end()); + auto sizeWStr = std::wstring(sizeStr.begin(), sizeStr.end()); + + replyString << TEXT("\"") << relativePath.replace_extension(TEXT("")) + << TEXT("\" ") << clipttype + << TEXT(" ") << sizeStr + << TEXT(" ") << writeTimeWStr + << TEXT("\r\n"); + } + } + } + return boost::to_upper_copy(replyString.str()); +} + +std::wstring ListTemplates() +{ + std::wstringstream replyString; + + for (boost::filesystem::wrecursive_directory_iterator itr(server::template_folder()), end; itr != end; ++itr) + { + if(boost::filesystem::is_regular_file(itr->path()) && itr->path().extension() == L".ft") + { + auto relativePath = boost::filesystem::wpath(itr->path().file_string().substr(server::template_folder().size()-1, itr->path().file_string().size())); + + auto writeTimeStr = boost::posix_time::to_iso_string(boost::posix_time::from_time_t(boost::filesystem::last_write_time(itr->path()))); + writeTimeStr.erase(std::remove_if(writeTimeStr.begin(), writeTimeStr.end(), [](char c){ return std::isdigit(c) == 0;}), writeTimeStr.end()); + auto writeTimeWStr = std::wstring(writeTimeStr.begin(), writeTimeStr.end()); + + auto sizeStr = boost::lexical_cast(boost::filesystem::file_size(itr->path())); + sizeStr.erase(std::remove_if(sizeStr.begin(), sizeStr.end(), [](char c){ return std::isdigit(c) == 0;}), sizeStr.end()); + + auto sizeWStr = std::wstring(sizeStr.begin(), sizeStr.end()); + + replyString << TEXT("\"") << relativePath.replace_extension(TEXT("")) + << TEXT("\" ") << sizeWStr + << TEXT(" ") << writeTimeWStr + << TEXT("\r\n"); + } + } + return boost::to_upper_copy(replyString.str()); +} + +namespace amcp { + +using namespace common; + +AMCPCommand::AMCPCommand() : channelIndex_(0), scheduling_(Default), layerIndex_(-1) +{} + +void AMCPCommand::SendReply() +{ + if(!pClientInfo_) + return; + + if(replyString_.empty()) + return; + pClientInfo_->Send(replyString_); +} + +void AMCPCommand::Clear() +{ + pChannel_.reset(); + pClientInfo_.reset(); + channelIndex_ = 0; + _parameters.clear(); +} + +bool LoadCommand::DoExecute() +{ + //Perform loading of the clip + try + { + auto pFP = load_media(_parameters, GetChannel()->frame_format_desc()); + bool autoPlay = std::find(_parameters.begin(), _parameters.end(), TEXT("AUTOPLAY")) != _parameters.end(); + GetChannel()->load(GetLayerIndex(), pFP, autoPlay ? renderer::load_option::auto_play : renderer::load_option::preview); + + CASPAR_LOG(info) << "Loaded " << _parameters[0] << TEXT(" successfully"); + + SetReplyString(TEXT("202 LOAD OK\r\n")); + + GetChannel()->monitor().Inform(LOAD, _parameters[0]); + return true; + } + catch(file_not_found&) + { + CASPAR_LOG_CURRENT_EXCEPTION(); + SetReplyString(TEXT("404 LOADBG ERROR\r\n")); + return false; + } + catch(...) + { + CASPAR_LOG_CURRENT_EXCEPTION(); + SetReplyString(TEXT("502 LOADBG FAILED\r\n")); + return false; + } +} + +bool LoadbgCommand::DoExecute() +{ + transition_info transitionInfo; + + bool bLoop = false; + unsigned short transitionParameterIndex = 1; + + if(_parameters.size() > 1 && _parameters[1] == TEXT("LOOP")) + ++transitionParameterIndex; + + //Setup transition info + if(_parameters.size() > transitionParameterIndex) //type + { + std::wstring transitionType = _parameters[transitionParameterIndex]; + + if(transitionType == TEXT("CUT")) + transitionInfo.type = transition_type::cut; + else if(transitionType == TEXT("MIX")) + transitionInfo.type = transition_type::mix; + else if(transitionType == TEXT("PUSH")) + transitionInfo.type = transition_type::push; + else if(transitionType == TEXT("SLIDE")) + transitionInfo.type = transition_type::slide; + else if(transitionType == TEXT("WIPE")) + transitionInfo.type = transition_type::wipe; + + if(_parameters.size() > static_cast(transitionParameterIndex+1)) //duration + { + int duration = _ttoi(_parameters[transitionParameterIndex+1].c_str()); + if(duration > 0) + transitionInfo.duration = duration; + + if(_parameters.size() > static_cast(transitionParameterIndex+2)) //direction + { + std::wstring direction = _parameters[transitionParameterIndex+2]; + + if(direction == TEXT("FROMLEFT")) + transitionInfo.direction = transition_direction::from_left; + else if(direction == TEXT("FROMRIGHT")) + transitionInfo.direction = transition_direction::from_right; + else if(direction == TEXT("LEFT")) + transitionInfo.direction = transition_direction::from_right; + else if(direction == TEXT("RIGHT")) + transitionInfo.direction = transition_direction::from_left; + + if(_parameters.size() > static_cast(transitionParameterIndex+3)) //border + { + std::wstring border = _parameters[transitionParameterIndex+3]; + if(border.size()>0) + { + if(border[0] == TEXT('#')) + transitionInfo.border_color = border; + else + transitionInfo.border_image = border; + } + + if(_parameters.size() > static_cast(transitionParameterIndex+4)) //border width + transitionInfo.border_width = _ttoi(_parameters[transitionParameterIndex+4].c_str()); + } + } + } + } + + //Perform loading of the clip + try + { + auto pFP = load_media(_parameters, GetChannel()->frame_format_desc()); + if(pFP == nullptr) + BOOST_THROW_EXCEPTION(file_not_found() << msg_info(_parameters.size() > 0 ? common::narrow(_parameters[0]) : "")); + + pFP = std::make_shared(pFP, transitionInfo, GetChannel()->frame_format_desc()); + bool autoPlay = std::find(_parameters.begin(), _parameters.end(), TEXT("AUTOPLAY")) != _parameters.end(); + GetChannel()->load(GetLayerIndex(), pFP, autoPlay ? renderer::load_option::auto_play : renderer::load_option::none); // TODO: LOOP + + CASPAR_LOG(info) << "Loaded " << _parameters[0] << TEXT(" successfully to background"); + SetReplyString(TEXT("202 LOADBG OK\r\n")); + + GetChannel()->monitor().Inform(LOADBG, _parameters[0]); + return true; + } + catch(file_not_found&) + { + CASPAR_LOG_CURRENT_EXCEPTION(); + SetReplyString(TEXT("404 LOADBG ERROR\r\n")); + return false; + } + catch(...) + { + CASPAR_LOG_CURRENT_EXCEPTION(); + SetReplyString(TEXT("502 LOADBG FAILED\r\n")); + return false; + } +} + +bool PlayCommand::DoExecute() +{ + try + { + GetChannel()->play(GetLayerIndex()); + SetReplyString(TEXT("202 PLAY OK\r\n")); + return true; + } + catch(...) + { + SetReplyString(TEXT("501 PLAY FAILED\r\n")); + } + + return false; +} + +bool StopCommand::DoExecute() +{ + try + { + GetChannel()->stop(GetLayerIndex()); + SetReplyString(TEXT("202 STOP OK\r\n")); + return true; + } + catch(...) + { + SetReplyString(TEXT("501 STOP FAILED\r\n")); + } + + return false; +} + +bool ClearCommand::DoExecute() +{ + GetChannel()->clear(GetLayerIndex()); + SetReplyString(TEXT("202 CLEAR OK\r\n")); + + GetChannel()->monitor().Inform(CLEAR); + return true; +} + +bool CGCommand::DoExecute() +{ + std::wstring command = _parameters[0]; + if(command == TEXT("ADD")) + return DoExecuteAdd(); + else if(command == TEXT("PLAY")) + return DoExecutePlay(); + else if(command == TEXT("STOP")) + return DoExecuteStop(); + else if(command == TEXT("NEXT")) + return DoExecuteNext(); + else if(command == TEXT("REMOVE")) + return DoExecuteRemove(); + else if(command == TEXT("CLEAR")) + return DoExecuteClear(); + else if(command == TEXT("UPDATE")) + return DoExecuteUpdate(); + else if(command == TEXT("INVOKE")) + return DoExecuteInvoke(); + else if(command == TEXT("INFO")) + return DoExecuteInfo(); + + SetReplyString(TEXT("403 CG ERROR\r\n")); + return false; +} + +bool CGCommand::ValidateLayer(const std::wstring& layerstring) { + int length = layerstring.length(); + for(int i = 0; i < length; ++i) { + if(!_istdigit(layerstring[i])) { + return false; + } + } + + return true; +} + +bool CGCommand::DoExecuteAdd() { + //CG 1 ADD 0 "template_folder/templatename" [STARTLABEL] 0/1 [DATA] + + int layer = 0; //_parameters[1] +// std::wstring templateName; //_parameters[2] + std::wstring label; //_parameters[3] + bool bDoStart = false; //_parameters[3] alt. _parameters[4] +// std::wstring data; //_parameters[4] alt. _parameters[5] + + if(_parameters.size() < 4) + { + SetReplyString(TEXT("402 CG ERROR\r\n")); + return false; + } + unsigned int dataIndex = 4; + + if(!ValidateLayer(_parameters[1])) + { + SetReplyString(TEXT("403 CG ERROR\r\n")); + return false; + } + + layer = _ttoi(_parameters[1].c_str()); + + if(_parameters[3].length() > 1) + { //read label + label = _parameters[3]; + ++dataIndex; + + if(_parameters.size() > 4 && _parameters[4].length() > 0) //read play-on-load-flag + bDoStart = (_parameters[4][0]==TEXT('1')) ? true : false; + else + { + SetReplyString(TEXT("402 CG ERROR\r\n")); + return false; + } + } + else if(_parameters[3].length() > 0) { //read play-on-load-flag + bDoStart = (_parameters[3][0]==TEXT('1')) ? true : false; + } + else + { + SetReplyString(TEXT("403 CG ERROR\r\n")); + return false; + } + + const TCHAR* pDataString = 0; + std::wstringstream data; + std::wstring dataFromFile; + if(_parameters.size() > dataIndex) + { //read data + const std::wstring& dataString = _parameters[dataIndex]; + + if(dataString[0] == TEXT('<')) //the data is an XML-string + pDataString = dataString.c_str(); + else + { + //The data is not an XML-string, it must be a filename + std::wstring filename = server::data_folder(); + filename.append(dataString); + filename.append(TEXT(".ftd")); + + //open file + std::wifstream datafile(filename.c_str()); + if(datafile) + { + //read all data + data << datafile.rdbuf(); + datafile.close(); + + //extract data to _parameters + dataFromFile = data.str(); + pDataString = dataFromFile.c_str(); + } + } + } + + std::wstring fullFilename = flash::flash_producer::find_template(server::template_folder() + _parameters[2]); + if(!fullFilename.empty()) + { + std::wstring extension = boost::filesystem::wpath(fullFilename).extension(); + std::wstring filename = _parameters[2]; + filename.append(extension); + + flash::get_default_cg_producer(GetChannel(), GetLayerIndex(flash::CG_DEFAULT_LAYER))->add(layer, filename, bDoStart, label, (pDataString!=0) ? pDataString : TEXT("")); + SetReplyString(TEXT("202 CG OK\r\n")); + + GetChannel()->monitor().Inform(CG_ADD, _parameters[2]); + } + else + { + CASPAR_LOG(warning) << "Could not find template " << _parameters[2]; + SetReplyString(TEXT("404 CG ERROR\r\n")); + } + return true; +} + +bool CGCommand::DoExecutePlay() +{ + if(_parameters.size() > 1) + { + if(!ValidateLayer(_parameters[1])) + { + SetReplyString(TEXT("403 CG ERROR\r\n")); + return false; + } + int layer = _ttoi(_parameters[1].c_str()); + flash::get_default_cg_producer(GetChannel(), GetLayerIndex(flash::CG_DEFAULT_LAYER))->play(layer); + } + else + { + SetReplyString(TEXT("402 CG ERROR\r\n")); + return true; + } + + SetReplyString(TEXT("202 CG OK\r\n")); + return true; +} + +bool CGCommand::DoExecuteStop() +{ + if(_parameters.size() > 1) + { + if(!ValidateLayer(_parameters[1])) + { + SetReplyString(TEXT("403 CG ERROR\r\n")); + return false; + } + int layer = _ttoi(_parameters[1].c_str()); + flash::get_default_cg_producer(GetChannel(), GetLayerIndex(flash::CG_DEFAULT_LAYER))->stop(layer, 0); + } + else + { + SetReplyString(TEXT("402 CG ERROR\r\n")); + return true; + } + + SetReplyString(TEXT("202 CG OK\r\n")); + return true; +} + +bool CGCommand::DoExecuteNext() +{ + if(_parameters.size() > 1) + { + if(!ValidateLayer(_parameters[1])) + { + SetReplyString(TEXT("403 CG ERROR\r\n")); + return false; + } + int layer = _ttoi(_parameters[1].c_str()); + flash::get_default_cg_producer(GetChannel(), GetLayerIndex(flash::CG_DEFAULT_LAYER))->next(layer); + } + else + { + SetReplyString(TEXT("402 CG ERROR\r\n")); + return true; + } + + SetReplyString(TEXT("202 CG OK\r\n")); + return true; +} + +bool CGCommand::DoExecuteRemove() +{ + if(_parameters.size() > 1) + { + if(!ValidateLayer(_parameters[1])) + { + SetReplyString(TEXT("403 CG ERROR\r\n")); + return false; + } + int layer = _ttoi(_parameters[1].c_str()); + flash::get_default_cg_producer(GetChannel(), GetLayerIndex(flash::CG_DEFAULT_LAYER))->remove(layer); + } + else + { + SetReplyString(TEXT("402 CG ERROR\r\n")); + return true; + } + + SetReplyString(TEXT("202 CG OK\r\n")); + return true; +} + +bool CGCommand::DoExecuteClear() +{ + flash::get_default_cg_producer(GetChannel(), GetLayerIndex(flash::CG_DEFAULT_LAYER))->clear(); + SetReplyString(TEXT("202 CG OK\r\n")); + GetChannel()->monitor().Inform(CG_CLEAR); + return true; +} + +bool CGCommand::DoExecuteUpdate() +{ + if(_parameters.size() > 2) + { + if(!ValidateLayer(_parameters[1])) + { + SetReplyString(TEXT("403 CG ERROR\r\n")); + return false; + } + int layer = _ttoi(_parameters[1].c_str()); + //TODO: Implement indirect data loading from file. Same as in Add + flash::get_default_cg_producer(GetChannel(), GetLayerIndex(flash::CG_DEFAULT_LAYER))->update(layer, _parameters[2]); + } + else + { + SetReplyString(TEXT("402 CG ERROR\r\n")); + return true; + } + + SetReplyString(TEXT("202 CG OK\r\n")); + return true; +} + +bool CGCommand::DoExecuteInvoke() +{ + if(_parameters.size() > 2) + { + if(!ValidateLayer(_parameters[1])) + { + SetReplyString(TEXT("403 CG ERROR\r\n")); + return false; + } + int layer = _ttoi(_parameters[1].c_str()); + flash::get_default_cg_producer(GetChannel(), GetLayerIndex(flash::CG_DEFAULT_LAYER))->invoke(layer, _parameters[2]); + } + else + { + SetReplyString(TEXT("402 CG ERROR\r\n")); + return true; + } + + SetReplyString(TEXT("202 CG OK\r\n")); + return true; +} + +bool CGCommand::DoExecuteInfo() +{ + // TODO + //flash::get_default_cg_producer(GetChannel())->Info(); + SetReplyString(TEXT("600 CG FAILED\r\n")); + return true; +} + +bool DataCommand::DoExecute() +{ + std::wstring command = _parameters[0]; + if(command == TEXT("STORE")) + return DoExecuteStore(); + else if(command == TEXT("RETRIEVE")) + return DoExecuteRetrieve(); + else if(command == TEXT("LIST")) + return DoExecuteList(); + + SetReplyString(TEXT("403 DATA ERROR\r\n")); + return false; +} + +bool DataCommand::DoExecuteStore() +{ + if(_parameters.size() < 3) + { + SetReplyString(TEXT("402 DATA STORE ERROR\r\n")); + return false; + } + + std::wstring filename = server::data_folder(); + filename.append(_parameters[1]); + filename.append(TEXT(".ftd")); + + std::wofstream datafile(filename.c_str()); + if(!datafile) + { + SetReplyString(TEXT("501 DATA STORE FAILED\r\n")); + return false; + } + + datafile << _parameters[2]; + datafile.close(); + + std::wstring replyString = TEXT("202 DATA STORE OK\r\n"); + SetReplyString(replyString); + return true; +} + +bool DataCommand::DoExecuteRetrieve() +{ + if(_parameters.size() < 2) + { + SetReplyString(TEXT("402 DATA RETRIEVE ERROR\r\n")); + return false; + } + + std::wstring filename = server::data_folder(); + filename.append(_parameters[1]); + filename.append(TEXT(".ftd")); + + std::wifstream datafile(filename.c_str()); + if(!datafile) + { + SetReplyString(TEXT("404 DATA RETRIEVE ERROR\r\n")); + return false; + } + + std::wstringstream reply(TEXT("201 DATA RETRIEVE OK\r\n")); + std::wstring line; + bool bFirstLine = true; + while(std::getline(datafile, line)) + { + if(!bFirstLine) + reply << "\\n"; + else + bFirstLine = false; + + reply << line; + } + datafile.close(); + + reply << "\r\n"; + SetReplyString(reply.str()); + return true; +} + +bool DataCommand::DoExecuteList() +{ + std::wstringstream replyString; + replyString << TEXT("200 DATA LIST OK\r\n"); + replyString << ListMedia(); + replyString << TEXT("\r\n"); + + SetReplyString(boost::to_upper_copy(replyString.str())); + return true; +} + +bool CinfCommand::DoExecute() +{ + std::wstringstream replyString; + + std::wstring filename = server::media_folder()+_parameters[0]; + + // TODO: + + //FileInfo fileInfo; + + //MediaManagerPtr pMediaManager = GetApplication()->FindMediaFile(filename, &fileInfo); + //if(pMediaManager != 0 && fileInfo.filetype.length() >0) //File was found + //{ + // if(pMediaManager->getFileInfo(&fileInfo)) + // { + // TCHAR numBuffer[32]; + // _ui64tot_s(fileInfo.size, numBuffer, 32, 10); + + // replyString << TEXT("201 CINF OK\r\n\"") << fileInfo.filename << TEXT("\" ") << fileInfo.type << TEXT("/") << fileInfo.filetype << TEXT("/") << fileInfo.encoding << TEXT(" ") << numBuffer << TEXT("\r\n"); + + // SetReplyString(replyString.str()); + // return true; + // } + //} + + SetReplyString(TEXT("404 CINF ERROR\r\n")); + return false; +} + +void GenerateChannelInfo(int index, const renderer::render_device_ptr& pChannel, std::wstringstream& replyString) +{ + replyString << index << TEXT(" ") << pChannel->frame_format_desc().name << TEXT("\r\n") << (pChannel->active(0) != nullptr ? TEXT(" PLAYING") : TEXT(" STOPPED")); +} + +bool InfoCommand::DoExecute() +{ + std::wstringstream replyString; + + if(_parameters.size() >= 1) + { + int channelIndex = _ttoi(_parameters[0].c_str())-1; + + if(channelIndex < channels_.size()) + { + replyString << TEXT("201 INFO OK\r\n"); + GenerateChannelInfo(channelIndex, channels_[channelIndex], replyString); + } + else + { + SetReplyString(TEXT("401 INFO ERROR\r\n")); + return false; + } + } + else + { + replyString << TEXT("200 INFO OK\r\n"); + for(size_t n = 0; n < channels_.size(); ++n) + GenerateChannelInfo(n, channels_[n], replyString); + replyString << TEXT("\r\n"); + } + + SetReplyString(replyString.str()); + return true; +} + +bool ClsCommand::DoExecute() +{ +/* + wav = audio + mp3 = audio + swf = movie + dv = movie + tga = still + col = still + */ + std::wstringstream replyString; + replyString << TEXT("200 CLS OK\r\n"); + replyString << ListMedia(); + replyString << TEXT("\r\n"); + SetReplyString(boost::to_upper_copy(replyString.str())); + return true; +} + +bool TlsCommand::DoExecute() +{ + std::wstringstream replyString; + replyString << TEXT("200 TLS OK\r\n"); + + replyString << ListTemplates(); + replyString << TEXT("\r\n"); + + SetReplyString(replyString.str()); + return true; +} + +bool VersionCommand::DoExecute() +{ + std::wstringstream replyString; + replyString << TEXT("201 VERSION OK\r\n") << TEXT(CASPAR_VERSION_STR) << TEXT("\r\n"); + + SetReplyString(replyString.str()); + return true; +} + +bool ByeCommand::DoExecute() +{ + GetClientInfo()->Disconnect(); + return true; +} + +bool SetCommand::DoExecute() +{ + std::wstring name = _parameters[0]; + std::transform(name.begin(), name.end(), name.begin(), toupper); + + std::wstring value = _parameters[1]; + std::transform(value.begin(), value.end(), value.begin(), toupper); + + if(name == TEXT("MODE")) + { + //if(this->GetChannel()->SetVideoFormat(value)) TODO + // this->SetReplyString(TEXT("202 SET MODE OK\r\n")); + //else + this->SetReplyString(TEXT("501 SET MODE FAILED\r\n")); + } + else + { + this->SetReplyString(TEXT("403 SET ERROR\r\n")); + } + + return true; +} + +bool MonitorCommand::DoExecute() +{ + std::wstring cmd = _parameters[0]; + + if(cmd == TEXT("START")) { + GetChannel()->monitor().AddListener(GetClientInfo()); + SetReplyString(TEXT("202 MONITOR START OK\r\n")); + } + else if(cmd == TEXT("STOP")) { + GetChannel()->monitor().RemoveListener(GetClientInfo()); + SetReplyString(TEXT("202 MONITOR STOP OK\r\n")); + } + else + SetReplyString(TEXT("403 MONITOR ERROR\r\n")); + + return true; +} + +} //namespace amcp +} //namespace caspar \ No newline at end of file diff --git a/core/protocol/amcp/AMCPCommandsImpl.h b/core/protocol/amcp/AMCPCommandsImpl.h new file mode 100644 index 000000000..677e7be7b --- /dev/null +++ b/core/protocol/amcp/AMCPCommandsImpl.h @@ -0,0 +1,147 @@ +/* +* copyright (c) 2010 Sveriges Television AB +* +* This file is part of CasparCG. +* +* CasparCG is free software: you can redistribute it and/or modify +* it under the terms of the GNU General Public License as published by +* the Free Software Foundation, either version 3 of the License, or +* (at your option) any later version. +* +* CasparCG is distributed in the hope that it will be useful, +* but WITHOUT ANY WARRANTY; without even the implied warranty of +* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +* GNU General Public License for more details. + +* You should have received a copy of the GNU General Public License +* along with CasparCG. If not, see . +* +*/ + +#ifndef __AMCPCOMMANDSIMPL_H__ +#define __AMCPCOMMANDSIMPL_H__ + +#include "AMCPCommand.h" + +namespace caspar { + +std::wstring ListMedia(); +std::wstring ListTemplates(); + +namespace amcp { + +class LoadCommand : public AMCPCommandBase +{ + bool DoExecute(); +}; + +class LoadbgCommand : public AMCPCommandBase +{ + bool DoExecute(); +}; + +class PlayCommand: public AMCPCommandBase +{ + bool DoExecute(); +}; + +class StopCommand : public AMCPCommandBase +{ + bool DoExecute(); +}; + +class ClearCommand : public AMCPCommandBase +{ + bool DoExecute(); +}; + +class CGCommand : public AMCPCommandBase +{ + bool DoExecute(); + bool ValidateLayer(const std::wstring& layerstring); + + bool DoExecuteAdd(); + bool DoExecutePlay(); + bool DoExecuteStop(); + bool DoExecuteNext(); + bool DoExecuteRemove(); + bool DoExecuteClear(); + bool DoExecuteUpdate(); + bool DoExecuteInvoke(); + bool DoExecuteInfo(); +}; + +class DataCommand : public AMCPCommandBase +{ + bool DoExecute(); + bool DoExecuteStore(); + bool DoExecuteRetrieve(); + bool DoExecuteList(); +}; + +class ClsCommand : public AMCPCommandBase +{ + bool DoExecute(); +}; + +class TlsCommand : public AMCPCommandBase +{ + bool DoExecute(); +}; + +class CinfCommand : public AMCPCommandBase +{ + bool DoExecute(); +}; + +class InfoCommand : public AMCPCommandBase +{ +public: + InfoCommand(const std::vector& channels) : channels_(channels){} + bool DoExecute(); +private: + const std::vector& channels_; +}; + +class VersionCommand : public AMCPCommandBase +{ + bool DoExecute(); +}; + +class ByeCommand : public AMCPCommandBase +{ + bool DoExecute(); +}; + +class SetCommand : public AMCPCommandBase +{ + bool DoExecute(); +}; + +class MonitorCommand : public AMCPCommandBase +{ + bool DoExecute(); +}; + +//class KillCommand : public AMCPCommand +//{ +//public: +// KillCommand() {} +// virtual bool DoExecute(); +// virtual AMCPCommandCondition CheckConditions(); +// +// virtual bool NeedChannel() { +// return false; +// } +// virtual AMCPCommandScheduling GetDefaultScheduling() { +// return AddToQueue; +// } +// virtual int GetMinimumParameters() { +// return 0; +// } +//}; + +} //namespace amcp +} //namespace caspar + +#endif //__AMCPCOMMANDSIMPL_H__ \ No newline at end of file diff --git a/core/protocol/amcp/AMCPProtocolStrategy.cpp b/core/protocol/amcp/AMCPProtocolStrategy.cpp new file mode 100644 index 000000000..8a0fd71b8 --- /dev/null +++ b/core/protocol/amcp/AMCPProtocolStrategy.cpp @@ -0,0 +1,421 @@ +/* +* copyright (c) 2010 Sveriges Television AB +* +* This file is part of CasparCG. +* +* CasparCG is free software: you can redistribute it and/or modify +* it under the terms of the GNU General Public License as published by +* the Free Software Foundation, either version 3 of the License, or +* (at your option) any later version. +* +* CasparCG is distributed in the hope that it will be useful, +* but WITHOUT ANY WARRANTY; without even the implied warranty of +* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +* GNU General Public License for more details. + +* You should have received a copy of the GNU General Public License +* along with CasparCG. If not, see . +* +*/ + +#include "../../StdAfx.h" +#include "../../renderer/render_device.h" + +#include "AMCPProtocolStrategy.h" + +#include "../../../common/io/AsyncEventServer.h" +#include "AMCPCommandsImpl.h" + +#include +#include +#include +#include +#include + +#include +#include +#include + +#if defined(_MSC_VER) +#pragma warning (push, 1) // TODO: Legacy code, just disable warnings +#endif + +namespace caspar { namespace amcp { + +using namespace common; +using IO::ClientInfoPtr; + +const std::wstring AMCPProtocolStrategy::MessageDelimiter = TEXT("\r\n"); + +inline renderer::render_device_ptr GetChannelSafe(unsigned int index, const std::vector& channels) +{ + return index < channels.size() ? channels[index] : nullptr; +} + +AMCPProtocolStrategy::AMCPProtocolStrategy(const std::vector& channels) : channels_(channels) { + AMCPCommandQueuePtr pGeneralCommandQueue(new AMCPCommandQueue()); + if(!pGeneralCommandQueue->Start()) { + CASPAR_LOG(error) << "Failed to start the general command-queue"; + + //TODO: THROW! + } + else + commandQueues_.push_back(pGeneralCommandQueue); + + + renderer::render_device_ptr pChannel; + unsigned int index = -1; + //Create a commandpump for each channel + while((pChannel = GetChannelSafe(++index, channels_)) != 0) { + AMCPCommandQueuePtr pChannelCommandQueue(new AMCPCommandQueue()); + std::wstring title = TEXT("CHANNEL "); + + //HACK: Perform real conversion from int to string + TCHAR num = TEXT('1')+static_cast(index); + title += num; + + if(!pChannelCommandQueue->Start()) { + std::wstring logString = TEXT("Failed to start command-queue for "); + logString += title; + CASPAR_LOG(error) << logString; + + //TODO: THROW! + } + else + commandQueues_.push_back(pChannelCommandQueue); + } +} + +AMCPProtocolStrategy::~AMCPProtocolStrategy() { +} + +void AMCPProtocolStrategy::Parse(const TCHAR* pData, int charCount, ClientInfoPtr pClientInfo) +{ + size_t pos; + std::wstring recvData(pData, charCount); + std::wstring availibleData = (pClientInfo != nullptr ? pClientInfo->currentMessage_ : L"") + recvData; + + while(true) { + pos = availibleData.find(MessageDelimiter); + if(pos != std::wstring::npos) + { + std::wstring message = availibleData.substr(0,pos); + + //This is where a complete message gets taken care of + if(message.length() > 0) { + ProcessMessage(message, pClientInfo); + } + + std::size_t nextStartPos = pos + MessageDelimiter.length(); + if(nextStartPos < availibleData.length()) + availibleData = availibleData.substr(nextStartPos); + else { + availibleData.clear(); + break; + } + } + else + { + break; + } + } + if(pClientInfo) + pClientInfo->currentMessage_ = availibleData; +} + +void AMCPProtocolStrategy::ProcessMessage(const std::wstring& message, ClientInfoPtr& pClientInfo) +{ + bool bError = true; + MessageParserState state = New; + + AMCPCommandPtr pCommand; + + pCommand = InterpretCommandString(message, &state); + + if(pCommand != 0) { + pCommand->SetClientInfo(pClientInfo); + if(QueueCommand(pCommand)) + bError = false; + else + state = GetChannel; + } + + if(bError == true) { + std::wstringstream answer; + switch(state) + { + case GetCommand: + answer << TEXT("400 ERROR\r\n") + message << "\r\n"; + break; + case GetChannel: + answer << TEXT("401 ERROR\r\n"); + break; + case GetParameters: + answer << TEXT("402 ERROR\r\n"); + break; + default: + answer << TEXT("500 FAILED\r\n"); + break; + } + pClientInfo->Send(answer.str()); + } +} + +AMCPCommandPtr AMCPProtocolStrategy::InterpretCommandString(const std::wstring& message, MessageParserState* pOutState) +{ + std::vector tokens; + unsigned int currentToken = 0; + std::wstring commandSwitch; + + AMCPCommandPtr pCommand; + MessageParserState state = New; + + CASPAR_LOG(trace) << message; + + std::size_t tokensInMessage = TokenizeMessage(message, &tokens); + + //parse the message one token at the time + while(currentToken < tokensInMessage) + { + switch(state) + { + case New: + if(tokens[currentToken][0] == TEXT('/')) + state = GetSwitch; + else + state = GetCommand; + break; + + case GetSwitch: + commandSwitch = tokens[currentToken]; + state = GetCommand; + ++currentToken; + break; + + case GetCommand: + pCommand = CommandFactory(tokens[currentToken]); + if(pCommand == 0) { + goto ParseFinnished; + } + else + { + //Set scheduling + if(commandSwitch.size() > 0) { + transform(commandSwitch.begin(), commandSwitch.end(), commandSwitch.begin(), toupper); + + if(commandSwitch == TEXT("/APP")) + pCommand->SetScheduling(AddToQueue); + else if(commandSwitch == TEXT("/IMMF")) + pCommand->SetScheduling(ImmediatelyAndClear); + } + + if(pCommand->NeedChannel()) + state = GetChannel; + else + state = GetParameters; + } + ++currentToken; + break; + + case GetParameters: + { + _ASSERTE(pCommand != 0); + int parameterCount=0; + while(currentTokenAddParameter(tokens[currentToken++]); + ++parameterCount; + } + + if(parameterCount < pCommand->GetMinimumParameters()) { + goto ParseFinnished; + } + + state = Done; + break; + } + + case GetChannel: + { +// assert(pCommand != 0); + + std::wstring str = boost::trim_copy(tokens[currentToken]); + std::vector split; + boost::split(split, str, boost::is_any_of("-")); + + int channelIndex = boost::lexical_cast(split[0]) - 1; + + int layerIndex = -1; + if(split.size() > 1) + layerIndex = boost::lexical_cast(split[1]); + + renderer::render_device_ptr pChannel = GetChannelSafe(channelIndex, channels_); + if(pChannel == 0) { + goto ParseFinnished; + } + + pCommand->SetChannel(pChannel); + pCommand->SetChannelIndex(channelIndex); + pCommand->SetLayerIntex(layerIndex); + + state = GetParameters; + ++currentToken; + break; + } + + default: //Done and unexpected + goto ParseFinnished; + } + } + +ParseFinnished: + if(state == GetParameters && pCommand->GetMinimumParameters()==0) + state = Done; + + if(state != Done) { + pCommand.reset(); + } + + if(pOutState != 0) { + *pOutState = state; + } + + return pCommand; +} + +bool AMCPProtocolStrategy::QueueCommand(AMCPCommandPtr pCommand) { + if(pCommand->NeedChannel()) { + unsigned int channelIndex = pCommand->GetChannelIndex() + 1; + if(commandQueues_.size() > channelIndex) { + commandQueues_[channelIndex]->AddCommand(pCommand); + } + else + return false; + } + else { + commandQueues_[0]->AddCommand(pCommand); + } + return true; +} + +AMCPCommandPtr AMCPProtocolStrategy::CommandFactory(const std::wstring& str) +{ + std::wstring s = str; + transform(s.begin(), s.end(), s.begin(), toupper); + + AMCPCommandPtr result; + + if(s == TEXT("LOAD")) + result = AMCPCommandPtr(new LoadCommand()); + else if(s == TEXT("LOADBG")) + result = AMCPCommandPtr(new LoadbgCommand()); + else if(s == TEXT("PLAY")) + result = AMCPCommandPtr(new PlayCommand()); + else if(s == TEXT("STOP")) + result = AMCPCommandPtr(new StopCommand()); + else if(s == TEXT("CLEAR")) + result = AMCPCommandPtr(new ClearCommand()); + else if(s == TEXT("CG")) + result = AMCPCommandPtr(new CGCommand()); + else if(s == TEXT("DATA")) + result = AMCPCommandPtr(new DataCommand()); + else if(s == TEXT("CINF")) + result = AMCPCommandPtr(new CinfCommand()); + else if(s == TEXT("INFO")) + result = AMCPCommandPtr(new InfoCommand(channels_)); + else if(s == TEXT("CLS")) + result = AMCPCommandPtr(new ClsCommand()); + else if(s == TEXT("TLS")) + result = AMCPCommandPtr(new TlsCommand()); + else if(s == TEXT("VERSION")) + result = AMCPCommandPtr(new VersionCommand()); + else if(s == TEXT("BYE")) + result = AMCPCommandPtr(new ByeCommand()); + else if(s == TEXT("SET")) + result = AMCPCommandPtr(new SetCommand()); + //else if(s == TEXT("MONITOR")) + //{ + // result = AMCPCommandPtr(new MonitorCommand()); + //} + //else if(s == TEXT("KILL")) + //{ + // result = AMCPCommandPtr(new KillCommand()); + //} + return result; +} + +std::size_t AMCPProtocolStrategy::TokenizeMessage(const std::wstring& message, std::vector* pTokenVector) +{ + //split on whitespace but keep strings within quotationmarks + //treat \ as the start of an escape-sequence: the following char will indicate what to actually put in the string + + std::wstring currentToken; + + char inQuote = 0; + bool getSpecialCode = false; + + for(unsigned int charIndex=0; charIndex0) + { + pTokenVector->push_back(currentToken); + currentToken.clear(); + } + continue; + } + + if(message[charIndex]==TEXT('\"')) + { + inQuote ^= 1; + + if(currentToken.size()>0) + { + pTokenVector->push_back(currentToken); + currentToken.clear(); + } + continue; + } + + currentToken += message[charIndex]; + } + + if(currentToken.size()>0) + { + pTokenVector->push_back(currentToken); + currentToken.clear(); + } + + return pTokenVector->size(); +} + +} //namespace amcp +} //namespace caspar \ No newline at end of file diff --git a/core/protocol/amcp/AMCPProtocolStrategy.h b/core/protocol/amcp/AMCPProtocolStrategy.h new file mode 100644 index 000000000..f2a101de6 --- /dev/null +++ b/core/protocol/amcp/AMCPProtocolStrategy.h @@ -0,0 +1,67 @@ +/* +* copyright (c) 2010 Sveriges Television AB +* +* This file is part of CasparCG. +* +* CasparCG is free software: you can redistribute it and/or modify +* it under the terms of the GNU General Public License as published by +* the Free Software Foundation, either version 3 of the License, or +* (at your option) any later version. +* +* CasparCG is distributed in the hope that it will be useful, +* but WITHOUT ANY WARRANTY; without even the implied warranty of +* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +* GNU General Public License for more details. + +* You should have received a copy of the GNU General Public License +* along with CasparCG. If not, see . +* +*/ +#pragma once + +#include "../../../common/io/protocolstrategy.h" +#include "AMCPCommand.h" +#include "AMCPCommandQueue.h" + +namespace caspar { namespace amcp { + +class AMCPProtocolStrategy : public IO::IProtocolStrategy +{ + enum MessageParserState { + New = 0, + GetSwitch, + GetCommand, + GetParameters, + GetChannel, + Done + }; + + AMCPProtocolStrategy(const AMCPProtocolStrategy&); + AMCPProtocolStrategy& operator=(const AMCPProtocolStrategy&); + +public: + AMCPProtocolStrategy(const std::vector& channels); + virtual ~AMCPProtocolStrategy(); + + virtual void Parse(const TCHAR* pData, int charCount, caspar::IO::ClientInfoPtr pClientInfo); + virtual UINT GetCodepage() { + return CP_UTF8; + } + + AMCPCommandPtr InterpretCommandString(const std::wstring& str, MessageParserState* pOutState=0); + +private: + friend class AMCPCommand; + + void ProcessMessage(const std::wstring& message, caspar::IO::ClientInfoPtr& pClientInfo); + std::size_t TokenizeMessage(const std::wstring& message, std::vector* pTokenVector); + AMCPCommandPtr CommandFactory(const std::wstring& str); + + bool QueueCommand(AMCPCommandPtr); + + const std::vector& channels_; + std::vector commandQueues_; + static const std::wstring MessageDelimiter; +}; + +}} diff --git a/core/protocol/cii/CIICommand.h b/core/protocol/cii/CIICommand.h new file mode 100644 index 000000000..dfb099c93 --- /dev/null +++ b/core/protocol/cii/CIICommand.h @@ -0,0 +1,38 @@ +/* +* copyright (c) 2010 Sveriges Television AB +* +* This file is part of CasparCG. +* +* CasparCG is free software: you can redistribute it and/or modify +* it under the terms of the GNU General Public License as published by +* the Free Software Foundation, either version 3 of the License, or +* (at your option) any later version. +* +* CasparCG is distributed in the hope that it will be useful, +* but WITHOUT ANY WARRANTY; without even the implied warranty of +* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +* GNU General Public License for more details. + +* You should have received a copy of the GNU General Public License +* along with CasparCG. If not, see . +* +*/ + +#pragma once + +namespace caspar { +namespace cii { + +class ICIICommand +{ +public: + virtual ~ICIICommand() {} + virtual int GetMinimumParameters() = 0; + virtual void Setup(const std::vector& parameters) = 0; + + virtual void Execute() = 0; +}; +typedef std::tr1::shared_ptr CIICommandPtr; + +} //namespace cii +} //namespace caspar \ No newline at end of file diff --git a/core/protocol/cii/CIICommandsImpl.cpp b/core/protocol/cii/CIICommandsImpl.cpp new file mode 100644 index 000000000..95265fb16 --- /dev/null +++ b/core/protocol/cii/CIICommandsImpl.cpp @@ -0,0 +1,192 @@ +/* +* copyright (c) 2010 Sveriges Television AB +* +* This file is part of CasparCG. +* +* CasparCG is free software: you can redistribute it and/or modify +* it under the terms of the GNU General Public License as published by +* the Free Software Foundation, either version 3 of the License, or +* (at your option) any later version. +* +* CasparCG is distributed in the hope that it will be useful, +* but WITHOUT ANY WARRANTY; without even the implied warranty of +* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +* GNU General Public License for more details. + +* You should have received a copy of the GNU General Public License +* along with CasparCG. If not, see . +* +*/ + +#include "../../StdAfx.h" + +#include "CIIProtocolStrategy.h" +#include "CIICommandsImpl.h" +#include +#include +#include "../../producer/flash/cg_producer.h" + +namespace caspar { namespace cii { + +///////////////// +// MediaCommand +void MediaCommand::Setup(const std::vector& parameters) +{ + graphicProfile_ = parameters[1].substr(2); +} + +void MediaCommand::Execute() +{ + pCIIStrategy_->SetProfile(graphicProfile_); +} + + +///////////////// +// WriteCommand +void WriteCommand::Setup(const std::vector& parameters) +{ + try + { + if(parameters.size() > 2) + { + targetName_ = parameters[1]; + templateName_ = parameters[2]; + + std::wstringstream dataStream; + + dataStream << TEXT(""); + + std::vector::size_type end = parameters.size(); + for(std::vector::size_type i = 3; i < end; ++i) + dataStream << TEXT(""); + + dataStream << TEXT(""); + xmlData_ = dataStream.str(); + } + } + catch(std::exception) { + } +} + +void WriteCommand::Execute() +{ + pCIIStrategy_->WriteTemplateData(templateName_, targetName_, xmlData_); +} + + +////////////////////// +// ImagestoreCommand +void ImagestoreCommand::Setup(const std::vector& parameters) +{ + if(parameters[1] == TEXT("7") && parameters.size() > 2) + titleName_ = parameters[2].substr(0, 4); +} + +void ImagestoreCommand::Execute() +{ + pCIIStrategy_->DisplayTemplate(titleName_); +} + + +////////////////////// +// MiscellaneousCommand +void MiscellaneousCommand::Setup(const std::vector& parameters) +{ + //HAWRYS: V\5\3\1\1\namn.tga\1 + // Display still + if((parameters.size() > 5) && parameters[1] == TEXT("5") && parameters[2] == TEXT("3")) + { + filename_ = parameters[5]; + filename_ = filename_.substr(0, filename_.find_last_of(TEXT('.'))); + state_ = 0; + return; + } + + //NEPTUNE: V\5\13\1\X\Template\0\TabField1\TabField2... + // Add Template to layer X in the active templatehost + if((parameters.size() > 5) && parameters[1] == TEXT("5") && parameters[2] == TEXT("13")) + { + layer_ = _ttoi(parameters[4].c_str()); + filename_ = parameters[5]; + state_ = 1; + if(parameters.size() > 7) { + std::wstringstream dataStream; + + dataStream << TEXT(""); + std::vector::size_type end = parameters.size(); + for(std::vector::size_type i = 7; i < end; ++i) { + dataStream << TEXT(""); + } + dataStream << TEXT(""); + + xmlData_ = dataStream.str(); + } + } + + // VIDEO MODE V\5\14\MODE + if((parameters.size() > 3) && parameters[1] == TEXT("5") && parameters[2] == TEXT("14")) + { + std::wstring value = parameters[3]; + std::transform(value.begin(), value.end(), value.begin(), toupper); + + //this->pCIIStrategy_->GetChannel()->SetVideoFormat(value); TODO + } +} + +void MiscellaneousCommand::Execute() +{ + if(state_ == 0) + pCIIStrategy_->DisplayMediaFile(filename_); + + //TODO: Need to be checked for validity + else if(state_ == 1) + flash::get_default_cg_producer(pCIIStrategy_->GetChannel())->add(layer_, filename_, false, TEXT(""), xmlData_); +} + + +/////////////////// +// KeydataCommand +void KeydataCommand::Execute() +{ + if(state_ == 0) + pCIIStrategy_->DisplayTemplate(titleName_); + + + //TODO: Need to be checked for validity + else if(state_ == 1) + flash::get_default_cg_producer(pCIIStrategy_->GetChannel())->stop(layer_, 0); + else if(state_ == 2) + flash::get_default_cg_producer(pCIIStrategy_->GetChannel())->clear(); + else if(state_ == 3) + flash::get_default_cg_producer(pCIIStrategy_->GetChannel())->play(layer_); +} + +void KeydataCommand::Setup(const std::vector& parameters) { + //HAWRYS: Y\<205><247><202><196><192><192><200><248> + //parameter[1] looks like this: "=g:XXXXh" where XXXX is the name that we want + if(parameters[1].size() > 6) + { + titleName_.resize(4); + for(int i=0;i<4;++i) + { + if(parameters[1][i+3] < 176) { + titleName_ = TEXT(""); + break; + } + titleName_[i] = parameters[1][i+3]-144; + } + state_ = 0; + } + + if(parameters.size() > 2) + layer_ = _ttoi(parameters[2].c_str()); + + if(parameters[1].at(0) == 27) //NEPTUNE: Y\<27>\X Stop layer X. + state_ = 1; + else if(static_cast(parameters[1].at(0)) == 254) //NEPTUNE: Y\<254> Clear Canvas. + state_ = 2; + else if(static_cast(parameters[1].at(0)) == 213) //NEPTUNE: Y\<213><243>\X Play layer X. + state_ = 3; +} + +}} \ No newline at end of file diff --git a/core/protocol/cii/CIICommandsImpl.h b/core/protocol/cii/CIICommandsImpl.h new file mode 100644 index 000000000..19ca55f8a --- /dev/null +++ b/core/protocol/cii/CIICommandsImpl.h @@ -0,0 +1,134 @@ +/* +* copyright (c) 2010 Sveriges Television AB +* +* This file is part of CasparCG. +* +* CasparCG is free software: you can redistribute it and/or modify +* it under the terms of the GNU General Public License as published by +* the Free Software Foundation, either version 3 of the License, or +* (at your option) any later version. +* +* CasparCG is distributed in the hope that it will be useful, +* but WITHOUT ANY WARRANTY; without even the implied warranty of +* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +* GNU General Public License for more details. + +* You should have received a copy of the GNU General Public License +* along with CasparCG. If not, see . +* +*/ + +#pragma once + +#include "ciicommand.h" + +namespace caspar { + +namespace cii { + +class CIIProtocolStrategy; + +class MediaCommand : public ICIICommand +{ +public: + MediaCommand(CIIProtocolStrategy* pPS) : pCIIStrategy_(pPS) + {} + + virtual int GetMinimumParameters() { + return 1; + } + + virtual void Setup(const std::vector& parameters); + virtual void Execute(); + +private: + std::wstring graphicProfile_; + + CIIProtocolStrategy* pCIIStrategy_; +}; + +class WriteCommand : public ICIICommand +{ +public: + WriteCommand(CIIProtocolStrategy* pPS) : pCIIStrategy_(pPS) + {} + + virtual int GetMinimumParameters() { + return 2; + } + + virtual void Setup(const std::vector& parameters); + virtual void Execute(); + +private: + std::wstring targetName_; + std::wstring templateName_; + std::wstring xmlData_; + + CIIProtocolStrategy* pCIIStrategy_; +}; + +class MiscellaneousCommand : public ICIICommand +{ +public: + MiscellaneousCommand(CIIProtocolStrategy* pPS) : pCIIStrategy_(pPS), state_(-1), layer_(0) + {} + + virtual int GetMinimumParameters() { + return 5; + } + + virtual void Setup(const std::vector& parameters); + virtual void Execute(); + +private: + std::wstring filename_; + std::wstring xmlData_; + int state_; + int layer_; + + CIIProtocolStrategy* pCIIStrategy_; +}; + +class ImagestoreCommand : public ICIICommand +{ +public: + ImagestoreCommand(CIIProtocolStrategy* pPS) : pCIIStrategy_(pPS) + {} + + virtual int GetMinimumParameters() { + return 1; + } + + virtual void Setup(const std::vector& parameters); + virtual void Execute(); + +private: + std::wstring titleName_; + + CIIProtocolStrategy* pCIIStrategy_; +}; + +class KeydataCommand : public ICIICommand +{ +public: + KeydataCommand(CIIProtocolStrategy* pPS) : pCIIStrategy_(pPS), state_(-1), layer_(0) + {} + + virtual int GetMinimumParameters() { + return 1; + } + + virtual void Setup(const std::vector& parameters); + virtual void Execute(); + +private: + std::wstring titleName_; + int state_; + int layer_; + + CIIProtocolStrategy* pCIIStrategy_; +}; + +} //namespace cii +} //namespace caspar \ No newline at end of file diff --git a/core/protocol/cii/CIIProtocolStrategy.cpp b/core/protocol/cii/CIIProtocolStrategy.cpp new file mode 100644 index 000000000..996744064 --- /dev/null +++ b/core/protocol/cii/CIIProtocolStrategy.cpp @@ -0,0 +1,286 @@ +/* +* copyright (c) 2010 Sveriges Television AB +* +* This file is part of CasparCG. +* +* CasparCG is free software: you can redistribute it and/or modify +* it under the terms of the GNU General Public License as published by +* the Free Software Foundation, either version 3 of the License, or +* (at your option) any later version. +* +* CasparCG is distributed in the hope that it will be useful, +* but WITHOUT ANY WARRANTY; without even the implied warranty of +* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +* GNU General Public License for more details. + +* You should have received a copy of the GNU General Public License +* along with CasparCG. If not, see . +* +*/ + +#include "../../StdAfx.h" + +#include +#include +#include +#include "../media.h" +#include "CIIProtocolStrategy.h" +#include "CIICommandsimpl.h" +#include "../../producer/flash/flash_producer.h" +#include "../../producer/transition/transition_producer.h" +#include "../../Server.h" +#include "../../producer/frame_producer.h" + +#if defined(_MSC_VER) +#pragma warning (push, 1) // TODO: Legacy code, just disable warnings +#endif + +namespace caspar { namespace cii { + +using namespace common; + +const std::wstring CIIProtocolStrategy::MessageDelimiter = TEXT("\r\n"); +const TCHAR CIIProtocolStrategy::TokenDelimiter = TEXT('\\'); + +CIIProtocolStrategy::CIIProtocolStrategy(const std::vector& channels) +{ + if(channels.empty()) + BOOST_THROW_EXCEPTION(invalid_argument() << arg_name_info("channels")); + pChannel_ = channels[0]; + executor_.start(); +} + +void CIIProtocolStrategy::Parse(const TCHAR* pData, int charCount, caspar::IO::ClientInfoPtr pClientInfo) +{ + std::size_t pos; + std::wstring msg(pData, charCount); + std::wstring availibleData = currentMessage_ + msg; + + while(true) + { + pos = availibleData.find(MessageDelimiter); + if(pos != std::wstring::npos) + { + std::wstring message = availibleData.substr(0,pos); + + if(message.length() > 0) { + ProcessMessage(message); + if(pClientInfo != 0) + pClientInfo->Send(TEXT("*\r\n")); + } + + std::size_t nextStartPos = pos + MessageDelimiter.length(); + if(nextStartPos < availibleData.length()) + availibleData = availibleData.substr(nextStartPos); + else + { + availibleData.clear(); + break; + } + } + else + break; + } + currentMessage_ = availibleData; +} + +void CIIProtocolStrategy::ProcessMessage(const std::wstring& message) +{ + CASPAR_LOG(debug) << message.c_str(); + + std::vector tokens; + int tokenCount = TokenizeMessage(message, &tokens); + + CIICommandPtr pCommand = Create(tokens[0]); + if((pCommand != 0) && (tokenCount-1) >= pCommand->GetMinimumParameters()) + { + pCommand->Setup(tokens); + executor_.begin_invoke([=]{pCommand->Execute();}); + } + else {} //report error +} + +int CIIProtocolStrategy::TokenizeMessage(const std::wstring& message, std::vector* pTokenVector) +{ + std::wstringstream currentToken; + + for(unsigned int charIndex=0; charIndexpush_back(currentToken.str()); + currentToken.str(TEXT("")); + continue; + } + + if(message[charIndex] == TEXT('\"')) + currentToken << TEXT("""); + else if(message[charIndex] == TEXT('<')) + currentToken << TEXT("<"); + else if(message[charIndex] == TEXT('>')) + currentToken << TEXT(">"); + else + currentToken << message[charIndex]; + } + + if(currentToken.str().size() > 0) + pTokenVector->push_back(currentToken.str()); + + return (int)pTokenVector->size(); +} + +/************ +// Examples ( = ASCIICHAR X) + +I\25\3\VII\\ sätter outputtype till 'vii' +I\25\4\1\\ enablar framebuffer (ignore this) + +M\C/SVTNEWS\\ pekar ut vilken grafisk profil som skall användas + +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 + +T\7\4009.VII\A\\ lägger ut skylt 4009 + +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) + +V\5\3\1\1\namn.tga\1\\ lägger ut bilden namn.tga +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. + +*************/ + +/********************** +New Commands to support the Netupe automation system +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 +Y\<27>\\ Stop. Här kommer ett lagerID också att skickas med (<27> = ESC) +Y\<254>\\ Clear Canvas. Här kommer ett lagerID också att skickas med, utan det skall allt tömmas +Y\<213><243>\\ Play. Här kommer ett lagerID också att skickas med + +**********************/ +CIICommandPtr CIIProtocolStrategy::Create(const std::wstring& name) +{ + switch(name[0]) + { + case TEXT('M'): return std::make_shared(this); + case TEXT('W'): return std::make_shared(this); + case TEXT('T'): return std::make_shared(this); + case TEXT('V'): return std::make_shared(this); + case TEXT('Y'): return std::make_shared(this); + default: return nullptr; + } +} + +void CIIProtocolStrategy::WriteTemplateData(const std::wstring& templateName, const std::wstring& titleName, const std::wstring& xmlData) +{ + std::wstring fullTemplateFilename = server::template_folder(); + if(currentProfile_.size() > 0) + { + fullTemplateFilename += currentProfile_; + fullTemplateFilename += TEXT("\\"); + } + fullTemplateFilename += templateName; + fullTemplateFilename = flash::flash_producer::find_template(fullTemplateFilename); + if(fullTemplateFilename.empty()) + { + CASPAR_LOG(error) << "Failed to save instance of " << templateName << TEXT(" as ") << titleName << TEXT(", template ") << fullTemplateFilename << " not found"; + return; + } + + std::vector params; + params.push_back(server::template_folder()+TEXT("CG.fth")); + auto pFP = flash::create_flash_producer(params, GetChannel()->frame_format_desc()); + if(pFP != 0) + { + //TODO: Initialize with valid FrameFactory +// pFP->Initialize(0, false); + + std::wstringstream flashParam; + flashParam << TEXT("1") << currentProfile_ << '/' << templateName << TEXT("0 "); + pFP->param(flashParam.str()); + + CASPAR_LOG(info) << "Saved an instance of " << templateName << TEXT(" as ") << titleName ; + + PutPreparedTemplate(titleName, std::static_pointer_cast(pFP)); + } +} + +void CIIProtocolStrategy::DisplayTemplate(const std::wstring& titleName) +{ + try + { + pChannel_->load(0, GetPreparedTemplate(titleName)); + pChannel_->play(0); + + CASPAR_LOG(info) << L"Displayed title " << titleName ; + } + catch(caspar_exception&) + { + CASPAR_LOG(error) << L"Failed to display title " << titleName; + } +} + +void CIIProtocolStrategy::DisplayMediaFile(const std::wstring& filename) +{ + transition_info transition; + transition.type = transition_type::mix; + transition.duration = 12; + + auto pFP = load_media(boost::assign::list_of(filename), pChannel_->frame_format_desc()); + auto pTransition = std::make_shared(pFP, transition, pChannel_->frame_format_desc()); + + try + { + pChannel_->load(0, pTransition); + } + catch(...) + { + CASPAR_LOG_CURRENT_EXCEPTION(); + CASPAR_LOG(error) << L"Failed to display " << filename ; + return; + } + + pChannel_->play(0); + + CASPAR_LOG(info) << L"Displayed " << filename; +} + +frame_producer_ptr CIIProtocolStrategy::GetPreparedTemplate(const std::wstring& titleName) +{ + frame_producer_ptr result; + + TitleList::iterator it = std::find(titles_.begin(), titles_.end(), titleName); + if(it != titles_.end()) { + CASPAR_LOG(debug) << L"Found title with name " << it->titleName; + result = (*it).pframe_producer; + } + else + CASPAR_LOG(error) << L"Could not find title with name " << titleName; + + return result; +} + +void CIIProtocolStrategy::PutPreparedTemplate(const std::wstring& titleName, frame_producer_ptr& pFP) +{ + CASPAR_LOG(debug) << L"Saved title with name " << titleName; + + TitleList::iterator it = std::find(titles_.begin(), titles_.end(), titleName); + if(it != titles_.end()) { + titles_.remove((*it)); + } + + titles_.push_front(TitleHolder(titleName, pFP)); + + if(titles_.size() >= 6) + titles_.resize(5); +} + +bool operator==(const CIIProtocolStrategy::TitleHolder& lhs, const std::wstring& rhs) +{ + return lhs.titleName == rhs; +} + +bool operator==(const std::wstring& lhs, const CIIProtocolStrategy::TitleHolder& rhs) +{ + return lhs == rhs.titleName; +} + +}} diff --git a/core/protocol/cii/CIIProtocolStrategy.h b/core/protocol/cii/CIIProtocolStrategy.h new file mode 100644 index 000000000..860340d53 --- /dev/null +++ b/core/protocol/cii/CIIProtocolStrategy.h @@ -0,0 +1,88 @@ +/* +* copyright (c) 2010 Sveriges Television AB +* +* This file is part of CasparCG. +* +* CasparCG is free software: you can redistribute it and/or modify +* it under the terms of the GNU General Public License as published by +* the Free Software Foundation, either version 3 of the License, or +* (at your option) any later version. +* +* CasparCG is distributed in the hope that it will be useful, +* but WITHOUT ANY WARRANTY; without even the implied warranty of +* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +* GNU General Public License for more details. + +* You should have received a copy of the GNU General Public License +* along with CasparCG. If not, see . +* +*/ + +#pragma once + +#include "../../../common/io/ProtocolStrategy.h" +#include "CIICommand.h" +#include "../../consumer/frame_consumer.h" +#include "../../../common/concurrency/executor.h" +#include "../../renderer/render_device.h" + +namespace caspar { namespace cii { + +class CIIProtocolStrategy : public caspar::IO::IProtocolStrategy +{ +public: + CIIProtocolStrategy(const std::vector& channels); + + void Parse(const TCHAR* pData, int charCount, caspar::IO::ClientInfoPtr pClientInfo); + UINT GetCodepage() {return 28591;} //ISO 8859-1 + + void SetProfile(const std::wstring& profile) {currentProfile_ = profile;} + + renderer::render_device_ptr GetChannel() const{return this->pChannel_;} + + void DisplayMediaFile(const std::wstring& filename); + void DisplayTemplate(const std::wstring& titleName); + void WriteTemplateData(const std::wstring& templateName, const std::wstring& titleName, const std::wstring& xmlData); + +public: + struct TitleHolder + { + TitleHolder() : titleName(TEXT("")) {} + TitleHolder(const std::wstring& name, frame_producer_ptr pFP) : titleName(name), pframe_producer(pFP) {} + TitleHolder(const TitleHolder& th) : titleName(th.titleName), pframe_producer(th.pframe_producer) {} + const TitleHolder& operator=(const TitleHolder& th) + { + titleName = th.titleName; + pframe_producer = th.pframe_producer; + } + bool operator==(const TitleHolder& rhs) + { + return pframe_producer == rhs.pframe_producer; + } + + std::wstring titleName; + frame_producer_ptr pframe_producer; + friend CIIProtocolStrategy; + }; +private: + + typedef std::list TitleList; + TitleList titles_; + frame_producer_ptr GetPreparedTemplate(const std::wstring& name); + void PutPreparedTemplate(const std::wstring& name, frame_producer_ptr& pframe_producer); + + static const TCHAR TokenDelimiter; + static const std::wstring MessageDelimiter; + + void ProcessMessage(const std::wstring& message); + int TokenizeMessage(const std::wstring& message, std::vector* pTokenVector); + CIICommandPtr Create(const std::wstring& name); + + common::executor executor_; + std::wstring currentMessage_; + + std::wstring currentProfile_; + renderer::render_device_ptr pChannel_; +}; + +}} \ No newline at end of file diff --git a/core/protocol/clk/CLKCommand.cpp b/core/protocol/clk/CLKCommand.cpp new file mode 100644 index 000000000..315b0b617 --- /dev/null +++ b/core/protocol/clk/CLKCommand.cpp @@ -0,0 +1,94 @@ +/* +* copyright (c) 2010 Sveriges Television AB +* +* This file is part of CasparCG. +* +* CasparCG is free software: you can redistribute it and/or modify +* it under the terms of the GNU General Public License as published by +* the Free Software Foundation, either version 3 of the License, or +* (at your option) any later version. +* +* CasparCG is distributed in the hope that it will be useful, +* but WITHOUT ANY WARRANTY; without even the implied warranty of +* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +* GNU General Public License for more details. + +* You should have received a copy of the GNU General Public License +* along with CasparCG. If not, see . +* +*/ + +#include "..\..\stdafx.h" +#include +#include +#include "CLKCommand.h" + +namespace caspar { namespace CLK { + +CLKCommand::CLKCommand() : clockID_(0), command_(CLKInvalidCommand) {} + +CLKCommand::~CLKCommand() {} + +const std::wstring& CLKCommand::GetData() +{ + std::wstringstream dataStream; + + dataStream << TEXT(""); + dataStream << TEXT(""); + dataStream << TEXT(""); + + std::vector::const_iterator it = parameters_.begin(); + std::vector::const_iterator end = parameters_.end(); + for(; it != end; ++it) { + dataStream << TEXT("") << (*it) << TEXT(""); + } + + dataStream << TEXT(""); + dataStream << TEXT(""); + dataStream << TEXT(""); + + dataCache_ = dataStream.str(); + return dataCache_; +} + +bool CLKCommand::SetCommand() +{ + bool bResult = true; + std::transform(commandString_.begin(), commandString_.end(), commandString_.begin(), toupper); + + if(commandString_ == TEXT("DUR")) + command_ = CLKDuration; + else if(commandString_ == TEXT("NEWDUR")) + command_ = CLKNewDuration; + else if(commandString_ == TEXT("NEXTEVENT")) + command_ = CLKNextEvent; + else if(commandString_ == TEXT("STOP")) + command_ = CLKStop; + else if(commandString_ == TEXT("UNTIL")) + command_ = CLKUntil; + else if(commandString_ == TEXT("ADD")) + command_ = CLKAdd; + else if(commandString_ == TEXT("SUB")) + command_ = CLKSub; + else if(commandString_ == TEXT("RESET")) + command_ = CLKReset; + else + { + command_ = CLKInvalidCommand; + bResult = false; + } + + return bResult; +} + +void CLKCommand::Clear() +{ + dataCache_.clear(); + commandString_.clear(); + time_.clear(); + command_ = CLKDuration; + clockID_ = 0; + parameters_.clear(); +} + +}} \ No newline at end of file diff --git a/core/protocol/clk/CLKCommand.h b/core/protocol/clk/CLKCommand.h new file mode 100644 index 000000000..79d58598c --- /dev/null +++ b/core/protocol/clk/CLKCommand.h @@ -0,0 +1,61 @@ +/* +* copyright (c) 2010 Sveriges Television AB +* +* This file is part of CasparCG. +* +* CasparCG is free software: you can redistribute it and/or modify +* it under the terms of the GNU General Public License as published by +* the Free Software Foundation, either version 3 of the License, or +* (at your option) any later version. +* +* CasparCG is distributed in the hope that it will be useful, +* but WITHOUT ANY WARRANTY; without even the implied warranty of +* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +* GNU General Public License for more details. + +* You should have received a copy of the GNU General Public License +* along with CasparCG. If not, see . +* +*/ + +#pragma once + +namespace caspar{ namespace CLK { + +class CLKCommand +{ +public: + enum CLKCommands + { + CLKDuration, + CLKNewDuration, + CLKNextEvent, + CLKStop, + CLKUntil, + CLKAdd, + CLKSub, + CLKReset, + CLKInvalidCommand + }; + + CLKCommand(); + virtual ~CLKCommand(); + + bool SetCommand(); + bool NeedsTime() const + { + return !(command_ == CLKNextEvent || command_ == CLKStop); + } + + void Clear(); + const std::wstring& GetData(); + + std::wstring dataCache_; + std::wstring commandString_; + CLKCommands command_; + int clockID_; + std::wstring time_; + std::vector parameters_; +}; + +}} \ No newline at end of file diff --git a/core/protocol/clk/CLKProtocolStrategy.cpp b/core/protocol/clk/CLKProtocolStrategy.cpp new file mode 100644 index 000000000..216620952 --- /dev/null +++ b/core/protocol/clk/CLKProtocolStrategy.cpp @@ -0,0 +1,151 @@ +/* +* copyright (c) 2010 Sveriges Television AB +* +* This file is part of CasparCG. +* +* CasparCG is free software: you can redistribute it and/or modify +* it under the terms of the GNU General Public License as published by +* the Free Software Foundation, either version 3 of the License, or +* (at your option) any later version. +* +* CasparCG is distributed in the hope that it will be useful, +* but WITHOUT ANY WARRANTY; without even the implied warranty of +* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +* GNU General Public License for more details. + +* You should have received a copy of the GNU General Public License +* along with CasparCG. If not, see . +* +*/ + +#include "..\..\StdAfx.h" + +#include "CLKProtocolStrategy.h" + +#include "..\..\producer\flash\cg_producer.h" +#include "..\..\renderer\render_device.h" + +#include +#include +#include + +namespace caspar { namespace CLK { + +using namespace common; + +CLKProtocolStrategy::CLKProtocolStrategy(const std::vector& channels) + : currentState_(ExpectingNewCommand), bClockLoaded_(false) +{ + if(channels.empty()) + BOOST_THROW_EXCEPTION(invalid_argument() << arg_name_info("channels")); + pChannel_ = channels[0]; +} + +void CLKProtocolStrategy::Parse(const TCHAR* pData, int charCount, caspar::IO::ClientInfoPtr pClientInfo) +{ + for(int index = 0; index < charCount; ++index) + { + if(currentState_ == ExpectingNewCommand) + currentCommandString_.str(TEXT("")); + + TCHAR currentByte = pData[index]; + if(currentByte < 32) + currentCommandString_ << TEXT("<") << (int)currentByte << TEXT(">"); + else + currentCommandString_ << currentByte; + + if(currentByte != 0) + { + switch(currentState_) + { + case ExpectingNewCommand: + if(currentByte == 1) + currentState_ = ExpectingCommand; + //just throw anything else away + break; + + case ExpectingCommand: + if(currentByte == 2) + { + if(!currentCommand_.SetCommand()) + { + CASPAR_LOG(error) << "CLK: Failed to interpret command"; + currentState_ = ExpectingNewCommand; + currentCommand_.Clear(); + } + else + currentState_ = ExpectingClockID; + } + else + currentCommand_.commandString_ += currentByte; + break; + + case ExpectingClockID: + if(currentByte == 2) + currentState_ = currentCommand_.NeedsTime() ? ExpectingTime : ExpectingParameter; + else + currentCommand_.clockID_ = currentByte - TCHAR('0'); + break; + + case ExpectingTime: + if(currentByte == 2) + currentState_ = ExpectingParameter; + else + currentCommand_.time_ += currentByte; + break; + + case ExpectingParameter: + //allocate new parameter + if(currentCommand_.parameters_.size() == 0 || currentByte == 2) + currentCommand_.parameters_.push_back(std::wstring()); + + //add the character to end end of the last parameter + if(currentByte == TEXT('<')) + currentCommand_.parameters_[currentCommand_.parameters_.size()-1] += TEXT("<"); + else if(currentByte == TEXT('>')) + currentCommand_.parameters_[currentCommand_.parameters_.size()-1] += TEXT(">"); + else if(currentByte == TEXT('\"')) + currentCommand_.parameters_[currentCommand_.parameters_.size()-1] += TEXT("""); + else + currentCommand_.parameters_[currentCommand_.parameters_.size()-1] += currentByte; + + break; + } + } + else + { + if(currentState_ == ExpectingCommand) + { + if(!currentCommand_.SetCommand()) + CASPAR_LOG(error) << "CLK: Failed to interpret command"; + } + + if(currentCommand_.command_ == CLKCommand::CLKReset) + { + flash::get_default_cg_producer(pChannel_)->clear(); + bClockLoaded_ = false; + + CASPAR_LOG(info) << L"CLK: Recieved and executed reset-command"; + } + else if(currentCommand_.command_ != CLKCommand::CLKInvalidCommand) + { + if(!bClockLoaded_) + { + flash::get_default_cg_producer(pChannel_)->add(0, TEXT("hawrysklocka/clock"), true, TEXT(""), currentCommand_.GetData()); + bClockLoaded_ = true; + } + else + flash::get_default_cg_producer(pChannel_)->update(0, currentCommand_.GetData()); + + CASPAR_LOG(debug) << L"CLK: Clockdata sent: " << currentCommand_.GetData(); + CASPAR_LOG(debug) << L"CLK: Executed valid command: " << currentCommandString_.str(); + } + + currentState_ = ExpectingNewCommand; + currentCommand_.Clear(); + } + } +} + +} //namespace CLK +} //namespace caspar \ No newline at end of file diff --git a/core/protocol/clk/CLKProtocolStrategy.h b/core/protocol/clk/CLKProtocolStrategy.h new file mode 100644 index 000000000..1a6d5145a --- /dev/null +++ b/core/protocol/clk/CLKProtocolStrategy.h @@ -0,0 +1,56 @@ +/* +* copyright (c) 2010 Sveriges Television AB +* +* This file is part of CasparCG. +* +* CasparCG is free software: you can redistribute it and/or modify +* it under the terms of the GNU General Public License as published by +* the Free Software Foundation, either version 3 of the License, or +* (at your option) any later version. +* +* CasparCG is distributed in the hope that it will be useful, +* but WITHOUT ANY WARRANTY; without even the implied warranty of +* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +* GNU General Public License for more details. + +* You should have received a copy of the GNU General Public License +* along with CasparCG. If not, see . +* +*/ + +#pragma once + +#include "CLKCommand.h" +#include "../../../common/io/ProtocolStrategy.h" +#include "../../renderer/render_device.h" + +namespace caspar { namespace CLK { + +class CLKProtocolStrategy : public caspar::IO::IProtocolStrategy +{ +public: + CLKProtocolStrategy(const std::vector& channels); + + void Parse(const TCHAR* pData, int charCount, caspar::IO::ClientInfoPtr pClientInfo); + UINT GetCodepage() { return 28591; } //ISO 8859-1 + +private: + enum ParserState + { + ExpectingNewCommand, + ExpectingCommand, + ExpectingClockID, + ExpectingTime, + ExpectingParameter + }; + + ParserState currentState_; + CLKCommand currentCommand_; + std::wstringstream currentCommandString_; + + renderer::render_device_ptr pChannel_; + + bool bClockLoaded_; +}; + +}} diff --git a/core/protocol/media.cpp b/core/protocol/media.cpp new file mode 100644 index 000000000..0a4a892c9 --- /dev/null +++ b/core/protocol/media.cpp @@ -0,0 +1,53 @@ +#include "../StdAfx.h" + +#include "media.h" + +#include "../producer/color/color_producer.h" +#include "../producer/ffmpeg/ffmpeg_producer.h" +#include "../producer/flash/flash_producer.h" +#include "../producer/flash/ct_producer.h" +#include "../producer/image/image_producer.h" +#include "../producer/image/image_scroll_producer.h" + +#include "../../common/exception/exceptions.h" + +#include +#include + +using namespace boost::assign; + +namespace caspar { + +frame_producer_ptr load_media(const std::vector& params, const frame_format_desc& format_desc) +{ + typedef std::function&, const frame_format_desc&)> ProducerFactory; + + const auto producerFactories = list_of + (&flash::create_flash_producer) + (&flash::create_ct_producer) + (&caspar::image::create_image_producer) + (&caspar::image::create_image_scroll_producer) + (&ffmpeg::create_ffmpeg_producer) + (&create_color_producer); + + if(params.empty()) + BOOST_THROW_EXCEPTION(invalid_argument() << arg_name_info("params") << arg_value_info("")); + + frame_producer_ptr pProducer; + std::any_of(producerFactories.begin(), producerFactories.end(), [&](const ProducerFactory& producerFactory) -> bool + { + try + { + pProducer = producerFactory(params, format_desc); + } + catch(...) + { + CASPAR_LOG_CURRENT_EXCEPTION(); + } + return pProducer != nullptr; + }); + + return pProducer; +} + +} diff --git a/core/protocol/media.h b/core/protocol/media.h new file mode 100644 index 000000000..8b6e292ac --- /dev/null +++ b/core/protocol/media.h @@ -0,0 +1,13 @@ +#pragma once + +#include "../frame/frame_fwd.h" +#include "../producer/frame_producer.h" + +#include +#include + +namespace caspar { + +frame_producer_ptr load_media(const std::vector& params, const frame_format_desc& format_desc); + +} diff --git a/core/protocol/monitor/Monitor.cpp b/core/protocol/monitor/Monitor.cpp new file mode 100644 index 000000000..7be14e6b1 --- /dev/null +++ b/core/protocol/monitor/Monitor.cpp @@ -0,0 +1,182 @@ +/* +* copyright (c) 2010 Sveriges Television AB +* +* This file is part of CasparCG. +* +* CasparCG is free software: you can redistribute it and/or modify +* it under the terms of the GNU General Public License as published by +* the Free Software Foundation, either version 3 of the License, or +* (at your option) any later version. +* +* CasparCG is distributed in the hope that it will be useful, +* but WITHOUT ANY WARRANTY; without even the implied warranty of +* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +* GNU General Public License for more details. + +* You should have received a copy of the GNU General Public License +* along with CasparCG. If not, see . +* +*/ + +#include "..\..\stdAfx.h" + +#if defined(_MSC_VER) +#pragma warning (push, 1) // marked as __forceinline not inlined +#endif + +#include "Monitor.h" +#include "..\..\..\common\io\AsyncEventServer.h" +#include "..\..\..\common\concurrency\function_task.h" + +namespace caspar { + +using namespace std; + +const int Monitor::ResponseCodeNoParam = 102; +const int Monitor::ResponseCodeWithParam = 101; + +Monitor::MonitorList Monitor::monitors_; + +Monitor::Monitor(int channelIndex) : channelIndex_(channelIndex) +{ + monitors_.push_back(this); +} + +Monitor::~Monitor() +{ + monitors_.remove(this); +} + +void Monitor::ClearListener(const caspar::IO::ClientInfoPtr& pClient) +{ + std::for_each(monitors_.begin(), monitors_.end(), std::bind(&Monitor::RemoveListener, std::placeholders::_1, pClient)); +} + +void Monitor::Inform(MonitorEventType type, const std::wstring& parameter, MonitorParameterFormatter formatter) +{ + common::function_task::enqueue(std::bind(&Monitor::internal_Inform, this, type, parameter, formatter)); +} + +void Monitor::internal_Inform(MonitorEventType type, const std::wstring parameter, MonitorParameterFormatter formatter) +{ + //lock the list and make a local copy + ListenerList localListeners; + { + tbb::mutex::scoped_lock lock(mutex_); + localListeners = listeners_; + } + + if(localListeners.empty()) + return; + + std::wstringstream msg; + int code = ResponseCodeNoParam; + if(!parameter.empty()) + code = ResponseCodeWithParam; + + msg << code << TEXT(' '); + + FormatInfo(msg, type); + + if(!parameter.empty()) + { + if(formatter) + msg << formatter(parameter) << TEXT("\r\n"); + else + msg << parameter << TEXT("\r\n"); + } + + std::wstring message(msg.str()); + + std::for_each(localListeners.begin(), localListeners.end(), std::bind(&IO::ClientInfo::Send, std::placeholders::_1, message)); + CASPAR_LOG(debug) << "Monitor:" << msg; +} + +void Monitor::FormatInfo(std::wstringstream& msg, MonitorEventType type) +{ + switch(type) + { + case LOADBG: + msg << TEXT("LOADBG"); + break; + case LOAD: + msg << TEXT("LOAD"); + break; + case PLAY: + msg << TEXT("PLAY"); + break; + case STOPPED: + msg << TEXT("STOP"); + break; + case CLEAR: + msg << TEXT("CLEAR"); + break; + + case CG_ADD: + case CG_CLEAR: + case CG_PLAY: + case CG_STOP: + case CG_NEXT: + case CG_REMOVE: + case CG_UPDATE: + case CG_INVOKE: + msg << TEXT("CG"); + break; + + default: + break; + } + + if(channelIndex_ > 0) + msg << TEXT(' ') << channelIndex_; + + switch(type) + { + case CG_ADD: + msg << TEXT(" ADD"); + break; + case CG_CLEAR: + msg << TEXT(" CLEAR"); + break; + case CG_PLAY: + msg << TEXT(" PLAY"); + break; + case CG_STOP: + msg << TEXT(" STOP"); + break; + case CG_NEXT: + msg << TEXT(" NEXT"); + break; + case CG_REMOVE: + msg << TEXT(" REMOVE"); + break; + case CG_UPDATE: + msg << TEXT(" UPDATE"); + break; + case CG_INVOKE: + msg << TEXT(" INVOKE"); + break; + default: + break; + } + msg << TEXT("\r\n"); +} + +void Monitor::AddListener(caspar::IO::ClientInfoPtr& pClient) +{ + tbb::mutex::scoped_lock lock(mutex_); + ListenerList::iterator it = std::find(listeners_.begin(), listeners_.end(), pClient); + if(it == listeners_.end()) + { + CASPAR_LOG(debug) << "Added a client as listener"; + listeners_.push_back(pClient); + } +} + +void Monitor::RemoveListener(const caspar::IO::ClientInfoPtr& pClient) +{ + tbb::mutex::scoped_lock lock(mutex_); + listeners_.remove(pClient); +} + +} //namespace caspar \ No newline at end of file diff --git a/core/protocol/monitor/Monitor.h b/core/protocol/monitor/Monitor.h new file mode 100644 index 000000000..146d1185f --- /dev/null +++ b/core/protocol/monitor/Monitor.h @@ -0,0 +1,78 @@ +/* +* copyright (c) 2010 Sveriges Television AB +* +* This file is part of CasparCG. +* +* CasparCG is free software: you can redistribute it and/or modify +* it under the terms of the GNU General Public License as published by +* the Free Software Foundation, either version 3 of the License, or +* (at your option) any later version. +* +* CasparCG is distributed in the hope that it will be useful, +* but WITHOUT ANY WARRANTY; without even the implied warranty of +* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +* GNU General Public License for more details. + +* You should have received a copy of the GNU General Public License +* along with CasparCG. If not, see . +* +*/ +#pragma once + +#include "../../../common/io/ClientInfo.h" +#include + +namespace caspar { + +typedef std::function MonitorParameterFormatter; + +enum MonitorEventType +{ + LOADBG, + LOAD, + PLAY, + STOPPED, + CLEAR, + + CG_ADD, + CG_CLEAR, + CG_PLAY, + CG_STOP, + CG_NEXT, + CG_REMOVE, + CG_UPDATE, + CG_INVOKE +}; + +class Monitor : boost::noncopyable +{ +public: + static const int ResponseCodeNoParam; + static const int ResponseCodeWithParam; + + //removes the client from all monitors + static void ClearListener(const caspar::IO::ClientInfoPtr& pClient); + + explicit Monitor(int channelIndex); + virtual ~Monitor(); + + void Inform(MonitorEventType type, const std::wstring& parameter = TEXT(""), MonitorParameterFormatter formatter = 0); + + void AddListener(caspar::IO::ClientInfoPtr& pClient); + void RemoveListener(const caspar::IO::ClientInfoPtr& pClient); + +private: + void internal_Inform(MonitorEventType type, const std::wstring parameter, MonitorParameterFormatter formatter); + + void FormatInfo(std::wstringstream& sstream, MonitorEventType type); + + int channelIndex_; + typedef std::list ListenerList; + typedef std::list MonitorList; + + ListenerList listeners_; + static MonitorList monitors_; + tbb::mutex mutex_; +}; + +} \ No newline at end of file diff --git a/core/renderer/layer.cpp b/core/renderer/layer.cpp new file mode 100644 index 000000000..ab5b36f78 --- /dev/null +++ b/core/renderer/layer.cpp @@ -0,0 +1,113 @@ +#include "../stdafx.h" + +#include "layer.h" + +#include "../producer/frame_producer.h" + +#include "../frame/system_frame.h" +#include "../frame/frame_format.h" + +namespace caspar { namespace renderer { + +struct layer::implementation +{ + implementation() : preview_frame_(nullptr), active_(nullptr), background_(nullptr) {} + + void load(const frame_producer_ptr& frame_producer, load_option option) + { + if(frame_producer == nullptr) + BOOST_THROW_EXCEPTION(null_argument() << arg_name_info("frame_producer")); + + if(option == load_option::preview) + { + preview_frame_ = frame_producer->get_frame(); + if(preview_frame_ != nullptr) + preview_frame_->audio_data().clear(); // No audio + active_ = nullptr; + background_ = frame_producer; + } + else if(option == load_option::auto_play) + { + background_ = frame_producer; + play(); + } + else + background_ = frame_producer; + } + + void play() + { + if(background_ == nullptr) + BOOST_THROW_EXCEPTION(invalid_operation() << msg_info("No background clip to play.")); + + background_->set_leading_producer(active_); + active_ = background_; + background_ = nullptr; + preview_frame_ = nullptr; + } + + void stop() + { + active_ = nullptr; + preview_frame_ = nullptr; + } + + void clear() + { + active_ = nullptr; + background_ = nullptr; + } + + frame_ptr get_frame() + { + if(!active_) + return preview_frame_; + + frame_ptr frame; + try + { + frame = active_->get_frame(); + } + catch(...) + { + CASPAR_LOG_CURRENT_EXCEPTION(); + active_ = nullptr; + CASPAR_LOG(warning) << "Removed producer from layer."; + } + + if(frame == nullptr) + { + active_ = active_->get_following_producer(); + frame = get_frame(); + } + return frame; + } + + frame_ptr preview_frame_; + frame_producer_ptr active_; + frame_producer_ptr background_; +}; + +layer::layer() : impl_(new implementation()){} +layer::layer(layer&& other) : impl_(std::move(other.impl_)){other.impl_ = nullptr;} +layer::layer(const layer& other) : impl_(new implementation(*other.impl_)) {} +layer& layer::operator=(layer&& other) +{ + impl_ = std::move(other.impl_); + other.impl_ = nullptr; + return *this; +} +layer& layer::operator=(const layer& other) +{ + layer temp(other); + impl_.swap(temp.impl_); + return *this; +} +void layer::load(const frame_producer_ptr& frame_producer, load_option option){return impl_->load(frame_producer, option);} +void layer::play(){impl_->play();} +void layer::stop(){impl_->stop();} +void layer::clear(){impl_->clear();} +frame_ptr layer::get_frame() {return impl_->get_frame();} +frame_producer_ptr layer::active() const { return impl_->active_;} +frame_producer_ptr layer::background() const { return impl_->background_;} +}} \ No newline at end of file diff --git a/core/renderer/layer.h b/core/renderer/layer.h new file mode 100644 index 000000000..a770ceff5 --- /dev/null +++ b/core/renderer/layer.h @@ -0,0 +1,39 @@ +#pragma once + +#include "../producer/frame_producer.h" + +namespace caspar { namespace renderer { + +enum load_option +{ + none, + preview, + auto_play +}; + +class layer +{ +public: + layer(); + layer(layer&& other); + layer(const layer& other); + layer& operator=(layer&& other); + layer& operator=(const layer& other); + + void load(const frame_producer_ptr& pProducer, load_option option); + void play(); + void stop(); + void clear(); + + frame_producer_ptr active() const; + frame_producer_ptr background() const; + + frame_ptr get_frame(); +private: + struct implementation; + std::shared_ptr impl_; +}; +typedef std::shared_ptr layer_ptr; +typedef std::unique_ptr layer_uptr; + +}} \ No newline at end of file diff --git a/core/renderer/render_device.cpp b/core/renderer/render_device.cpp new file mode 100644 index 000000000..dcecc613b --- /dev/null +++ b/core/renderer/render_device.cpp @@ -0,0 +1,243 @@ +#include "..\StdAfx.h" + +#include "render_device.h" +#include "layer.h" + +#include "../protocol/monitor/Monitor.h" +#include "../consumer/frame_consumer.h" + +#include "../frame/system_frame.h" +#include "../frame/frame_format.h" + +#include "../../common/utility/scope_exit.h" +#include "../../common/image/image.h" + +#include + +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include + +using namespace boost::assign; + +namespace caspar{ namespace renderer{ + +std::vector render_frames(std::map& layers) +{ + std::vector frames(layers.size(), nullptr); + tbb::parallel_for(tbb::blocked_range(0, frames.size()), [&](const tbb::blocked_range& r) + { + auto it = layers.begin(); + std::advance(it, r.begin()); + for(size_t i = r.begin(); i != r.end(); ++i, ++it) + frames[i] = it->second.get_frame(); + }); + boost::range::remove_erase(frames, nullptr); + boost::range::remove_erase_if(frames, [](const frame_const_ptr& frame) { return *frame == *frame::null();}); + return frames; +} + +struct render_device::implementation : boost::noncopyable +{ + implementation(const caspar::frame_format_desc& format_desc, unsigned int index, const std::vector& consumers) + : consumers_(consumers), monitor_(index), fmt_(format_desc) + { + is_running_ = true; + if(consumers.empty()) + BOOST_THROW_EXCEPTION(invalid_argument() << arg_name_info("consumer") + << msg_info("render_device requires atleast one consumer")); + + if(std::any_of(consumers.begin(), consumers.end(), [&](const frame_consumer_ptr& pConsumer){ return pConsumer->get_frame_format_desc() != format_desc;})) + BOOST_THROW_EXCEPTION(invalid_argument() << arg_name_info("consumer") + << msg_info("All consumers must have same frameformat as renderdevice.")); + + frame_buffer_.set_capacity(3); + display_thread_ = boost::thread([=]{display();}); + render_thread_ = boost::thread([=]{render();}); + + CASPAR_LOG(info) << L"Initialized render_device with " << format_desc; + } + + ~implementation() + { + is_running_ = false; + frame_buffer_.clear(); + frame_buffer_.push(nullptr); + render_thread_.join(); + display_thread_.join(); + } + + void render() + { + CASPAR_LOG(info) << L"Started render_device::render Thread"; + win32_exception::install_handler(); + + std::vector current_frames; + + while(is_running_) + { + try + { + std::vector next_frames; + frame_ptr composite_frame; + + { + tbb::mutex::scoped_lock lock(layers_mutex_); + tbb::parallel_invoke( + [&]{next_frames = render_frames(layers_);}, + [&]{composite_frame = compose_frames(current_frames.empty() ? std::make_shared(fmt_.size) : current_frames[0], current_frames);}); + } + + current_frames = std::move(next_frames); + frame_buffer_.push(std::move(composite_frame)); + } + catch(...) + { + CASPAR_LOG_CURRENT_EXCEPTION(); + layers_.clear(); + CASPAR_LOG(error) << "Unexpected exception. Cleared layers in render-device"; + } + } + + CASPAR_LOG(info) << L"Ended render_device::render Thread"; + } + + void display() + { + CASPAR_LOG(info) << L"Started render_device::display Thread"; + win32_exception::install_handler(); + + frame_ptr frame = clear_frame(std::make_shared(fmt_.size)); + std::deque prepared(3, frame); + + while(is_running_) + { + if(!frame_buffer_.try_pop(frame)) + { + CASPAR_LOG(trace) << "Display Buffer Underrun"; + frame_buffer_.pop(frame); + } + if(frame != nullptr) + { + send_frame(prepared.front(), frame); + prepared.push_back(frame); + prepared.pop_front(); + } + } + + CASPAR_LOG(info) << L"Ended render_device::display Thread"; + } + + void send_frame(const frame_ptr& pPreparedFrame, const frame_ptr& pNextFrame) + { + BOOST_FOREACH(const frame_consumer_ptr& consumer, consumers_) + { + try + { + consumer->prepare(pNextFrame); // Could block + consumer->display(pPreparedFrame); // Could block + } + catch(...) + { + CASPAR_LOG_CURRENT_EXCEPTION(); + boost::range::remove_erase(consumers_, consumer); + CASPAR_LOG(warning) << "Removed consumer from render-device."; + if(consumers_.empty()) + { + CASPAR_LOG(warning) << "No consumers available. Shutting down render-device."; + is_running_ = false; + } + } + } + } + + void load(int exLayer, const frame_producer_ptr& producer, load_option option) + { + if(producer->get_frame_format_desc() != fmt_) + BOOST_THROW_EXCEPTION(invalid_argument() << arg_name_info("pProducer") << msg_info("Invalid frame format")); + + tbb::mutex::scoped_lock lock(layers_mutex_); + layers_[exLayer].load(producer, option); + } + + void play(int exLayer) + { + tbb::mutex::scoped_lock lock(layers_mutex_); + auto it = layers_.find(exLayer); + if(it != layers_.end()) + it->second.play(); + } + + void stop(int exLayer) + { + tbb::mutex::scoped_lock lock(layers_mutex_); + auto it = layers_.find(exLayer); + if(it != layers_.end()) + it->second.stop(); + } + + void clear(int exLayer) + { + tbb::mutex::scoped_lock lock(layers_mutex_); + auto it = layers_.find(exLayer); + if(it != layers_.end()) + it->second.clear(); + } + + void clear() + { + tbb::mutex::scoped_lock lock(layers_mutex_); + layers_.clear(); + } + + frame_producer_ptr active(int exLayer) const + { + tbb::mutex::scoped_lock lock(layers_mutex_); + auto it = layers_.find(exLayer); + return it != layers_.end() ? it->second.active() : nullptr; + } + + frame_producer_ptr background(int exLayer) const + { + tbb::mutex::scoped_lock lock(layers_mutex_); + auto it = layers_.find(exLayer); + return it != layers_.end() ? it->second.background() : nullptr; + } + + boost::thread render_thread_; + boost::thread display_thread_; + + caspar::frame_format_desc fmt_; + tbb::concurrent_bounded_queue frame_buffer_; + + std::vector consumers_; + + mutable tbb::mutex layers_mutex_; + std::map layers_; + + tbb::atomic is_running_; + + caspar::Monitor monitor_; +}; + +render_device::render_device(const caspar::frame_format_desc& format_desc, unsigned int index, const std::vector& consumers) + : impl_(new implementation(format_desc, index, consumers)){} +void render_device::load(int exLayer, const frame_producer_ptr& pProducer, load_option option){impl_->load(exLayer, pProducer, option);} +void render_device::play(int exLayer){impl_->play(exLayer);} +void render_device::stop(int exLayer){impl_->stop(exLayer);} +void render_device::clear(int exLayer){impl_->clear(exLayer);} +void render_device::clear(){impl_->clear();} +frame_producer_ptr render_device::active(int exLayer) const {return impl_->active(exLayer);} +frame_producer_ptr render_device::background(int exLayer) const {return impl_->background(exLayer);} +const frame_format_desc& render_device::frame_format_desc() const{return impl_->fmt_;} +caspar::Monitor& render_device::monitor(){return impl_->monitor_;} +}} + diff --git a/core/renderer/render_device.h b/core/renderer/render_device.h new file mode 100644 index 000000000..60c78644e --- /dev/null +++ b/core/renderer/render_device.h @@ -0,0 +1,37 @@ +#pragma once + +#include "../producer/frame_producer.h" +#include "../consumer/frame_consumer.h" + +#include "layer.h" + +namespace caspar{ + +class Monitor; + +namespace renderer{ + +class render_device : boost::noncopyable +{ +public: + render_device(const frame_format_desc& format_desc, unsigned int index, const std::vector& consumers); + + void load(int exLayer, const frame_producer_ptr& pProducer, load_option option = load_option::none); + void play(int exLayer); + void stop(int exLayer); + void clear(int exLayer); + void clear(); + + frame_producer_ptr active(int exLayer) const; + frame_producer_ptr background(int exLayer) const; + + const frame_format_desc& frame_format_desc() const; + Monitor& monitor(); +private: + struct implementation; + std::shared_ptr impl_; +}; +typedef std::shared_ptr render_device_ptr; +typedef std::unique_ptr render_device_uptr; + +}} diff --git a/core/renderer/renderer_fwd.h b/core/renderer/renderer_fwd.h new file mode 100644 index 000000000..6f8aa0c51 --- /dev/null +++ b/core/renderer/renderer_fwd.h @@ -0,0 +1,18 @@ +#pragma once + +#include + +namespace caspar { + +class Monitor; + +namespace renderer { + +class render_device; +typedef std::shared_ptr render_device_ptr; +typedef std::unique_ptr render_device_uptr; +class layer; +typedef std::shared_ptr layer_ptr; +typedef std::unique_ptr layer_uptr; + +}} diff --git a/core/server.cpp b/core/server.cpp new file mode 100644 index 000000000..e0d4dcc9f --- /dev/null +++ b/core/server.cpp @@ -0,0 +1,231 @@ +#include "StdAfx.h" + +#include "server.h" + +#include "consumer/oal/oal_frame_consumer.h" +#ifndef DISABLE_BLUEFISH +#include "consumer/bluefish/BlueFishVideoConsumer.h" +#endif +#include "consumer/decklink/DecklinkVideoConsumer.h" +#include "consumer/ogl/ogl_frame_consumer.h" + +#include + +#include "protocol/amcp/AMCPProtocolStrategy.h" +#include "protocol/cii/CIIProtocolStrategy.h" +#include "protocol/CLK/CLKProtocolStrategy.h" +#include "producer/flash/FlashAxContainer.h" +#include "protocol/monitor/Monitor.h" + +#include "../common/io/AsyncEventServer.h" +#include "../common/io/SerialPort.h" +#include "../common/utility/string_convert.h" + +#include +#include +#include +#include +#include +#include + +namespace caspar{ + +struct server::implementation : boost::noncopyable +{ + implementation() + { + FreeImage_Initialise(true); + + boost::property_tree::ptree pt; + boost::property_tree::read_xml(boost::filesystem::initial_path().file_string() + "\\caspar.config", pt); + + setup_paths(); + setup_channels(pt); + setup_controllers(pt); + + if(!flash::FlashAxContainer::CheckForFlashSupport()) + CASPAR_LOG(error) << "No flashplayer activex-control installed. Flash support will be disabled"; + } + + ~implementation() + { + FreeImage_DeInitialise(); + serial_ports_.clear(); + async_servers_.clear(); + channels_.clear(); + } + + static void setup_paths() + { + if(!media_folder_.empty()) + return; + + std::string initialPath = boost::filesystem::initial_path().file_string(); + boost::property_tree::ptree pt; + boost::property_tree::read_xml(initialPath + "\\caspar.config", pt); + + auto paths = pt.get_child("configuration.paths"); + media_folder_ = common::widen(paths.get("media-path", initialPath + "\\media\\")); + log_folder_ = common::widen(paths.get("log-path", initialPath + "\\log\\")); + template_folder_ = common::widen(paths.get("template-path", initialPath + "\\template\\")); + data_folder_ = common::widen(paths.get("data-path", initialPath + "\\data\\")); + } + + void setup_channels(boost::property_tree::ptree& pt) + { + using boost::property_tree::ptree; + BOOST_FOREACH(auto& xml_channel, pt.get_child("configuration.channels")) + { + auto format_desc = get_video_format_desc(common::widen(xml_channel.second.get("videomode", "PAL"))); + std::vector consumers; + + BOOST_FOREACH(auto& xml_consumer, xml_channel.second.get_child("consumers")) + { + try + { + frame_consumer_ptr pConsumer; + std::string name = xml_consumer.first; + if(name == "ogl") + { + int device = xml_consumer.second.get("device", 0); + + ogl::stretch stretch = ogl::stretch::fill; + std::string stretchStr = xml_consumer.second.get("stretch", ""); + if(stretchStr == "none") + stretch = ogl::stretch::none; + else if(stretchStr == "uniform") + stretch = ogl::stretch::uniform; + else if(stretchStr == "uniformtofill") + stretch = ogl::stretch::uniform_to_fill; + + bool windowed = xml_consumer.second.get("windowed", false); + pConsumer = std::make_shared(format_desc, device, stretch, windowed); + } + #ifndef DISABLE_BLUEFISH + else if(name == "bluefish") + pConsumer = caspar::bluefish::BlueFishVideoConsumer::Create(format_desc, xml_consumer.second.get("device", 0)); + #endif + else if(name == "decklink") + pConsumer = std::make_shared(format_desc, xml_consumer.second.get("internalkey", false)); + else if(name == "audio") + pConsumer = std::make_shared(format_desc); + + if(pConsumer) + consumers.push_back(pConsumer); + } + catch(...) + { + CASPAR_LOG_CURRENT_EXCEPTION(); + } + } + + channels_.push_back(std::make_shared(format_desc, channels_.size() + 1, consumers)); + } + } + + void setup_controllers(boost::property_tree::ptree& pt) + { + using boost::property_tree::ptree; + BOOST_FOREACH(auto& xml_controller, pt.get_child("configuration.controllers")) + { + try + { + std::string name = xml_controller.first; + std::string protocol = xml_controller.second.get("protocol"); + + if(name == "tcpcontroller") + { + unsigned int port = xml_controller.second.get("port"); + port = port != 0 ? port : 5250; + auto asyncserver = std::make_shared(create_protocol(protocol), port); + asyncserver->SetClientDisconnectHandler(std::tr1::bind(&Monitor::ClearListener, std::tr1::placeholders::_1)); + asyncserver->Start(); + async_servers_.push_back(asyncserver); + } + else if(name == "serialcontroller") + { + std::wstring portName = common::widen(xml_controller.second.get("port-name")); + unsigned int baudRate = xml_controller.second.get("baud-rate"); + unsigned int dataBits = xml_controller.second.get("data-bits"); + unsigned int parity = xml_controller.second.get("parity"); + unsigned int stopBits = xml_controller.second.get("stop-bits"); + + baudRate = baudRate != 0 ? baudRate : 19200; + dataBits = dataBits != 0 ? dataBits : 8; + parity = parity != 0 ? parity : NOPARITY; + stopBits = stopBits != 0 ? stopBits : ONESTOPBIT; + + auto serialPort = std::make_shared(create_protocol(protocol), baudRate, parity, dataBits, stopBits, portName, xml_controller.second.get("spy", false)); + serialPort->Start(); + serial_ports_.push_back(serialPort); + } + else + BOOST_THROW_EXCEPTION(invalid_configuration() << arg_name_info(name) << msg_info("Invalid controller")); + } + catch(...) + { + CASPAR_LOG_CURRENT_EXCEPTION(); + throw; + } + } + } + + IO::ProtocolStrategyPtr create_protocol(const std::string& name) const + { + if(name == "AMCP") + return std::make_shared(channels_); + else if(name == "CII") + return std::make_shared(channels_); + else if(name == "CLOCK") + return std::make_shared(channels_); + + BOOST_THROW_EXCEPTION(invalid_configuration() << arg_name_info("name") << arg_value_info(name) << msg_info("Invalid protocol")); + } + + std::vector serial_ports_; + std::vector async_servers_; + + std::vector channels_; + + int logLevel_; + + static std::wstring media_folder_; + static std::wstring log_folder_; + static std::wstring template_folder_; + static std::wstring data_folder_; +}; + +std::wstring server::implementation::media_folder_ = L""; +std::wstring server::implementation::log_folder_ = L""; +std::wstring server::implementation::template_folder_ = L""; +std::wstring server::implementation::data_folder_ = L""; + +server::server() : impl_(new implementation()){} + +const std::wstring& server::media_folder() +{ + server::implementation::setup_paths(); + return server::implementation::media_folder_; +} + +const std::wstring& server::log_folder() +{ + server::implementation::setup_paths(); + return server::implementation::log_folder_; +} + +const std::wstring& server::template_folder() +{ + server::implementation::setup_paths(); + return server::implementation::template_folder_; +} + +const std::wstring& server::data_folder() +{ + server::implementation::setup_paths(); + return server::implementation::data_folder_; +} + +const std::vector& server::get_channels() const{ return impl_->channels_; } + +} \ No newline at end of file diff --git a/core/server.h b/core/server.h new file mode 100644 index 000000000..6085b0d5e --- /dev/null +++ b/core/server.h @@ -0,0 +1,25 @@ +#pragma once + +#include "renderer/renderer_fwd.h" + +namespace caspar { + +struct invalid_configuration : virtual boost::exception, virtual std::exception {}; + +class server : boost::noncopyable +{ +public: + server(); + + static const std::wstring& media_folder(); + static const std::wstring& log_folder(); + static const std::wstring& template_folder(); + static const std::wstring& data_folder(); + + const std::vector& get_channels() const; +private: + struct implementation; + std::shared_ptr impl_; +}; + +} \ No newline at end of file