UltraGrid
UltraGrid Low-Latency High-Resolution Transmission System
Loading...
Searching...
No Matches
deltacast_dvi.cpp File Reference
#include "config.h"
#include "config_unix.h"
#include "config_win32.h"
#include <stdio.h>
#include <stdlib.h>
#include <fcntl.h>
#include <unistd.h>
#include <string.h>
#include <sys/stat.h>
#include <sys/poll.h>
#include <sys/ioctl.h>
#include <sys/time.h>
#include <semaphore.h>
#include <map>
#include <mutex>
#include <queue>
#include <string>
#include <unordered_map>
#include "audio/types.h"
#include "debug.h"
#include "host.h"
#include "deltacast_common.hpp"
#include "lib_common.h"
#include "tv.h"
#include "utils/color_out.h"
#include "video.h"
#include "video_capture.h"
Include dependency graph for deltacast_dvi.cpp:

Go to the source code of this file.

Classes

struct  vidcap_deltacast_dispose_udata
 
struct  vidcap_deltacast_dvi_state
 

Macros

#define BADEEDID   1
 
#define DEFAULT_BUFFERQUEUE_DEPTH   5
 
#define EEDDIDOK   0
 

Functions

static decltype(EEDDIDOK) CheckEEDID (BYTE pEEDIDBuffer[256])
 
static bool load_custom_edid (const char *filename, BYTE *pEEDIDBuffer, ULONG *pEEDIDBufferSize)
 
 REGISTER_MODULE (deltacast-dv, &vidcap_deltacast_dvi_info, LIBRARY_CLASS_VIDEO_CAPTURE, VIDEO_CAPTURE_ABI_VERSION)
 
static void usage (void)
 
static void vidcap_deltacast_dvi_dispose (struct video_frame *f)
 
static void vidcap_deltacast_dvi_done (void *state)
 
static struct video_frame * vidcap_deltacast_dvi_grab (void *state, struct audio_frame **audio)
 
static int vidcap_deltacast_dvi_init (struct vidcap_params *params, void **state)
 
static void vidcap_deltacast_dvi_probe (device_info **available_cards, int *count, void(**deleter)(void *))
 
static bool wait_for_channel_locked (struct vidcap_deltacast_dvi_state *s, bool have_dvi_a_format, VHD_DV_MODE DviMode, ULONG Width, ULONG Height, ULONG RefreshRate)
 

Variables

static const map< VHD_DV_EEDID_PRESET, const char * > edid_presets
 
static const unordered_map< codec_t, ULONG, hash< int > > ug_delta_codec_mapping
 
static const struct video_capture_info vidcap_deltacast_dvi_info
 

Detailed Description

Macro Definition Documentation

◆ BADEEDID

#define BADEEDID   1

Definition at line 92 of file deltacast_dvi.cpp.

Referenced by CheckEEDID(), and vidcap_deltacast_dvi_init().

◆ DEFAULT_BUFFERQUEUE_DEPTH

#define DEFAULT_BUFFERQUEUE_DEPTH   5

Definition at line 74 of file deltacast_dvi.cpp.

Referenced by vidcap_deltacast_dvi_init().

◆ EEDDIDOK

#define EEDDIDOK   0

Definition at line 91 of file deltacast_dvi.cpp.

Referenced by CheckEEDID().

Function Documentation

◆ CheckEEDID()

decltype(EEDDIDOK) static CheckEEDID ( BYTE pEEDIDBuffer[256])
static

Definition at line 152 of file deltacast_dvi.cpp.

153{
154 int i;
155 UBYTE sum1 = 0,sum2 = 0;
156 decltype(EEDDIDOK) Return = EEDDIDOK;
157
158 /* Verify checksum */
159 for(i=0;i<128;i++)
160 {
161 sum1 += pEEDIDBuffer[i];
162 sum2 += pEEDIDBuffer[i+128];
163 }
164 if(sum1 != 0 || sum2 != 0)
165 Return = BADEEDID;
166
167 /* Verify header */
168 if(pEEDIDBuffer[0] != 0x00u || pEEDIDBuffer[1] != 0xFFu || pEEDIDBuffer[2] != 0xFFu || pEEDIDBuffer[3] != 0xFFu
169 || pEEDIDBuffer[4] != 0xFFu || pEEDIDBuffer[5] != 0xFFu || pEEDIDBuffer[6] != 0xFFu || pEEDIDBuffer[7] != 0x00u)
170 Return = BADEEDID;
171
172 return Return;
173}
#define EEDDIDOK
#define BADEEDID

References BADEEDID, and EEDDIDOK.

Referenced by vidcap_deltacast_dvi_init().

◆ load_custom_edid()

static bool load_custom_edid ( const char * filename,
BYTE * pEEDIDBuffer,
ULONG * pEEDIDBufferSize )
static

Definition at line 428 of file deltacast_dvi.cpp.

428 {
429 FILE *edid = fopen(filename, "rb");
430 if (!edid) {
431 perror("EDID open");
432 return false;
433 }
434 *pEEDIDBufferSize = fread((void *) pEEDIDBuffer, 1, *pEEDIDBufferSize, edid);
435 bool ret = ferror(edid);
436 if (!ret) {
437 perror("EDID fread");
438 }
439 fclose(edid);
440 return ret;
441}

Referenced by vidcap_deltacast_dvi_init().

◆ REGISTER_MODULE()

REGISTER_MODULE ( deltacast- dv,
& vidcap_deltacast_dvi_info,
LIBRARY_CLASS_VIDEO_CAPTURE ,
VIDEO_CAPTURE_ABI_VERSION  )

◆ usage()

static void usage ( void )
static

Definition at line 125 of file deltacast_dvi.cpp.

