UltraGrid
UltraGrid Low-Latency High-Resolution Transmission System
Loading...
Searching...
No Matches
aja.cpp File Reference
#include "config_msvc.h"
#include "config_unix.h"
#include "config_win32.h"
#include "debug.h"
#include <algorithm>
#include <chrono>
#include <condition_variable>
#include <cstdint>
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <iostream>
#include <memory>
#include <mutex>
#include <sstream>
#include <stdexcept>
#include <string>
#include <thread>
#include <unordered_map>
#include <utility>
#include "audio/types.h"
#include "audio/utils.h"
#include "host.h"
#include "lib_common.h"
#include "utils/video_frame_pool.h"
#include "video.h"
#include "video_capture.h"
#include "ajatypes.h"
#include <ajantv2/includes/ntv2rp188.h>
#include "ntv2devicescanner.h"
#include "ajabase/common/types.h"
#include "ajabase/common/videotypes.h"
#include "ajabase/common/circularbuffer.h"
#include "ajabase/system/process.h"
#include "ajabase/system/systemtime.h"
#include "ajabase/system/thread.h"
#include "ntv2utils.h"
#include "ntv2devicefeatures.h"
#include "aja_common.hpp"
Include dependency graph for aja.cpp:

Go to the source code of this file.

Classes

struct  aligned_data_allocator
 
class  vidcap_state_aja
 
struct  vidcap_state_aja::mAudio
 

Macros

#define CHECK(cmd)
 
#define CHECK_OK(cmd, msg, action_failed)
 
#define CHECK_RET_FAIL(cmd)
 
#define LINK_SPEC   static
 
#define MOD_NAME   "[AJA cap.] "
 
#define NOOP   ((void)0)
 
#define NTV2_AUDIOSIZE_MAX   (401 * 1024)
 

Functions

 ADD_TO_PARAM ("aja-fourcc", "* aja-fourcc\n" " Specifies application FourCC for AJA.\n")
 
 REGISTER_MODULE (aja, &vidcap_aja_info, LIBRARY_CLASS_VIDEO_CAPTURE, VIDEO_CAPTURE_ABI_VERSION)
 
static void show_help ()
 
LINK_SPEC void vidcap_aja_done (void *state)
 
LINK_SPEC struct video_frame * vidcap_aja_grab (void *state, struct audio_frame **audio)
 
LINK_SPEC int vidcap_aja_init (struct vidcap_params *params, void **state)
 
LINK_SPEC void vidcap_aja_probe (device_info **available_cards, int *count, void(**deleter)(void *))
 

Variables

unsigned int * aja_audio_capture_channels = &audio_capture_channels
 
static const ULWord app = AJA_FOURCC ('U','L','G','R')
 
static const struct video_capture_info vidcap_aja_info
 

Detailed Description

Author
Martin Pulec pulec.nosp@m.@ces.nosp@m.net.c.nosp@m.z

Based on AJA samples ntv2framegrabber, ntv2capture and ntv2llburn (Ping-Pong)

Todo
Capture what is on the wire (RGB if RGB, YCbCr otherwise)

Definition in file aja.cpp.

Macro Definition Documentation

◆ CHECK

◆ CHECK_OK

#define CHECK_OK ( cmd,
msg,
action_failed )
Value:
do { bool ret = cmd; if (!ret) {\
LOG(LOG_LEVEL_WARNING) << MOD_NAME << (msg) << "\n";\
action_failed;\
}\
} while(0)
#define LOG_LEVEL_WARNING
less severe errors
Definition debug.h:60
struct msghdr msg
#define MOD_NAME
Definition aja.cpp:110

Definition at line 127 of file aja.cpp.

127#define CHECK_OK(cmd, msg, action_failed) do { bool ret = cmd; if (!ret) {\
128 LOG(LOG_LEVEL_WARNING) << MOD_NAME << (msg) << "\n";\
129 action_failed;\
130}\
131} while(0)

Referenced by vidcap_state_aja::Init(), vidcap_state_aja::SetupAudio(), and vidcap_state_aja::SetupVideo().

◆ CHECK_RET_FAIL

