desarrollo de una librería de comunicaciones para la

34
Trabajo Final de Grado Grado en Ingeniería de Sistemas Audiovisuales Desarrollo de una librería de comunicaciones para la gestión de mezcladores de vídeo ATEM Autor: Manel Salvador Hernàndez Director: Juan Jose Alins Delgado Universidad Politécnica de Cataluña Convocatoria de Junio 2020

Upload: others

Post on 01-Jul-2022

1 views

Category:

Documents


0 download

TRANSCRIPT

Page 1: Desarrollo de una librería de comunicaciones para la

Trabajo Final de Grado Grado en Ingeniería de Sistemas Audiovisuales

Desarrollo de una librería de comunicaciones para la gestión de

mezcladores de vídeo ATEM

Autor: Manel Salvador Hernàndez

Director: Juan Jose Alins Delgado

Universidad Politécnica de Cataluña

Convocatoria de Junio 2020

Page 2: Desarrollo de una librería de comunicaciones para la
Page 3: Desarrollo de una librería de comunicaciones para la

3

Resumen Los mezcladores de vídeo son dispositivos de gran importancia en el mundo de la televisión, ya que permiten realizar funciones de producción y posproducción de vídeo.

En este proyecto, se realiza el estudio de los mezcladores de vídeo, en concreto el ATEM Television Studio Pro HD, con el objetivo de implementar un software que permita controlar sus funciones. Se realiza una introducción sobre los mezcladores de vídeo para informar sobre su funcionalidad. Este proyecto se centra en unas librerías, creadas por la empresa SKAARHOJ, escritas en código Arduino que fueron creadas con ingeniería inversa para poder controlar los mezcladores de vídeo de la marca ATEM. Se realiza un estudio de las librerías con el que se determina la funcionalidad de las mismas.

A raíz del estudio de las librerías se crea el equivalente en código C/C++ para que funcionen en sistemas no Arduino, como Linux y Windows.

Page 4: Desarrollo de una librería de comunicaciones para la

4

Abstract Video Mixers are devices of great importance in the world of television, as they can perform video production and post-production functions.

In this project, a study about video mixers is carried out, specifically the ATEM Television Studio Pro HD, in order to create software that allows a user to control its functions. An introduction to video mixers is made to inform about their functionality. This project focuses on a set of libraries, created by the company SKAARHOJ, written in Arduino code that were created with reverse engineering to control ATEM video mixers. A study of the libraries is made to determine their functionality.

As a result of the study of the libraries, the equivalent in C/C ++ code is created so that they work on non-Arduino systems, such as Linux and Windows.

Page 5: Desarrollo de una librería de comunicaciones para la

5

Declaración de Honor I declare that,

the work in this Master Thesis / Degree Thesis (choose one) is completely my

own work,

no part of this Master Thesis / Degree Thesis (choose one) is taken from other

people’s work without giving them credit,

all references have been clearly cited,

I’m authorized to make use of the company’s / research group (choose one)

related information I’m providing in this document (select when it applies).

I understand that an infringement of this declaration leaves me subject to the

foreseen disciplinary actions by The Universitat Politècnica de Catalunya -

BarcelonaTECH.

Manel Salvador Hernàndez November 2020

______________________ __________________ _________________

Student Name Signature Date

Title of the Thesis: Desarrollo de una librería de comunicaciones para la gestión de mezcladores de vídeo ATEM

Page 6: Desarrollo de una librería de comunicaciones para la

6

Índice Capítulo 1: Introducción ......................................................................................... 9

Capítulo 2: Objetivos ............................................................................................ 11

2.1 Ingeniería Inversa ....................................................................................... 11

2.1.1 Legalidad en la Ingeniería Inversa ...................................................... 12

2.2 Grupo de desarrollo SKAARHOJ .............................................................. 13

Capítulo 3: Librerías de SKAARHOJ .................................................................. 14

3.1 Arduino ....................................................................................................... 14

3.1.2 Modelo de programación Arduino ...................................................... 16

3.2 Estudio de las Librerías .............................................................................. 17

3.2.1 Análisis del envío ................................................................................ 18

3.2.2 Función Begin ..................................................................................... 19

3.2.3 Función Connect .................................................................................. 19

3.2.4 Función SendPacketBuffer .................................................................. 20

3.2.5 Función RunLoop ................................................................................ 20

3.2.6 Función ParsePacket ............................................................................ 21

3.2.7 Diagrama de Flujo de las librerías ....................................................... 21

3.3 Comandos Disponibles ............................................................................... 24

3.3.1 Comandos “sets” ................................................................................. 24

3.3.2 Comandos “gets” ................................................................................. 25

3.3.3 Comandos “sets / gets” ........................................................................ 26

3.4 Modificaciones requeridas .......................................................................... 28

Capítulo 4: Implementación ................................................................................. 29

4.1 Sockets ........................................................................................................ 29

4.2 Modificaciones Realizadas ......................................................................... 30

4.2.1 Modificaciones de conexión ................................................................ 30

4.2.2 Modificaciones de Funciones Arduino ................................................ 31

4.2.3 Modificaciones Varias ......................................................................... 31

4.3 Nuevo Diagrama de Flujo .......................................................................... 31

4.4 Problemas Encontrados .............................................................................. 32

4.5 Trabajo Futuros .......................................................................................... 32

Bibliografía ........................................................................................................... 33

Page 7: Desarrollo de una librería de comunicaciones para la

7

Listado de Ilustraciones

Ilustración 1. ATEM Television Studio Pro HD .................................................. 10 Ilustración 2. Arduino UNO ................................................................................. 15 Ilustración 3. Diagrama de Flujo Arduino ............................................................ 16 Ilustración 4. Cabecera del paquete de envío ....................................................... 18 Ilustración 5. Contenido del paquete de envío ..................................................... 19 Ilustración 6. Diagrama de Flujo de las librerías .................................................. 22 Ilustración 7. Esquema de conexión ..................................................................... 23 Ilustración 8. Diagrama de estado sockets UDP .................................................. 29

Page 8: Desarrollo de una librería de comunicaciones para la

8

Listado de Tablas

Tabla 3.3.1 Comandos "Gets" .............................................................................. 25 Tabla 3.3.2. Comandos “gets” .............................................................................. 25 Tabla 3.3.3. Comandos “sets” / “gets” ................................................................. 27

Page 9: Desarrollo de una librería de comunicaciones para la

9

Capítulo 1: Introducción Tal como se indica en el título de este proyecto, el objetivo principal es la creación de un software capaz de gestionar las operaciones de un mezclador de vídeo.