126{
127 col() << "Usage:\n";
128 col() << SBOLD(SRED("\t-t deltacast-dv") << "[:device=<index>][:channel=<channel>][:codec=<color_spec>][:preset=<preset>|:format=<format>]") << "\n";
129 col() << "where\n";
130
131 col() << SBOLD("\t<index>") << " - index of DVI card\n";
133
134 col() << SBOLD("\t<channel>") << " may be channel index (for cards which have multiple inputs, max 4)\n";
135
136 col() << SBOLD("\t<preset>") << " may be one of following\n";
137 for (const auto &it : edid_presets) {
138 col() << SBOLD("\t\t " << setw(2) << it.first) << " - " << it.second << "\n";
139 }
140
141 col() << SBOLD("\t<color_spec>") << " may be one of following\n";
142 col() << SBOLD("\t\tUYVY\n");
143 col() << SBOLD("\t\tv210\n");
144 col() << SBOLD("\t\tRGBA\n");
145 col() << SBOLD("\t\tBGR") << " (default)\n";
146
147 col() << SBOLD("\t<format>") << " may be format description (DVI-A), E-EDID will be ignored\n";
148 col() << "\t\tvideo format is in the format " << SBOLD("<width>x<height>@<fps>") << "\n";
149
150}
#define SRED(x)
Definition color_out.h:85
#define SBOLD(x)
Definition color_out.h:80
static void print_available_delta_boards()
static const map< VHD_DV_EEDID_PRESET, const char * > edid_presets

References edid_presets, print_available_delta_boards(), SBOLD, and SRED.

Referenced by vidcap_deltacast_dvi_init().

Here is the call graph for this function:

◆ vidcap_deltacast_dvi_dispose()

static void vidcap_deltacast_dvi_dispose ( struct video_frame * f)
static

Definition at line 708 of file deltacast_dvi.cpp.

709{
711 data->s->lock.lock();
712 data->s->frames_to_free.push(data->SlotHandle);
713 data->s->lock.unlock();
714 delete data;
715 vf_free(f);
716}
void vf_free(struct video_frame *buf)
Frees video_frame structure.
struct video_frame_callbacks callbacks
Definition types.h:324

References video_frame::callbacks, video_frame_callbacks::dispose_udata, and vf_free().

Referenced by vidcap_deltacast_dvi_grab().

Here is the call graph for this function:

◆ vidcap_deltacast_dvi_done()

static void vidcap_deltacast_dvi_done ( void * state)
static

Definition at line 682 of file deltacast_dvi.cpp.

683{
685
686 assert(s != NULL);
687
688 while (!s->frames_to_free.empty()) {
689 HANDLE h = s->frames_to_free.front();
690 s->frames_to_free.pop();
691 VHD_UnlockSlotHandle(h);
692 }
693
694 VHD_StopStream(s->StreamHandle);
695 VHD_CloseStreamHandle(s->StreamHandle);
696 /* Re-establish RX0-TX0 by-pass relay loopthrough */
697 VHD_SetBoardProperty(s->BoardHandle,VHD_CORE_BP_BYPASS_RELAY_0,TRUE);
698 VHD_CloseBoardHandle(s->BoardHandle);
699
700 delete s;
701}
void ** state
#define TRUE

References vidcap_deltacast_dvi_state::BoardHandle, vidcap_deltacast_dvi_state::frames_to_free, state, vidcap_deltacast_dvi_state::StreamHandle, and TRUE.

◆ vidcap_deltacast_dvi_grab()

static struct video_frame * vidcap_deltacast_dvi_grab ( void * state,
struct audio_frame ** audio )
static

Definition at line 719 of file deltacast_dvi.cpp.

720{
722
723 ULONG /*SlotsCount, SlotsDropped,*/BufferSize;
724 ULONG Result;
725 BYTE *pBuffer=NULL;
726 HANDLE SlotHandle;
727 queue<HANDLE> queue;
728
729 s->lock.lock();
730 swap(queue, s->frames_to_free); // empty the synchronized queue and unlock the slots without a lock
731 s->lock.unlock();
732 while (!queue.empty()) {
733 HANDLE h = queue.front();
734 queue.pop();
735 VHD_UnlockSlotHandle(h);
736 }
737
738 if(!s->configured) {
739 s->configured = wait_for_channel_locked(s, false, NB_VHD_DV_MODES, 0, 0, 0);
740 }
741 if(!s->configured) {
742 return NULL;
743 }
744
745 *audio = NULL;
746
747 Result = VHD_LockSlotHandle(s->StreamHandle, &SlotHandle);
748 if (Result != VHDERR_NOERROR) {
749 if (Result != VHDERR_TIMEOUT) {
750 log_msg(LOG_LEVEL_ERROR, "ERROR : Cannot lock slot on RX0 stream. Result = 0x%08" PRIX_ULONG "\n", Result);
751 }
752 else {
753 log_msg(LOG_LEVEL_WARNING, "Timeout \n");
754 }
755 return NULL;
756 }
757
758 Result = VHD_GetSlotBuffer(SlotHandle, VHD_DV_BT_VIDEO, &pBuffer, &BufferSize);
759
760 if (Result != VHDERR_NOERROR) {
761 log_msg(LOG_LEVEL_ERROR, "\nERROR : Cannot get slot buffer. Result = 0x%08" PRIX_ULONG "\n",Result);
762 return NULL;
763 }
764
765 struct video_frame *out;
766 if (s->desc.color_spec == RGBA) { // DELTACAST uses BGRA
767 out = vf_alloc_desc_data(s->desc);
768 vc_copylineRGBA(reinterpret_cast<unsigned char *>(out->tiles[0].data), pBuffer, out->tiles[0].data_len, 16, 8, 0);
769 VHD_UnlockSlotHandle(SlotHandle);
771 } else {
772 out = vf_alloc_desc(s->desc);
773 out->tiles[0].data = (char*) pBuffer;
774 out->tiles[0].data_len = BufferSize;
777 }
778
779 /* Print some statistics */
780 /*VHD_GetStreamProperty(s->StreamHandle,VHD_CORE_SP_SLOTS_COUNT,&SlotsCount);
781 VHD_GetStreamProperty(s->StreamHandle,VHD_CORE_SP_SLOTS_DROPPED,&SlotsDropped);
782 printf("%u frames received (%u dropped) \r",SlotsCount,SlotsDropped);*/
783 gettimeofday(&s->t, NULL);
784 double seconds = tv_diff(s->t, s->t0);
785 if (seconds >= 5) {
786 float fps = s->frames / seconds;
787 log_msg(LOG_LEVEL_INFO, "[DELTACAST cap.] %d frames in %g seconds = %g FPS\n", s->frames, seconds, fps);
788 s->t0 = s->t;
789 s->frames = 0;
790 }
791 s->frames++;
792
793 return out;
794}
struct audio_frame ** audio
struct video_frame * vf_alloc_desc(struct video_desc desc)
Allocates video frame accordig given desc.
struct video_frame * vf_alloc_desc_data(struct video_desc desc)
unsigned char BYTE
Definition crypt_aes.h:71
static __device__ void swap(T &a, T &b)
Swaps two referenced values.
Definition cuda_dxt.cu:456
void log_msg(int level, const char *format,...)
Definition debug.cpp:130
#define LOG_LEVEL_INFO
normal reporting
Definition debug.h:62
#define LOG_LEVEL_ERROR
general errors
Definition debug.h:59
#define LOG_LEVEL_WARNING
less severe errors
Definition debug.h:60
#define PRIX_ULONG
static void vidcap_deltacast_dvi_dispose(struct video_frame *f)
static bool wait_for_channel_locked(struct vidcap_deltacast_dvi_state *s, bool have_dvi_a_format, VHD_DV_MODE DviMode, ULONG Width, ULONG Height, ULONG RefreshRate)
static struct item * queue
Definition hd-rum.c:33
decoder_func_t vc_copylineRGBA
char * data
Raw tile data. Pointer must be at least 4B aligned.
Definition types.h:287
unsigned int data_len
length of the data
Definition types.h:288
codec_t color_spec
Definition types.h:182
void(* dispose)(struct video_frame *)
Definition types.h:245
Struct video_frame represents a video frame and contains video description.
Definition types.h:305
struct tile tiles[FLEXIBLE_ARRAY_MEMBER]
Definition types.h:345
double fps
Definition types.h:308
double tv_diff(struct timeval curr_time, struct timeval prev_time)
Definition tv.c:97
@ RGBA
RGBA 8-bit, big-endian.
Definition types.h:70