#define CHECK_RET_FAIL ( cmd)
Value:
CHECK_OK(cmd, #cmd " failed", return AJA_STATUS_FAIL)

Definition at line 134 of file aja.cpp.

Referenced by vidcap_state_aja::SetupHDMI().

◆ LINK_SPEC

#define LINK_SPEC   static

Definition at line 124 of file aja.cpp.

◆ MOD_NAME

◆ NOOP

#define NOOP   ((void)0)

◆ NTV2_AUDIOSIZE_MAX

#define NTV2_AUDIOSIZE_MAX   (401 * 1024)

Function Documentation

◆ ADD_TO_PARAM()

ADD_TO_PARAM ( "aja-fourcc" ,
"* aja-fourcc\n" " Specifies application FourCC for AJA.\n"  )

◆ REGISTER_MODULE()

REGISTER_MODULE ( aja ,
& vidcap_aja_info,
LIBRARY_CLASS_VIDEO_CAPTURE ,
VIDEO_CAPTURE_ABI_VERSION  )

◆ show_help()

static void show_help ( void )
static

Definition at line 992 of file aja.cpp.

992 {
993 col() << "Usage:\n";
994 col() << SBOLD(SRED("\t-t aja") << "[[:4K][:clear-routing][:channel=<ch>][:codec=<pixfmt>][:connection=<c>][:device=<idx>][:format=<fmt>][:progressive][:RGB|:YUV]|:help] -r [embedded|AESEBU|analog]")"\n";
995 col() << "where\n";
996
997 col() << SBOLD("\t4K") << "\n";
998 col() << "\t\tVideo input is 4K.\n";
999
1000 col() << SBOLD("\tclear-routing") "\n" <<
1001 "\t\tremove all existing signal paths for device\n";
1002
1003 col() << SBOLD("\tchannel") "\n";
1004 col() << "\t\tChannel number to use (indexed from 1). Doesn't need to "
1005 "be set for SDI, useful for HDMI (capture and display should "
1006 "have different channel numbers if both used, also other than "
1007 "1 if SDI1 is in use).\n";
1008
1009 col() << SBOLD("\tconnection") "\n" <<
1010 "\t\tConnection can be one of: ";
1011 NTV2InputSource source = NTV2InputSource();
1012 while (source != NTV2_INPUTSOURCE_INVALID) {
1013 if (source > 0) {
1014 col() << ", ";
1015 }
1016 col() << NTV2InputSourceToString(source, true);
1017 // should be this, but GetNTV2InputSourceForIndex knows only SDIs
1018 //source = ::GetNTV2InputSourceForIndex(::GetIndexForNTV2InputSource(source) + 1);
1019 source = (NTV2InputSource) ((int) source + 1);
1020 }
1021 col() << "\n";
1022
1023 col() << SBOLD("\tprogressive") "\n";
1024 col() << "\t\tVideo input is progressive.\n";
1025
1026 col() << SBOLD("\tRGB|YUV") "\n";
1027 col() << "\t\tSet SDI video input to RGB or YCbCr explicitly. If "
1028 "capture pixel format is set, expect the same encoding on "
1029 "input. You can override this setting by specifying the "
1030 "signal color space explicitly by this option (see "
1031 "https://github.com/CESNET/UltraGrid/wiki/"
1032 "Device-Settings#RGB_over_SDI for details).\n";
1033 col() << "\n";
1034
1035 printf("Available devices:\n");
1036 CNTV2DeviceScanner deviceScanner;
1037 for (unsigned int i = 0; i < deviceScanner.GetNumDevices (); i++) {
1038 CNTV2Card device;
1039 if (!CNTV2DeviceScanner::GetDeviceAtIndex(i, device)) {
1040 MSG(WARNING, "Cannot get device at index #%u!\n", i);
1041 continue;
1042 }
1043
1044 col() << "\t" << SBOLD(i) << ") "
1045 << SBOLD(device.GetDisplayName());
1046 print_aja_device_details(&device);
1047 const NTV2DeviceID deviceID = device.GetBaseDeviceID();
1048 NTV2VideoFormatSet fmt_set;
1049 if (NTV2DeviceGetSupportedVideoFormats(deviceID, fmt_set)) {
1050 col() << SUNDERLINE("\tAvailable formats:");
1051 for (auto fmt : fmt_set) {
1052 if (fmt != *fmt_set.begin()) {
1053 col()<< ",";
1054 }
1055 col() << " \"" << NTV2VideoFormatToString(fmt)
1056 << "\"";
1057 }
1058 col() << "\n";
1059 }
1060 NTV2FrameBufferFormatSet pix_fmts;
1061 if (NTV2DeviceGetSupportedPixelFormats(deviceID, pix_fmts)) {
1062 if (pix_fmts.count(NTV2_FBF_10BIT_YCBCR) == 0 && NTV2DeviceCanDoFrameBufferFormat(deviceID, NTV2_FBF_10BIT_YCBCR)) {
1063 pix_fmts.insert(NTV2_FBF_10BIT_YCBCR); // workaround NTV2 bug
1064 }
1065 col() << SUNDERLINE("\tAvailable pixel formats:");
1066 for (auto fmt : pix_fmts) {
1067 if (fmt != *pix_fmts.begin()) {
1068 col() << ",";
1069 }
1070 if (ugaja::codec_map.find(fmt) ==
1071 ugaja::codec_map.end()) {
1072 col() << " "
1073 << NTV2FrameBufferFormatToString(
1074 fmt)
1075 << " (unsupported)";
1076 } else {
1077 col() << " "
1078 << get_codec_name(
1079 ugaja::codec_map.at(fmt));
1080 }
1081 }
1082 col() << "\n";
1083 }
1084 col() << SUNDERLINE("\tNumber of frame stores: ") << NTV2DeviceGetNumFrameStores (deviceID) << "\n";
1085 }
1086 if (deviceScanner.GetNumDevices() == 0) {
1087 col() << SUNDERLINE("\tno devices found") "\n";
1088 }
1089 col() << "\n";
1090}
void print_aja_device_details(CNTV2Card *device)
const char * fmt
const char * get_codec_name(codec_t codec)
#define SRED(x)
Definition color_out.h:85
#define SBOLD(x)
Definition color_out.h:80
#define SUNDERLINE(x)
Definition color_out.h:81
#define MSG(l, fmt,...)
Definition debug.h:96
static const std::map< NTV2FrameBufferFormat, codec_t > codec_map
Definition rtp.c:206

References ultragrid::aja::codec_map, fmt, get_codec_name(), MSG, print_aja_device_details(), SBOLD, SRED, and SUNDERLINE.

Referenced by vidcap_aja_init().

Here is the call graph for this function:

◆ vidcap_aja_done()

LINK_SPEC void vidcap_aja_done ( void * state)

Definition at line 1131 of file aja.cpp.

1132{
1133 auto s = static_cast<vidcap_state_aja *>(state);
1134 s->Quit();
1135 delete s;
1136}
void ** state
void Quit()
Definition aja.cpp:789

References vidcap_state_aja::Quit(), and state.

Here is the call graph for this function:

◆ vidcap_aja_grab()

LINK_SPEC struct video_frame * vidcap_aja_grab ( void * state,
struct audio_frame ** audio )

Definition at line 1138 of file aja.cpp.

1139{
1140 return ((vidcap_state_aja *) state)->grab(audio);
1141}
struct audio_frame ** audio

References audio, and state.

◆ vidcap_aja_init()

LINK_SPEC int vidcap_aja_init ( struct vidcap_params * params,
void ** state )

Definition at line 1092 of file aja.cpp.

1093{
1094 unordered_map<string, string> parameters_map;
1095 char *tmp = strdup(vidcap_params_get_fmt(params));
1096 if (strcmp(tmp, "help") == 0) {
1097 show_help();
1098 free(tmp);
1099 return VIDCAP_INIT_NOERR;
1100 }
1101 char *item, *cfg = tmp;
1102 while ((item = strtok(cfg, ":"))) {
1103 char *key_cstr = item;
1104 if (strchr(item, '=')) {
1105 char *val_cstr = strchr(item, '=') + 1;
1106 *strchr(item, '=') = '\0';
1107 parameters_map[key_cstr] = val_cstr;
1108 } else {
1109 parameters_map[key_cstr] = string();
1110 }
1111 cfg = NULL;
1112 }
1113 free(tmp);
1114
1115 vidcap_state_aja *ret = nullptr;
1116 try {
1118 ret->Run();
1119 } catch (string const & s) {
1120 LOG(LOG_LEVEL_ERROR) << "[AJA cap.] " << s << "\n";
1121 delete ret;
1122 return VIDCAP_INIT_FAIL;
1123 } catch (...) {
1124 delete ret;
1125 return VIDCAP_INIT_FAIL;
1126 }
1127 *state = ret;
1128 return VIDCAP_INIT_OK;
1129}
AJAStatus Run()
Definition aja.cpp:774
#define LOG_LEVEL_ERROR
general errors
Definition debug.h:59
#define LOG(level)
Definition debug.h:313
#define VIDCAP_INIT_NOERR
state not initialized, other action performed (typically help)
#define VIDCAP_INIT_OK
initialization successful
#define VIDCAP_INIT_FAIL
error ocured
Definition hd-rum.c:27
static void show_help()
Definition aja.cpp:992
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 LOG, LOG_LEVEL_ERROR, vidcap_state_aja::Run(), show_help(), state, VIDCAP_FLAG_AUDIO_ANY, VIDCAP_INIT_FAIL, VIDCAP_INIT_NOERR, VIDCAP_INIT_OK, vidcap_params_get_flags(), and vidcap_params_get_fmt().

Referenced by vidcap_aja_init_proxy().

Here is the call graph for this function:

◆ vidcap_aja_probe()

LINK_SPEC void vidcap_aja_probe ( device_info ** available_cards,
int * count,
void(** deleter )(void *) )

Definition at line 1143 of file aja.cpp.

1144{
1145 *deleter = free;
1146
1147 device_info *cards = nullptr;
1148 int card_count = 0;
1149
1150 CNTV2DeviceScanner deviceScanner;
1151 for (unsigned int i = 0; i < deviceScanner.GetNumDevices (); i++) {
1152 CNTV2Card device;
1153 if (!CNTV2DeviceScanner::GetDeviceAtIndex(i, device)) {
1154 MSG(WARNING, "Cannot get device at index #%u!\n", i);
1155 continue;
1156 }
1157 card_count += 1;
1158 cards = (struct device_info *)
1159 realloc(cards, card_count * sizeof(struct device_info));
1160 memset(&cards[card_count - 1], 0, sizeof(struct device_info));
1161 snprintf(cards[card_count - 1].dev, sizeof cards[card_count - 1].dev,
1162 ":device=%d", i);
1163 snprintf(cards[card_count - 1].name, sizeof cards[card_count - 1].name,
1164 "AJA %s", device.GetDisplayName().c_str());
1165 snprintf(cards[card_count - 1].extra, sizeof cards[card_count - 1].extra,
1166 "\"embeddedAudioAvailable\":\"t\"");
1167 }
1168
1169 *available_cards = cards;
1170 *count = card_count;
1171}
int void(** deleter)(void *))
int count
Definition hd-rum.c:44
const char * name
Definition settings.cpp:193
char extra[1024]
Definition types.h:389
char dev[1024]
Definition types.h:383

References count, deleter, device_info::dev, device_info::extra, MSG, and name.

Variable Documentation

◆ aja_audio_capture_channels

unsigned int* aja_audio_capture_channels = &audio_capture_channels

Definition at line 118 of file aja.cpp.

Referenced by vidcap_state_aja::SetupAudio(), and vidcap_aja_init_proxy().

◆ app

const ULWord app = AJA_FOURCC ('U','L','G','R')
static

◆ vidcap_aja_info

const struct video_capture_info vidcap_aja_info
static
Initial value:
= {
}
#define VIDCAP_NO_GENERIC_FPS_INDICATOR
LINK_SPEC int vidcap_aja_init(struct vidcap_params *params, void **state)
Definition aja.cpp:1092
LINK_SPEC struct video_frame * vidcap_aja_grab(void *state, struct audio_frame **audio)
Definition aja.cpp:1138
LINK_SPEC void vidcap_aja_probe(device_info **available_cards, int *count, void(**deleter)(void *))
Definition aja.cpp:1143
LINK_SPEC void vidcap_aja_done(void *state)
Definition aja.cpp:1131

Definition at line 1174 of file aja.cpp.