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.

videohubctrl.c 4.4KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173
  1. /*
  2. * Blackmagic Design Videohub control application
  3. * Copyright (C) 2014 Unix Solutions Ltd.
  4. * Written by Georgi Chorbadzhiyski
  5. *
  6. * Released under MIT license.
  7. * See LICENSE-MIT.txt for license terms.
  8. *
  9. */
  10. #include <stdio.h>
  11. #include <stdlib.h>
  12. #include <string.h>
  13. #include <getopt.h>
  14. #include "data.h"
  15. #include "cmd.h"
  16. #include "net.h"
  17. #include "util.h"
  18. #include "version.h"
  19. #include "libfuncs/libfuncs.h"
  20. int verbose;
  21. int quiet;
  22. static struct videohub_data maindata;
  23. static int show_info = 1;
  24. static const char *program_id = PROGRAM_NAME " Version: " VERSION " Git: " GIT_VER;
  25. static const char short_options[] = "s:p:qvhVi";
  26. static const struct option long_options[] = {
  27. { "host", required_argument, NULL, 's' },
  28. { "port", required_argument, NULL, 'p' },
  29. { "quiet", no_argument, NULL, 'q' },
  30. { "verbose", no_argument, NULL, 'v' },
  31. { "help", no_argument, NULL, 'h' },
  32. { "version", no_argument, NULL, 'V' },
  33. { "info", no_argument, NULL, 'i' },
  34. { 0, 0, 0, 0 }
  35. };
  36. static void show_help(struct videohub_data *data) {
  37. printf("\n");
  38. printf(" Usage: " PROGRAM_NAME " --host <host> [..commands..]\n");
  39. printf("\n");
  40. printf("Main options:\n");
  41. printf(" -s --host <hostname> | Set device hostname.\n");
  42. printf(" -p --port <port_number> | Set device port (default: 9990).\n");
  43. printf("\n");
  44. printf("Misc options:\n");
  45. printf(" -v --verbose | Enable verbose logging.\n");
  46. printf(" -q --quiet | Suppress warnings.\n");
  47. printf(" -h --help | Show help screen.\n");
  48. printf(" -V --version | Show program version.\n");
  49. printf("\n");
  50. printf("Commands:\n");
  51. printf(" -i --info | Show device info (default command).\n");
  52. printf("\n");
  53. }
  54. static void parse_options(struct videohub_data *data, int argc, char **argv) {
  55. int j, err = 0;
  56. // Set defaults
  57. data->dev_port = "9990";
  58. while ((j = getopt_long(argc, argv, short_options, long_options, NULL)) != -1) {
  59. switch (j) {
  60. case 's': // --host
  61. data->dev_host = optarg;
  62. break;
  63. case 'p': // --port
  64. data->dev_port = optarg;
  65. break;
  66. case 'v': // --verbose
  67. verbose = !verbose;
  68. if (verbose)
  69. quiet = 0; // Disable quiet
  70. break;
  71. case 'q': // --quiet
  72. quiet = !quiet;
  73. break;
  74. case 'i': // --info
  75. show_info = 1;
  76. break;
  77. case 'h': // --help
  78. show_help(data);
  79. exit(EXIT_SUCCESS);
  80. case 'V': // --version
  81. // program_id is already printed on startup, just exit.
  82. exit(EXIT_SUCCESS);
  83. }
  84. }
  85. if (!data->dev_host || !strtoul(data->dev_port, NULL, 10))
  86. err = 1;
  87. if (err) {
  88. show_help(data);
  89. if (!data->dev_host)
  90. fprintf(stderr, "ERROR: host is not set. Use --host option.\n");
  91. exit(EXIT_FAILURE);
  92. }
  93. v("Device address: %s:%s\n", data->dev_host, data->dev_port);
  94. }
  95. static void print_device_desc(struct device_desc *d) {
  96. printf("\n");
  97. printf("Protocol version: %s\n", d->protocol_ver);
  98. printf("Model name: %s\n", d->model_name);
  99. printf("Unique ID: %s\n", d->unique_id);
  100. printf("Video inputs: %u\n", d->num_video_inputs);
  101. printf("Video processing units: %u\n", d->num_video_processing_units);
  102. printf("Video outputs: %u\n", d->num_video_outputs);
  103. printf("Video monitoring outputs: %u\n", d->num_video_monitoring_outputs);
  104. printf("Serial ports: %u\n", d->num_serial_ports);
  105. }
  106. static void printf_line(int len) {
  107. int i;
  108. for (i = 0; i < len; i++)
  109. printf("-");
  110. printf("\n");
  111. }
  112. static void print_device_settings(struct videohub_data *d) {
  113. unsigned int i;
  114. printf("\n");
  115. printf_line(76);
  116. printf("| # | x | %-30s | %-30s |\n", "Input name", "Output name");
  117. printf_line(76);
  118. for(i = 0; i < d->device.num_video_inputs; i++) {
  119. printf("| %2d | %c | %-30s | %-30s |\n",
  120. i + 1,
  121. d->inputs[i].locked ? 'L' : ' ',
  122. d->inputs[i].name,
  123. d->outputs[d->inputs[i].routed_to].name
  124. );
  125. }
  126. printf_line(76);
  127. }
  128. int main(int argc, char **argv) {
  129. struct videohub_data *data = &maindata;
  130. printf("%s\n", program_id);
  131. parse_options(data, argc, argv);
  132. set_log_io_errors(0);
  133. data->dev_fd = connect_client(SOCK_STREAM, data->dev_host, data->dev_port);
  134. if (data->dev_fd < 0)
  135. exit(EXIT_FAILURE);
  136. int ret;
  137. char buf[8192 + 1];
  138. memset(buf, 0, sizeof(buf));
  139. while ((ret = fdread_ex(data->dev_fd, buf, sizeof(buf) - 1, 5, 0, 0)) >= 0) {
  140. parse_command(data, buf);
  141. memset(buf, 0, sizeof(buf));
  142. }
  143. shutdown_fd(&data->dev_fd);
  144. if (show_info) {
  145. print_device_desc(&data->device);
  146. print_device_settings(data);
  147. fflush(stdout);
  148. }
  149. return 0;
  150. }