References audio, video_frame::callbacks, video_desc::color_spec, vidcap_deltacast_dvi_state::configured, tile::data, tile::data_len, vidcap_deltacast_dvi_state::desc, video_frame_callbacks::dispose, video_frame_callbacks::dispose_udata, video_frame::fps, vidcap_deltacast_dvi_state::frames, vidcap_deltacast_dvi_state::frames_to_free, vidcap_deltacast_dvi_state::lock, LOG_LEVEL_ERROR, LOG_LEVEL_INFO, LOG_LEVEL_WARNING, log_msg(), PRIX_ULONG, queue, RGBA, state, vidcap_deltacast_dvi_state::StreamHandle, swap(), vidcap_deltacast_dvi_state::t0, video_frame::tiles, tv_diff(), vc_copylineRGBA, vf_alloc_desc(), vf_alloc_desc_data(), vf_free(), vidcap_deltacast_dvi_dispose(), and wait_for_channel_locked().

Here is the call graph for this function:

◆ vidcap_deltacast_dvi_init()

static int vidcap_deltacast_dvi_init ( struct vidcap_params * params,
void ** state )
static

Definition at line 444 of file deltacast_dvi.cpp.

445{
447 ULONG Width = 0, Height = 0, RefreshRate = 0;
448 ULONG Result = VHDERR_NOERROR,DllVersion,NbBoards;
449 ULONG BrdId = 0;
450 ULONG Packing;
451 int edid_preset = -1;
452 BYTE pEEDIDBuffer[256];
453 ULONG pEEDIDBufferSize=256;
454 int channel = 0;
455 ULONG ChannelId;
456 bool have_custom_edid = false;
457 bool have_dvi_a_format = false;
458 VHD_DV_MODE DviMode = NB_VHD_DV_MODES;
459
460 printf("vidcap_deltacast_dvi_init\n");
461
464 }
465
466 char *init_fmt = NULL,
467 *tmp = NULL;
468 if (vidcap_params_get_fmt(params) != NULL)
469 tmp = init_fmt = strdup(vidcap_params_get_fmt(params));
470 if(init_fmt && strcmp(init_fmt, "help") == 0) {
471 free(tmp);
472 usage();
473 return VIDCAP_INIT_NOERR;
474 }
475
477 if(s == NULL) {
478 printf("Unable to allocate DELTACAST state\n");
479 goto error;
480 }
481
482 s->codec = BGR;
483 s->configured = false;
484 s->BoardHandle = s->StreamHandle = NULL;
485
486 if(init_fmt)
487 {
488 char *save_ptr = NULL;
489 char *tok;
490
491 while((tok = strtok_r(init_fmt, ":", &save_ptr)) != NULL) {
492 if (strncasecmp(tok, "device=", strlen("device=")) == 0) {
493 BrdId = atoi(tok + strlen("device="));
494 } else if(strncasecmp(tok, "board=", strlen("board=")) == 0) {
495 // compat, should be device= instead
496 BrdId = atoi(tok + strlen("board="));
497 } else if(strncasecmp(tok, "codec=", strlen("codec=")) == 0) {
498 char *codec_str = tok + strlen("codec=");
499
500 s->codec = get_codec_from_name(codec_str);
501 if (s->codec == VIDEO_CODEC_NONE) {
502 log_msg(LOG_LEVEL_ERROR, "Unable to find codec: %s\n",
503 codec_str);
504 goto error;
505 }
506 } else if (strncasecmp(tok, "edid=", strlen("edid=")) == 0) {
507 if (!load_custom_edid(strchr(tok, '=') + 1, pEEDIDBuffer, &pEEDIDBufferSize)) {
508 goto error;
509 }
510 have_custom_edid = true;
511 } else if(strncasecmp(tok, "preset=", strlen("preset=")) == 0) {
512 edid_preset = atoi(strchr(tok, '=') + 1);
513 if (edid_preset < 0 || edid_preset >= NB_VHD_DV_EEDID_PRESET) {
514 log_msg(LOG_LEVEL_ERROR, "[DELTA] Error: Wrong "
515 "EDID entered on commandline. "
516 "Expected 0-%d, got %d.\n",
517 (int) NB_VHD_DV_EEDID_PRESET - 1, edid_preset);
518 goto error;
519
520 }
521 } else if(strncasecmp(tok, "channel=", strlen("channel=")) == 0) {
522 channel = atoi(tok + strlen("channel="));
523 } else if(strncasecmp(tok, "format=", strlen("format=")) == 0) {
524 have_dvi_a_format = true;
525 char *ptr = strchr(tok, '=') + 1;
526 char *save_ptr, *item;
527 if((item = strtok_r(ptr, "x@", &save_ptr))) {
528 Width = atoi(item);
529 }
530 if((item = strtok_r(NULL, "x@", &save_ptr))) {
531 Height = atoi(item);
532 }
533 if((item = strtok_r(NULL, "x@", &save_ptr))) {
534 RefreshRate = atof(item);
535 }
536 } else {
537 log_msg(LOG_LEVEL_ERROR, "[DELTA] Error: Unrecongnized "
538 "trailing parameter %s\n", tok);
539 goto error;
540 }
541 init_fmt = NULL;
542 }
543 } else {
544 BrdId = 0;
545 printf("[DELTACAST] Automatically choosen device nr. 0\n");
546 }
547 free(tmp);
548 tmp = NULL;
549
550 /* Query VideoMasterHD information */
551 Result = VHD_GetApiInfo(&DllVersion,&NbBoards);
552 if (Result != VHDERR_NOERROR) {
553 log_msg(LOG_LEVEL_ERROR, "[DELTACAST] ERROR : Cannot query VideoMasterHD"
554 " information. Result = 0x%08" PRIX_ULONG "\n",
555 Result);
556 goto error;
557 }
558 if (NbBoards == 0) {
559 log_msg(LOG_LEVEL_ERROR, "[DELTACAST] No DELTA board detected, exiting...\n");
560 goto error;
561 }
562
563 if(BrdId >= NbBoards) {
564 log_msg(LOG_LEVEL_ERROR, "[DELTACAST] Wrong index %" PRIu_ULONG ". Found %" PRIu_ULONG " cards.\n", BrdId, NbBoards);
565 goto error;
566 }
567
568 /* Open a handle on first DELTA-hd/sdi/codec board */
569 Result = VHD_OpenBoardHandle(BrdId,&s->BoardHandle,NULL,0);
570 if (Result != VHDERR_NOERROR)
571 {
572 log_msg(LOG_LEVEL_ERROR, "[DELTACAST] ERROR : Cannot open DELTA board %" PRIu_ULONG " handle. Result = 0x%08" PRIX_ULONG "\n", BrdId, Result);
573 goto error;
574 }
575 VHD_GetBoardProperty(s->BoardHandle, VHD_CORE_BP_BOARD_TYPE, &s->BoardType);
576 if (s->BoardType != VHD_BOARDTYPE_DVI && s->BoardType != VHD_BOARDTYPE_HDMI) {
577 log_msg(LOG_LEVEL_ERROR, "[DELTACAST] ERROR : The selected board is not an DVI or HDMI one\n");
578 goto bad_channel;
579 }
580
581 switch(channel) {
582 case 0:
583 ChannelId = VHD_ST_RX0;
584 break;
585 case 1:
586 ChannelId = VHD_ST_RX1;
587 break;
588 case 2:
589 ChannelId = VHD_ST_RX2;
590 break;
591 case 3:
592 ChannelId = VHD_ST_RX3;
593 break;
594 default:
595 log_msg(LOG_LEVEL_ERROR, "[DELTACAST] Bad channel index!\n");
596 goto no_stream;
597 }
598 Result = VHD_OpenStreamHandle(s->BoardHandle, ChannelId,
599 s->BoardType == VHD_BOARDTYPE_HDMI ? VHD_DV_STPROC_JOINED : VHD_DV_STPROC_DEFAULT,
600 NULL, &s->StreamHandle, NULL);
601 if (Result != VHDERR_NOERROR)
602 {
603 log_msg(LOG_LEVEL_ERROR, "ERROR : Cannot open RX0 stream on DELTA-DVI board handle. "
604 "Result = 0x%08" PRIX_ULONG "\n", Result);
605 goto no_stream;
606 }
607
608 /* Configure color space reception (RGBA for no color-space conversion) */
610 Packing = ug_delta_codec_mapping.at(s->codec);
611 } else {
612 log_msg(LOG_LEVEL_ERROR, "Unknown pixel formate entered.\n");
613 goto no_format;
614 }
615
616 Result = VHD_SetStreamProperty(s->StreamHandle,VHD_CORE_SP_BUFFER_PACKING,
617 Packing);
618 if(Result != VHDERR_NOERROR) {
619 log_msg(LOG_LEVEL_ERROR, "Unable to set packing format.\n");
620 goto no_format;
621 }
622 VHD_SetStreamProperty(s->StreamHandle,VHD_CORE_SP_TRANSFER_SCHEME,
623 VHD_TRANSFER_SLAVED);
624
625 Result = VHD_SetStreamProperty(s->StreamHandle, VHD_CORE_SP_BUFFERQUEUE_DEPTH,
627 if(Result != VHDERR_NOERROR) {
628 log_msg(LOG_LEVEL_ERROR, "[Delta-dvi] Warning: Unable to set buffer queue length.\n");
629 }
630
631 if(have_dvi_a_format) {
632 DviMode = VHD_DV_MODE_DVI_A;
633 } else {
634 if (edid_preset >= 0 && edid_preset < NB_VHD_DV_EEDID_PRESET) {
635 VHD_PresetEEDID((VHD_DV_EEDID_PRESET)edid_preset,pEEDIDBuffer,256);
636 VHD_LoadEEDID(s->StreamHandle,pEEDIDBuffer,256);
637 }
638 if (have_custom_edid) {
639 VHD_LoadEEDID(s->StreamHandle,pEEDIDBuffer,pEEDIDBufferSize);
640 }
641 /* Read EEDID and check its validity */
642 Result = VHD_ReadEEDID(s->BoardHandle,VHD_ST_RX0,pEEDIDBuffer,&pEEDIDBufferSize);
643 if(Result == VHDERR_NOTIMPLEMENTED || CheckEEDID(pEEDIDBuffer) == BADEEDID)
644 {
645 /* Propose edid preset to user and load */
646 log_msg(LOG_LEVEL_ERROR, "\nNo valid EEDID detected or DELTA-dvi board V1.\n");
647 log_msg(LOG_LEVEL_ERROR, "Please set it as a command-line option.\n");
648 goto no_format;
649 }
650 }
651
652 s->configured = wait_for_channel_locked(s, have_dvi_a_format, DviMode, Width, Height, RefreshRate);
653 if(!s->configured &&
654 have_dvi_a_format) {
655 log_msg(LOG_LEVEL_ERROR, "Unable to set preset format!\n");
656 goto no_format;
657 }
658
659 gettimeofday(&s->t0, NULL);
660 s->frames = 0;
661
662 *state = s;
663 return VIDCAP_INIT_OK;
664
665no_format:
666 /* Close stream handle */
667 VHD_CloseStreamHandle(s->StreamHandle);
668
669no_stream:
670
671 /* Re-establish RX0-TX0 by-pass relay loopthrough */
672 VHD_SetBoardProperty(s->BoardHandle,VHD_CORE_BP_BYPASS_RELAY_0,TRUE);
673bad_channel:
674 VHD_CloseBoardHandle(s->BoardHandle);
675error:
676 free(tmp);
677 delete s;
678 return VIDCAP_INIT_FAIL;
679}
codec_t get_codec_from_name(const char *name)
#define PRIu_ULONG
#define DEFAULT_BUFFERQUEUE_DEPTH
static bool load_custom_edid(const char *filename, BYTE *pEEDIDBuffer, ULONG *pEEDIDBufferSize)
static decltype(EEDDIDOK) CheckEEDID(BYTE pEEDIDBuffer[256])
static const unordered_map< codec_t, ULONG, hash< int > > ug_delta_codec_mapping
static void usage(void)
#define VIDCAP_INIT_NOERR
state not initialized, other action performed (typically help)
#define VIDCAP_INIT_OK
initialization successful
#define VIDCAP_INIT_FAIL
error ocured
#define VIDCAP_INIT_AUDIO_NOT_SUPPORTED
card does not support audio
Definition hd-rum.c:27
@ VIDEO_CODEC_NONE
dummy color spec
Definition types.h:66
@ BGR
8-bit BGR
Definition types.h:88
const char * vidcap_params_get_fmt(const struct vidcap_params *params)
unsigned int vidcap_params_get_flags(const struct vidcap_params *params)
#define VIDCAP_FLAG_AUDIO_ANY

