UltraGrid
UltraGrid Low-Latency High-Resolution Transmission System
Loading...
Searching...
No Matches
display_bluefish444_state Struct Reference
Collaboration diagram for display_bluefish444_state:
Collaboration graph

Public Member Functions

 display_bluefish444_state (unsigned int flags, int deviceId=1) noexcept(false)
 
virtual ~display_bluefish444_state () noexcept
 
void cleanup () noexcept
 
struct video_frame * getf () noexcept
 
void * playback_loop () noexcept
 
void putf (struct video_frame *) noexcept(false)
 
void reconfigure (struct video_desc) noexcept(false)
 

Static Public Member Functions

static void * playback_thread (void *arg) noexcept
 

Private Attributes

int m_AttachedDevicesCount
 
pthread_cond_t m_BossCv
 
int m_CardFirmware
 
BLUE_S32 m_CardType
 
ULONG m_CurrentVideoMode
 
int m_deviceId
 
struct video_frame * m_frame
 
queue< struct av_buffer * > m_FreeFrameQueue
 
BLUE_U32 m_GoldenSize
 
ULONG m_InvalidVideoModeFlag
 
unsigned long int m_LastFieldCount
 
pthread_mutex_t m_lock
 
uint32_t m_magic
 
int m_Offset [MAX_BLUE_OUT_CHANNELS]
 
bool m_PlayAudio
 
struct av_buffer * m_pPlayingBuffer
 
BLUEVELVETC_HANDLE m_pSDK [MAX_BLUE_OUT_CHANNELS]
 
av_buffer * m_pTmpFrame
 
queue< struct av_buffer * > m_ReadyFrameQueue
 
pthread_t m_thread
 
int m_TileCount
 
pthread_cond_t m_WorkerCv
 
bool m_WorkerWaiting
 

Detailed Description

Definition at line 102 of file bluefish444.cpp.

Constructor & Destructor Documentation

◆ display_bluefish444_state()

display_bluefish444_state::display_bluefish444_state ( unsigned int flags,
int deviceId = 1 )

Definition at line 158 of file bluefish444.cpp.

159 :
161 m_frame(NULL),
162 m_deviceId(deviceId),
164 m_GoldenSize(0),
166 m_pPlayingBuffer(NULL),
167#ifdef HAVE_BLUE_AUDIO
168 m_AudioRingBuffer(ring_buffer_init(48000*4*16*8)),
169#endif
170 m_PlayAudio(false)
171{
172 BLUE_S32 iDevices = 0;
173 BLUE_U32 val32;
174
175 if(flags) {
176#ifdef HAVE_BLUE_AUDIO
177 m_PlayAudio = true;
178#else
179 throw runtime_error("Audio support missing in this build");
180#endif
181 }
182 pthread_mutex_init(&m_lock, NULL);
183 pthread_cond_init(&m_WorkerCv, NULL);
184 pthread_cond_init(&m_BossCv, NULL);
185
186 BLUEVELVETC_HANDLE pSDK = bfcFactory();
187 bfcEnumerate(pSDK, &iDevices);
188 if(iDevices < 1) {
189 bfcDestroy(pSDK);
190 throw runtime_error("No Bluefish card detected");
191 }
192
193 bfcQueryCardType(pSDK, &m_CardType, m_deviceId);
194 bfcQueryCardProperty32(pSDK, INVALID_VIDEO_MODE_FLAG, &val32);
196
197 if(BLUE_FAIL(bfcAttach(pSDK, m_deviceId))) {
198 bfcDestroy(pSDK);
199 throw runtime_error("Unable to attach card");
200 }
201
202 bfcQueryCardProperty32(pSDK, EPOCH_GET_PRODUCT_ID, &val32);
203
204 m_CardFirmware = val32;
205 m_deviceId = deviceId;
206
207 bfcDetach(pSDK);
208 bfcDestroy(pSDK);
209
210#ifdef HAVE_BLUE_AUDIO
211 memset(&m_AudioDesc, 0, sizeof(m_AudioDesc));
212 memset(&m_HancInfo, 0, sizeof(m_HancInfo));
213 for(int i = 0; i < 4; ++i) {
214 m_HancInfo.AudioDBNArray[i] = -1;
215 }
216 m_HancInfo.hanc_data_ptr = (unsigned int *) bfAlloc(MAX_HANC_SIZE);
217 pthread_spin_init(&m_AudioSpinLock, 0);
218#endif
219
220 pthread_create(&m_thread, NULL, playback_thread, this);
221}
const char unsigned int flags
#define MAX_HANC_SIZE
struct ring_buffer * ring_buffer_init(int size)
unsigned long int m_LastFieldCount
static void * playback_thread(void *arg) noexcept
struct video_frame * m_frame
struct av_buffer * m_pPlayingBuffer
#define BLUEFISH444_MAGIC

