UltraGrid
UltraGrid Low-Latency High-Resolution Transmission System
Loading...
Searching...
No Matches
VideoDelegate Class Reference
Inheritance diagram for VideoDelegate:
Inheritance graph
Collaboration diagram for VideoDelegate:
Collaboration graph

Public Member Functions

 VideoDelegate (struct vidcap_decklink_state *state, struct device_state &device_)
 
virtual ~VideoDelegate ()
 
virtual ULONG STDMETHODCALLTYPE AddRef (void) override
 
virtual HRESULT STDMETHODCALLTYPE QueryInterface (REFIID, LPVOID *) override
 
virtual ULONG STDMETHODCALLTYPE Release (void) override
 
virtual HRESULT STDMETHODCALLTYPE VideoInputFormatChanged (BMDVideoInputFormatChangedEvents notificationEvents, IDeckLinkDisplayMode *mode, BMDDetectedVideoInputFormatFlags flags) noexcept override
 
virtual HRESULT STDMETHODCALLTYPE VideoInputFrameArrived (IDeckLinkVideoInputFrame *, IDeckLinkAudioInputPacket *) override
 

Static Public Member Functions

static auto getNotificationEventsStr (BMDVideoInputFormatChangedEvents notificationEvents, BMDDetectedVideoInputFormatFlags flags) noexcept
 

Public Attributes

struct device_state & device
 
BMDTimeValue frameTime {}
 
IDeckLinkVideoInputFrame * lastFrame {nullptr}
 
int newFrameReady {}
 
void * pixelFrame {}
 
void * pixelFrameRight {}
 
IDeckLinkVideoFrame * rightEyeFrame {}
 
struct vidcap_decklink_state * s
 
uint32_t timecode {}
 

Private Attributes

BMDDetectedVideoInputFormatFlags configuredCsBitDepth {}
 
int32_t mRefCount {}
 

Static Private Attributes

static constexpr BMDDetectedVideoInputFormatFlags bitDepthMask {bmdDetectedVideoInput8BitDepth | bmdDetectedVideoInput10BitDepth | bmdDetectedVideoInput12BitDepth}
 
static constexpr BMDDetectedVideoInputFormatFlags csMask {bmdDetectedVideoInputYCbCr422 | bmdDetectedVideoInputRGB444}
 

Detailed Description

Definition at line 231 of file decklink.cpp.

Constructor & Destructor Documentation

◆ VideoDelegate()

VideoDelegate::VideoDelegate ( struct vidcap_decklink_state * state,
struct device_state & device_ )
inline

Definition at line 249 of file decklink.cpp.

249 : s(state), device(device_) {
250 }
void ** state
struct vidcap_decklink_state * s
Definition decklink.cpp:246
struct device_state & device
Definition decklink.cpp:247

◆ ~VideoDelegate()

virtual VideoDelegate::~VideoDelegate ( )
inlinevirtual

Definition at line 252 of file decklink.cpp.

252 {
255 }
IDeckLinkVideoInputFrame * lastFrame
Definition decklink.cpp:244
IDeckLinkVideoFrame * rightEyeFrame
Definition decklink.cpp:241

References lastFrame, RELEASE_IF_NOT_NULL, and rightEyeFrame.

Member Function Documentation

◆ AddRef()

virtual ULONG STDMETHODCALLTYPE VideoDelegate::AddRef ( void )
inlineoverridevirtual

Definition at line 258 of file decklink.cpp.

258 {
259 return mRefCount++;
260 }
int32_t mRefCount
Definition decklink.cpp:233

References mRefCount.

◆ getNotificationEventsStr()

static auto VideoDelegate::getNotificationEventsStr ( BMDVideoInputFormatChangedEvents notificationEvents,
BMDDetectedVideoInputFormatFlags flags )
inlinestaticnoexcept

Definition at line 270 of file decklink.cpp.