References BADEEDID, BGR, vidcap_deltacast_dvi_state::BoardHandle, vidcap_deltacast_dvi_state::BoardType, CheckEEDID(), vidcap_deltacast_dvi_state::codec, vidcap_deltacast_dvi_state::configured, DEFAULT_BUFFERQUEUE_DEPTH, vidcap_deltacast_dvi_state::frames, get_codec_from_name(), load_custom_edid(), LOG_LEVEL_ERROR, log_msg(), PRIu_ULONG, PRIX_ULONG, state, vidcap_deltacast_dvi_state::StreamHandle, vidcap_deltacast_dvi_state::t0, TRUE, ug_delta_codec_mapping, usage(), VIDCAP_FLAG_AUDIO_ANY, VIDCAP_INIT_AUDIO_NOT_SUPPORTED, VIDCAP_INIT_FAIL, VIDCAP_INIT_NOERR, VIDCAP_INIT_OK, vidcap_params_get_flags(), vidcap_params_get_fmt(), VIDEO_CODEC_NONE, and wait_for_channel_locked().

Here is the call graph for this function:

◆ vidcap_deltacast_dvi_probe()

static void vidcap_deltacast_dvi_probe ( device_info ** available_cards,
int * count,
void(** deleter )(void *) )
static

Definition at line 175 of file deltacast_dvi.cpp.