References flags, and MAX_HANC_SIZE.

◆ ~display_bluefish444_state()

display_bluefish444_state::~display_bluefish444_state ( )
virtualnoexcept

Definition at line 223 of file bluefish444.cpp.

224{
225 assert(m_magic == BLUEFISH444_MAGIC);
226 // Kill thread
227 pthread_mutex_lock(&m_lock);
228 m_ReadyFrameQueue.push(NULL);
229 pthread_cond_signal(&m_WorkerCv);
230 pthread_mutex_unlock(&m_lock);
231 unsigned long int FieldCount;
232 //cards must be genlocked; only then all for output channels are completely in synch
233 bfcWaitVideoOutputSync(m_pSDK[0], UPD_FMT_FRAME, &FieldCount);
234
235 pthread_join(m_thread, NULL);
236
237 cleanup();
238
239 pthread_mutex_destroy(&m_lock);
240 pthread_cond_destroy(&m_WorkerCv);
241 pthread_cond_destroy(&m_BossCv);
242
243#ifdef HAVE_BLUE_AUDIO
244 ring_buffer_destroy(m_AudioRingBuffer);
245 bfFree(MAX_HANC_SIZE, m_HancInfo.hanc_data_ptr);
246 pthread_spin_destroy(&m_AudioSpinLock);
247#endif
248}
void ring_buffer_destroy(struct ring_buffer *ring)
queue< struct av_buffer * > m_ReadyFrameQueue
BLUEVELVETC_HANDLE m_pSDK[MAX_BLUE_OUT_CHANNELS]

References BLUEFISH444_MAGIC, cleanup(), m_BossCv, m_lock, m_magic, m_pSDK, m_ReadyFrameQueue, m_thread, m_WorkerCv, MAX_HANC_SIZE, and ring_buffer_destroy().

Here is the call graph for this function:

Member Function Documentation

◆ cleanup()

void display_bluefish444_state::cleanup ( )
noexcept

Definition at line 453 of file bluefish444.cpp.

454{
455 //turn on black generator (unless we want to keep displaying the last rendered frame)
456 for(int i = 0; i < m_AttachedDevicesCount; ++i) {
457 uint32_t value;
458
459 value = ENUM_BLACKGENERATOR_ON;
460 bfcSetCardProperty32(m_pSDK[i], VIDEO_BLACKGENERATOR, value);
461
462 bfcVideoPlaybackStop(m_pSDK[i], 1, 1);
463 }
464
465 while(!m_FreeFrameQueue.empty()) {
466 struct av_buffer *frame = m_FreeFrameQueue.front();
467 m_FreeFrameQueue.pop();
468 delete frame;
469 }
470
471 if(m_pPlayingBuffer) {
472 delete m_pPlayingBuffer;
473 m_pPlayingBuffer = NULL;
474 }
475
477 m_frame = NULL;
478
479 for(int i = 0; i < m_AttachedDevicesCount; ++i) {
480 bfcDetach(m_pSDK[i]);
481 bfcDestroy(m_pSDK[i]);
482 }
483
485}
struct video_frame * frame
void vf_free(struct video_frame *buf)
Frees video_frame structure.
queue< struct av_buffer * > m_FreeFrameQueue

References frame, m_AttachedDevicesCount, m_frame, m_FreeFrameQueue, m_pPlayingBuffer, m_pSDK, and vf_free().

Referenced by ~display_bluefish444_state().

Here is the call graph for this function:

◆ getf()

struct video_frame * display_bluefish444_state::getf ( )
noexcept

Definition at line 702 of file bluefish444.cpp.

703{
704 pthread_mutex_lock(&m_lock);
705 while(m_FreeFrameQueue.empty()) {
706 pthread_cond_wait(&m_BossCv, &m_lock);
707 }
709 m_FreeFrameQueue.pop();
710 for(int i = 0; i < m_TileCount; ++i) {
711 m_frame->tiles[i].data = (char *) m_pTmpFrame->pVideoBuffer[i];
712 }
713 pthread_mutex_unlock(&m_lock);
714
715 return m_frame;
716}
vector< unsigned int * > pVideoBuffer
char * data
Raw tile data. Pointer must be at least 4B aligned.
Definition types.h:287
struct tile tiles[FLEXIBLE_ARRAY_MEMBER]
Definition types.h:345

References tile::data, m_BossCv, m_frame, m_FreeFrameQueue, m_lock, m_pTmpFrame, m_TileCount, av_buffer::pVideoBuffer, and video_frame::tiles.

Referenced by display_bluefish444_getf().

◆ playback_loop()

void * display_bluefish444_state::playback_loop ( )
noexcept

Definition at line 257 of file bluefish444.cpp.

258{
259 uint32_t FrameCount = 0;
260 struct timeval t0;
261#ifdef HAVE_BLUE_AUDIO
262 uint32_t EmbAudioFlag = blue_enable_hanc_timestamp_pkt | blue_emb_audio_enable; // enable timecode
263#endif
264
265 gettimeofday(&t0, NULL);
266
267#ifdef _WIN32
268 OVERLAPPED Overlapped[MAX_BLUE_OUT_CHANNELS];
269 for (int i = 0;i < MAX_BLUE_OUT_CHANNELS; ++ i) {
270 Overlapped[i].hEvent = CreateEvent(NULL, TRUE, FALSE, NULL);
271 }
272#endif
273
274 while(1) {
275 struct av_buffer *frame;
276 pthread_mutex_lock(&m_lock);
277 while(m_ReadyFrameQueue.empty()) {
278 m_WorkerWaiting = true;
279 pthread_cond_wait(&m_WorkerCv, &m_lock);
280 m_WorkerWaiting = false;
281 }
282
283 frame = m_ReadyFrameQueue.front();
284 m_ReadyFrameQueue.pop();
285 pthread_mutex_unlock(&m_lock);
286
287 if(frame == NULL) {
288 return NULL;
289 }
290
291 unsigned long int FieldCount = 0;
292
293 // for more than one input, cards must be genlocked
294 bfcWaitVideoOutputSync(m_pSDK[0], UPD_FMT_FRAME, &FieldCount);
295 if(m_pPlayingBuffer) {
296 pthread_mutex_lock(&m_lock);
298 pthread_cond_signal(&m_BossCv);
299 pthread_mutex_unlock(&m_lock);
300 }
301
302 bool WaitResult = true;
303
304 for(int i = 0; i < m_AttachedDevicesCount; ++i) {
305 unsigned char *videoBuffer;
306#ifdef _WIN32
307 OVERLAPPED *OverlapCh = &Overlapped[i];
308#endif
310 videoBuffer = (unsigned char *) frame->pVideoBuffer[i];
311 } else { // untiled 4K
312 videoBuffer = (unsigned char *) frame->pVideoBuffer[0];
313 }
314#ifdef _WIN32
315 int err = bfcSystemBufferWriteAsync(
316#else
317 int err = bfcSystemBufferWrite(
318#endif
319 m_pSDK[i], videoBuffer + m_Offset[i], m_GoldenSize,
320#ifdef _WIN32
321 OverlapCh,
322#endif
323 (m_PlayAudio && i == 0 ?
324 BlueImage_HANC_DMABuffer(frame->BufferId, BLUE_DATA_IMAGE) :
325 BlueImage_DMABuffer(frame->BufferId, BLUE_DATA_IMAGE)), 0
326 );
327 if(!BLUE_OK(err)) {
328 cerr << "Write failed (Channel " << (char) ('A' + i) << ")" << endl;
329 WaitResult = false;
330 }
331 }
332#ifdef _WIN32
333 if(WaitResult) {
334 for(int i = 0; i < m_AttachedDevicesCount; ++i) {
335 DWORD BytesReturned = 0;
336 GetOverlappedResult(bfcGetHandle(m_pSDK[i]), &Overlapped[i], &BytesReturned, TRUE);
337 ResetEvent(Overlapped[i].hEvent);
338 }
339 }
340#else
341 UNUSED(WaitResult);
342#endif
343
344#ifdef HAVE_BLUE_AUDIO
345 if(m_PlayAudio) {
346 m_HancInfo.time_code = 0LL; //RP188 VITC time code
347 m_HancInfo.rp188_ltc_time_code = 0LL; //RP188 LTC time code
348 m_HancInfo.ltc_time_code = 0LL; //external LTC time code
349 m_HancInfo.sd_vitc_time_code = 0LL; //this field is only valid for SD video signal
350 m_HancInfo.video_mode = m_CurrentVideoMode;
351
352 uint32_t NrSamples = 0;
353 pthread_spin_lock(&m_AudioSpinLock);
354 uint32_t NumberAudioChannels = m_AudioDesc.ch_count;
355 char audio_data[2002*4*16];
356 unsigned int nSampleType;
357 ULONG EmbAudioProp = 0;
358
359 if(NumberAudioChannels > 0) {
361 FrameCount);
362 switch(m_AudioDesc.bps) {
363 case 2:
364 nSampleType = AUDIO_CHANNEL_16BIT; // AUDIO_CHANNEL_LITTLEENDIAN
365 break;
366 case 3:
367 nSampleType = AUDIO_CHANNEL_24BIT;
368 break;
369 default:
370 fprintf(stderr, "[Blue] Unhandled audio sample type!\n");
371 abort();
372 }
373
374 if(NumberAudioChannels > 0)
375 EmbAudioProp |= (blue_emb_audio_group1_enable);
376 if(NumberAudioChannels > 4)
377 EmbAudioProp |= (blue_emb_audio_group2_enable);
378 if(NumberAudioChannels > 8)
379 EmbAudioProp |= (blue_emb_audio_group3_enable);
380 if(NumberAudioChannels > 12)
381 EmbAudioProp |= (blue_emb_audio_group4_enable);
382
383 int bytes = ring_buffer_read(m_AudioRingBuffer, audio_data, NrSamples *
384 m_AudioDesc.bps *m_AudioDesc.ch_count);
385 NrSamples = bytes / m_AudioDesc.bps / m_AudioDesc.ch_count;
386 }
387 pthread_spin_unlock(&m_AudioSpinLock);
388
389 if(NrSamples > 0) {
390 bfcEncodeHancFrameEx(m_pSDK[0], m_CardType, &m_HancInfo, audio_data,
391 m_AudioDesc.ch_count, NrSamples,
392 nSampleType, EmbAudioProp | EmbAudioFlag);
393
394 //wait for both DMA transfers to be finished
395 //GetOverlappedResult(pSDK->m_hDevice, &OverlapChA, &BytesReturnedChA, TRUE);
396 //ResetEvent(OverlapChA.hEvent);
397
398 //now we can DMA the HANC frame
399#ifdef _WIN32
400 bfcSystemBufferWriteAsync(m_pSDK[0], (unsigned char *) m_HancInfo.hanc_data_ptr,
402 NULL, BlueImage_HANC_DMABuffer(frame->BufferId, BLUE_DATA_HANC));
403#else
404 bfcSystemBufferWrite(m_pSDK[0], (unsigned char *) m_HancInfo.hanc_data_ptr,
406 BlueImage_HANC_DMABuffer(frame->BufferId, BLUE_DATA_HANC), 0);
407#endif
408 }
409 }
410#endif
411 //tell the card to playback the frames on the next interrupt
412 for(int i = 0; i < m_AttachedDevicesCount; ++i) {
413 bfcRenderBufferUpdate(m_pSDK[i],
414 (m_PlayAudio && i == 0 ?
415 BlueBuffer_Image_HANC(frame->BufferId) :
416 BlueBuffer_Image(frame->BufferId))
417 );
418 }
419
420 if(FieldCount != m_LastFieldCount + 2) {
421 cerr << "[Blue444 disp] " << "Dropped " <<
422 ((FieldCount - m_LastFieldCount + 2)/2) <<
423 " frames." << endl;
424 }
425
426 m_LastFieldCount = FieldCount;
427
428 FrameCount++;
429
430 struct timeval t;
431 gettimeofday(&t, NULL);
432 double seconds = tv_diff(t, t0);
433 if (seconds >= 5) {
434 float fps = FrameCount / seconds;
435 log_msg(LOG_LEVEL_INFO, "[Blue disp] %d frames in %g seconds = %g FPS\n",
436 FrameCount, seconds, fps);
437 t0 = t;
438 FrameCount = 0;
439 }
440
442 }
443
444#ifdef _WIN32
445 for(int i = 0; i < m_AttachedDevicesCount; ++i) {
446 CloseHandle(Overlapped[i].hEvent);
447 }
448#endif
449
450 return NULL;
451}
#define UNUSED(x)
static uint32_t GetNumberOfAudioSamplesPerFrame(uint32_t VideoMode, uint32_t FrameNumber) __attribute__((unused))
#define TRUE
#define FALSE
void log_msg(int level, const char *format,...)
Definition debug.cpp:130
#define LOG_LEVEL_INFO
normal reporting
Definition debug.h:62
int ring_buffer_read(struct ring_buffer *ring, char *out, int max_len)
int m_Offset[MAX_BLUE_OUT_CHANNELS]
double tv_diff(struct timeval curr_time, struct timeval prev_time)
Definition tv.c:97
#define MAX_BLUE_OUT_CHANNELS

References FALSE, frame, GetNumberOfAudioSamplesPerFrame(), LOG_LEVEL_INFO, log_msg(), m_AttachedDevicesCount, m_BossCv, m_CardType, m_CurrentVideoMode, m_FreeFrameQueue, m_GoldenSize, m_LastFieldCount, m_lock, m_Offset, m_PlayAudio, m_pPlayingBuffer, m_pSDK, m_ReadyFrameQueue, m_TileCount, m_WorkerCv, m_WorkerWaiting, MAX_BLUE_OUT_CHANNELS, MAX_HANC_SIZE, ring_buffer_read(), TRUE, tv_diff(), and UNUSED.

Referenced by playback_thread().

Here is the call graph for this function:

◆ playback_thread()

void * display_bluefish444_state::playback_thread ( void * arg)
staticnoexcept

Definition at line 250 of file bluefish444.cpp.

References playback_loop().

Here is the call graph for this function:

◆ putf()

void display_bluefish444_state::putf ( struct video_frame * frame)

Definition at line 718 of file bluefish444.cpp.

719{
720 if (!frame)
721 return;
722
723 if (frame->tiles[0].data !=
724 (char *) m_pTmpFrame->pVideoBuffer[0]) {
725 throw invalid_argument("Invalid frame supplied!");
726 }
727
728 pthread_mutex_lock(&m_lock);
729 for(int i = 0; i < m_TileCount; ++i) {
730 m_pTmpFrame->pVideoBuffer[i] = (unsigned int *)(void *) m_frame->tiles[i].data;
731 }
733 pthread_cond_signal(&m_WorkerCv);
734 pthread_mutex_unlock(&m_lock);
735}

References tile::data, frame, and video_frame::tiles.

Referenced by display_bluefish444_putf().

◆ reconfigure()

void display_bluefish444_state::reconfigure ( struct video_desc desc)

Definition at line 487 of file bluefish444.cpp.

489{
490 ULONG VideoMode;
491 BLUE_U32 val32;
492 bool is4K;
493 bool isTiled4K;
494 int tile_width, tile_height;
495
496 pthread_mutex_lock(&m_lock);
497 while(!m_ReadyFrameQueue.empty() ||
499 pthread_cond_wait(&m_BossCv, &m_lock);
500 pthread_mutex_unlock(&m_lock);
501
502 cleanup();
503
504 tile_width = desc.width;
505 tile_height = desc.height;
506
507 // 4K
508 if((desc.width == 4096 || desc.width == 3840) && desc.height == 2160) {
509 is4K = true;
510 isTiled4K = false;
511 tile_width /= 2;
512 tile_height /= 2;
513 } else if(desc.tile_count == 4 &&
514 (desc.width == 2048 || desc.width == 1920) &&
515 desc.height == 1080) {
516 // tiled 4K
517 is4K = true;
518 isTiled4K = true;
519 } else {
520 is4K = false;
521 isTiled4K = false;
522 }
523
525
526 if(is4K) {
527 // we need a SuperNova QuadOut card
528 if(m_CardType != CRD_BLUE_SUPER_NOVA) {
529 throw runtime_error("We need a SuperNova card for 4K mode! "
530 "Let us know if you need a different combination "
531 "(eg. 2x Bluefish card");
532 }
533
534 if(m_CardFirmware != ORAC_4SDIOUTPUT_FIRMWARE_PRODUCTID)
535 {
536 throw runtime_error("Wrong firmware; need 4 output channels (QuadOut)");
537 }
538
540 } else {
542 }
543
544 for(int i = 0; i < m_AttachedDevicesCount; ++i) {
545 m_pSDK[i] = bfcFactory();
546
547 //Attach the SDK object to a specific card, in this case card 1
548 if(BLUE_FAIL(bfcAttach(m_pSDK[i], m_deviceId)))
549 {
550 throw runtime_error("Error on device attach");
551 }
552 }
553
554 VideoMode = m_InvalidVideoModeFlag;
555
556 for(int i = 0; i < bluefish_frame_modes_count; ++i) {
557 if((int) bluefish_frame_modes[i].width == tile_width &&
558 (int) bluefish_frame_modes[i].height == tile_height &&
559 fabs(bluefish_frame_modes[i].fps - desc.fps) < 0.01 &&
561 {
562 VideoMode =
564 }
565 }
566
567 if(VideoMode == m_InvalidVideoModeFlag) {
568 ostringstream msg_ss;
569 msg_ss << "Unable to find appropriate video format for " <<
570 tile_width << "x" << tile_height <<
572 " @" << fixed << setprecision(2) << desc.fps;
573 throw runtime_error(msg_ss.str());
574 }
575
576 m_CurrentVideoMode = VideoMode;
577
578 ULONG UpdateFormat = UPD_FMT_FRAME;
579 ULONG MemoryFormat;
580 switch(desc.color_spec) {
581 case UYVY:
582 MemoryFormat = MEM_FMT_2VUY;
583 break;
584 case v210:
585 MemoryFormat = MEM_FMT_V210;
586 break;
587 case RGBA:
588 MemoryFormat = MEM_FMT_RGBA;
589 break;
590 // case DPX10:
591 // MemoryFormat = MEM_FMT_CINEON_LITTLE_ENDIAN;
592 // break;
593 default:
594 throw logic_error("Unknown video format!!!");
595 }
596
597 ULONG VideoEngine = VIDEO_ENGINE_FRAMESTORE;
598
599 ULONG OutputChannels[4] = {
600 BLUE_VIDEO_OUTPUT_CHANNEL_A,
601 BLUE_VIDEO_OUTPUT_CHANNEL_B,
602 BLUE_VIDEO_OUTPUT_CHANNEL_C,
603 BLUE_VIDEO_OUTPUT_CHANNEL_D
604 };
605 ULONG Sources[4] = { EPOCH_SRC_OUTPUT_MEM_INTERFACE_CHA,
606 EPOCH_SRC_OUTPUT_MEM_INTERFACE_CHB,
607 EPOCH_SRC_OUTPUT_MEM_INTERFACE_CHC,
608 EPOCH_SRC_OUTPUT_MEM_INTERFACE_CHD
609 };
610 ULONG Destinations[4] = { EPOCH_DEST_SDI_OUTPUT_A,
611 EPOCH_DEST_SDI_OUTPUT_B,
612 EPOCH_DEST_SDI_OUTPUT_C,
613 EPOCH_DEST_SDI_OUTPUT_D
614 };
615
616 for(int i = 0; i < m_AttachedDevicesCount; ++i) {
617 InitOutputChannel(m_pSDK[i], OutputChannels[i],
618 UpdateFormat, MemoryFormat, VideoEngine);
619 RouteChannel(m_pSDK[i], Sources[i],
620 Destinations[i],
621 BLUE_CONNECTOR_PROP_SINGLE_LINK);
622 }
623
624 if(m_PlayAudio) {
625 //route the same audio to AES as well (AES only supports 8 channels, though)
626 val32 = EPOCH_SET_ROUTING(EPOCH_SRC_OUTPUT_MEM_INTERFACE_CHA,
627 EPOCH_DEST_AES_ANALOG_AUDIO_OUTPUT, BLUE_CONNECTOR_PROP_SINGLE_LINK);
628 bfcSetCardProperty32(m_pSDK[0], MR2_ROUTING, val32);
629
630 val32 = blue_emb_audio_group1_enable | blue_emb_audio_enable | blue_enable_hanc_timestamp_pkt;
631 bfcSetCardProperty32(m_pSDK[0], EMBEDDED_AUDIO_OUTPUT, val32);
632 }
633
634 //Set the required video mode
635 for(int i = 0; i < m_AttachedDevicesCount; ++i) {
636 val32 = VideoMode;
637 bfcSetCardProperty32(m_pSDK[i], VIDEO_MODE, val32);
638 bfcQueryCardProperty32(m_pSDK[i], VIDEO_MODE, &val32);
639 if(val32 != VideoMode)
640 {
641 throw logic_error("Can't set video mode; FIFO running already?");
642 }
643 }
644
645 for(int i = 0; i < m_AttachedDevicesCount; ++i) {
646 val32 = vc_get_linesize(tile_width, desc.color_spec);
647 bfcSetCardProperty32(m_pSDK[i], VIDEO_IMAGE_WIDTH, val32);
648 val32 = tile_height;
649 bfcSetCardProperty32(m_pSDK[i], VIDEO_IMAGE_HEIGHT, val32);
651 bfcSetCardProperty32(m_pSDK[i], VIDEO_IMAGE_PITCH, val32);
652 }
653
654 BLUE_U32 Width, Height, BytesPerLine, BytesPerFrame, GoldenSize;
655 bfcGetVideoInfo(VideoMode, UpdateFormat, MemoryFormat, &Width, &Height, &BytesPerLine, &BytesPerFrame, &GoldenSize);
656
657 ULONG FrameSize = GoldenSize;
658 if(is4K && !isTiled4K) {
659 BytesPerFrame = vc_get_linesize(desc.width, desc.color_spec) *
660 desc.height;
661 // 4 * GoldenSize should be AFAIK correct but it keeps failing during
662 // DMA transfer of last segment of 4K video
663 FrameSize = 5 * GoldenSize;
664 }
665
666 cout << "Video Golden: " << GoldenSize << endl;
667 cout << "Video Pixels per line: " << Width << endl;
668 cout << "Video lines: " << Height << endl;
669 cout << "Video Bytes per frame: " << BytesPerFrame << endl;
670 cout << "Video Bytes per line: " << BytesPerLine << endl;
671
672 for(int i = 0; i < BUFFER_COUNT; ++i) {
673 av_buffer *new_buffer = new av_buffer(desc.tile_count, FrameSize);
674 m_FreeFrameQueue.push(new_buffer);
675 }
676
678 for(unsigned int i = 0; i < desc.tile_count; ++i) {
679 m_frame->tiles[i].data_len = BytesPerFrame;
680 }
681
682 if(!is4K || isTiled4K) {
683 m_GoldenSize = GoldenSize;
684 for(int i = 0; i < m_AttachedDevicesCount; ++i) {
685 m_Offset[i] = 0;
686 }
687 } else {
689 for(int i = 0; i < m_AttachedDevicesCount; ++i) {
690 int x = i % 2;
691 int y = i / 2;
692 m_Offset[i] = y * m_GoldenSize + x *
693 vc_get_linesize(tile_width, desc.color_spec);
694 }
695 }
696
697 for(int i = 0; i < m_AttachedDevicesCount; ++i) {
698 bfcVideoPlaybackStart(m_pSDK[i], 0, 0);
699 }
700}
struct video_desc desc
int vc_get_linesize(unsigned int width, codec_t codec)
struct video_frame * vf_alloc_desc(struct video_desc desc)
Allocates video frame accordig given desc.
static const int bluefish_frame_modes_count
static const struct bluefish_frame_mode_t bluefish_frame_modes[]
enum interlacing_t interlacing
unsigned int data_len
length of the data
Definition types.h:288
unsigned int tile_count
Definition types.h:185
codec_t color_spec
Definition types.h:182
enum interlacing_t interlacing
Definition types.h:184
double fps
Definition types.h:183
unsigned int width
width of every tile (!)
Definition types.h:179
unsigned int height
height of every tile (!)
Definition types.h:180
@ UYVY
YCbCr 422 8-bit - Cb Y0 Cr Y1.
Definition types.h:71
@ 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
static void RouteChannel(BLUEVELVETC_HANDLE pSDK, ULONG Source, ULONG Destination, ULONG LinkType)
#define BUFFER_COUNT
static void InitOutputChannel(BLUEVELVETC_HANDLE pSDK, ULONG DefaultOutputChannel, ULONG UpdateFormat, ULONG MemoryFormat, ULONG VideoEngine)
const char * get_interlacing_suffix(enum interlacing_t interlacing)
Returns suffix describing interlacing Eg. p, i or psf.

References av_buffer::av_buffer(), bluefish_frame_modes, bluefish_frame_modes_count, BUFFER_COUNT, cleanup(), video_desc::color_spec, desc, video_desc::fps, get_interlacing_suffix(), video_desc::height, InitOutputChannel(), bluefish_frame_mode_t::interlacing, video_desc::interlacing, bluefish_frame_mode_t::mode, RGBA, RouteChannel(), video_desc::tile_count, UYVY, v210, vc_get_linesize(), vf_alloc_desc(), and video_desc::width.

Referenced by display_bluefish444_reconfigure().

Here is the call graph for this function:

Member Data Documentation

◆ m_AttachedDevicesCount

int display_bluefish444_state::m_AttachedDevicesCount
private

Definition at line 127 of file bluefish444.cpp.

Referenced by cleanup(), and playback_loop().

◆ m_BossCv

pthread_cond_t display_bluefish444_state::m_BossCv
private

Definition at line 140 of file bluefish444.cpp.

Referenced by ~display_bluefish444_state(), getf(), and playback_loop().

◆ m_CardFirmware

int display_bluefish444_state::m_CardFirmware
private

Definition at line 129 of file bluefish444.cpp.

◆ m_CardType

BLUE_S32 display_bluefish444_state::m_CardType
private

Definition at line 128 of file bluefish444.cpp.

Referenced by playback_loop().

◆ m_CurrentVideoMode

ULONG display_bluefish444_state::m_CurrentVideoMode
private

Definition at line 134 of file bluefish444.cpp.

Referenced by playback_loop().

◆ m_deviceId

int display_bluefish444_state::m_deviceId
private

Definition at line 125 of file bluefish444.cpp.

◆ m_frame

struct video_frame* display_bluefish444_state::m_frame
private

Definition at line 123 of file bluefish444.cpp.

Referenced by cleanup(), and getf().

◆ m_FreeFrameQueue

queue<struct av_buffer *> display_bluefish444_state::m_FreeFrameQueue
private

Definition at line 144 of file bluefish444.cpp.

Referenced by cleanup(), getf(), and playback_loop().

◆ m_GoldenSize

BLUE_U32 display_bluefish444_state::m_GoldenSize
private

Definition at line 135 of file bluefish444.cpp.

Referenced by playback_loop().

◆ m_InvalidVideoModeFlag

ULONG display_bluefish444_state::m_InvalidVideoModeFlag
private

Definition at line 133 of file bluefish444.cpp.

◆ m_LastFieldCount

unsigned long int display_bluefish444_state::m_LastFieldCount
private

Definition at line 136 of file bluefish444.cpp.

Referenced by playback_loop().

◆ m_lock

pthread_mutex_t display_bluefish444_state::m_lock
private

Definition at line 138 of file bluefish444.cpp.

Referenced by ~display_bluefish444_state(), getf(), and playback_loop().

◆ m_magic

uint32_t display_bluefish444_state::m_magic
private

Definition at line 121 of file bluefish444.cpp.

Referenced by ~display_bluefish444_state().

◆ m_Offset

int display_bluefish444_state::m_Offset[MAX_BLUE_OUT_CHANNELS]
private

Definition at line 131 of file bluefish444.cpp.

Referenced by playback_loop().

◆ m_PlayAudio

bool display_bluefish444_state::m_PlayAudio
private

Definition at line 155 of file bluefish444.cpp.

Referenced by playback_loop().

◆ m_pPlayingBuffer

struct av_buffer* display_bluefish444_state::m_pPlayingBuffer
private

Definition at line 145 of file bluefish444.cpp.

Referenced by cleanup(), and playback_loop().

◆ m_pSDK

BLUEVELVETC_HANDLE display_bluefish444_state::m_pSDK[MAX_BLUE_OUT_CHANNELS]
private

Definition at line 126 of file bluefish444.cpp.

Referenced by ~display_bluefish444_state(), cleanup(), and playback_loop().

◆ m_pTmpFrame

av_buffer* display_bluefish444_state::m_pTmpFrame
private

Definition at line 148 of file bluefish444.cpp.

Referenced by getf().

◆ m_ReadyFrameQueue

queue<struct av_buffer *> display_bluefish444_state::m_ReadyFrameQueue
private

Definition at line 142 of file bluefish444.cpp.

Referenced by ~display_bluefish444_state(), and playback_loop().

◆ m_thread

pthread_t display_bluefish444_state::m_thread
private

Definition at line 141 of file bluefish444.cpp.

Referenced by ~display_bluefish444_state().

◆ m_TileCount

int display_bluefish444_state::m_TileCount
private

Definition at line 130 of file bluefish444.cpp.

Referenced by getf(), and playback_loop().

◆ m_WorkerCv

pthread_cond_t display_bluefish444_state::m_WorkerCv
private

Definition at line 139 of file bluefish444.cpp.

Referenced by ~display_bluefish444_state(), and playback_loop().

◆ m_WorkerWaiting

bool display_bluefish444_state::m_WorkerWaiting
private

Definition at line 143 of file bluefish444.cpp.

Referenced by playback_loop().


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