videohubctrl can be used to control Blackmagic Design Videohub SDI router device over the network.
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

display.c 8.0KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283
  1. /*
  2. * === Display functions ===
  3. *
  4. * Blackmagic Design Videohub control application
  5. * Copyright (C) 2014 Unix Solutions Ltd.
  6. * Written by Georgi Chorbadzhiyski
  7. *
  8. * Released under MIT license.
  9. * See LICENSE-MIT.txt for license terms.
  10. *
  11. */
  12. #include <stdio.h>
  13. #include <string.h>
  14. #include "data.h"
  15. #include "cmd.h"
  16. #include "util.h"
  17. #include "display.h"
  18. static void printf_line(int len) {
  19. int i;
  20. printf(" ");
  21. for (i = 0; i < len; i++)
  22. printf("-");
  23. printf("\n");
  24. }
  25. static char format_status(enum port_status status) {
  26. switch (status) {
  27. case S_UNKNOWN: return ' ';
  28. case S_BNC : return 'B';
  29. case S_OPTICAL: return 'o';
  30. case S_THUNDERBOLT: return 'T';
  31. case S_NONE : return 'x';
  32. case S_RS422 : return '4'; // For serial ports
  33. }
  34. return '?';
  35. }
  36. void print_device_info(struct videohub_data *d) {
  37. int len = 67;
  38. printf("Device info\n");
  39. printf_line(len);
  40. printf(" | %-26s | %-34s |\n", "Device address", d->dev_host);
  41. printf(" | %-26s | %-34s |\n", "Device port", d->dev_port);
  42. printf(" | %-26s | %-34s |\n", "Model name", d->device.model_name);
  43. if (d->device.friendly_name[0])
  44. printf(" | %-26s | %-34s |\n", "Friendly name", d->device.friendly_name);
  45. printf(" | %-26s | %-34s |\n", "Unique ID", d->device.unique_id);
  46. printf(" | %-26s | %-34s |\n", "Protocol", d->device.protocol_ver);
  47. printf(" | %-26s | %-34u |\n", "Video inputs", d->inputs.num);
  48. printf(" | %-26s | %-34u |\n", "Video outputs", d->outputs.num);
  49. if (d->serial.num)
  50. printf(" | %-26s | %-34u |\n", "Serial ports", d->serial.num);
  51. if (d->proc_units.num)
  52. printf(" | %-26s | %-34u |\n", "Video processing units", d->proc_units.num);
  53. if (d->mon_outputs.num)
  54. printf(" | %-26s | %-34u |\n", "Video monitoring outputs", d->mon_outputs.num);
  55. printf_line(len);
  56. printf("\n");
  57. }
  58. void print_device_video_inputs(struct videohub_data *d) {
  59. unsigned int i, r, len = 70;
  60. if (!d->inputs.num)
  61. return;
  62. printf("Video inputs\n");
  63. printf_line(len);
  64. printf(" | ### | %-24s | nn | %-24s | s |\n", "Video input name", "Routed to output");
  65. printf_line(len);
  66. for(i = 0; i < d->inputs.num; i++) {
  67. unsigned int num_outputs = 0, routed_to = 0;
  68. for(r = 0; r < d->outputs.num; r++) {
  69. if (d->outputs.port[r].routed_to == i) {
  70. num_outputs++;
  71. if (num_outputs == 1)
  72. routed_to = r; // The first output
  73. }
  74. }
  75. printf(" | %3d | %-24s | %2d | ", i + 1, d->inputs.port[i].name,
  76. num_outputs);
  77. if (num_outputs == 0) {
  78. printf("%-24s | %c |\n", "-", format_status(d->inputs.port[i].status));
  79. } else {
  80. printf("%-24s | %c |\n",
  81. routed_to == NO_PORT ? "" : d->outputs.port[routed_to].name,
  82. format_status(d->inputs.port[i].status)
  83. );
  84. bool first_skipped = false;
  85. for(r = 0; r < d->outputs.num; r++) {
  86. if (d->outputs.port[r].routed_to == i) {
  87. if (!first_skipped) {
  88. first_skipped = true;
  89. continue;
  90. }
  91. printf(" | %3s | %-24s | %2s | %-24s | %c |\n",
  92. " ", " ", " ", d->outputs.port[r].name, ' ');
  93. }
  94. }
  95. }
  96. }
  97. printf_line(len);
  98. printf("\n");
  99. }
  100. static char port_lock_symbol(enum port_lock p) {
  101. switch(p) {
  102. case PORT_UNLOCKED : return ' ';
  103. case PORT_LOCKED : return 'O';
  104. case PORT_LOCKED_OTHER: return 'L';
  105. }
  106. return '?';
  107. }
  108. void print_device_video_outputs(struct videohub_data *d) {
  109. unsigned int i, len = 69;
  110. if (!d->outputs.num)
  111. return;
  112. printf("Video outputs\n");
  113. printf_line(len);
  114. printf(" | ### | x | %-24s | %-24s | s |\n", "Video output name", "Connected video input");
  115. printf_line(len);
  116. for(i = 0; i < d->outputs.num; i++) {
  117. printf(" | %3d | %c | %-24s | %-24s | %c |\n",
  118. i + 1,
  119. port_lock_symbol(d->outputs.port[i].lock),
  120. d->outputs.port[i].name,
  121. d->outputs.port[i].routed_to == NO_PORT ? "" : d->inputs.port[d->outputs.port[i].routed_to].name,
  122. format_status(d->outputs.port[i].status)
  123. );
  124. }
  125. printf_line(len);
  126. printf("\n");
  127. }
  128. void print_device_monitoring_outputs(struct videohub_data *d) {
  129. unsigned int i, len = 65;
  130. if (!d->mon_outputs.num)
  131. return;
  132. printf("Monitoring outputs\n");
  133. printf_line(len);
  134. printf(" | ### | x | %-24s | %-24s |\n", "Monitoring output name", "Connected video input");
  135. printf_line(len);
  136. for(i = 0; i < d->mon_outputs.num; i++) {
  137. printf(" | %3d | %c | %-24s | %-24s |\n",
  138. i + 1,
  139. port_lock_symbol(d->mon_outputs.port[i].lock),
  140. d->mon_outputs.port[i].name,
  141. d->mon_outputs.port[i].routed_to == NO_PORT ? "" : d->inputs.port[d->mon_outputs.port[i].routed_to].name
  142. );
  143. }
  144. printf_line(len);
  145. printf("\n");
  146. }
  147. static char *dir2opt(enum serial_dir dir) {
  148. switch (dir) {
  149. case DIR_CONTROL: return "in";
  150. case DIR_SLAVE : return "out";
  151. case DIR_AUTO : return "auto";
  152. }
  153. return "auto";
  154. }
  155. void print_device_serial_ports(struct videohub_data *d) {
  156. unsigned int i, len = 64;
  157. if (!d->serial.num)
  158. return;
  159. printf("Serial ports\n");
  160. printf_line(len);
  161. printf(" | ### | x | Dir | %-18s | %-18s | s |\n", "Serial port", "Connected serial");
  162. printf_line(len);
  163. for(i = 0; i < d->serial.num; i++) {
  164. printf(" | %3d | %c | %4s | %-18s | %-18s | %c |\n",
  165. i + 1,
  166. port_lock_symbol(d->serial.port[i].lock),
  167. dir2opt(d->serial.port[i].direction),
  168. d->serial.port[i].name,
  169. d->serial.port[i].routed_to == NO_PORT ? "" : d->serial.port[d->serial.port[i].routed_to].name,
  170. format_status(d->serial.port[i].status)
  171. );
  172. }
  173. printf_line(len);
  174. printf("\n");
  175. }
  176. void print_device_processing_units(struct videohub_data *d) {
  177. unsigned int i, len = 44;
  178. if (!d->proc_units.num)
  179. return;
  180. printf("Processing units\n");
  181. printf_line(len);
  182. printf(" | Proc Unit | x | %-24s |\n", "Connected video input");
  183. printf_line(len);
  184. for(i = 0; i < d->proc_units.num; i++) {
  185. printf(" | %9d | %c | %-24s |\n",
  186. i + 1,
  187. port_lock_symbol(d->proc_units.port[i].lock),
  188. d->proc_units.port[i].routed_to == NO_PORT ? "" : d->inputs.port[d->proc_units.port[i].routed_to].name
  189. );
  190. }
  191. printf_line(len);
  192. printf("\n");
  193. }
  194. void print_device_frame_buffers(struct videohub_data *d) {
  195. unsigned int i, len = 65;
  196. if (!d->frames.num)
  197. return;
  198. printf("Frames\n");
  199. printf_line(len);
  200. printf(" | ### | x | %-24s | %-24s |\n", "Frame name", "Connected output");
  201. printf_line(len);
  202. for(i = 0; i < d->frames.num; i++) {
  203. printf(" | %3d | %c | %-24s | %-24s |\n",
  204. i + 1,
  205. port_lock_symbol(d->frames.port[i].lock),
  206. d->frames.port[i].name,
  207. d->frames.port[i].routed_to == NO_PORT ? "" : d->outputs.port[d->frames.port[i].routed_to].name
  208. );
  209. }
  210. printf_line(len);
  211. printf("\n");
  212. }
  213. static void __print_opt(struct videohub_data *d, enum vcmd vcmd) {
  214. unsigned int i, last = 0;
  215. struct videohub_commands *v = &videohub_commands[vcmd];
  216. struct port_set *s_port = !v->ports1 ? NULL : (void *)d + v->ports1;
  217. const char *p = v->opt_prefix;
  218. for(i = 0; i < s_port->num; i++) {
  219. switch (v->type) {
  220. case PARSE_LABEL:
  221. printf(" --%s-name %3d \"%s\" \\\n", p, i + 1, s_port->port[i].name);
  222. break;
  223. case PARSE_ROUTE:
  224. if (s_port->port[i].routed_to == NO_PORT)
  225. continue;
  226. printf(" --%s-input %3d %3d \\\n", p, i + 1, s_port->port[i].routed_to + 1);
  227. break;
  228. case PARSE_LOCK:
  229. last = i + 1 < s_port->num;
  230. if (s_port->port[i].lock != PORT_UNLOCKED) {
  231. printf(" --%s-unlock %3d --%s-lock %3d%s\n",
  232. p, i + 1, p, i + 1, last ? " \\" : "");
  233. } else {
  234. printf(" --%s-unlock %3d%s\n", p, i + 1, last ? " \\" : "");
  235. }
  236. break;
  237. case PARSE_DIR:
  238. printf(" --%s-dir %3d %s \\\n", p, i + 1, dir2opt(s_port->port[i].direction));
  239. break;
  240. default: break;
  241. }
  242. }
  243. }
  244. void print_device_backup(struct videohub_data *d) {
  245. unsigned int i;
  246. printf("videohubctrl \\\n");
  247. if (d->device.friendly_name[0]) {
  248. printf(" --set-name \"%s\" \\\n", d->device.friendly_name);
  249. }
  250. for (i = 0; i < NUM_COMMANDS; i++) {
  251. if (videohub_commands[i].type == PARSE_LABEL)
  252. __print_opt(d, videohub_commands[i].cmd);
  253. }
  254. for (i = 0; i < NUM_COMMANDS; i++) {
  255. if (videohub_commands[i].type == PARSE_ROUTE)
  256. __print_opt(d, videohub_commands[i].cmd);
  257. }
  258. for (i = 0; i < NUM_COMMANDS; i++) {
  259. if (videohub_commands[i].type == PARSE_DIR)
  260. __print_opt(d, videohub_commands[i].cmd);
  261. }
  262. for (i = 0; i < NUM_COMMANDS; i++) {
  263. if (videohub_commands[i].type == PARSE_LOCK)
  264. __print_opt(d, videohub_commands[i].cmd);
  265. }
  266. printf("\n");
  267. }