Un mezclador de vídeo es un dispositivo, o programa de software, que permite seleccionar entre varias señales de vídeo entrantes y dirigir una de ellas hacia una salida. Pueden crear diferentes efectos visuales, desde transiciones al cambiar de cámara a realizar operaciones para manipular y generar señales de color.

La mayoría de mezcladores de vídeo poseen dos buses, uno de programa y otro de vista previa, cada uno con un monitor propio. El bus de programa es la fuente de salida principal, mientras que el bus de vista previa sirve para elegir y obtener una vista previa de la fuente que está a punto de enviar. El uso del bus de vista previa es opcional. Sin embargo, el bus de vista previa es necesario en el caso de efectos visuales.

Un mezclador de vídeo moderno tiene características adicionales como la capacidad de almacenar configuraciones complejas del mezclador.

Hay varias situaciones en las que un mezclador de vídeo puede ser muy útil, como:

• Difusión por web con varias cámaras: En este tipo de transmisiones es muy importante tener varias cámaras para poder tener planos amplios y cortos, con un mezclador de vídeo ese ajuste es muy sencillo.

• Podcast de vídeo: A medida que los podcasts están pasando de audio, a audio y vídeo, la necesidad de mezcladores de vídeo está creciendo a un ritmo significativo, cuantas más personas tenga el podcast más se necesita planos cortos para crear un ambiente más profesional.

• Eventos en directo: En eventos en directo donde ocurren varias escenas simultáneamente es muy importante poder cambiar rápidamente de cámara y usar la que más convenga. Un mezclador de vídeo permite realizar transiciones impecables de las fuentes de vídeo entrantes, al igual que con los ejemplos anteriores no es posible una transmisión profesional sin un mezclador de vídeo.

Hay dos tipos de mezcladores de vídeo, de hardware o software.

Los mezcladores de tipo hardware son dispositivos dedicados que tienen todas las entradas y salidas de vídeo y audio directamente en el dispositivo. Normalmente son más caros que los de software.

Los mezcladores de tipo software son programas que se pueden ejecutar desde un ordenador no especializado, son generalmente más económicos, sin embargo, puede ser necesario adquirir alguna tarjeta de vídeo dedicada, para entradas y salidas de vídeo extras.

Page 10: Desarrollo de una librería de comunicaciones para la

10

Cuantas más cámaras se tengan más será necesaria la compra de un mezclador de vídeo de tipo hardware.

El mezclador con el que se ha trabajado es el que dispone la Universidad, es de la marca BlackMagic Design, se trata del mezclador hardware, el ATEM Television Pro HD (Ilustración 1) que tiene 8 entradas combinadas entre 4 HDMI y HD-SDI, capaces de soportar un amplio rango de resoluciones SD y HD tanto de vídeo como informáticas.

Una de las grandes ventajas de este mezclador que se va a aprovechar para realizar este proyecto es la capacidad de conectar el dispositivo a una red informática para poder controlarlo.

Ilustración 1. ATEM Television Studio Pro HD

Page 11: Desarrollo de una librería de comunicaciones para la

11

Capítulo 2: Objetivos El objetivo principal de este proyecto es crear un software con el que se pueda controlar las funciones principales del mezclador de vídeo desde un ordenador conectado a la misma red.

Para crear el software mencionado se realizó una búsqueda exhaustiva, y se encontraron unas librerías de libre uso (Capítulo 3) que permiten operar un mezclador de vídeo con una placa Arduino desde la red en que esté conectada.

Uno de los requisitos es que se pueda operar desde un ordenador no especializado, por lo tanto, hay que traducir las librerías de Arduino a C/C++ para que se pueda operar desde un sistema operativo Linux.

En el momento de realización de este proyecto existe un software que cumple con los objetivos del proyecto, pero se trata de un software de código cerrado y de pago. Por esa razón la empresa SKAARHOJ, creadora de las librerías mencionadas, tuvo que usar ingeniería inversa para analizar el mezclador de vídeo y programar las librerías.

2.1 Ingeniería Inversa La ingeniería inversa es un proceso en el que se deconstruyen software, máquinas, aeronaves, estructuras arquitectónicas y otros productos para extraer información de diseño de ellos. A menudo, la ingeniería inversa implica la deconstrucción de componentes individuales de productos más grandes.

El proceso de ingeniería inversa permite determinar cómo se diseñó una pieza para que se pueda recrear. Las empresas a menudo utilizan este enfoque cuando la compra de una pieza de repuesto de un fabricante de equipos originales no es una opción.

Un gran impacto en el mundo de la informática generado por la ingeniería inversa fue a principios de los 80. La empresa IBM, con su producto IBM PC (Personal Computer), monopolizaba el mercado de los ordenadores gracias a su código de la BIOS que les permitía ser los únicos en ofrecer sus PC. La empresa Phoenix Technologies usando el enfoque ”clean room”, estudió la BIOS y consiguió realizar un clon de la misma.

La técnica de ingeniería inversa se denomina así, ya que implica trabajar atrás en el proceso del diseño original. El desafío consiste en obtener el conocimiento práctico del diseño original desmontando la pieza o el software para aprender cómo se creó el producto.

En algunos casos, la única forma de obtener el diseño de un producto original es mediante ingeniería inversa. Con algunos productos más antiguos que no se han fabricado durante 20 años o más, los dibujos 2D originales ya no están

Page 12: Desarrollo de una librería de comunicaciones para la

12

disponibles. A menudo, no habrá forma de comunicarse con el fabricante original, ya que es posible que la empresa ya no esté en funcionamiento.

Para la aplicación de ingeniería inversa en un producto físico, es necesario el producto original en cuestión y se desarmará para examinar los mecanismos internos. Cuando se realiza ingeniería inversa de un producto mecánico, se comienza analizando las dimensiones y los atributos del producto en cuestión, ya sea un avión, barco, vehículo, ordenador o pieza de maquinaria industrial.

Cuando se aplica la ingeniería inversa en software, el objetivo principal es recuperar el código fuente del programa para, ser corregido, mejorado o estudiado para ser nuevamente escrito.

El uso de la ingeniería inversa de software con el objetivo de duplicar o estudiar un programa con propósito comercial puede ser considerado como una violación de las leyes de copyright. En el caso de hardware también existe esta posibilidad.

2.1.1 Legalidad en la Ingeniería Inversa La legalidad de la ingeniería inversa varía dependiendo del lugar en el que se quiera usar. Los dos casos más notorios son en Europa y Estados Unidos.

En Estados Unidos los riesgos del uso de ingeniería inversa son mayores a los de Europa. Solo se puede usar ingeniería inversa legalmente con permiso directo del creador del software original o para la interoperabilidad, aunque la segunda implica más riesgos.

En Europa existe la directiva de programas informáticos, que controla la protección legal de los programas informáticos. Es muy similar a la de Estados Unidos, pero se disminuyen en gran parte los riesgos del uso de la ingeniería inversa. El propietario de los derechos de autor tiene el derecho exclusivo de autorizar que tipo de uso se le puede dar a su software. Estos derechos de autor están sujetos a ciertas limitaciones. El software se puede descompilar si es necesario garantizar la interoperabilidad con otro software, pero el resultado no pude utilizarse para otro propósito.

En España se podría decir que la ingeniería inversa es legal, siempre que se realice en las estrictas condiciones que marca la normativa vigente. Si se realiza para finalidades distintas de las determinadas por la Ley, se estarían vulnerando derechos de propiedad intelectual y se podrían estar cometiendo uno o varios delitos.

El caso más común de uso de la ingeniería inversa se encuentra en intentar compatibilizar el software de una empresa con el de otra, en el caso de que ninguna de las empresas facilite esa información, es decir, proporcionarles interoperabilidad.

Para que la ingeniería inversa sea legal, es muy importante tener en cuenta la finalidad del uso de esta, primero hay que distinguir entre la observación o análisis del programa respecto a la recuperación y uso del propio código fuente, en cuanto a la simple observación.

Page 13: Desarrollo de una librería de comunicaciones para la

13

El artículo 100.3 de la Ley de Propiedad Intelectual (LPI) indica que si se posee una copia del programa no hace falta informar al titular de este si se realiza un análisis o estudio sobre el mismo.

Art. 100.3 LPI: “El usuario legítimo de la copia de un programa estará facultado para observar, estudiar o verificar su funcionamiento, sin autorización previa del titular, con el fin de determinar las ideas y principios implícitos en cualquier elemento del programa, siempre que lo haga durante cualquiera de las operaciones de carga, visualización, ejecución, transmisión o almacenamiento del programa que tiene derecho a hacer”.

También los artículos 100.5, 100.6 y 100.7 de la LPI indican que mientras la empresa titular del programa no proporcione la información necesaria para la interoperabilidad de este, y tener una copia del mismo legalmente se puede usar la ingeniería inversa.

Existen otros requisitos que se tienen que cumplir, uno de los más importantes es la prohibición de la comercialización del programa generado por ingeniería inversa.

En nuestro caso cumplimos con la ley, ya que el grupo creador de las librerías no ha incumplido ninguna de las normas anteriormente explicadas y proporciona de manera gratuita y libre su código.

2.2 Grupo de desarrollo SKAARHOJ El grupo desarrollador de estas librerías pertenece a una empresa llamada SKAARHOJ, creada en 2012 por su CEO actual, Kasper Skårhøj, junto a un equipo pequeño.

Uno de los elementos clave en la estrategia de SKAARHOJ es la integración de softwares de control con sistemas de terceros, es decir, de otros fabricantes.

Un ejemplo de un software de control creado para un sistema de terceros son las librerías usadas en este proyecto, creadas en 2011. Estas librerías están creadas con una ingeniería inversa casi completa de los comandos del protocolo ATEM, proporcionan esta información de forma gratuita junto a una API de Arduino.

Presentan diferentes opciones de las librerías según qué finalidad se tenga, subidas a la nube en su proyecto en GitHub. También proporcionan una lista de los comandos usados en las librerías.

Page 14: Desarrollo de una librería de comunicaciones para la

14

Capítulo 3: Librerías de

SKAARHOJ En este capítulo se van a analizar las librerías comentadas anteriormente para llevar a cabo la programación de estas en plataformas no Arduino. Como ya se ha mencionado anteriormente, las librerías que se han usado para realizar este proyecto están escritas en código Arduino.

El ecosistema Arduino consiste en una combinación de hardware y software, con una versatilidad y una interfaz muy simple que lo convierte en la opción líder para una amplia gama de usuarios y proyectos, ya que es útil para aficionados y profesionales al mismo tiempo.

Una de las grandes ventajas del código abierto de Arduino, es la facilidad que tienen nuevos usuarios de encontrar información sobre el tema gracias a su comunidad y a los miles de ejemplos de código Arduino disponibles en línea.

3.1 Arduino Un sistema Arduino está formado por un hardware y software específico que solo se puede usar con un conjunto de microcontroladores específicos. Existe una amplia variedad de microcontroladores, o placas, que funcionan con Arduino dependiendo de las necesidades del usuario.

El código Arduino está escrito en C ++ con una adición de métodos y funciones especiales, que solo se pueden usar con los microcontroladores de las placas Arduino.

Para usar Arduino hace falta una placa o microcontrolador específico y un ordenador con el software de Arduino IDE, que es el entorno de desarrollo Arduino. El usuario escribe el código de Arduino en el IDE, luego lo carga en el microcontrolador, y este, ejecuta el código.

El entorno de desarrollo integrado de Arduino (IDE) es el principal programa de edición de código utilizado para la programación de Arduino.

En Arduino, al igual que otras plataformas de programación, es posible importar librerías externas para expandir las capacidades y características del sistema. Por ejemplo, las librerías creadas por el grupo SKAARHOJ para controlar los mezcladores de vídeo ATEM. Estas librerías se pueden clasificar en librerías que interactúan con un componente específico externo, por ejemplo, un sensor, o aquellas que implementan nuevas funciones internas.

Como ya se ha comentado, existen distintas variantes de placas Arduino. La placa que se usa con las librerías estudiadas en este proyecto es la Arduino Ethernet, ya

Page 15: Desarrollo de una librería de comunicaciones para la

15

que incorpora un puerto ethernet y permite conectarse a la red del mezclador de vídeo.

La placa Arduino más popular es la Arduino UNO (Ilustración 3), en la imagen podemos observar la placa y sus componentes integrados.

Ilustración 2. Arduino UNO

El Arduino UNO usa una conexión USB (1) con el ordenador o una fuente de alimentación de pared que termina con un “barrel jack” (2) para alimentarse. La conexión USB también sirve para cargar el código a la placa.

Las placas de Arduino disponen de unos pines externos que permiten realizar la conexión con circuitos externos. Estos tienen varios usos.

Existe GND (3), que es la conexión a tierra, se pueden distinguir pines que dan voltaje, uno que da 5 V (4), y otro que da 3.3 V (5).

La placa dispone de 6 pines (6) que funcionan como entradas analógicas, del A0 al A5, leen señales de sensores analógicos y la convierten en valores digitales que se pueden leer.

También existen 14 pines digitales (7), del 0 al 13, que se pueden usar tanto como entrada digital como para salida digital.

Algunos pines digitales llevan una marca (~), que se pueden usar como pines digitales, pero también sirven para modulación de ancho de pulso (PWM) (8).

El pin AREF (9) significa Referencia analógica, el cual la mayoría de veces se deja vacío, pero a veces se utiliza para establecer un voltaje de referencia externo (entre 0 y 5 voltios) como límite superior para los pines de entrada analógica.

Page 16: Desarrollo de una librería de comunicaciones para la

16

El botón de reinicio (11) sirve para reiniciar la placa de manera manual, que conecta temporalmente el pin de reinicio a tierra para reiniciar el código cargado en la placa.

También dispone de unos leds de transmisión, TX, y recepción, RX, (12), que dan indicaciones visuales cada vez que nuestro Arduino esté recibiendo o transmitiendo datos.

El componente identificado con el número 13 es el microcontrolador de la placa Arduino sirve como cerebro de este, y finalmente un regulador de voltaje (14).

3.1.2 Modelo de programación Arduino El funcionamiento de los microcontroladores Arduino es muy distinto al de otros microcontroladores, principalmente porque realiza la inicialización del sistema de manera automática.

El código Arduino se divide en dos funciones, setup y loop.

Ilustración 3. Diagrama de Flujo Arduino

El setup es una función que se ejecuta una sola vez, que permite definir ciertas configuraciones previas necesarias antes de la ejecución.

El loop se trata de una función repetitiva, es decir, que cuando acaba de ejecutar todo el código dentro de la misma se vuelve a ejecutar desde el principio, como se puede observar en el diagrama de flujo (Ilustración 3). Solo se puede parar la ejecución del programa con el botón de reinicio o si existe un error en el código.

La función loop suele tener una estructura “if-then”, y se puede dividir en 3 bloques:

Entrada (Input): Al comienzo del loop se leen las entradas, se consideran condiciones (if).

Manipulación de datos: Esta sección se utiliza para transformar los datos en una forma más conveniente o realizar cálculos.

Salida (Output): En esta sección se define el resultado final de acuerdo a los datos calculados en los pasos anteriores (then).

En el caso de las librerías de SKAARHOJ se podría decir que usan una estructura similar a la explicada previamente, ya que recogen datos del mezclador de vídeo

Page 17: Desarrollo de una librería de comunicaciones para la

17

ATEM, para descifrarlos y según el resultado obtenido se realiza alguna acción, como ya se explicará más adelante (3.2), y finalmente enviar el resultado a la máquina ATEM.

El sistema de programación de Arduino está basado en C++, por lo tanto, la estructura de funciones y variables es muy similar. Al usar métodos de librerías propias de Arduino tienen poca compatibilidad cuando se quiere traducir un código de Arduino a C++ estándar, esa es la situación desde la que parte este proyecto.

Aunque a diferencia de lo comentado anteriormente, es muy sencillo trabajar con métodos del lenguaje C++ en el código Arduino.

Un programa en C++ tiene una estructura con una función principal y funciones secundarias que ejecutan procesos, y no está sujeta al modelo de programación Arduino que acabamos de explicar, basado en una función loop continua.

3.2 Estudio de las Librerías Las librerías creadas por el grupo SKAARHOJ sirven para comunicar una placa Arduino con conexión a la misma red que un mezclador de vídeo de la marca ATEM.

Para realizar los envíos las librerías usan el protocolo de transporte UDP (User Datagram Protocol), que consiste en un protocolo ethernet basado en intercambio de datagramas. Permite el envío de datagramas a través de una red sin que se haya establecido previamente una conexión.

Para explicarlo brevemente, las librerías permiten que la placa Arduino reciba información del mezclador de vídeo. Las librerías procesan el envío, extraen el comando o información que está enviando el mezclador, guarda la información y, a partir del comando que se desee realizar, envía un mensaje de vuelta al mezclador. Este flujo de trabajo se explicará más adelante (3.2.7).

Antes de explicar el diagrama de flujo de estas librerías, es importante explicar cómo trabajan las funciones principales de estas. Analizando el código se ha identificado que las funciones principales son Begin, Connect, SendPacketBuffer, RunLoop y ParsePacket.

El mezclador de vídeo ATEM tiene un conjunto de comandos muy extenso, por esa razón el grupo SKAARHOJ dividió las librerías en distintas versiones con diferentes comandos en ellas, aunque todas tienen en común ATEMbase como fundamento. ATEMbase proporciona la parte de conexión y envío de datos, y la parte de configuración básica, el resto de librerías son subclases creadas para usar comandos específicos.

Para la realización de este proyecto se ha utilizado ATEMstd, ya que contiene los comandos estándar que se necesitan.

Page 18: Desarrollo de una librería de comunicaciones para la

18

Antes de explicar las funciones principales de las librerías es necesario analizar el paquete de envío para entender cómo se comunica la placa Arduino con el mezclador de vídeo.

3.2.1 Análisis del envío Tras analizar las librerías se ha descubierto el formato del paquete de envío (Ilustración 4).

Ilustración 4. Cabecera del paquete de envío

El paquete de envío se divide en la cabecera y el contenido del paquete. La cabecera contiene información de control de la conexión. Esta información está dividida en 12 bytes (96 bits):

• Bits 0 – 4: Contienen el “headerCmd”, que es el comando de cabecera que se envía o recibe del mezclador.

• Bits 5 – 15: Contienen el “lenghtofdata”, que es el tamaño total del paquete en binario.

• Bits 16 – 31: Contienen el “sessionID” explicado más adelante (3.2.3). • Bits 32 – 47: Contienen el “remotepacketID”, que consiste en el contador

de paquetes del mezclador. • Bits 48 – 71: En estos bits solo hay 0x00. • Bits 72 – 79: El contenido de estos bits depende de que función esté

enviando el paquete. Si se envía desde la función Connect (3.2.3) contiene el valor 0x3A. Desde cualquier otra función estos bits son 0x00.

• Bits 80 – 95: Contienen “_localpacketIDcounter”, que consiste en el contador local de paquete.

La función Connect también modifica los bits 95 – 103, que contienen el valor 0x01.

Page 19: Desarrollo de una librería de comunicaciones para la

19

Después de los 12 bytes de cabecera aparece el contenido del paquete.

Ilustración 5. Contenido del paquete de envío

El contenido del paquete (Ilustración 5) se divide en tres partes:

• Bits 96 – 111: Contienen “cmdlength”, que es el tamaño que ocupa el comando.

• Bits 112 – 143: Contienen “cmdStr”, que consiste en código de comando. • El tamaño restante de “cmdlength” es el contenido del comando.

Esta estructura se puede repetir varias veces, ya que un mismo paquete puede contener varios comandos.

3.2.2 Función Begin Esta función pertenece a ATEMbase, sirve para configurar la conexión.

Se almacena la dirección IP y la el puerto de salida de la placa Arduino. Es la primera llamada que se deberá ejecutar en el momento que se quiera hacer un software con estas librerías.

3.2.3 Función Connect La función Connect pertenece a ATEMbase, inicializa la conexión entre la placa Arduino y el mezclador de vídeo. Inicializa todos los valores y contadores que se van a usar en las transmisiones.

Utilizando UDP se establece una sesión de trabajo utilizando la variable, “_sessionID”, que se trata del ID de sesión que vincula la conexión con el mezclador. Lo primero que realiza es una limpieza del vector que contendrá los datos de envío, “_packetbuffer”, este vector tiene una longitud máxima de 96 bytes, información que se adquirió a través de la ingeniería inversa realizada.

Finalmente se genera un mensaje de inicialización, con el comando HelloPacket, que es el primer mensaje que tiene que recibir el mezclador de vídeo para que genere una sesión de conexión. Para transmitir el comando se usa la función SendPacketBuffer.

Page 20: Desarrollo de una librería de comunicaciones para la

20

3.2.4 Función SendPacketBuffer Antes de realizar la transmisión de un paquete con la función SendPacketBuffer se tiene que invocar la función _createCommandHeader. Esta, genera los 12 primeros bytes del mensaje, que funcionan como cabecera de este, es decir, contiene la información esencial que necesita el mezclador para que la conexión funcione. Esta información consiste en la longitud del paquete, el identificador de la sesión existente entre el mezclador y la placa, el identificador remoto del paquete y el identificador local del paquete.

La función SendPacketBuffer realiza este envío de los datos, es decir, el “_packetbuffer”, hacia el mezclador. Se envía al puerto 9910 del mezclador.

3.2.5 Función RunLoop La función RunLoop mantiene la conexión activa con el mezclador de vídeo. Esta se lanza dentro del loop de Arduino, ya que se necesita ejecutar continuamente.

La función RunLoop monitoriza constantemente si hay algún paquete entrante procedente del mezclador de vídeo. Al recibir un paquete este se procesa y se analiza la cabecera.

A partir de la información recibida se examina el “headerBitmask”, que son 3 bits del primer byte del “_packetbuffer” recibido, estos, informan del comando que quiere ejecutar el mezclador, por lo tanto, hay varias opciones de cómo tratarlo.

Si se trata del comando HelloPacket (Ilustración 7) significa que es la respuesta del primer envío realizado en ATEM Connect. Se enviará un paquete con el comando ACK para que el mezclador entienda que la conexión se ha realizado con éxito.

Si se tratase de un paquete de longitud 12 bytes, significaría que el mezclador de vídeo ya ha enviado toda la información inicial y está preparado para recibir comandos.

Otra opción es que el mezclador pida información de reconocimiento, si se recibiera un comando “ACKRequest” por parte del mezclador, se enviaría un comando “ACK” como anteriormente.

El mezclador puede también perder o recibir en orden incorrecto los paquetes, en este caso se recibiría un comando de “RequestNextAfter”, al que se respondería con un paquete vacío para qué la máquina no dejase de funcionar.

Finalmente, el resto de comandos que se puedan recibir no los gestionará el Runloop, sino que se le pasa el paquete a la función ParsePacket. El paquete que entre en esta función, normalmente proporciona información adicional del estado del mezclador.

Page 21: Desarrollo de una librería de comunicaciones para la

21

3.2.6 Función ParsePacket Esta función existe en ATEMbase, sirve para analizar los paquetes recibidos del mezclador de vídeo.

Lee el paquete a partir de los 12 primeros bytes, que como se ha explicado anteriormente, forman la cabecera del paquete. A partir de estos (Ilustración 5), se leen los siguientes 8 bytes, que aportan la información del comando que contiene este paquete. Un mismo paquete perteneciente del mezclador puede incluir varios comandos, por esa razón, se realizan las acciones de esta función hasta que no quede paquete para analizar. Estos 8 bytes son la cabecera del comando, que contiene la información de longitud del comando y que tipo de comando se está enviando.

A partir de esa información se llama a la función ParseGetCommands, que analiza el comando recibido, de forma diferente según que tipo de comando sea.

3.2.6.1 Función ParseGetCommands Esta función existe tanto en ATEMbase como en ATEMstd, pero su funcionamiento cambia según se use la subclase ATEMstd o no, ya que la superpone.

En ATEMbase no analiza los datos, solo hace una limpieza del vector “_packetbuffer” para que pueda recibir más daros.

En ATEMstd, analiza los datos del paquete, y, según el comando que se haya recibido, almacena la información en una de las variables preparadas.

Los comandos que se pueden recibir consisten en 4 bytes tipo char, es decir, 4 letras o símbolos. Estos se explicarán más adelante (3.3).

3.2.7 Diagrama de Flujo de las librerías En el diagrama de flujo (Ilustración 6) podemos observar que la primera función que se va a ejecutar en un software con estas librerías sería la función Begin.

Page 22: Desarrollo de una librería de comunicaciones para la

22

Ilustración 6. Diagrama de Flujo de las librerías

Para inicializar la función Begin (3.2.2) hace falta pasarle la dirección IP y el puerto de salida de la placa Arduino que se vaya a usar. Estos valores quedan almacenados para su futuro uso. También reinicia información guardada de conexiones anteriores.

La siguiente función que se ejecuta es el Serialoutput, esta función se utiliza para tareas de depuración, sirve para elegir si enviar información sensible y valores importantes al ordenador o no.

A continuación, se ejecuta la función Connect (3.2.3), que inicializa la conexión UDP de la placa Arduino con el mezclador de vídeo. En esta función se crea la conexión con el método EthernetUDP de Arduino. Finalmente se envía un paquete al mezclador con el comando HelloPacket, que es el paquete que espera recibir para inicializar la conexión.

Page 23: Desarrollo de una librería de comunicaciones para la

23

Los tres pasos anteriores se ejecutan en el setup de Arduino, el siguiente se ejecuta en el loop. La siguiente función del diagrama es RunLoop que necesita estar en constante ejecución.

El proceso de conexión debería ser (Ilustración 7):

Ilustración 7. Esquema de conexión

1. Primero se envía el comando HelloPacket comentado anteriormente. 2. Se debería recibir una respuesta del paquete HelloPacket enviado en la

función Connect, que significa que la conexión se ha establecido. 3. Se contesta con un comando ACK para que el mezclador sepa que se ha

recibido correctamente. 4. El mezclador debería enviar la información inicial, que consiste en las

configuraciones principales del mezclador y las versiones del mismo. Estos paquetes pasan por la función ParsePacket (3.2.6), que las analiza y almacena las variables recibidas.

5. Al acabar de recibir toda esta información inicial, el mezclador enviará un paquete con solo 12 bytes, solo la cabecera, cosa que se interpreta como que toda la información inicial se ha enviado y se puede comenzar a ejecutar comandos libremente.

De aquí hasta que se ponga fin a la conexión se ejecutarán los comandos que se desee.

Al realizar un comando se prepara con la función PrepareCommandPacket, que prepara el paquete de envío para que el mezclador lo entienda.

Page 24: Desarrollo de una librería de comunicaciones para la

24

3.3 Comandos Disponibles Los comandos disponibles son los definidos en la librería ATEMstd que se ha usado para este proyecto.

Estos comandos se pueden clasificar en dos grupos:

• El conjunto de comandos para modificar la configuración del mezclador (sets).

• El conjunto de comandos para pedir información al mezclador (gets). • Un conjunto de comandos reducido que tienen opción de modificar y

extraer información (sets / gets)

A continuación, se explicarán algunos de los comandos más útiles que se pueden encontrar en las librerías ATEMstd.

3.3.1 Comandos “sets” Los siguientes comandos solo se pueden usar para modificar valores en el mezclador de vídeo, es decir, los “sets”.

Comando Título Función Descripción DCut Cut void performCutME(uint8_t mE) Realiza un corte en la

retransmisión. CTPr Transition

Preview void setTransitionPreviewEnabled(uint8_t mE, bool enabled)

Sirve para activar o desactivar la transición que esté seleccionada al pasar del bus de Programa al de Vista previa.

CTWp Transition Wipe

Varias Funciones

Sirve para modificar o crear un diseño de Transición personalizado. Contiene varias funciones de diseño de Transición.

SCPS Clip Player Varias Funciones Permite controlar opciones del reproductor de multimedia del mezclador.

CAMM Audio Mixer Master

void setAudioMixerMasterVolume(uint16_t volume)

Sirve para elegir la ganancia en dB de la salida del bus de Programa.

SALN Audio Levels

void setAudioLevelsEnable(bool enable)

El envío de este comando permitirá que los niveles de audio se envíen unas 10 veces por segundo al cliente. Obviamente, esto es mucho tráfico. Por lo tanto, este también es un servicio de suscripción

Page 25: Desarrollo de una librería de comunicaciones para la

25

Tabla 3.3.1 Comandos "Gets"

3.3.2 Comandos “gets” Los siguientes comandos solo se pueden usar para extraer información del mezclador de vídeo, es decir, los “gets”.

Tabla 3.3.2. Comandos “gets”

de ATEM y no el predeterminado

SRsv Save Startup State

void settingsMemorySave() Guarda el estado del mezclador para que la configuración actual se mantenga al apagarlo.

SRcl Clear Startup State

void settingsMemoryClear() Limpia la configuración guardada.

Comando Título Función Descripción _ver Protocol Version uint16_t

getProtocolVersionMajor() uint16_t getProtocolVersionMinor()

El mezclador envía el número de versión del software de ATEM, si se usa VersionMajor, o el número de versión del firmware de ATEM, si se usa VersionMinor

_pin Product ID char * getProductIdName() Se recibe el modelo de mezclador de vídeo que se esté usando

AMLv Audio Mixer Levels Varias Funciones Son varias funciones que permiten acceder a distinta información sobre los niveles de audio del mezclador.

Page 26: Desarrollo de una librería de comunicaciones para la

26

3.3.3 Comandos “sets / gets” Finalmente, la siguiente tabla contiene los comandos que tienen opción de modificar y extraer información. Comando Título Función Descripción PrgI Program Input uint16_t

getProgramInputVideoSource(uint8_t mE) void setProgramInputVideoSource(uint8_t mE, uint16_t videoSource)

Con el “set” se puede modificar que fuente de vídeo poner en el bus de programa. Con el “get” se puede obtener la información de que fuente de vídeo está en el bus de Programa.

PrvI Preview Input uint16_t getPreviewInputVideoSource(uint8_t mE) void setPreviewInputVideoSource(uint8_t mE, uint16_t videoSource)

Funciona de la misma manera que el Programa Input, pero en vez de usar el bus de Programa, se usa el bus de Vista Previa.

VidM Video Mode uint8_t getVideoModeFormat() void setVideoModeFormat(uint8_t format)

Sirve para obtener o modificar la resolución a la que se trabajará.

TrSS Transition Varias funciones Con las funciones de “get” se pueden obtener los detalles de la configuración establecida para las Transiciones. Con las de “set” se pueden modificar estas configuraciones.

TrPs Transition Position Varias Funciones Con las funciones de “set” se puede manipular el interruptor de Transición que sirve para pasar el bus de Vista previa a Programa. Con las funciones de “get” se obtiene la información de posición del

Page 27: Desarrollo de una librería de comunicaciones para la

27

interruptor de Transición.

KeOn Keyer On Air bool getKeyerOnAirEnabled(uint8_t mE, uint8_t keyer) void setKeyerOnAirEnabled(uint8_t mE, uint8_t keyer, bool enabled)

Sirve para cambiar el valor del botón “On Air”, que indica si se está retransmitiendo o no, o para obtener en qué estado se encuentra.

FtbP Fade-To-Black uint8_t getFadeToBlackRate(uint8_t mE) void setFadeToBlackRate(uint8_t mE, uint8_t rate)

Sirve para modificar u obtener el valor de tiempo del “Fade to Black”.

AuxS Aux Source uint16_t getAuxSourceInput(uint8_t aUXChannel) void setAuxSourceInput(uint8_t aUXChannel, uint16_t input)

Sirve para modificar la fuente de vídeo del canal Aux o para obtener el valor de que fuente contiene.

AMIP Audio Mixer Input Varias Funciones Con el “set” se pueden modificar los valores de audio de las cámaras conectadas al mezclador. Con el “get” se puede obtener la información de los valores de audio de las cámaras conectadas.

ColV Color Generator Varias Funciones Con el “set” se puede generar un color cualquiera, por si lo tiene que usar el mezclador como salida de alguno de los buses. Con el “get” se puede obtener la información de los colores guardados en el mezclador.

Tabla 3.3.3. Comandos “sets” / “gets”

Page 28: Desarrollo de una librería de comunicaciones para la

28

3.4 Modificaciones requeridas Todas las librerías están programadas en Arduino, como ya se ha comentado anteriormente, pero, se quiere usar en un software en un dispositivo Linux. Por lo tanto, se tienen que traducir las funciones que se vayan a usar.

Las modificaciones principales que se deben realizar son las de conexión, ya que por el momento usa un método de Arduino que no puede funcionar en un ordenador Linux. Se van a usar Sockets (4.1) para poder hacer esta modificación.

Arduino trabaja directamente modificando los bytes de los paquetes, ya que no requiere ninguna dificultad a sus funciones pertenecientes a librerías Arduino. Se tienen que crear funciones equivalentes en código C/C++.

Una de las tareas más largas que se tienen que realizar, son las modificaciones de lenguaje básicas entre Arduino y C/C++. Arduino fue creado a partir de C/C++, pero al ser un lenguaje distinto todas las librerías que usa Arduino para algunas funciones se tienen que crear o buscar su equivalente en C/C++.

Page 29: Desarrollo de una librería de comunicaciones para la

29

Capítulo 4: Implementación Al estudiar las librerías, se tuvo que analizar las modificaciones que se tenían que realizar, como se ha comentado anteriormente una de las más importantes era la conexión de red.

El código con la implementación realizada se puede consultar en los anexos adjuntos a esta memoria. En el Anexo A y B se ha desarrollado las librerías ATEMbase, y en el Anexo C y D está el código de ATEMstd.

Se determinó que la mejor forma para realizar el tipo de conexiones que se necesita seria usando sockets.

4.1 Sockets La programación de sockets es una forma de conectar dos nodos en una red para comunicarse entre sí. Un socket (nodo) escucha en un puerto particular en una IP, mientras que otro socket se acerca al otro para formar una conexión. El servidor forma el socket del oyente mientras que el cliente se comunica con el servidor.

Ilustración 8. Diagrama de estado sockets UDP

Para la creación de sockets son necesarios, un descriptor de socket o “socketfd”, para poder distinguir el socket generado, la dirección IP del cliente, en nuestro caso la del mezclador y finalmente que tipo de protocolo de conexión se desea usar. En

Page 30: Desarrollo de una librería de comunicaciones para la

30

el caso de estas librerías es necesario usar el protocolo UDP, ya que se trata del mismo tipo de conexión que se usa con Arduino.

El protocolo de conexión UDP es el ideal en estas librerías, ya que genera un nivel de transporte que no añade información extra en la comunicación extremo a extremo. Es usada en tareas de control y transmisión de audio y vídeo, y gracias a que no mantiene estado de conexión, no introduce ningún tipo de retardo.

Al usar sockets se pueden enviar y recibir datos de una manera muy sencilla en el momento que se haya realizado la conexión. Otra de las ventajas de su uso son los select, que permiten manejar la conexión y bloquear el programa hasta que no detecte datos recibidos.

4.2 Modificaciones Realizadas Las modificaciones que se han tenido que realizar para que el programa funcione en C++ se pueden dividir en tres secciones,

1. Las modificaciones para que la conexión entre el programa y el mezclador funcione.

2. Las modificaciones de funciones que se usan en Arduino pero que en C++ no existen, por lo tanto, se han tenido que crear.

3. Modificaciones varias que consisten en una gran parte traducciones de sintaxis, ya que Arduino y C++ son lenguajes de programación distintos y hay ocasiones donde existen funciones en los dos, pero que su sintaxis y ejecución son distintas.

4.2.1 Modificaciones de conexión Como se ha comentado antes, para realizar la conexión con el mezclador se han usado sockets.

Se han modificado las funciones de Begin, Connect (llamada Connectto) y RunLoop.

En el Begin, ahora solo se le tiene que pasar la dirección IP del mezclador y no el puerto, aquí se crea el socket.

En el Connectto se realiza la función de connect() de sockets, y si funciona se crea una variable en estado “true” que indica que se han conectado correctamente.

Finalmente, en el RunLoop se crea un select(), con el cual, como se ha comentado con brevedad anteriormente, se genera un bloqueo en el programa. Este bloqueo se detiene en el momento que el socket reciba datos del cliente, en nuestro caso el mezclador. Al select() se le ha creado una variable timeout para que si se da el caso de que no reciba datos durante un periodo de tiempo se renueve la conexión con el mezclador.

Otro de los cambios que se han tenido que realizar que entran en el colectivo de conexión, es la función que lee el paquete entrante de datos. En Arduino existe una función que permite leer un paquete entrante de datos byte a byte, mientras que en

Page 31: Desarrollo de una librería de comunicaciones para la

31

C++ se recibe el paquete entero, con eso en mente se ha creado una función, readUDP(), que permite leer el paquete recibido de la misma manera que lo hacía el programa en Arduino.

4.2.2 Modificaciones de Funciones Arduino Algunas de las funciones utilizadas en las librerías de Arduino de SKAARHOJ no tienen equivalente en C++ y ha sido necesario reescribirlas,

Hay unas funciones que permiten manipular bytes con mucha facilidad en Arduino, que son:

• lowbyte(), que permite extraer el byte de bajo orden (más a la derecha) de una palabra 2 bytes y los extrae en otra variable.

• hightbyte(), que funciona relativamente parecido a “lowbyte()”pero extrae el byte de mayor orden.

• word(), que permite unir dos variables de 1 byte para generar una palabra de 2 bytes.

Estas tres funciones han sido traducidas a C++ e implementadas de la misma forma que se usa en Arduino.

Otra función que es muy típica de Arduino usada en las librerías es millis(). La función millis() crea un contador que cada vez que se llama a la función devuelve el valor, en milisegundos, de tiempo que se lleva ejecutando el programa. Se ha creado una muy similar que su única diferencia consiste en que se tiene que llamar en el Begin para que empiece a contar los milisegundos.

4.2.3 Modificaciones Varias Todo el código ha sido traducido a la sintaxis de C++, se han tenido que modificar varias funciones que son distintas de Arduino a C++.

Se ha modificado la inicialización de variables, las cuales no son compatibles, o la impresión por pantalla para realizar las pruebas. También se han encontrado muchas diferencias de sintaxis en el uso de binarios y hexadecimales.

4.3 Nuevo Diagrama de Flujo El nuevo Diagrama de Flujo tiene un funcionamiento muy similar al original, ya que se ha querido mantener el mismo funcionamiento de las librerías.

Como el Diagrama de Flujo anterior (3.2.7) ya explicaba el funcionamiento, solo se comentarán las modificaciones realizadas a este.

La primera diferencia se encuentra en el Begin, donde se inicializa el socket que se va a usar con su identificador. También se inicializa el contador millis() traducido que se ha creado.

Page 32: Desarrollo de una librería de comunicaciones para la

32

Serialoutput funciona de la misma manera.

En Connect en vez de hacer la conexión con la función de Arduino UDP, se usa la función connect() de sockets para enlazar el programa que esté usando las librerías con el mezclador de vídeo.

Y para finalizar, en la función RunLoop hay dos modificaciones importantes, ahora existe un select(), que ya se ha explicado anteriormente (4.2.1), que bloquea el programa hasta que no se reciban datos, de esta manera se evitan errores. En el momento que se detectan datos entrantes se ejecuta la función de sockets recv() permite recibir los datos enviados por el mezclador de vídeo hacia el vector “_buffertotal”, el cual se usará por la función readUDP() en el momento que sea necesario.

Para enviar datos al mezclador de vídeo se usa la misma función que en Arduino, “_sendPacketBuffer”, pero modificada para que use sockets. Esta, usa la función send() de sockets para enviar la información del vector “_packetbuffer” al mezclador. El funcionamiento restante de las librerías es igual al que proporciona Arduino.

4.4 Problemas Encontrados El problema principal que ha surgido, han sido las restricciones provocadas por la pandemia COVID-19, que han hecho imposible las pruebas prácticas para este proyecto. Tanto como para el estudio de las librerías en el lenguaje Arduino, las cuales no se han podido ejecutar y observar, sino que se ha deducido su forma de funcionamiento gracias a la información obtenida de sus creadores y a un arduo trabajo de investigación realizado en este proyecto.

Tampoco se han podido realizar pruebas para las librerías traducidas a causa de las mismas restricciones y al poco tiempo de margen entre el inicio de la apertura de laboratorios y el cierre de los mismos.

4.5 Trabajo Futuros A partir del trabajo realizado, el futuro de este proyecto es la implementación de un software que use las librerías para verificar la funcionalidad de las mismas.

Al verificar las librerías se podrán realizar, si fueran necesarios, los cambios necesarios para que funcionen. A raíz de las librerías implementadas se podría crear un software que funcione de manera similar al mismo mezclador de vídeo.

Page 33: Desarrollo de una librería de comunicaciones para la

33

Bibliografía Clemence, J. (2018, 13 febrero). What is a Video Switcher (Mixer)? BOXCAST. https://www.boxcast.com/blog/what-is-a-video-switcher

How to be a vision mixer. (2011, 6 septiembre). [Vídeo]. YouTube. https://www.youtube.com/watch?v=8hdlBBV4iII&ab_channel=BBCAcademy%3AProduction

Kettner Creative. (2020, 15 abril). What Does A Video Switcher Do? | Kettner Creative Audio Visual. https://kettnercreative.com/equipment/need-video-mixer/

Techopedia.com. (s. f.). Video Switcher. https://www.techopedia.com/definition/4732/video-switcher

What is a Video Switcher? (2016, 9 mayo). [Vídeo]. YouTube. https://www.youtube.com/watch?v=apaKF_lbS74&feature=emb_title&ab_channel=BoxCast

About SKAARHOJ: SKAARHOJ.com. (s. f.). SKAARHOJ. https://www.skaarhoj.com/about/about-skaarhoj/

Astro Machine Works. (2019, 9 septiembre). What Is Reverse Engineering and How Does It Work? https://astromachineworks.com/what-is-reverse-engineering/

BlackMagic Design ATEM Protocol by SKAARHOJ K/S. (2011). BMDPROTOCOL. https://www.skaarhoj.com/fileadmin/BMDPROTOCOL.html

Burgueño, P. F. (2015, 7 diciembre). La ingeniería inversa es legal en España. Abanlex. https://www.abanlex.com/2013/12/la-ingenieria-inversa-es-legal-en-espana/

Far, R. (2020, 14 septiembre). ¿Qué es la ingeniería inversa y cómo funciona? - Blog de Tecnicoo. Acento. https://acentocoop.es/blog/ingenieria-inversa/

Pastor, J. (2019, 17 junio). Así es como la ingeniería inversa cambió la historia de la informática para siempre. Xataka. https://www.xataka.com/historia-tecnologica/asi-es-como-la-ingenieria-inverso-cambio-la-historia-de-la-informatica-para-siempre

Schwartz, M. (2001, 12 noviembre). Reverse-Engineering. Computerworld. https://www.computerworld.com/article/2585652/reverse-engineering.html

ATEM Television Studio Pro 4K combina un panel de control profesional con un mezclador de ocho entradas SDI 12G. (2019, 21 diciembre). Panorama Audiovisual. https://www.panoramaaudiovisual.com/2018/04/12/blackmagic-atem-television-studio-pro-4k/

Page 34: Desarrollo de una librería de comunicaciones para la

34

Blackmagic ATEM Television Studio Pro 4K. (s. f.). Medialuz Equipamiento. https://www.medialuzequipamiento.es/producto/alquiler-blackmagic-atem-television-studio-pro-hd/

Everything You Need to Know About Arduino Code. (2019, 1 enero). circuito.io blog. https://www.circuito.io/blog/arduino-code/

What is an Arduino? - learn.sparkfun.com. (s. f.). learn.sparkfun.com. https://learn.sparkfun.com/tutorials/what-is-an-arduino/all

C++ Sockets - Server & Client - 2020. (s. f.). C++ Sockets. https://www.bogotobogo.com/cplusplus/sockets_server_client.php

lcmgcd, M. T. K. (2019, 31 mayo). Socket Programming in C/C++. GeeksforGeeks. https://www.geeksforgeeks.org/socket-programming-cc/