]> git.sesse.net Git - casparcg/blob - modules/bluefish/util/blue_velvet.cpp
a8384f349a2af4d2db79d3e87bcd695604faf353
[casparcg] / modules / bluefish / util / blue_velvet.cpp
1 /*
2 * Copyright (c) 2011 Sveriges Television AB <info@casparcg.com>
3 *
4 * This file is part of CasparCG (www.casparcg.com).
5 *
6 * CasparCG is free software: you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation, either version 3 of the License, or
9 * (at your option) any later version.
10 *
11 * CasparCG is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14 * GNU General Public License for more details.
15 *
16 * You should have received a copy of the GNU General Public License
17 * along with CasparCG. If not, see <http://www.gnu.org/licenses/>.
18 *
19 * Author: Robert Nagy, ronag89@gmail.com
20 */
21
22 #include "../StdAfx.h"
23 #include "blue_velvet.h"
24 #include <common/utf.h> 
25 #include <core/video_format.h>
26 #include <bluefish/interop/BlueVelvetCUtils.h>
27
28 #if defined(__APPLE__)
29         #include <dlfcn.h>
30 #endif
31
32 #if defined(_WIN32)
33         #define GET_PROCADDR_FOR_FUNC(name, module) { name = (pFunc_##name)GetProcAddress(module, #name); if(!name) { return false; } }
34 #elif defined(__APPLE__)
35         #define GET_PROCADDR_FOR_FUNC(name, module) { name = (pFunc_##name)dlsym(module, #name); if(!name) { return false; } }
36 #endif
37
38 namespace caspar { namespace bluefish {
39
40         BvcWrapper::BvcWrapper()
41         {
42                 bvc = nullptr;
43                 hModule = nullptr;
44                 InitFunctionsPointers();
45                 if (bfcFactory)
46                         bvc = bfcFactory();
47         }
48
49         BvcWrapper::~BvcWrapper()
50         {
51                 if (bvc)
52                         bfcDestroy(bvc);
53                 if (hModule)
54                 {
55 #if defined(_WIN32)
56                         FreeLibrary(hModule);
57 #elif defined(__APPLE__)
58                         dlclose(hModule);
59 #endif
60                 }
61         }
62
63         bool BvcWrapper::InitFunctionsPointers()
64         {
65                 bool bRes = false;
66
67 #if defined(_WIN32)
68 #ifdef _DEBUG
69                 hModule = LoadLibraryExA("BlueVelvetC64_d.dll", NULL, 0);
70 #else
71                 hModule = LoadLibraryExA("BlueVelvetC64.dll", NULL, 0);
72 #endif
73                 
74 #elif defined(__APPLE__)
75                 // Look for the framework and load it accordingly.
76                 char* libraryPath("/Library/Frameworks/BlueVelvetC.framework");         // full path may not be required, OSX might check in /l/f by default - MUST TEST!
77                 hModule = dlopen(libraryPath, RTLD_NOW);
78 #endif
79                 
80                 if (hModule)
81                 {
82                         GET_PROCADDR_FOR_FUNC(bfcGetVersion, hModule);
83                         GET_PROCADDR_FOR_FUNC(bfcFactory, hModule);
84                         GET_PROCADDR_FOR_FUNC(bfcDestroy, hModule);
85                         GET_PROCADDR_FOR_FUNC(bfcEnumerate, hModule);
86                         GET_PROCADDR_FOR_FUNC(bfcQueryCardType, hModule);
87                         GET_PROCADDR_FOR_FUNC(bfcAttach, hModule);
88                         GET_PROCADDR_FOR_FUNC(bfcDetach, hModule);
89                         GET_PROCADDR_FOR_FUNC(bfcQueryCardProperty32, hModule);
90                         GET_PROCADDR_FOR_FUNC(bfcQueryCardProperty64, hModule);
91                         GET_PROCADDR_FOR_FUNC(bfcSetCardProperty32, hModule);
92                         GET_PROCADDR_FOR_FUNC(bfcSetCardProperty64, hModule);
93                         GET_PROCADDR_FOR_FUNC(bfcGetCardSerialNumber, hModule);
94                         GET_PROCADDR_FOR_FUNC(bfcGetCardFwVersion, hModule);
95                         GET_PROCADDR_FOR_FUNC(bfcWaitVideoSyncAsync, hModule);
96                         GET_PROCADDR_FOR_FUNC(bfcWaitVideoInputSync, hModule);
97                         GET_PROCADDR_FOR_FUNC(bfcWaitVideoOutputSync, hModule);
98                         GET_PROCADDR_FOR_FUNC(bfcGetVideoOutputCurrentFieldCount, hModule);
99                         GET_PROCADDR_FOR_FUNC(bfcGetVideoInputCurrentFieldCount, hModule);
100                         GET_PROCADDR_FOR_FUNC(bfcVideoCaptureStart, hModule);
101                         GET_PROCADDR_FOR_FUNC(bfcVideoCaptureStop, hModule);
102                         GET_PROCADDR_FOR_FUNC(bfcVideoPlaybackStart, hModule);
103                         GET_PROCADDR_FOR_FUNC(bfcVideoPlaybackStop, hModule);
104                         GET_PROCADDR_FOR_FUNC(bfcVideoPlaybackAllocate, hModule);
105                         GET_PROCADDR_FOR_FUNC(bfcVideoPlaybackPresent, hModule);
106                         GET_PROCADDR_FOR_FUNC(bfcVideoPlaybackRelease, hModule);
107                         GET_PROCADDR_FOR_FUNC(bfcGetCaptureVideoFrameInfoEx, hModule);
108                         GET_PROCADDR_FOR_FUNC(bfcRenderBufferCapture, hModule);
109                         GET_PROCADDR_FOR_FUNC(bfcRenderBufferUpdate, hModule);
110                         GET_PROCADDR_FOR_FUNC(bfcGetRenderBufferCount, hModule);
111                         GET_PROCADDR_FOR_FUNC(bfcEncodeHancFrameEx, hModule);
112                         GET_PROCADDR_FOR_FUNC(bfcDecodeHancFrameEx, hModule);
113                         GET_PROCADDR_FOR_FUNC(bfcSystemBufferReadAsync, hModule);
114                         GET_PROCADDR_FOR_FUNC(bfcSystemBufferWriteAsync, hModule);
115                         GET_PROCADDR_FOR_FUNC(bfcGetBytesForGroupPixels, hModule);
116                         GET_PROCADDR_FOR_FUNC(bfcGetPixelsPerLine, hModule);
117                         GET_PROCADDR_FOR_FUNC(bfcGetLinesPerFrame, hModule);
118                         GET_PROCADDR_FOR_FUNC(bfcGetBytesPerLine, hModule);
119                         GET_PROCADDR_FOR_FUNC(bfcGetBytesPerFrame, hModule);
120                         GET_PROCADDR_FOR_FUNC(bfcGetGoldenValue, hModule);
121                         GET_PROCADDR_FOR_FUNC(bfcGetVBILines, hModule);
122                         GET_PROCADDR_FOR_FUNC(bfcGetVANCGoldenValue, hModule);
123                         GET_PROCADDR_FOR_FUNC(bfcGetVANCLineBytes, hModule);
124                         GET_PROCADDR_FOR_FUNC(bfcGetVANCLineCount, hModule);
125                         GET_PROCADDR_FOR_FUNC(bfcGetWindowsDriverHandle, hModule);
126                         GET_PROCADDR_FOR_FUNC(bfcUtilsGetStringForCardType, hModule);
127                         GET_PROCADDR_FOR_FUNC(bfcUtilsGetStringForBlueProductId, hModule);
128                         GET_PROCADDR_FOR_FUNC(bfcUtilsGetStringForVideoMode, hModule);
129                         GET_PROCADDR_FOR_FUNC(bfcUtilsGetStringForMemoryFormat, hModule);
130                         GET_PROCADDR_FOR_FUNC(bfcUtilsGetMR2Routing, hModule);
131                         GET_PROCADDR_FOR_FUNC(bfcUtilsSetMR2Routing, hModule);
132                         GET_PROCADDR_FOR_FUNC(bfcUtilsGetAudioOutputRouting, hModule);
133                         GET_PROCADDR_FOR_FUNC(bfcUtilsSetAudioOutputRouting, hModule);
134                         GET_PROCADDR_FOR_FUNC(bfcUtilsIsVideoModeProgressive, hModule);
135                         GET_PROCADDR_FOR_FUNC(bfcUtilsIsVideoMode1001Framerate, hModule);
136                         GET_PROCADDR_FOR_FUNC(bfcUtilsGetFpsForVideoMode, hModule);
137                         GET_PROCADDR_FOR_FUNC(bfcUtilsGetVideoModeForFrameInfo, hModule);
138                         GET_PROCADDR_FOR_FUNC(bfcUtilsGetFrameInfoForVideoMode, hModule);
139                         GET_PROCADDR_FOR_FUNC(bfcUtilsGetAudioSamplesPerFrame, hModule);
140
141                         bRes = true;
142                 }
143
144                 return bRes;
145         }
146
147         bool BvcWrapper::IsBvcValid()
148         {
149                 if (bvc)
150                         return true;
151                 else
152                         return false;
153         }
154
155         const char * BvcWrapper::GetVersion()
156         {
157                 return bfcGetVersion();
158         }
159
160         BLUE_UINT32 BvcWrapper::Attach(int iDeviceId)
161         {
162                 return bfcAttach(bvc, iDeviceId);
163         }
164
165         BLUE_UINT32 BvcWrapper::Detach()
166         {
167                 return bfcDetach(bvc);
168         }
169
170         BLUE_UINT32 BvcWrapper::QueryCardProperty32(const int iProperty, unsigned int & nValue)
171         {
172                 if (bvc)
173                         return (BLUE_UINT32)bfcQueryCardProperty32(bvc, iProperty, nValue);
174                 else
175                         return 0;
176         }
177
178         BLUE_UINT32 BvcWrapper::SetCardProperty32(const int iProperty, const unsigned int nValue)
179         {
180                 return bfcSetCardProperty32(bvc, iProperty, nValue);
181         }
182
183         BLUE_UINT32 BvcWrapper::Enumerate(int & iDevices)
184         {
185                 return bfcEnumerate(bvc, iDevices);
186         }
187
188         BLUE_UINT32 BvcWrapper::QueryCardType(int & iCardType, int iDeviceID)
189         {
190                 return bfcQueryCardType(bvc, iCardType, iDeviceID);
191         }
192
193         BLUE_UINT32 BvcWrapper::SystemBufferWrite(unsigned char * pPixels, unsigned long ulSize, unsigned long ulBufferID, unsigned long ulOffset)
194         {
195                 return bfcSystemBufferWriteAsync(bvc, pPixels, ulSize, nullptr, ulBufferID, ulOffset);
196         }
197
198         BLUE_UINT32 BvcWrapper::SystemBufferRead(unsigned char* pPixels, unsigned long ulSize, unsigned long ulBufferID, unsigned long ulOffset)
199         {
200                 return bfcSystemBufferReadAsync(bvc, pPixels, ulSize, nullptr, ulBufferID, ulOffset);
201         }
202
203         BLUE_UINT32 BvcWrapper::VideoPlaybackStop(int iWait, int iFlush)
204         {
205                 return bfcVideoPlaybackStop(bvc, iWait, iFlush);
206         }
207
208         BLUE_UINT32 BvcWrapper::WaitVideoOutputSync(unsigned long ulUpdateType, unsigned long & ulFieldCount)
209         {
210                 return bfcWaitVideoOutputSync(bvc, ulUpdateType, ulFieldCount);
211         }
212
213         BLUE_UINT32 BvcWrapper::WaitVideoInputSync(unsigned long ulUpdateType, unsigned long & ulFieldCount)
214         {
215                 return bfcWaitVideoInputSync(bvc, ulUpdateType, ulFieldCount);
216         }
217
218         BLUE_UINT32 BvcWrapper::RenderBufferUpdate( unsigned long ulBufferID)
219         {
220                 return bfcRenderBufferUpdate(bvc, ulBufferID);
221         }
222
223         BLUE_UINT32 BvcWrapper::RenderBufferCapture(unsigned long ulBufferID)
224         {
225                 return bfcRenderBufferCapture(bvc, ulBufferID);
226         }
227
228         BLUE_UINT32 BvcWrapper::EncodeHancFrameEx(unsigned int nCardType, hanc_stream_info_struct * pHancEncodeInfo, void * pAudioBuffer, unsigned int nAudioChannels, unsigned int nAudioSamples, unsigned int nSampleType, unsigned int nAudioFlags)
229         {
230                 return bfcEncodeHancFrameEx(bvc, CRD_BLUE_NEUTRON, pHancEncodeInfo, pAudioBuffer, nAudioChannels, nAudioSamples, nSampleType, nAudioFlags);
231         }
232
233         BLUE_UINT32 BvcWrapper::DecodeHancFrameEx(unsigned int nCardType, unsigned int * pHancBuffer, hanc_decode_struct * pHancDecodeInfo)
234         {
235                 return bfcDecodeHancFrameEx(bvc, CRD_BLUE_NEUTRON, pHancBuffer, pHancDecodeInfo);
236         }
237
238         BLUE_UINT32 BvcWrapper::GetFrameInfoForVideoVode(const unsigned int nVideoMode, unsigned int&  nWidth, unsigned int& nHeight, unsigned int& nRate, unsigned int& bIs1001, unsigned int& bIsProgressive)
239         {
240                 return bfcUtilsGetFrameInfoForVideoMode(nVideoMode, nWidth, nHeight, nRate, bIs1001, bIsProgressive);
241         }
242
243         BLUE_UINT32 BvcWrapper::GetBytesPerFrame(EVideoMode nVideoMode, EMemoryFormat nMemoryFormat, EUpdateMethod nUpdateMethod, unsigned int& nBytesPerFrame)
244         {
245                 return bfcGetBytesPerFrame(nVideoMode, nMemoryFormat, nUpdateMethod, nBytesPerFrame);
246         }
247
248
249 EVideoMode vid_fmt_from_video_format(const core::video_format& fmt) 
250 {
251         switch(fmt)
252         {
253         case core::video_format::pal:                   return VID_FMT_PAL;
254         case core::video_format::ntsc:                  return VID_FMT_NTSC;
255         case core::video_format::x576p2500:             return VID_FMT_INVALID; //not supported
256         case core::video_format::x720p2398:             return VID_FMT_720P_2398;
257         case core::video_format::x720p2400:             return VID_FMT_720P_2400;
258         case core::video_format::x720p2500:             return VID_FMT_720P_2500;
259         case core::video_format::x720p5000:             return VID_FMT_720P_5000;
260         case core::video_format::x720p2997:             return VID_FMT_720P_2997;
261         case core::video_format::x720p5994:             return VID_FMT_720P_5994;
262         case core::video_format::x720p3000:             return VID_FMT_720P_3000;
263         case core::video_format::x720p6000:             return VID_FMT_720P_6000;
264         case core::video_format::x1080p2398:    return VID_FMT_1080P_2397;
265         case core::video_format::x1080p2400:    return VID_FMT_1080P_2400;
266         case core::video_format::x1080i5000:    return VID_FMT_1080I_5000;
267         case core::video_format::x1080i5994:    return VID_FMT_1080I_5994;
268         case core::video_format::x1080i6000:    return VID_FMT_1080I_6000;
269         case core::video_format::x1080p2500:    return VID_FMT_1080P_2500;
270         case core::video_format::x1080p2997:    return VID_FMT_1080P_2997;
271         case core::video_format::x1080p3000:    return VID_FMT_1080P_3000;
272         case core::video_format::x1080p5000:    return VID_FMT_1080P_5000;
273         case core::video_format::x1080p5994:    return VID_FMT_1080P_5994;
274         case core::video_format::x1080p6000:    return VID_FMT_1080P_6000;
275         default:                                                                return VID_FMT_INVALID;
276         }
277 }
278
279 bool is_epoch_card(BvcWrapper& blue)
280 {
281         int iDeviceID = 1;
282         int iCardType = 0;
283         blue.QueryCardType(iCardType, iDeviceID);
284
285         switch(iCardType)
286         {
287                 case CRD_BLUE_EPOCH_HORIZON:
288                 case CRD_BLUE_EPOCH_CORE:
289                 case CRD_BLUE_EPOCH_ULTRA:
290                 case CRD_BLUE_EPOCH_2K_HORIZON:
291                 case CRD_BLUE_EPOCH_2K_CORE:
292                 case CRD_BLUE_EPOCH_2K_ULTRA:
293                 case CRD_BLUE_CREATE_HD:
294                 case CRD_BLUE_CREATE_2K:
295                 case CRD_BLUE_CREATE_2K_ULTRA:
296                 case CRD_BLUE_SUPER_NOVA:
297                 case CRD_BLUE_SUPER_NOVA_S_PLUS:
298                 case CRD_BLUE_NEUTRON:
299                 case CRD_BLUE_EPOCH_CG:
300                 return true;
301         default:
302                 return false;
303         }
304 }
305
306 bool is_epoch_neutron_1i2o_card(BvcWrapper& blue)
307 {
308         BLUE_UINT32 val = 0;
309         blue.QueryCardProperty32(EPOCH_GET_PRODUCT_ID, val);
310
311         if (val == ORAC_NEUTRON_1_IN_2_OUT_FIRMWARE_PRODUCTID)
312                 return true;
313         else
314                 return false;
315 }
316
317 bool is_epoch_neutron_3o_card(BvcWrapper& blue)
318 {
319         BLUE_UINT32 val = 0;
320         blue.QueryCardProperty32(EPOCH_GET_PRODUCT_ID, val);
321
322         if (val == ORAC_NEUTRON_0_IN_3_OUT_FIRMWARE_PRODUCTID)
323                 return true;
324         else
325                 return false;
326 }
327
328
329 std::wstring get_card_desc(BvcWrapper& blue, int iDeviceID)
330 {
331         int iCardType = 0;
332         blue.QueryCardType(iCardType, iDeviceID);
333
334         switch(iCardType) 
335         {
336                 case CRD_BLUEDEEP_LT:                           return L"Deepblue LT";// D64 Lite
337                 case CRD_BLUEDEEP_SD:                           return L"Iridium SD";// Iridium SD
338                 case CRD_BLUEDEEP_AV:                           return L"Iridium AV";// Iridium AV
339                 case CRD_BLUEDEEP_IO:                           return L"Deepblue IO";// D64 Full
340                 case CRD_BLUEWILD_AV:                           return L"Wildblue AV";// D64 AV
341                 case CRD_IRIDIUM_HD:                            return L"Iridium HD";// * Iridium HD
342                 case CRD_BLUEWILD_RT:                           return L"Wildblue RT";// D64 RT
343                 case CRD_BLUEWILD_HD:                           return L"Wildblue HD";// * BadAss G2
344                 case CRD_REDDEVIL:                                      return L"Iridium Full";// Iridium Full
345                 case CRD_BLUEDEEP_HD:   
346                 case CRD_BLUEDEEP_HDS:                          return L"Reserved for \"BasAss G2";// * BadAss G2 variant, proposed, reserved
347                 case CRD_BLUE_ENVY:                                     return L"Blue Envy"; // Mini Din 
348                 case CRD_BLUE_PRIDE:                            return L"Blue Pride";//Mini Din Output 
349                 case CRD_BLUE_GREED:                            return L"Blue Greed";
350                 case CRD_BLUE_INGEST:                           return L"Blue Ingest";
351                 case CRD_BLUE_SD_DUALLINK:                      return L"Blue SD Duallink";
352                 case CRD_BLUE_CATALYST:                         return L"Blue Catalyst";
353                 case CRD_BLUE_SD_DUALLINK_PRO:          return L"Blue SD Duallink Pro";
354                 case CRD_BLUE_SD_INGEST_PRO:            return L"Blue SD Ingest pro";
355                 case CRD_BLUE_SD_DEEPBLUE_LITE_PRO:     return L"Blue SD Deepblue lite Pro";
356                 case CRD_BLUE_SD_SINGLELINK_PRO:        return L"Blue SD Singlelink Pro";
357                 case CRD_BLUE_SD_IRIDIUM_AV_PRO:        return L"Blue SD Iridium AV Pro";
358                 case CRD_BLUE_SD_FIDELITY:                      return L"Blue SD Fidelity";
359                 case CRD_BLUE_SD_FOCUS:                         return L"Blue SD Focus";
360                 case CRD_BLUE_SD_PRIME:                         return L"Blue SD Prime";
361                 case CRD_BLUE_EPOCH_2K_CORE:            return L"Blue Epoch 2K Core";
362                 case CRD_BLUE_EPOCH_2K_ULTRA:           return L"Blue Epoch 2K Ultra";
363                 case CRD_BLUE_EPOCH_HORIZON:            return L"Blue Epoch Horizon";
364                 case CRD_BLUE_EPOCH_CORE:                       return L"Blue Epoch Core";
365                 case CRD_BLUE_EPOCH_ULTRA:                      return L"Blue Epoch Ultra";
366                 case CRD_BLUE_CREATE_HD:                        return L"Blue Create HD";
367                 case CRD_BLUE_CREATE_2K:                        return L"Blue Create 2K";
368                 case CRD_BLUE_CREATE_2K_ULTRA:          return L"Blue Create 2K Ultra";
369                 case CRD_BLUE_SUPER_NOVA:                       return L"Blue SuperNova";
370                 case CRD_BLUE_SUPER_NOVA_S_PLUS:        return L"Blue SuperNova s+";
371                 case CRD_BLUE_NEUTRON:                          return L"Blue Neutron 4k";
372                 case CRD_BLUE_EPOCH_CG:                         return L"Blue Epopch CG";
373                 default:                                                        return L"Unknown";
374         }
375 }
376
377 EVideoMode get_video_mode(BvcWrapper& blue, const core::video_format_desc& format_desc)
378 {
379         EVideoMode vid_fmt = VID_FMT_INVALID;
380         BLUE_UINT32 inValidFmt = 0;
381         BErr err = 0;
382         err = blue.QueryCardProperty32(INVALID_VIDEO_MODE_FLAG, inValidFmt);
383         vid_fmt = vid_fmt_from_video_format(format_desc.format);
384
385         if (vid_fmt == VID_FMT_INVALID)
386                 CASPAR_THROW_EXCEPTION(not_supported() << msg_info(L"video-mode not supported: " + format_desc.name));
387
388
389         if ((unsigned int)vid_fmt >= inValidFmt)
390                 CASPAR_THROW_EXCEPTION(not_supported() << msg_info(L"video-mode not supported - Outside of valid range: " + format_desc.name));
391
392         return vid_fmt;
393 }
394
395 spl::shared_ptr<BvcWrapper> create_blue()
396 {
397         auto pWrap = new BvcWrapper();
398         if (!pWrap->IsBvcValid())
399                 CASPAR_THROW_EXCEPTION(not_supported() << msg_info("Bluefish drivers not found."));
400
401         return spl::shared_ptr<BvcWrapper>(pWrap);
402 }
403
404 spl::shared_ptr<BvcWrapper> create_blue(int device_index)
405 {
406         auto blue = create_blue();
407         
408         if(BLUE_FAIL(blue->Attach(device_index)))
409                 CASPAR_THROW_EXCEPTION(caspar_exception() << msg_info("Failed to attach device."));
410
411         return blue;
412 }
413
414 core::video_format video_format_from_vid_fmt(EVideoMode fmt)
415 {
416         switch (fmt)
417         {
418         case VID_FMT_PAL: return core::video_format::pal;
419         case VID_FMT_NTSC: return core::video_format::ntsc;
420         case VID_FMT_720P_2398: return core::video_format::x720p2398;
421         case VID_FMT_720P_2400: return core::video_format::x720p2400;
422         case VID_FMT_720P_2500: return core::video_format::x720p2500;
423         case VID_FMT_720P_5000: return core::video_format::x720p5000;
424         case VID_FMT_720P_2997: return core::video_format::x720p2997;
425         case VID_FMT_720P_5994: return core::video_format::x720p5994;
426         case VID_FMT_720P_3000: return core::video_format::x720p3000;
427         case VID_FMT_720P_6000: return core::video_format::x720p6000;
428         case VID_FMT_1080P_2397: return core::video_format::x1080p2398;
429         case VID_FMT_1080P_2400: return core::video_format::x1080p2400;
430         case VID_FMT_1080I_5000: return core::video_format::x1080i5000;
431         case VID_FMT_1080I_5994: return core::video_format::x1080i5994;
432         case VID_FMT_1080I_6000: return core::video_format::x1080i6000;
433         case VID_FMT_1080P_2500: return core::video_format::x1080p2500;
434         case VID_FMT_1080P_2997: return core::video_format::x1080p2997;
435         case VID_FMT_1080P_3000: return core::video_format::x1080p3000;
436         case VID_FMT_1080P_5000: return core::video_format::x1080p5000;
437         case VID_FMT_1080P_5994: return core::video_format::x1080p5994;
438         case VID_FMT_1080P_6000: return core::video_format::x1080p6000;
439         default: return core::video_format::invalid;
440         }
441 }
442
443 core::video_format_desc get_format_desc(BvcWrapper& blue, EVideoMode vid_fmt, EMemoryFormat mem_fmt)
444 {
445         core::video_format_desc fmt;
446         unsigned int width, height, duration = 0, time_scale = 0, rate = 0, bIs1001 = 0, bIsProgressive = 0, size = 0;
447         std::vector<int>        audio_cadence;
448         core::field_mode video_field_mode = core::field_mode::progressive;
449
450         blue.GetFrameInfoForVideoVode(vid_fmt, width, height, rate, bIs1001, bIsProgressive);
451         blue.GetBytesPerFrame(vid_fmt, mem_fmt, UPD_FMT_FRAME, size);
452
453         switch (vid_fmt)
454         {
455         case VID_FMT_NTSC:
456         case VID_FMT_1080I_5994:
457                 duration = 30000;
458                 time_scale = 1001;
459                 audio_cadence = { 1601,1602,1601,1602,1602 };
460                 video_field_mode = core::field_mode::upper;
461                 break;
462         case VID_FMT_2048_1080P_2500:
463         case VID_FMT_2048_1080PSF_2500:
464         case VID_FMT_576I_5000:
465         case VID_FMT_1080P_2500:
466         case VID_FMT_1080I_5000:
467         case VID_FMT_1080PSF_2500:
468         case VID_FMT_720P_2500:
469                 duration = 25000;
470                 time_scale = 1000;
471                 audio_cadence = { 1920,1920,1920,1920,1920 };
472                 break;
473
474         case VID_FMT_720P_5994:
475         case VID_FMT_2048_1080P_5994:
476         case VID_FMT_1080P_5994:
477                 duration = 60000;
478                 time_scale = 1001;
479                 audio_cadence = { 801,800,801,800,800 };
480                 break;
481
482         case VID_FMT_1080P_6000:
483         case VID_FMT_2048_1080P_6000:
484         case VID_FMT_720P_6000:
485                 duration = 60000;
486                 time_scale = 1000;
487                 audio_cadence = { 801,800,801,800,800 };
488                 break;
489
490         case VID_FMT_1080PSF_2397:
491         case VID_FMT_1080P_2397:
492         case VID_FMT_720P_2398:
493         case VID_FMT_2048_1080PSF_2397:
494         case VID_FMT_2048_1080P_2397:
495                 duration = 24000;
496                 time_scale = 1000;
497                 break;
498
499         case VID_FMT_1080PSF_2400:
500         case VID_FMT_1080P_2400:
501         case VID_FMT_720P_2400:
502         case VID_FMT_2048_1080PSF_2400:
503         case VID_FMT_2048_1080P_2400:
504                 duration = 24000;
505                 time_scale = 1000;
506                 break;
507
508         case VID_FMT_1080I_6000:
509         case VID_FMT_1080PSF_3000:
510                 duration = 30000;
511                 time_scale = 1000;
512                 break;
513
514         case VID_FMT_720P_2997:
515         case VID_FMT_1080P_2997:
516         case VID_FMT_2048_1080PSF_2997:
517         case VID_FMT_2048_1080P_2997:
518         case VID_FMT_1080PSF_2997:
519                 duration = 30000;
520                 time_scale = 1001;
521                 break;
522
523         case VID_FMT_720P_3000:
524         case VID_FMT_1080P_3000:
525         case VID_FMT_2048_1080PSF_3000:
526         case VID_FMT_2048_1080P_3000:
527                 duration = 30000;
528                 time_scale = 1001;
529                 break;
530
531         case VID_FMT_720P_5000:
532         case VID_FMT_1080P_5000:
533         case VID_FMT_2048_1080P_5000:
534                 audio_cadence = { 960,960,960,960,960 };
535                 duration = 50000;
536                 time_scale = 1000;
537                 break;
538                 /*case VID_FMT_1080P_4800:
539                 case VID_FMT_2048_1080P_4800:
540                 fmt.duration = 48000;
541                 fmt.time_scale = 1000;
542                 break;*/
543         }
544         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);
545         fmt.size = size;
546         return fmt;
547 }
548
549 }}