270 {
271 string status{};
272 map<BMDDetectedVideoInputFormatFlags, string> change_map {
273 { bmdVideoInputDisplayModeChanged, "display mode"s },
274 { bmdVideoInputFieldDominanceChanged, "field dominance"s },
275 { bmdVideoInputColorspaceChanged, "color space"s },
276 };
277 for (auto &i : change_map) {
278 if ((notificationEvents & i.first) != 0U) {
279 if (!status.empty()) {
280 status += ", "s;
281 }
282 status += i.second;
283 }
284 }
285 if (status.empty()) {
286 status = "unknown"s;
287 }
288 status += " - ";
289 map<BMDDetectedVideoInputFormatFlags, string> flag_map {
290 { bmdDetectedVideoInputYCbCr422, "YCbCr422"s },
291 { bmdDetectedVideoInputRGB444, "RGB444"s },
292 { bmdDetectedVideoInputDualStream3D, "DualStream3D"s },
293 { bmdDetectedVideoInput12BitDepth, "12bit"s },
294 { bmdDetectedVideoInput10BitDepth, "10bit"s },
295 { bmdDetectedVideoInput8BitDepth, "8bit"s },
296 };
297 bool first = true;
298 for (auto &i : flag_map) {
299 if ((flags & i.first) != 0U) {
300 if (!first) {
301 status += ", "s;
302 }
303 status += i.second;
304 first = false;
305 }
306 }
307 return status;
308 }
const char unsigned int flags
codec_t first
Definition sdl2.c:423

References first, flags, and s.

Referenced by VideoInputFormatChanged().

◆ QueryInterface()

virtual HRESULT STDMETHODCALLTYPE VideoDelegate::QueryInterface ( REFIID ,
LPVOID *  )
inlineoverridevirtual

Definition at line 257 of file decklink.cpp.

257{ return E_NOINTERFACE; }

◆ Release()

virtual ULONG STDMETHODCALLTYPE VideoDelegate::Release ( void )
inlineoverridevirtual

Definition at line 261 of file decklink.cpp.

261 {
262 int32_t newRefValue = mRefCount--;
263 if (newRefValue == 0)
264 {
265 delete this;
266 return 0;
267 }
268 return newRefValue;
269 }

References mRefCount.

◆ VideoInputFormatChanged()

virtual HRESULT STDMETHODCALLTYPE VideoDelegate::VideoInputFormatChanged ( BMDVideoInputFormatChangedEvents notificationEvents,
IDeckLinkDisplayMode * mode,
BMDDetectedVideoInputFormatFlags flags )
inlineoverridevirtualnoexcept

Definition at line 310 of file decklink.cpp.