176{
177 *deleter = free;
178 *count = 0;
179 *available_cards = nullptr;
180
181 ULONG Result,DllVersion,NbBoards;
182 Result = VHD_GetApiInfo(&DllVersion,&NbBoards);
183 if (Result != VHDERR_NOERROR) {
184 return;
185 }
186
187 *available_cards = (struct device_info *) calloc(NbBoards, sizeof(struct device_info));
188 *count = NbBoards;
189 for (ULONG i = 0; i < NbBoards; ++i) {
190 string board{"Unknown board type"};
191 ULONG BoardType;
192 HANDLE BoardHandle = NULL;
193 Result = VHD_OpenBoardHandle(i, &BoardHandle, NULL, 0);
194 VHD_GetBoardProperty(BoardHandle, VHD_CORE_BP_BOARD_TYPE, &BoardType);
195 if (Result == VHDERR_NOERROR)
196 {
197 auto it = board_type_map.find(BoardType);
198 if (it != board_type_map.end()) {
199 board = it->second;
200 }
201 }
202 VHD_CloseBoardHandle(BoardHandle);
203
204 auto& card = (*available_cards)[i];
205 snprintf(card.dev, sizeof card.dev, ":device=%" PRIu_ULONG, i);
206 snprintf(card.name, sizeof card.name, "DELTACAST %s #%" PRIu_ULONG,
207 board.c_str(), i);
208 }
209}
int void(** deleter)(void *))
static std::unordered_map< ULONG, std::string > board_type_map
int count
Definition hd-rum.c:44

References board_type_map, count, deleter, and PRIu_ULONG.

◆ wait_for_channel_locked()

static bool wait_for_channel_locked ( struct vidcap_deltacast_dvi_state * s,
bool have_dvi_a_format,
VHD_DV_MODE DviMode,
ULONG Width,
ULONG Height,
ULONG RefreshRate )
static

Definition at line 211 of file deltacast_dvi.cpp.

