*/
#include "../StdAfx.h"
-
#include "blue_velvet.h"
+#include <common/utf.h>
+#include <core/video_format.h>
+#include <BlueVelvetCUtils.h>
-#include <common/utf.h>
+#if defined(__APPLE__)
+#include <dlfcn.h>
+#endif
-#include <core/video_format.h>
+#if defined(_WIN32)
+ #define GET_PROCADDR_FOR_FUNC(name, module) { name = (pFunc_##name)GetProcAddress(reinterpret_cast<HMODULE>(module), #name); if(!name) { return false; } }
+// #define GET_PROCADDR_FOR_FUNC(name, module) { name = (pFunc_##name)GetProcAddress(module, #name); if(!name) { return false; } }
+#elif defined(__APPLE__)
+ #define GET_PROCADDR_FOR_FUNC(name, module) { name = (pFunc_##name)dlsym(module, #name); if(!name) { return false; } }
+#endif
namespace caspar { namespace bluefish {
-
-CBlueVelvet4* (*BlueVelvetFactory4)() = nullptr;
-void (*BlueVelvetDestroy)(CBlueVelvet4* pObj) = nullptr;
-const char* (*BlueVelvetVersion)() = nullptr;
-BLUE_UINT32 (*encode_hanc_frame)(struct hanc_stream_info_struct * hanc_stream_ptr, void * audio_pcm_ptr,BLUE_UINT32 no_audio_ch,BLUE_UINT32 no_audio_samples,BLUE_UINT32 nTypeOfSample,BLUE_UINT32 emb_audio_flag) = nullptr;
-BLUE_UINT32 (*encode_hanc_frame_ex)(BLUE_UINT32 card_type, struct hanc_stream_info_struct * hanc_stream_ptr, void * audio_pcm_ptr, BLUE_UINT32 no_audio_ch, BLUE_UINT32 no_audio_samples, BLUE_UINT32 nTypeOfSample, BLUE_UINT32 emb_audio_flag) = nullptr;
-void blue_velvet_initialize()
-{
-#ifdef _DEBUG
- std::string module_str = "BlueVelvet64_d.dll";
+ bvc_wrapper::bvc_wrapper()
+ {
+ bvc_ = nullptr;
+ h_module_ = nullptr;
+ init_function_pointers();
+ bvc_ = std::shared_ptr<void>(bfcFactory(), bfcDestroy);
+
+ if (!bvc_)
+ CASPAR_THROW_EXCEPTION(not_supported() << msg_info("Bluefish drivers not found."));
+ }
+
+ bool bvc_wrapper::init_function_pointers()
+ {
+ bool res = false;
+ bfcGetVersion = nullptr;
+ bfcFactory = nullptr;
+ bfcDestroy = nullptr;
+ bfcEnumerate = nullptr;
+ bfcQueryCardType = nullptr;
+ bfcAttach = nullptr;
+ bfcDetach = nullptr;
+ bfcQueryCardProperty32 = nullptr;
+ bfcQueryCardProperty64 = nullptr;
+ bfcSetCardProperty32 = nullptr;
+ bfcSetCardProperty64 = nullptr;
+ bfcGetCardSerialNumber = nullptr;
+ bfcGetCardFwVersion = nullptr;
+ bfcWaitVideoSyncAsync = nullptr;
+ bfcWaitVideoInputSync = nullptr;
+ bfcWaitVideoOutputSync = nullptr;
+ bfcGetVideoOutputCurrentFieldCount = nullptr;
+ bfcGetVideoInputCurrentFieldCount = nullptr;
+ bfcVideoCaptureStart = nullptr;
+ bfcVideoCaptureStop = nullptr;
+ bfcVideoPlaybackStart = nullptr;
+ bfcVideoPlaybackStop = nullptr;
+ bfcVideoPlaybackAllocate = nullptr;
+ bfcVideoPlaybackPresent = nullptr;
+ bfcVideoPlaybackRelease = nullptr;
+ bfcGetCaptureVideoFrameInfoEx = nullptr;
+ bfcRenderBufferCapture = nullptr;
+ bfcRenderBufferUpdate = nullptr;
+ bfcGetRenderBufferCount = nullptr;
+ bfcEncodeHancFrameEx = nullptr;
+ bfcDecodeHancFrameEx = nullptr;
+#if defined(_WIN32)
+ bfcSystemBufferReadAsync = nullptr;
+ bfcSystemBufferWriteAsync = nullptr;
#else
- std::string module_str = "BlueVelvet64.dll";
+ bfcSystemBufferRead = nullptr;
+ bfcSystemBufferWrite = nullptr;
#endif
+ bfcGetBytesForGroupPixels = nullptr;
+ bfcGetPixelsPerLine = nullptr;
+ bfcGetLinesPerFrame = nullptr;
+ bfcGetBytesPerLine = nullptr;
+ bfcGetBytesPerFrame = nullptr;
+ bfcGetGoldenValue = nullptr;
+ bfcGetVBILines = nullptr;
+ bfcGetVANCGoldenValue = nullptr;
+ bfcGetVANCLineBytes = nullptr;
+ bfcGetVANCLineCount = nullptr;
+ bfcGetWindowsDriverHandle = nullptr;
+ bfcUtilsGetStringForCardType = nullptr;
+ bfcUtilsGetStringForBlueProductId = nullptr;
+ bfcUtilsGetStringForVideoMode = nullptr;
+ bfcUtilsGetStringForMemoryFormat = nullptr;
+ bfcUtilsGetMR2Routing = nullptr;
+ bfcUtilsSetMR2Routing = nullptr;
+ bfcUtilsGetAudioOutputRouting = nullptr;
+ bfcUtilsSetAudioOutputRouting = nullptr;
+ bfcUtilsIsVideoModeProgressive = nullptr;
+ bfcUtilsIsVideoMode1001Framerate = nullptr;
+ bfcUtilsGetFpsForVideoMode = nullptr;
+ bfcUtilsGetVideoModeForFrameInfo = nullptr;
+ bfcUtilsGetFrameInfoForVideoMode = nullptr;
+ bfcUtilsGetAudioSamplesPerFrame = nullptr;
- auto module = LoadLibrary(u16(module_str).c_str());
- if(!module)
- LoadLibrary(u16(std::string(getenv("SystemDrive")) + "\\Program Files\\Bluefish444\\Driver\\" + module_str).c_str());
- if(!module)
- LoadLibrary(u16(std::string(getenv("SystemDrive")) + "\\Program Files (x86)\\BlueFish444\\Driver\\" + module_str).c_str());
- if(!module)
- CASPAR_THROW_EXCEPTION(file_not_found() << msg_info("Could not find BlueVelvet3.dll. Required drivers are not installed."));
- static std::shared_ptr<void> lib(module, FreeLibrary);
- BlueVelvetFactory4 = reinterpret_cast<decltype(BlueVelvetFactory4)>(GetProcAddress(module, "BlueVelvetFactory4"));
- BlueVelvetDestroy = reinterpret_cast<decltype(BlueVelvetDestroy)>(GetProcAddress(module, "BlueVelvetDestroy"));
- BlueVelvetVersion = reinterpret_cast<decltype(BlueVelvetVersion)>(GetProcAddress(module, "BlueVelvetVersion"));
-}
-
-void blue_hanc_initialize()
-{
+#if defined(_WIN32)
#ifdef _DEBUG
- std::string module_str = "BlueHancUtils64_d.dll";
+ h_module_ = std::shared_ptr<void>(LoadLibraryExA("BlueVelvetC64_d.dll", NULL, 0), FreeLibrary);
#else
- std::string module_str = "BlueHancUtils64.dll";
+ h_module_ = std::shared_ptr<void>(LoadLibraryExA("BlueVelvetC64.dll", NULL, 0), FreeLibrary);
#endif
-
- auto module = LoadLibrary(u16(module_str).c_str());
- if(!module)
- LoadLibrary(u16(std::string(getenv("SystemDrive")) + "\\Program Files\\Bluefish444\\Driver\\" + module_str).c_str());
- if(!module)
- LoadLibrary(u16(std::string(getenv("SystemDrive")) + "\\Program Files (x86)\\BlueFish444\\Driver\\" + module_str).c_str());
- if(!module)
- CASPAR_THROW_EXCEPTION(file_not_found() << msg_info("Could not find BlueHancUtils.dll. Required drivers are not installed."));
- static std::shared_ptr<void> lib(module, FreeLibrary);
- encode_hanc_frame = reinterpret_cast<decltype(encode_hanc_frame)>(GetProcAddress(module, "encode_hanc_frame"));
- encode_hanc_frame_ex = reinterpret_cast<decltype(encode_hanc_frame_ex)>(GetProcAddress(module, "encode_hanc_frame_ex"));
-}
+
+#elif defined(__APPLE__)
+ // Look for the framework and load it accordingly.
+ char* libraryPath("/Library/Frameworks/BlueVelvetC.framework"); // full path may not be required, OSX might check in /l/f by default - MUST TEST!
+ h_module_ = std::shared_ptr<void>(dlopen(libraryPath, RTLD_NOW), dlclose);
+#endif
+
+ if (h_module_)
+ {
+ GET_PROCADDR_FOR_FUNC(bfcGetVersion, h_module_.get());
+ GET_PROCADDR_FOR_FUNC(bfcFactory, h_module_.get());
+ GET_PROCADDR_FOR_FUNC(bfcDestroy, h_module_.get());
+ GET_PROCADDR_FOR_FUNC(bfcEnumerate, h_module_.get());
+ GET_PROCADDR_FOR_FUNC(bfcQueryCardType, h_module_.get());
+ GET_PROCADDR_FOR_FUNC(bfcAttach, h_module_.get());
+ GET_PROCADDR_FOR_FUNC(bfcDetach, h_module_.get());
+ GET_PROCADDR_FOR_FUNC(bfcQueryCardProperty32, h_module_.get());
+ GET_PROCADDR_FOR_FUNC(bfcQueryCardProperty64, h_module_.get());
+ GET_PROCADDR_FOR_FUNC(bfcSetCardProperty32, h_module_.get());
+ GET_PROCADDR_FOR_FUNC(bfcSetCardProperty64, h_module_.get());
+ GET_PROCADDR_FOR_FUNC(bfcGetCardSerialNumber, h_module_.get());
+ GET_PROCADDR_FOR_FUNC(bfcGetCardFwVersion, h_module_.get());
+ GET_PROCADDR_FOR_FUNC(bfcWaitVideoSyncAsync, h_module_.get());
+ GET_PROCADDR_FOR_FUNC(bfcWaitVideoInputSync, h_module_.get());
+ GET_PROCADDR_FOR_FUNC(bfcWaitVideoOutputSync, h_module_.get());
+ GET_PROCADDR_FOR_FUNC(bfcGetVideoOutputCurrentFieldCount, h_module_.get());
+ GET_PROCADDR_FOR_FUNC(bfcGetVideoInputCurrentFieldCount, h_module_.get());
+ GET_PROCADDR_FOR_FUNC(bfcVideoCaptureStart, h_module_.get());
+ GET_PROCADDR_FOR_FUNC(bfcVideoCaptureStop, h_module_.get());
+ GET_PROCADDR_FOR_FUNC(bfcVideoPlaybackStart, h_module_.get());
+ GET_PROCADDR_FOR_FUNC(bfcVideoPlaybackStop, h_module_.get());
+ GET_PROCADDR_FOR_FUNC(bfcVideoPlaybackAllocate, h_module_.get());
+ GET_PROCADDR_FOR_FUNC(bfcVideoPlaybackPresent, h_module_.get());
+ GET_PROCADDR_FOR_FUNC(bfcVideoPlaybackRelease, h_module_.get());
+ GET_PROCADDR_FOR_FUNC(bfcGetCaptureVideoFrameInfoEx, h_module_.get());
+ GET_PROCADDR_FOR_FUNC(bfcRenderBufferCapture, h_module_.get());
+ GET_PROCADDR_FOR_FUNC(bfcRenderBufferUpdate, h_module_.get());
+ GET_PROCADDR_FOR_FUNC(bfcGetRenderBufferCount, h_module_.get());
+ GET_PROCADDR_FOR_FUNC(bfcEncodeHancFrameEx, h_module_.get());
+ GET_PROCADDR_FOR_FUNC(bfcDecodeHancFrameEx, h_module_.get());
+ GET_PROCADDR_FOR_FUNC(bfcSystemBufferReadAsync, h_module_.get());
+ GET_PROCADDR_FOR_FUNC(bfcSystemBufferWriteAsync, h_module_.get());
+ GET_PROCADDR_FOR_FUNC(bfcGetBytesForGroupPixels, h_module_.get());
+ GET_PROCADDR_FOR_FUNC(bfcGetPixelsPerLine, h_module_.get());
+ GET_PROCADDR_FOR_FUNC(bfcGetLinesPerFrame, h_module_.get());
+ GET_PROCADDR_FOR_FUNC(bfcGetBytesPerLine, h_module_.get());
+ GET_PROCADDR_FOR_FUNC(bfcGetBytesPerFrame, h_module_.get());
+ GET_PROCADDR_FOR_FUNC(bfcGetGoldenValue, h_module_.get());
+ GET_PROCADDR_FOR_FUNC(bfcGetVBILines, h_module_.get());
+ GET_PROCADDR_FOR_FUNC(bfcGetVANCGoldenValue, h_module_.get());
+ GET_PROCADDR_FOR_FUNC(bfcGetVANCLineBytes, h_module_.get());
+ GET_PROCADDR_FOR_FUNC(bfcGetVANCLineCount, h_module_.get());
+ GET_PROCADDR_FOR_FUNC(bfcGetWindowsDriverHandle, h_module_.get());
+ GET_PROCADDR_FOR_FUNC(bfcUtilsGetStringForCardType, h_module_.get());
+ GET_PROCADDR_FOR_FUNC(bfcUtilsGetStringForBlueProductId, h_module_.get());
+ GET_PROCADDR_FOR_FUNC(bfcUtilsGetStringForVideoMode, h_module_.get());
+ GET_PROCADDR_FOR_FUNC(bfcUtilsGetStringForMemoryFormat, h_module_.get());
+ GET_PROCADDR_FOR_FUNC(bfcUtilsGetMR2Routing, h_module_.get());
+ GET_PROCADDR_FOR_FUNC(bfcUtilsSetMR2Routing, h_module_.get());
+ GET_PROCADDR_FOR_FUNC(bfcUtilsGetAudioOutputRouting, h_module_.get());
+ GET_PROCADDR_FOR_FUNC(bfcUtilsSetAudioOutputRouting, h_module_.get());
+ GET_PROCADDR_FOR_FUNC(bfcUtilsIsVideoModeProgressive, h_module_.get());
+ GET_PROCADDR_FOR_FUNC(bfcUtilsIsVideoMode1001Framerate, h_module_.get());
+ GET_PROCADDR_FOR_FUNC(bfcUtilsGetFpsForVideoMode, h_module_.get());
+ GET_PROCADDR_FOR_FUNC(bfcUtilsGetVideoModeForFrameInfo, h_module_.get());
+ GET_PROCADDR_FOR_FUNC(bfcUtilsGetFrameInfoForVideoMode, h_module_.get());
+ GET_PROCADDR_FOR_FUNC(bfcUtilsGetAudioSamplesPerFrame, h_module_.get());
+ res = true;
+ }
+ return res;
+ }
+
+ const char * bvc_wrapper::get_version()
+ {
+ return bfcGetVersion();
+ }
+
+ BLUE_UINT32 bvc_wrapper::attach(int iDeviceId)
+ {
+ return bfcAttach((BLUEVELVETC_HANDLE)bvc_.get(), iDeviceId);
+ }
+
+ BLUE_UINT32 bvc_wrapper::detach()
+ {
+ // disable the audio on detach
+ unsigned int audio_value = 0;
+ bfcQueryCardProperty32((BLUEVELVETC_HANDLE)bvc_.get(), EMBEDEDDED_AUDIO_OUTPUT, audio_value);
+ return bfcDetach((BLUEVELVETC_HANDLE)bvc_.get());
+ }
+
+ BLUE_UINT32 bvc_wrapper::get_card_property32(const int iProperty, unsigned int & nValue)
+ {
+ if (bvc_)
+ return (BLUE_UINT32)bfcQueryCardProperty32((BLUEVELVETC_HANDLE)bvc_.get(), iProperty, nValue);
+ else
+ return 0;
+ }
+
+ BLUE_UINT32 bvc_wrapper::set_card_property32(const int iProperty, const unsigned int nValue)
+ {
+ return bfcSetCardProperty32((BLUEVELVETC_HANDLE)bvc_.get(), iProperty, nValue);
+ }
+
+ BLUE_UINT32 bvc_wrapper::enumerate(int & iDevices)
+ {
+ return bfcEnumerate((BLUEVELVETC_HANDLE)bvc_.get(), iDevices);
+ }
+
+ BLUE_UINT32 bvc_wrapper::query_card_type(int & iCardType, int iDeviceID)
+ {
+ return bfcQueryCardType((BLUEVELVETC_HANDLE)bvc_.get(), iCardType, iDeviceID);
+ }
+
+ BLUE_UINT32 bvc_wrapper::system_buffer_write(unsigned char * pPixels, unsigned long ulSize, unsigned long ulBufferID, unsigned long ulOffset)
+ {
+ return bfcSystemBufferWriteAsync((BLUEVELVETC_HANDLE)bvc_.get(), pPixels, ulSize, nullptr, ulBufferID, ulOffset);
+ }
+
+ BLUE_UINT32 bvc_wrapper::system_buffer_read(unsigned char* pPixels, unsigned long ulSize, unsigned long ulBufferID, unsigned long ulOffset)
+ {
+ return bfcSystemBufferReadAsync((BLUEVELVETC_HANDLE)bvc_.get(), pPixels, ulSize, nullptr, ulBufferID, ulOffset);
+ }
+
+ BLUE_UINT32 bvc_wrapper::video_playback_stop(int iWait, int iFlush)
+ {
+ return bfcVideoPlaybackStop((BLUEVELVETC_HANDLE)bvc_.get(), iWait, iFlush);
+ }
+
+ BLUE_UINT32 bvc_wrapper::wait_video_output_sync(unsigned long ulUpdateType, unsigned long & ulFieldCount)
+ {
+ return bfcWaitVideoOutputSync((BLUEVELVETC_HANDLE)bvc_.get(), ulUpdateType, ulFieldCount);
+ }
+
+ BLUE_UINT32 bvc_wrapper::wait_video_input_sync(unsigned long ulUpdateType, unsigned long & ulFieldCount)
+ {
+ return bfcWaitVideoInputSync((BLUEVELVETC_HANDLE)bvc_.get(), ulUpdateType, ulFieldCount);
+ }
+
+ BLUE_UINT32 bvc_wrapper::render_buffer_update( unsigned long ulBufferID)
+ {
+ return bfcRenderBufferUpdate((BLUEVELVETC_HANDLE)bvc_.get(), ulBufferID);
+ }
+
+ BLUE_UINT32 bvc_wrapper::render_buffer_capture(unsigned long ulBufferID)
+ {
+ return bfcRenderBufferCapture((BLUEVELVETC_HANDLE)bvc_.get(), ulBufferID);
+ }
+
+ BLUE_UINT32 bvc_wrapper::encode_hanc_frame(unsigned int nCardType, hanc_stream_info_struct * pHancEncodeInfo, void * pAudioBuffer, unsigned int nAudioChannels, unsigned int nAudioSamples, unsigned int nSampleType, unsigned int nAudioFlags)
+ {
+ return bfcEncodeHancFrameEx((BLUEVELVETC_HANDLE)bvc_.get(), CRD_BLUE_NEUTRON, pHancEncodeInfo, pAudioBuffer, nAudioChannels, nAudioSamples, nSampleType, nAudioFlags);
+ }
+
+ BLUE_UINT32 bvc_wrapper::decode_hanc_frame(unsigned int nCardType, unsigned int * pHancBuffer, hanc_decode_struct * pHancDecodeInfo)
+ {
+ return bfcDecodeHancFrameEx((BLUEVELVETC_HANDLE)bvc_.get(), CRD_BLUE_NEUTRON, pHancBuffer, pHancDecodeInfo);
+ }
+
+ BLUE_UINT32 bvc_wrapper::get_frame_info_for_video_mode(const unsigned int nVideoMode, unsigned int& nWidth, unsigned int& nHeight, unsigned int& nRate, unsigned int& bIs1001, unsigned int& bIsProgressive)
+ {
+ return bfcUtilsGetFrameInfoForVideoMode(nVideoMode, nWidth, nHeight, nRate, bIs1001, bIsProgressive);
+ }
+
+ BLUE_UINT32 bvc_wrapper::get_bytes_per_frame(EVideoMode nVideoMode, EMemoryFormat nMemoryFormat, EUpdateMethod nUpdateMethod, unsigned int& nBytesPerFrame)
+ {
+ return bfcGetBytesPerFrame(nVideoMode, nMemoryFormat, nUpdateMethod, nBytesPerFrame);
+ }
-void blue_initialize()
-{
- blue_hanc_initialize();
- blue_velvet_initialize();
-}
EVideoMode vid_fmt_from_video_format(const core::video_format& fmt)
{
- switch(fmt.value())
+ switch(fmt)
{
case core::video_format::pal: return VID_FMT_PAL;
case core::video_format::ntsc: return VID_FMT_NTSC;
}
}
-bool is_epoch_card(CBlueVelvet4& blue)
+bool is_epoch_card(bvc_wrapper& blue)
{
- switch(blue.has_video_cardtype())
- {
- case CRD_BLUE_EPOCH_HORIZON:
- case CRD_BLUE_EPOCH_CORE:
- case CRD_BLUE_EPOCH_ULTRA:
- case CRD_BLUE_EPOCH_2K_HORIZON:
- case CRD_BLUE_EPOCH_2K_CORE:
- case CRD_BLUE_EPOCH_2K_ULTRA:
- case CRD_BLUE_CREATE_HD:
- case CRD_BLUE_CREATE_2K:
- case CRD_BLUE_CREATE_2K_ULTRA:
- case CRD_BLUE_SUPER_NOVA:
+ int device_id = 1;
+ int card_type = 0;
+ blue.query_card_type(card_type, device_id);
+
+ switch(card_type)
+ {
+ case CRD_BLUE_EPOCH_HORIZON:
+ case CRD_BLUE_EPOCH_CORE:
+ case CRD_BLUE_EPOCH_ULTRA:
+ case CRD_BLUE_EPOCH_2K_HORIZON:
+ case CRD_BLUE_EPOCH_2K_CORE:
+ case CRD_BLUE_EPOCH_2K_ULTRA:
+ case CRD_BLUE_CREATE_HD:
+ case CRD_BLUE_CREATE_2K:
+ case CRD_BLUE_CREATE_2K_ULTRA:
+ case CRD_BLUE_SUPER_NOVA:
+ case CRD_BLUE_SUPER_NOVA_S_PLUS:
+ case CRD_BLUE_NEUTRON:
+ case CRD_BLUE_EPOCH_CG:
return true;
default:
return false;
}
}
-std::wstring get_card_desc(CBlueVelvet4& blue)
+bool is_epoch_neutron_1i2o_card(bvc_wrapper& blue)
{
- switch(blue.has_video_cardtype())
- {
- case CRD_BLUEDEEP_LT: return L"Deepblue LT";// D64 Lite
- case CRD_BLUEDEEP_SD: return L"Iridium SD";// Iridium SD
- case CRD_BLUEDEEP_AV: return L"Iridium AV";// Iridium AV
- case CRD_BLUEDEEP_IO: return L"Deepblue IO";// D64 Full
- case CRD_BLUEWILD_AV: return L"Wildblue AV";// D64 AV
- case CRD_IRIDIUM_HD: return L"Iridium HD";// * Iridium HD
- case CRD_BLUEWILD_RT: return L"Wildblue RT";// D64 RT
- case CRD_BLUEWILD_HD: return L"Wildblue HD";// * BadAss G2
- case CRD_REDDEVIL: return L"Iridium Full";// Iridium Full
- case CRD_BLUEDEEP_HD:
- case CRD_BLUEDEEP_HDS: return L"Reserved for \"BasAss G2";// * BadAss G2 variant, proposed, reserved
- case CRD_BLUE_ENVY: return L"Blue Envy"; // Mini Din
- case CRD_BLUE_PRIDE: return L"Blue Pride";//Mini Din Output
- case CRD_BLUE_GREED: return L"Blue Greed";
- case CRD_BLUE_INGEST: return L"Blue Ingest";
- case CRD_BLUE_SD_DUALLINK: return L"Blue SD Duallink";
- case CRD_BLUE_CATALYST: return L"Blue Catalyst";
- case CRD_BLUE_SD_DUALLINK_PRO: return L"Blue SD Duallink Pro";
- case CRD_BLUE_SD_INGEST_PRO: return L"Blue SD Ingest pro";
- case CRD_BLUE_SD_DEEPBLUE_LITE_PRO: return L"Blue SD Deepblue lite Pro";
- case CRD_BLUE_SD_SINGLELINK_PRO: return L"Blue SD Singlelink Pro";
- case CRD_BLUE_SD_IRIDIUM_AV_PRO: return L"Blue SD Iridium AV Pro";
- case CRD_BLUE_SD_FIDELITY: return L"Blue SD Fidelity";
- case CRD_BLUE_SD_FOCUS: return L"Blue SD Focus";
- case CRD_BLUE_SD_PRIME: return L"Blue SD Prime";
- case CRD_BLUE_EPOCH_2K_CORE: return L"Blue Epoch 2K Core";
- case CRD_BLUE_EPOCH_2K_ULTRA: return L"Blue Epoch 2K Ultra";
- case CRD_BLUE_EPOCH_HORIZON: return L"Blue Epoch Horizon";
- case CRD_BLUE_EPOCH_CORE: return L"Blue Epoch Core";
- case CRD_BLUE_EPOCH_ULTRA: return L"Blue Epoch Ultra";
- case CRD_BLUE_CREATE_HD: return L"Blue Create HD";
- case CRD_BLUE_CREATE_2K: return L"Blue Create 2K";
- case CRD_BLUE_CREATE_2K_ULTRA: return L"Blue Create 2K Ultra";
- default: return L"Unknown";
- }
+ BLUE_UINT32 val = 0;
+ blue.get_card_property32(EPOCH_GET_PRODUCT_ID, val);
+ if (val == ORAC_NEUTRON_1_IN_2_OUT_FIRMWARE_PRODUCTID)
+ return true;
+ else
+ return false;
}
-EVideoMode get_video_mode(CBlueVelvet4& blue, const core::video_format_desc& format_desc)
+bool is_epoch_neutron_3o_card(bvc_wrapper& blue)
{
- EVideoMode vid_fmt = VID_FMT_INVALID;
- auto desiredVideoFormat = vid_fmt_from_video_format(format_desc.format);
- int videoModeCount = blue.count_video_mode();
- for(int videoModeIndex = 1; videoModeIndex <= videoModeCount; ++videoModeIndex)
+ BLUE_UINT32 val = 0;
+ blue.get_card_property32(EPOCH_GET_PRODUCT_ID, val);
+
+ if (val == ORAC_NEUTRON_0_IN_3_OUT_FIRMWARE_PRODUCTID)
+ return true;
+ else
+ return false;
+}
+
+std::wstring get_card_desc(bvc_wrapper& blue, int device_id)
+{
+ int card_type = 0;
+ blue.query_card_type(card_type, device_id);
+
+ switch(card_type)
{
- EVideoMode videoMode = blue.enum_video_mode(videoModeIndex);
- if(videoMode == desiredVideoFormat)
- vid_fmt = videoMode;
+ case CRD_BLUEDEEP_LT: return L"Deepblue LT";// D64 Lite
+ case CRD_BLUEDEEP_SD: return L"Iridium SD";// Iridium SD
+ case CRD_BLUEDEEP_AV: return L"Iridium AV";// Iridium AV
+ case CRD_BLUEDEEP_IO: return L"Deepblue IO";// D64 Full
+ case CRD_BLUEWILD_AV: return L"Wildblue AV";// D64 AV
+ case CRD_IRIDIUM_HD: return L"Iridium HD";// * Iridium HD
+ case CRD_BLUEWILD_RT: return L"Wildblue RT";// D64 RT
+ case CRD_BLUEWILD_HD: return L"Wildblue HD";// * BadAss G2
+ case CRD_REDDEVIL: return L"Iridium Full";// Iridium Full
+ case CRD_BLUEDEEP_HD:
+ case CRD_BLUEDEEP_HDS: return L"Reserved for \"BasAss G2";// * BadAss G2 variant, proposed, reserved
+ case CRD_BLUE_ENVY: return L"Blue Envy"; // Mini Din
+ case CRD_BLUE_PRIDE: return L"Blue Pride";//Mini Din Output
+ case CRD_BLUE_GREED: return L"Blue Greed";
+ case CRD_BLUE_INGEST: return L"Blue Ingest";
+ case CRD_BLUE_SD_DUALLINK: return L"Blue SD Duallink";
+ case CRD_BLUE_CATALYST: return L"Blue Catalyst";
+ case CRD_BLUE_SD_DUALLINK_PRO: return L"Blue SD Duallink Pro";
+ case CRD_BLUE_SD_INGEST_PRO: return L"Blue SD Ingest pro";
+ case CRD_BLUE_SD_DEEPBLUE_LITE_PRO: return L"Blue SD Deepblue lite Pro";
+ case CRD_BLUE_SD_SINGLELINK_PRO: return L"Blue SD Singlelink Pro";
+ case CRD_BLUE_SD_IRIDIUM_AV_PRO: return L"Blue SD Iridium AV Pro";
+ case CRD_BLUE_SD_FIDELITY: return L"Blue SD Fidelity";
+ case CRD_BLUE_SD_FOCUS: return L"Blue SD Focus";
+ case CRD_BLUE_SD_PRIME: return L"Blue SD Prime";
+ case CRD_BLUE_EPOCH_2K_CORE: return L"Blue Epoch 2K Core";
+ case CRD_BLUE_EPOCH_2K_ULTRA: return L"Blue Epoch 2K Ultra";
+ case CRD_BLUE_EPOCH_HORIZON: return L"Blue Epoch Horizon";
+ case CRD_BLUE_EPOCH_CORE: return L"Blue Epoch Core";
+ case CRD_BLUE_EPOCH_ULTRA: return L"Blue Epoch Ultra";
+ case CRD_BLUE_CREATE_HD: return L"Blue Create HD";
+ case CRD_BLUE_CREATE_2K: return L"Blue Create 2K";
+ case CRD_BLUE_CREATE_2K_ULTRA: return L"Blue Create 2K Ultra";
+ case CRD_BLUE_SUPER_NOVA: return L"Blue SuperNova";
+ case CRD_BLUE_SUPER_NOVA_S_PLUS: return L"Blue SuperNova s+";
+ case CRD_BLUE_NEUTRON: return L"Blue Neutron 4k";
+ case CRD_BLUE_EPOCH_CG: return L"Blue Epopch CG";
+ default: return L"Unknown";
}
- if(vid_fmt == VID_FMT_INVALID)
- CASPAR_THROW_EXCEPTION(caspar_exception() << msg_info("video-mode not supported.") << arg_value_info(format_desc.name));
+}
+
+EVideoMode get_video_mode(bvc_wrapper& blue, const core::video_format_desc& format_desc)
+{
+ EVideoMode vid_fmt = VID_FMT_INVALID;
+ BLUE_UINT32 invalid_fmt = 0;
+ BErr err = 0;
+ err = blue.get_card_property32(INVALID_VIDEO_MODE_FLAG, invalid_fmt);
+ vid_fmt = vid_fmt_from_video_format(format_desc.format);
+
+ if (vid_fmt == VID_FMT_INVALID)
+ CASPAR_THROW_EXCEPTION(not_supported() << msg_info(L"video-mode not supported: " + format_desc.name));
+
+
+ if ((unsigned int)vid_fmt >= invalid_fmt)
+ CASPAR_THROW_EXCEPTION(not_supported() << msg_info(L"video-mode not supported - Outside of valid range: " + format_desc.name));
return vid_fmt;
}
-spl::shared_ptr<CBlueVelvet4> create_blue()
+spl::shared_ptr<bvc_wrapper> create_blue()
{
- if(!BlueVelvetFactory4 || !encode_hanc_frame)
- CASPAR_THROW_EXCEPTION(caspar_exception() << msg_info("Bluefish drivers not found."));
-
- return spl::shared_ptr<CBlueVelvet4>(BlueVelvetFactory4(), BlueVelvetDestroy);
+ auto pWrap = new bvc_wrapper();
+ return spl::shared_ptr<bvc_wrapper>(pWrap);
}
-spl::shared_ptr<CBlueVelvet4> create_blue(int device_index)
+spl::shared_ptr<bvc_wrapper> create_blue(int device_index)
{
auto blue = create_blue();
- if(BLUE_FAIL(blue->device_attach(device_index, FALSE)))
+ if(BLUE_FAIL(blue->attach(device_index)))
CASPAR_THROW_EXCEPTION(caspar_exception() << msg_info("Failed to attach device."));
return blue;
}
+core::video_format video_format_from_vid_fmt(EVideoMode fmt)
+{
+ switch (fmt)
+ {
+ case VID_FMT_PAL: return core::video_format::pal;
+ case VID_FMT_NTSC: return core::video_format::ntsc;
+ case VID_FMT_720P_2398: return core::video_format::x720p2398;
+ case VID_FMT_720P_2400: return core::video_format::x720p2400;
+ case VID_FMT_720P_2500: return core::video_format::x720p2500;
+ case VID_FMT_720P_5000: return core::video_format::x720p5000;
+ case VID_FMT_720P_2997: return core::video_format::x720p2997;
+ case VID_FMT_720P_5994: return core::video_format::x720p5994;
+ case VID_FMT_720P_3000: return core::video_format::x720p3000;
+ case VID_FMT_720P_6000: return core::video_format::x720p6000;
+ case VID_FMT_1080P_2397: return core::video_format::x1080p2398;
+ case VID_FMT_1080P_2400: return core::video_format::x1080p2400;
+ case VID_FMT_1080I_5000: return core::video_format::x1080i5000;
+ case VID_FMT_1080I_5994: return core::video_format::x1080i5994;
+ case VID_FMT_1080I_6000: return core::video_format::x1080i6000;
+ case VID_FMT_1080P_2500: return core::video_format::x1080p2500;
+ case VID_FMT_1080P_2997: return core::video_format::x1080p2997;
+ case VID_FMT_1080P_3000: return core::video_format::x1080p3000;
+ case VID_FMT_1080P_5000: return core::video_format::x1080p5000;
+ case VID_FMT_1080P_5994: return core::video_format::x1080p5994;
+ case VID_FMT_1080P_6000: return core::video_format::x1080p6000;
+ default: return core::video_format::invalid;
+ }
+}
+
+core::video_format_desc get_format_desc(bvc_wrapper& blue, EVideoMode vid_fmt, EMemoryFormat mem_fmt)
+{
+ core::video_format_desc fmt;
+ unsigned int width, height, duration = 0, time_scale = 0, rate = 0, bIs1001 = 0, bIsProgressive = 0, size = 0;
+ std::vector<int> audio_cadence;
+ core::field_mode video_field_mode = core::field_mode::progressive;
+
+ blue.get_frame_info_for_video_mode(vid_fmt, width, height, rate, bIs1001, bIsProgressive);
+ blue.get_bytes_per_frame(vid_fmt, mem_fmt, UPD_FMT_FRAME, size);
+
+ switch (vid_fmt)
+ {
+ case VID_FMT_NTSC:
+ case VID_FMT_1080I_5994:
+ duration = 30000;
+ time_scale = 1001;
+ audio_cadence = { 1601,1602,1601,1602,1602 };
+ video_field_mode = core::field_mode::upper;
+ break;
+ case VID_FMT_2048_1080P_2500:
+ case VID_FMT_2048_1080PSF_2500:
+ case VID_FMT_576I_5000:
+ case VID_FMT_1080P_2500:
+ case VID_FMT_1080I_5000:
+ case VID_FMT_1080PSF_2500:
+ case VID_FMT_720P_2500:
+ duration = 25000;
+ time_scale = 1000;
+ audio_cadence = { 1920,1920,1920,1920,1920 };
+ break;
+
+ case VID_FMT_720P_5994:
+ case VID_FMT_2048_1080P_5994:
+ case VID_FMT_1080P_5994:
+ duration = 60000;
+ time_scale = 1001;
+ audio_cadence = { 801,800,801,800,800 };
+ break;
+
+ case VID_FMT_1080P_6000:
+ case VID_FMT_2048_1080P_6000:
+ case VID_FMT_720P_6000:
+ duration = 60000;
+ time_scale = 1000;
+ audio_cadence = { 801,800,801,800,800 };
+ break;
+
+ case VID_FMT_1080PSF_2397:
+ case VID_FMT_1080P_2397:
+ case VID_FMT_720P_2398:
+ case VID_FMT_2048_1080PSF_2397:
+ case VID_FMT_2048_1080P_2397:
+ duration = 24000;
+ time_scale = 1000;
+ break;
+
+ case VID_FMT_1080PSF_2400:
+ case VID_FMT_1080P_2400:
+ case VID_FMT_720P_2400:
+ case VID_FMT_2048_1080PSF_2400:
+ case VID_FMT_2048_1080P_2400:
+ duration = 24000;
+ time_scale = 1000;
+ break;
+
+ case VID_FMT_1080I_6000:
+ case VID_FMT_1080PSF_3000:
+ duration = 30000;
+ time_scale = 1000;
+ break;
+
+ case VID_FMT_720P_2997:
+ case VID_FMT_1080P_2997:
+ case VID_FMT_2048_1080PSF_2997:
+ case VID_FMT_2048_1080P_2997:
+ case VID_FMT_1080PSF_2997:
+ duration = 30000;
+ time_scale = 1001;
+ break;
+
+ case VID_FMT_720P_3000:
+ case VID_FMT_1080P_3000:
+ case VID_FMT_2048_1080PSF_3000:
+ case VID_FMT_2048_1080P_3000:
+ duration = 30000;
+ time_scale = 1001;
+ break;
+
+ case VID_FMT_720P_5000:
+ case VID_FMT_1080P_5000:
+ case VID_FMT_2048_1080P_5000:
+ audio_cadence = { 960,960,960,960,960 };
+ duration = 50000;
+ time_scale = 1000;
+ break;
+ /*case VID_FMT_1080P_4800:
+ case VID_FMT_2048_1080P_4800:
+ fmt.duration = 48000;
+ fmt.time_scale = 1000;
+ break;*/
+ }
+ fmt = core::video_format_desc(video_format_from_vid_fmt(vid_fmt), width, height, width, height, video_field_mode, time_scale, duration, std::wstring(L""), audio_cadence);
+ fmt.size = size;
+ return fmt;
+}
+
}}
\ No newline at end of file