313 {
315 << MOD_NAME << "Format change detected ("
316 << getNotificationEventsStr(notificationEvents, flags)
317 << ").\n";
318
319 bool detected_3d = (flags & bmdDetectedVideoInputDualStream3D) != 0U;
320 if (detected_3d != s->stereo) {
322 << MOD_NAME << "Stereoscopic 3D "
323 << (detected_3d ? "" : "not ") << "detected but "
324 << (s->stereo ? "" : "not ")
325 << "enabled! "
326 "Switching automatically. This behavior is "
327 "experimental so please report any problems. "
328 "You can also specify `3D` option explicitly.\n";
329 s->stereo = detected_3d;
330 s->enable_flags ^= bmdVideoInputDualStream3D;
331 }
332 BMDDetectedVideoInputFormatFlags csBitDepth = flags & (csMask | bitDepthMask);
333 unique_lock<mutex> lk(s->lock);
334 if (notificationEvents & bmdVideoInputColorspaceChanged && csBitDepth != configuredCsBitDepth) {
335 if ((csBitDepth & bitDepthMask) == 0U) { // if no bit depth, assume 8-bit
336 csBitDepth |= bmdDetectedVideoInput8BitDepth;
337 }
338 if (s->requested_bit_depth != 0) {
339 csBitDepth = (flags & csMask) | s->requested_bit_depth;
340 }
341 unordered_map<BMDDetectedVideoInputFormatFlags, codec_t> m = {
342 {bmdDetectedVideoInputYCbCr422 | bmdDetectedVideoInput8BitDepth, UYVY},
343 {bmdDetectedVideoInputYCbCr422 | bmdDetectedVideoInput10BitDepth, v210},
344 {bmdDetectedVideoInputYCbCr422 | bmdDetectedVideoInput12BitDepth, v210}, // weird
345 {bmdDetectedVideoInputRGB444 | bmdDetectedVideoInput8BitDepth, RGBA},
346 {bmdDetectedVideoInputRGB444 | bmdDetectedVideoInput10BitDepth, R10k},
347 {bmdDetectedVideoInputRGB444 | bmdDetectedVideoInput12BitDepth, R12L},
348 };
349 if (s->requested_bit_depth == 0 && (csBitDepth & bmdDetectedVideoInput8BitDepth) == 0) {
350 const string & depth = (flags & bmdDetectedVideoInput10BitDepth) != 0U ? "10"s : "12"s;
352 << MOD_NAME << "Detected " << depth
353 << "-bit signal, use \":codec=UYVY\" to "
354 "enforce 8-bit capture (old "
355 "behavior).\n";
356 }
357
358 s->set_codec(m.at(csBitDepth));
359 configuredCsBitDepth = csBitDepth;
360 }
361
362 if (notificationEvents & bmdVideoInputDisplayModeChanged) {
363 IDeckLinkInput *deckLinkInput = device.deckLinkInput;
364 deckLinkInput->PauseStreams();
365 BMDPixelFormat pf{};
366 if (HRESULT result = set_display_mode_properties(s, device.tile, mode, /* out */ &pf); FAILED(result)) {
367 LOG(LOG_LEVEL_ERROR) << MOD_NAME << "set_display_mode_properties: " << bmd_hresult_to_string(result) << "\n";
368 return result;
369 }
370 CALL_AND_CHECK(deckLinkInput->EnableVideoInput(mode->GetDisplayMode(), pf, s->enable_flags), "EnableVideoInput");
371 deckLinkInput->FlushStreams();
372 deckLinkInput->StartStreams();
373 }
374
375 return S_OK;
376 }
string bmd_hresult_to_string(HRESULT res)
static constexpr BMDDetectedVideoInputFormatFlags csMask
Definition decklink.cpp:234
static auto getNotificationEventsStr(BMDVideoInputFormatChangedEvents notificationEvents, BMDDetectedVideoInputFormatFlags flags) noexcept
Definition decklink.cpp:270
static constexpr BMDDetectedVideoInputFormatFlags bitDepthMask
Definition decklink.cpp:235
BMDDetectedVideoInputFormatFlags configuredCsBitDepth
Definition decklink.cpp:236
#define LOG_LEVEL_NOTICE
information that may be interesting
Definition debug.h:61
#define LOG_LEVEL_ERROR
general errors
Definition debug.h:59
#define LOG(level)
Definition debug.h:313
#define LOG_LEVEL_WARNING
less severe errors
Definition debug.h:60
enum openssl_mode mode
struct tile * tile
Definition decklink.cpp:177
IDeckLinkInput * deckLinkInput
Definition decklink.cpp:171
depth
Definition types.h:125
@ R10k
RGB 10-bit packed - RGBX, big-endian (2 bit padding)
Definition types.h:73
@ UYVY
YCbCr 422 8-bit - Cb Y0 Cr Y1.
Definition types.h:71
@ R12L
RGB 12-bit packed, little-endian.
Definition types.h:74
@ RGBA
RGBA 8-bit, big-endian.
Definition types.h:70
@ v210
YCbCr 422 10-bit - xVY0U|xY2UY1|xUY3V|xY5VY4, little-endian (2 bit padding /'x'/),...
Definition types.h:75
@ FAILED

References bitDepthMask, bmd_hresult_to_string(), CALL_AND_CHECK, configuredCsBitDepth, csMask, device_state::deckLinkInput, device, vidcap_decklink_state::enable_flags, FAILED, flags, getNotificationEventsStr(), vidcap_decklink_state::lock, LOG, LOG_LEVEL_ERROR, LOG_LEVEL_NOTICE, LOG_LEVEL_WARNING, MOD_NAME, mode, R10k, R12L, vidcap_decklink_state::requested_bit_depth, RGBA, s, vidcap_decklink_state::set_codec(), set_display_mode_properties(), vidcap_decklink_state::stereo, device_state::tile, UYVY, and v210.