214{
215 BOOL32 Interlaced_B = FALSE;
216 ULONG Result = VHDERR_NOERROR;
217
218 struct timeval t0, t;
219
220 gettimeofday(&t0, NULL);
221
222 if(!have_dvi_a_format) {
223 /* Wait for channel locked */
224 printf("Waiting for incoming signal...\n");
225 do
226 {
227 Result = VHD_GetStreamProperty(s->StreamHandle, VHD_DV_SP_MODE, (ULONG *) &DviMode);
228 gettimeofday(&t, NULL);
229 if(tv_diff(t, t0) > 1.0) break;
230 } while (Result != VHDERR_NOERROR);
231
232 if(Result != VHDERR_NOERROR)
233 return false;
234 }
235
236 printf("\nIncoming Dvi mode detected: ");
237 switch(DviMode)
238 {
239 case VHD_DV_MODE_DVI_D : printf("DVI-D\n");break;
240 case VHD_DV_MODE_DVI_A : printf("DVI-A\n");break;
241 case VHD_DV_MODE_ANALOG_COMPONENT_VIDEO : printf("Analog component video\n");break;
242 case VHD_DV_MODE_HDMI : printf("HDMI\n");break;
243 default : break;
244 }
245
246 /* Disable EDID auto load */
247 Result = VHD_SetStreamProperty(s->StreamHandle,VHD_DV_SP_DISABLE_EDID_AUTO_LOAD,TRUE);
248 if(Result != VHDERR_NOERROR)
249 return false;
250
251 /* Set the DVI mode of this channel to the detected one */
252 Result = VHD_SetStreamProperty(s->StreamHandle,VHD_DV_SP_MODE, DviMode);
253 if(Result != VHDERR_NOERROR)
254 return false;
255
256 if(DviMode == VHD_DV_MODE_DVI_A)
257 {
258 VHD_DV_DVI_A_STANDARD DviAStd = VHD_DV_DVIA_STD_DMT;
259 if(!have_dvi_a_format) {
260 /* Auto-detection is now available for DVI-A.
261 VHD_DVI_SP_ACTIVE_HEIGHT, VHD_DVI_SP_INTERLACED, VHD_DVI_SP_REFRESH_RATE,
262 VHD_DVI_SP_PIXEL_CLOCK, VHD_DVI_SP_TOTAL_WIDTH, VHD_DVI_SP_TOTAL_HEIGHT,
263 VHD_DVI_SP_H_SYNC, VHD_DVI_SP_H_FRONT_PORCH, VHD_DVI_SP_V_SYNC and
264 VHD_DVI_SP_V_FRONT_PORCH properties are required for DVI-A but
265 the VHD_PresetDviAStreamProperties is a helper function to set all these
266 properties according to a resolution, a refresh rate and a graphic timing
267 standard. Manual setting or overriding of these properties is allowed
268 Resolution, refresh rate and graphic timing standard can be auto-detect
269 with VHD_DetectDviAFormat function */
270#if ! defined DELTA_DVI_DEPRECATED
271 Result = VHD_DetectDviAFormat(s->StreamHandle,&DviAStd,&Width,&Height,&RefreshRate,
272 &Interlaced_B);
273#else
274 Result = VHDERR_NOTIMPLEMENTED; // VHD_DetectDviAFormat was removed in v6.14
275#endif
276 }
277 if(Result == VHDERR_NOERROR)
278 {
279 printf("\nDVI-A format detected: %" PRIu_ULONG "x%" PRIu_ULONG " @%" PRIu_ULONG "Hz (%s)\n", Width, Height, RefreshRate, Interlaced_B ? "Interlaced" : "Progressive");
280 Result = VHD_PresetDviAStreamProperties(s->StreamHandle, DviAStd,Width,Height,
281 RefreshRate,Interlaced_B);
282 if(Result != VHDERR_NOERROR) {
283 printf("ERROR : Cannot set incoming DVI-A format. Result = 0x%08" PRIX_ULONG "\n", Result);
284 }
285 }
286 else {
287 printf("ERROR : Cannot detect incoming DVI-A format. Result = 0x%08" PRIX_ULONG ". Use 'preset=' option.\n", Result);
288 return false;
289 }
290 }
291 else if(DviMode == VHD_DV_MODE_DVI_D)
292 {
293 int Dual_B = FALSE;
294 /* Get auto-detected resolution */
295 Result = VHD_GetStreamProperty(s->StreamHandle,VHD_DV_SP_ACTIVE_WIDTH,&Width);
296 if(Result == VHDERR_NOERROR)
297 Result = VHD_GetStreamProperty(s->StreamHandle,VHD_DV_SP_ACTIVE_HEIGHT,&Height);
298 else
299 printf("ERROR : Cannot detect incoming active width from RX0. "
300 "Result = 0x%08" PRIX_ULONG "\n", Result);
301 if(Result == VHDERR_NOERROR)
302 Result = VHD_GetStreamProperty(s->StreamHandle,VHD_DV_SP_INTERLACED,(ULONG*)&Interlaced_B);
303 else
304 printf("ERROR : Cannot detect incoming active height from RX0. "
305 "Result = 0x%08" PRIX_ULONG "\n", Result);
306 if(Result == VHDERR_NOERROR)
307 Result = VHD_GetStreamProperty(s->StreamHandle,VHD_DV_SP_REFRESH_RATE,&RefreshRate);
308 else
309 printf("ERROR : Cannot detect if incoming stream from RX0 is "
310 "interlaced or progressive. Result = 0x%08" PRIX_ULONG "\n", Result);
311 if(Result == VHDERR_NOERROR)
312 Result = VHD_GetStreamProperty(s->StreamHandle,VHD_DV_SP_DUAL_LINK,(ULONG*)&Dual_B);
313 else
314 printf("ERROR : Cannot detect incoming refresh rate from RX0. "
315 "Result = 0x%08" PRIX_ULONG "\n", Result);
316
317 if(Result == VHDERR_NOERROR)
318 printf("\nIncoming graphic resolution : %" PRIu_ULONG "x%" PRIu_ULONG " @%" PRIu_ULONG "Hz (%s) %s link\n", Width, Height, RefreshRate, Interlaced_B ? "Interlaced" : "Progressive", Dual_B ? "Dual" : "Single");
319 else
320 printf("ERROR : Cannot detect if incoming stream from RX0 is dual or simple link. Result = 0x%08" PRIX_ULONG "\n", Result);
321
322 if(Result != VHDERR_NOERROR) {
323 return false;
324 }
325
326 /* Configure stream. Only VHD_DVI_SP_ACTIVE_WIDTH, VHD_DVI_SP_ACTIVE_HEIGHT and
327 VHD_DVI_SP_INTERLACED properties are required for DVI-D.
328 VHD_DVI_SP_REFRESH_RATE,VHD_DVI_SP_DUAL_LINK are optional
329 VHD_DVI_SP_PIXEL_CLOCK, VHD_DVI_SP_TOTAL_WIDTH, VHD_DVI_SP_TOTAL_HEIGHT,
330 VHD_DVI_SP_H_SYNC, VHD_DVI_SP_H_FRONT_PORCH, VHD_DVI_SP_V_SYNC and
331 VHD_DVI_SP_V_FRONT_PORCH properties are not applicable for DVI-D */
332
333 VHD_SetStreamProperty(s->StreamHandle,VHD_DV_SP_ACTIVE_WIDTH,Width);
334 VHD_SetStreamProperty(s->StreamHandle,VHD_DV_SP_ACTIVE_HEIGHT,Height);
335 VHD_SetStreamProperty(s->StreamHandle,VHD_DV_SP_INTERLACED,Interlaced_B);
336 VHD_SetStreamProperty(s->StreamHandle,VHD_DV_SP_REFRESH_RATE,RefreshRate);
337 VHD_SetStreamProperty(s->StreamHandle,VHD_DV_SP_DUAL_LINK,Dual_B);
338 }
339 else if(DviMode == VHD_DV_MODE_HDMI || DviMode == VHD_DV_MODE_ANALOG_COMPONENT_VIDEO)
340 {
341 VHD_DV_CS InputCS;
342 ULONG PxlClk = 0;
343 /* Get auto-detected resolution */
344 Result = VHD_GetStreamProperty(s->StreamHandle,VHD_DV_SP_ACTIVE_WIDTH,&Width);
345 if(Result == VHDERR_NOERROR)
346 Result = VHD_GetStreamProperty(s->StreamHandle,VHD_DV_SP_ACTIVE_HEIGHT,&Height);
347 else
348 printf("ERROR : Cannot detect incoming active width from RX0. "
349 "Result = 0x%08" PRIX_ULONG "\n", Result);
350 if(Result == VHDERR_NOERROR)
351 Result = VHD_GetStreamProperty(s->StreamHandle,VHD_DV_SP_INTERLACED,(ULONG*)&Interlaced_B);
352 else
353 printf("ERROR : Cannot detect incoming active height from RX0. "
354 "Result = 0x%08" PRIX_ULONG "\n", Result);
355 if(Result == VHDERR_NOERROR)
356 Result = VHD_GetStreamProperty(s->StreamHandle,VHD_DV_SP_REFRESH_RATE,&RefreshRate);
357 else
358 printf("ERROR : Cannot detect if incoming stream from RX0 is "
359 "interlaced or progressive. Result = 0x%08" PRIX_ULONG "\n", Result);
360
361 if (Result == VHDERR_NOERROR) {
362 Result = VHD_GetStreamProperty(s->StreamHandle,VHD_DV_SP_REFRESH_RATE,&RefreshRate);
363 if(s->BoardType == VHD_BOARDTYPE_HDMI)
364 Result = VHD_GetStreamProperty(s->StreamHandle,VHD_DV_SP_INPUT_CS,(ULONG*)&InputCS);
365 else
366 printf("ERROR : Cannot detect incoming color space from RX0. Result = 0x%08" PRIX_ULONG " (%s)\n", Result,
368 }
369
370 if (Result == VHDERR_NOERROR) {
371 if (s->BoardType == VHD_BOARDTYPE_HDMI)
372 Result = VHD_GetStreamProperty(s->StreamHandle,VHD_DV_SP_PIXEL_CLOCK,&PxlClk);
373 else
374 printf("ERROR : Cannot detect incoming pixel clock from RX0. Result = 0x%08" PRIX_ULONG " (%s)\n", Result,
376 }
377
378 if(Result == VHDERR_NOERROR)
379 printf("\nIncoming graphic resolution : %" PRIu_ULONG "x%" PRIu_ULONG " @%" PRIu_ULONG "Hz (%s)\n", Width, Height, RefreshRate, Interlaced_B ? "Interlaced" : "Progressive");
380 else
381 printf("ERROR : Cannot detect incoming refresh rate from RX0. "
382 "Result = 0x%08" PRIX_ULONG "\n", Result);
383
384 if(Result != VHDERR_NOERROR) {
385 return false;
386 }
387
388 /* Configure stream. Only VHD_DVI_SP_ACTIVE_WIDTH, VHD_DVI_SP_ACTIVE_HEIGHT and
389 VHD_DVI_SP_INTERLACED properties are required for HDMI and Component
390 VHD_DVI_SP_PIXEL_CLOCK, VHD_DVI_SP_TOTAL_WIDTH, VHD_DVI_SP_TOTAL_HEIGHT,
391 VHD_DVI_SP_H_SYNC, VHD_DVI_SP_H_FRONT_PORCH, VHD_DVI_SP_V_SYNC and
392 VHD_DVI_SP_V_FRONT_PORCH properties are not applicable for DVI-D, HDMI and Component */
393
394 VHD_SetStreamProperty(s->StreamHandle,VHD_DV_SP_ACTIVE_WIDTH,Width);
395 VHD_SetStreamProperty(s->StreamHandle,VHD_DV_SP_ACTIVE_HEIGHT,Height);
396 VHD_SetStreamProperty(s->StreamHandle,VHD_DV_SP_INTERLACED,Interlaced_B);
397 VHD_SetStreamProperty(s->StreamHandle,VHD_DV_SP_REFRESH_RATE, RefreshRate);
398 if (s->BoardType == VHD_BOARDTYPE_HDMI) {
399 VHD_SetStreamProperty(s->StreamHandle,VHD_DV_SP_INPUT_CS, InputCS);
400 VHD_SetStreamProperty(s->StreamHandle,VHD_DV_SP_PIXEL_CLOCK, PxlClk);
401 }
402 }
403
404 Result = VHD_StartStream(s->StreamHandle);
405
406 if(Result != VHDERR_NOERROR) {
407 log_msg(LOG_LEVEL_ERROR, "Cannot start stream!\n");
408 return false;
409 }
410
411 s->desc.color_spec = s->codec;
412 s->desc.width = Width;
413 s->desc.height = Height;
414 s->desc.fps = RefreshRate;
415 s->desc.interlacing = Interlaced_B ? LOWER_FIELD_FIRST : PROGRESSIVE;
416 s->desc.tile_count = 1;
417
418 return true;
419}
#define FALSE
static const char * delta_get_error_description(ULONG CodeError) __attribute__((unused))
unsigned int tile_count
Definition types.h:185
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
@ LOWER_FIELD_FIRST
First stored field is bottom, followed by top.
Definition types.h:166
@ PROGRESSIVE
progressive frame
Definition types.h:164

References vidcap_deltacast_dvi_state::BoardType, vidcap_deltacast_dvi_state::codec, video_desc::color_spec, delta_get_error_description(), vidcap_deltacast_dvi_state::desc, FALSE, video_desc::fps, video_desc::height, video_desc::interlacing, LOG_LEVEL_ERROR, log_msg(), LOWER_FIELD_FIRST, PRIu_ULONG, PRIX_ULONG, PROGRESSIVE, vidcap_deltacast_dvi_state::StreamHandle, video_desc::tile_count, TRUE, tv_diff(), and video_desc::width.

Referenced by vidcap_deltacast_dvi_grab(), and vidcap_deltacast_dvi_init().

Here is the call graph for this function:

Variable Documentation

◆ edid_presets

const map<VHD_DV_EEDID_PRESET, const char *> edid_presets
static
Initial value:
= {
{ VHD_DV_EEDID_EMPTY, "empty E-EDID - the host should force its output regardless of the DELTA-dvi E-EDID" },
{ VHD_DV_EEDID_DVIA, "DVI-A E-EDID" },
{ VHD_DV_EEDID_DVID, "DVI-D E-EDID" },
{ VHD_DV_EEDID_HDMI, "HDMI E-EDID" },
{ VHD_DV_EEDID_DVID_DUAL, "DVI-D E-EDID with dual-link formats" },
{ VHD_DV_EEDID_HDMI_H4K, "HDMI H4K E-EDID" },
{ VHD_DV_EEDID_DVID_H4K, "DVI-D H4K E-EDID" },
{ VHD_DV_EEDID_HDMI_H4K2, "HDMI H4K2 E-EDID" },
{ VHD_DV_EEDID_DVID_H4K2, "DVI-D H4K2 E-EDID" },
{ VHD_DV_EEDID_DISPLAYPORT_1_2, "DisplayPort 1.2 E-EDID" },
{ VHD_DV_EEDID_HDMI_FLEX_HMI, "HDMI FLEX-HMI E-EDID" },
{ VHD_DV_EEDID_DVID_FLEX_HMI, "DVI-D FLEX-HMI E-EDID" },
{ (VHD_DV_EEDID_PRESET) -1, "avoid E-EDID loading" },
}

Definition at line 109 of file deltacast_dvi.cpp.

109 {
110 { VHD_DV_EEDID_EMPTY, "empty E-EDID - the host should force its output regardless of the DELTA-dvi E-EDID" },
111 { VHD_DV_EEDID_DVIA, "DVI-A E-EDID" },
112 { VHD_DV_EEDID_DVID, "DVI-D E-EDID" },
113 { VHD_DV_EEDID_HDMI, "HDMI E-EDID" },
114 { VHD_DV_EEDID_DVID_DUAL, "DVI-D E-EDID with dual-link formats" },
115 { VHD_DV_EEDID_HDMI_H4K, "HDMI H4K E-EDID" },
116 { VHD_DV_EEDID_DVID_H4K, "DVI-D H4K E-EDID" },
117 { VHD_DV_EEDID_HDMI_H4K2, "HDMI H4K2 E-EDID" },
118 { VHD_DV_EEDID_DVID_H4K2, "DVI-D H4K2 E-EDID" },
119 { VHD_DV_EEDID_DISPLAYPORT_1_2, "DisplayPort 1.2 E-EDID" },
120 { VHD_DV_EEDID_HDMI_FLEX_HMI, "HDMI FLEX-HMI E-EDID" },
121 { VHD_DV_EEDID_DVID_FLEX_HMI, "DVI-D FLEX-HMI E-EDID" },
122 { (VHD_DV_EEDID_PRESET) -1, "avoid E-EDID loading" },
123};

Referenced by usage().

◆ ug_delta_codec_mapping

const unordered_map<codec_t, ULONG, hash<int> > ug_delta_codec_mapping
static
Initial value:
= {
{ BGR, VHD_BUFPACK_VIDEO_RGB_24 },
{ RGBA, VHD_BUFPACK_VIDEO_RGBA_32 },
{ UYVY, VHD_BUFPACK_VIDEO_YUV422_8 },
{ v210, VHD_BUFPACK_VIDEO_YUV422_10 },
}
@ UYVY
YCbCr 422 8-bit - Cb Y0 Cr Y1.
Definition types.h:71
@ v210
YCbCr 422 10-bit - xVY0U|xY2UY1|xUY3V|xY5VY4, little-endian (2 bit padding /'x'/),...
Definition types.h:75

Definition at line 421 of file deltacast_dvi.cpp.

421 {
422 { BGR, VHD_BUFPACK_VIDEO_RGB_24 },
423 { RGBA, VHD_BUFPACK_VIDEO_RGBA_32 },
424 { UYVY, VHD_BUFPACK_VIDEO_YUV422_8 },
425 { v210, VHD_BUFPACK_VIDEO_YUV422_10 },
426};

Referenced by vidcap_deltacast_dvi_init().

◆ vidcap_deltacast_dvi_info

const struct video_capture_info vidcap_deltacast_dvi_info
static
Initial value:
= {
}
static int vidcap_deltacast_dvi_init(struct vidcap_params *params, void **state)
static struct video_frame * vidcap_deltacast_dvi_grab(void *state, struct audio_frame **audio)
static void vidcap_deltacast_dvi_probe(device_info **available_cards, int *count, void(**deleter)(void *))
static void vidcap_deltacast_dvi_done(void *state)
#define VIDCAP_NO_GENERIC_FPS_INDICATOR

Definition at line 796 of file deltacast_dvi.cpp.