Here is the call graph for this function:

◆ VideoInputFrameArrived()

HRESULT VideoDelegate::VideoInputFrameArrived ( IDeckLinkVideoInputFrame * videoFrame,
IDeckLinkAudioInputPacket * audioPacket )
overridevirtual
Todo
videoFrame should be actually retained until the data are processed

Definition at line 381 of file decklink.cpp.

382{
383 bool nosig = false;
384
385 unique_lock<mutex> lk(s->lock);
386// LOCK - LOCK - LOCK - LOCK - LOCK - LOCK - LOCK - LOCK - LOCK - LOCK - LOCK //
387
388 // Video
389 if (videoFrame)
390 {
391 if (videoFrame->GetFlags() & bmdFrameHasNoInputSource) {
392 nosig = true;
393 log_msg(LOG_LEVEL_INFO, "Frame received (#%d) - No input signal detected\n", s->frames);
394 newFrameReady = s->nosig_send ? 1 : -1;
395 } else {
396 newFrameReady = 1; // The new frame is ready to grab
397 // printf("Frame received (#%lu) - Valid Frame (Size: %li bytes)\n", framecount, videoFrame->GetRowBytes() * videoFrame->GetHeight());
398 }
399
400 BMDTimeValue unused_duration = 0;
401 videoFrame->GetStreamTime(&frameTime, &unused_duration,
403 }
404
405 if (audioPacket && !nosig) {
406 if (s->audioPackets.size() < MAX_AUDIO_PACKETS) {
407 audioPacket->AddRef();
408 s->audioPackets.push(audioPacket);
409 } else {
410 LOG(LOG_LEVEL_WARNING) << MOD_NAME "Dropping audio packet, queue full.\n";
411 }
412 }
413
414 if (videoFrame && newFrameReady == 1 && (!nosig || !lastFrame)) {
416 videoFrame->GetBytes(&pixelFrame);
417
419 lastFrame = videoFrame;
420 lastFrame->AddRef();
421
422 IDeckLinkTimecode *tc = NULL;
423 if (videoFrame->GetTimecode(bmdTimecodeRP188Any, &tc) == S_OK) {
424 timecode = tc->GetBCD();
425 tc->Release();
426 } else {
427 timecode = 0;
428 if (s->sync_timecode) {
429 log_msg(LOG_LEVEL_ERROR, "Failed to acquire timecode from stream. Disabling sync.\n");
430 s->sync_timecode = false;
431 }
432 }
433
435 pixelFrameRight = NULL;
436
437 if(s->stereo) {
438 IDeckLinkVideoFrame3DExtensions *rightEye;
439 HRESULT result;
440 result = videoFrame->QueryInterface(IID_IDeckLinkVideoFrame3DExtensions, (void **)&rightEye);
441
442 if (result == S_OK) {
443 result = rightEye->GetFrameForRightEye(&rightEyeFrame);
444
445 if(result == S_OK) {
446 if (rightEyeFrame->GetFlags() & bmdFrameHasNoInputSource)
447 {
448 log_msg(LOG_LEVEL_ERROR, MOD_NAME "Right Eye Frame received (#%d) - No input signal detected\n", s->frames);
449 }
450 rightEyeFrame->GetBytes(&pixelFrameRight);
451 }
452 }
453 rightEye->Release();
454 if(!pixelFrameRight) {
455 log_msg(LOG_LEVEL_ERROR, MOD_NAME "Sending right eye error.\n");
456 }
457 }
458 }
459
460 lk.unlock();
461 s->boss_cv.notify_one();
462
463// UNLOCK - UNLOCK - UNLOCK - UNLOCK - UNLOCK - UNLOCK - UNLOCK - UNLOCK - UN //
464
465 return S_OK;
466}
void * pixelFrame
Definition decklink.cpp:242
uint32_t timecode
Definition decklink.cpp:245
BMDTimeValue frameTime
Definition decklink.cpp:240
void * pixelFrameRight
Definition decklink.cpp:243
void log_msg(int level, const char *format,...)
Definition debug.cpp:130
#define LOG_LEVEL_INFO
normal reporting
Definition debug.h:62

References vidcap_decklink_state::audioPackets, vidcap_decklink_state::boss_cv, vidcap_decklink_state::frameRateScale, vidcap_decklink_state::frames, frameTime, lastFrame, vidcap_decklink_state::lock, LOG, LOG_LEVEL_ERROR, LOG_LEVEL_INFO, LOG_LEVEL_WARNING, log_msg(), MAX_AUDIO_PACKETS, MOD_NAME, newFrameReady, vidcap_decklink_state::nosig_send, pixelFrame, pixelFrameRight, RELEASE_IF_NOT_NULL, rightEyeFrame, s, vidcap_decklink_state::stereo, vidcap_decklink_state::sync_timecode, and timecode.

Here is the call graph for this function:

Member Data Documentation

◆ bitDepthMask

BMDDetectedVideoInputFormatFlags VideoDelegate::bitDepthMask {bmdDetectedVideoInput8BitDepth | bmdDetectedVideoInput10BitDepth | bmdDetectedVideoInput12BitDepth}
staticconstexprprivate

Definition at line 235 of file decklink.cpp.

235{bmdDetectedVideoInput8BitDepth | bmdDetectedVideoInput10BitDepth | bmdDetectedVideoInput12BitDepth};

Referenced by VideoInputFormatChanged().

◆ configuredCsBitDepth

BMDDetectedVideoInputFormatFlags VideoDelegate::configuredCsBitDepth {}
private

Definition at line 236 of file decklink.cpp.

236{};

Referenced by VideoInputFormatChanged().

◆ csMask

BMDDetectedVideoInputFormatFlags VideoDelegate::csMask {bmdDetectedVideoInputYCbCr422 | bmdDetectedVideoInputRGB444}
staticconstexprprivate

Definition at line 234 of file decklink.cpp.

234{bmdDetectedVideoInputYCbCr422 | bmdDetectedVideoInputRGB444};

Referenced by VideoInputFormatChanged().

◆ device

struct device_state& VideoDelegate::device

Definition at line 247 of file decklink.cpp.

Referenced by VideoInputFormatChanged().

◆ frameTime

BMDTimeValue VideoDelegate::frameTime {}

Definition at line 240 of file decklink.cpp.

240{};

Referenced by VideoInputFrameArrived().

◆ lastFrame

IDeckLinkVideoInputFrame* VideoDelegate::lastFrame {nullptr}

Definition at line 244 of file decklink.cpp.

244{nullptr};

Referenced by ~VideoDelegate(), and VideoInputFrameArrived().

◆ mRefCount

int32_t VideoDelegate::mRefCount {}
private

Definition at line 233 of file decklink.cpp.

233{};

Referenced by AddRef(), and Release().

◆ newFrameReady

int VideoDelegate::newFrameReady {}

Definition at line 239 of file decklink.cpp.

239{}; // -1 == timeout

Referenced by VideoInputFrameArrived().

◆ pixelFrame

void* VideoDelegate::pixelFrame {}

Definition at line 242 of file decklink.cpp.

242{};

Referenced by VideoInputFrameArrived().

◆ pixelFrameRight

void* VideoDelegate::pixelFrameRight {}

Definition at line 243 of file decklink.cpp.

243{};

Referenced by VideoInputFrameArrived().

◆ rightEyeFrame

IDeckLinkVideoFrame* VideoDelegate::rightEyeFrame {}

Definition at line 241 of file decklink.cpp.

241{};

Referenced by ~VideoDelegate(), and VideoInputFrameArrived().

◆ s

struct vidcap_decklink_state* VideoDelegate::s

◆ timecode

uint32_t VideoDelegate::timecode {}

Definition at line 245 of file decklink.cpp.

245{};

Referenced by VideoInputFrameArrived().


The documentation for this class was generated from the following file: