]> git.sesse.net Git - mlt/blobdiff - src/modules/linsys/sdi_generator.c
Avoid unnecessary compilation when running "./configure; make; make install" multiple...
[mlt] / src / modules / linsys / sdi_generator.c
index 0004f741e6c0e59583425cfe48ab988a8b25d3f8..928be548719e6f192124dd01aebbd6c30c082c23 100644 (file)
  * System No.  System nomenclature             Form of scanning        Frame rate                              Embedded Audio                  MLT profile             Linsys board support (model)
  * SD PAL              720 × 576/50/I                 interlaced                      25 HZ                                   8 x AES (16 channels)   dv_pal                  180,145,159,107
  * SD PAL              720 × 576/50/I                 interlaced                      25 HZ                                   4 x AES (8 channels)    dv_pal                  193
- * SD NTSC             720 × 480/59.94/I              interlaced                      30000/1001 ~ 29.97 HZ   8 x AES (16 channels)   sdi_486i_5994   TODO:180,145,159,107
- * SD NTSC             720 × 480/59.94/I              interlaced                      30000/1001 ~ 29.97 HZ   4 x AES (8 channels)    sdi_486i_5994   193
+ * SD NTSC             720 × 486/59.94/I              interlaced                      30000/1001 ~ 29.97 HZ   8 x AES (16 channels)   sdi_486i_5994   TODO:180,145,159,107
+ * SD NTSC             720 × 486/59.94/I              interlaced                      30000/1001 ~ 29.97 HZ   4 x AES (8 channels)    sdi_486i_5994   193
  *
  **/
 
 #include "sdi_generator.h"
 
-/*!/brief Initialization of the file handlers for the Playout
+/*!/brief initialization of the file handlers for the playout
  * @param *device_video: file or SDITX device or SDIVIDEOTX device
  * @param *device_audio: file or SDIAUDIOTX device
  * @param blanking: true or false (if false the consumer write only active video data without any VANH or HANC)
  */
-static int sdi_init(char *device_video, char *device_audio, uint8_t blanking, mlt_profile myProfile) {
+static int sdi_init(char *device_video, char *device_audio, uint8_t blanking, mlt_profile myProfile,
+               const struct audio_format * audio_format) {
 
        // set device file
        device_file_video = device_video;
        device_file_audio = device_audio;
 
-       // set flag for using of blanking with anilary data
+       // set flag for using of blanking with ancillary data
        info.blanking = blanking;
 
-       // set pack methode for SDI word conversion
-       //pack = pack8;
+       // set pack method for SDI word conversion
+       pack = pack8;
        //pack = pack10;
-       pack = pack_v210;
+       //pack = pack_v210;
 
        // check format
-       if (myProfile->width == 1920 && myProfile->height == 1080 && myProfile->frame_rate_num == 30 && myProfile->frame_rate_den == 1 && myProfile->progressive
-                       == 0) {
-               info.fmt = &FMT_1080i60;
-       } else if (myProfile->width == 1920 && myProfile->height == 1080 && myProfile->frame_rate_num == 30000 && myProfile->frame_rate_den == 1001
+       if (myProfile->width == 1920 && myProfile->height == 1080 && myProfile->frame_rate_num == 30 && myProfile->frame_rate_den == 1
                        && myProfile->progressive == 0) {
+               info.fmt = &FMT_1080i60;
+               sdi_frame_mode = SDIVIDEO_CTL_SMPTE_274M_1080I_60HZ;
+       } else if (myProfile->width == 1920 && myProfile->height == 1080 && myProfile->frame_rate_num == 30000 && myProfile->frame_rate_den
+                       == 1001 && myProfile->progressive == 0) {
                info.fmt = &FMT_1080i5994;
+               sdi_frame_mode = SDIVIDEO_CTL_SMPTE_274M_1080I_59_94HZ;
        } else if (myProfile->width == 1920 && myProfile->height == 1080 && myProfile->frame_rate_num == 25 && myProfile->frame_rate_den == 1
                        && myProfile->progressive == 0) {
                info.fmt = &FMT_1080i50;
+               sdi_frame_mode = SDIVIDEO_CTL_SMPTE_274M_1080I_50HZ;
        } else if (myProfile->width == 1920 && myProfile->height == 1080 && myProfile->frame_rate_num == 30 && myProfile->frame_rate_den == 1
                        && myProfile->progressive == 1) {
                info.fmt = &FMT_1080p30;
-       } else if (myProfile->width == 1920 && myProfile->height == 1080 && myProfile->frame_rate_num == 30000 && myProfile->frame_rate_den == 1001
-                       && myProfile->progressive == 1) {
+               sdi_frame_mode = SDIVIDEO_CTL_SMPTE_274M_1080P_30HZ;
+       } else if (myProfile->width == 1920 && myProfile->height == 1080 && myProfile->frame_rate_num == 30000 && myProfile->frame_rate_den
+                       == 1001 && myProfile->progressive == 1) {
                info.fmt = &FMT_1080p2997;
+               sdi_frame_mode = SDIVIDEO_CTL_SMPTE_274M_1080P_29_97HZ;
        } else if (myProfile->width == 1920 && myProfile->height == 1080 && myProfile->frame_rate_num == 25 && myProfile->frame_rate_den == 1
                        && myProfile->progressive == 1) {
                info.fmt = &FMT_1080p25;
+               sdi_frame_mode = SDIVIDEO_CTL_SMPTE_274M_1080P_25HZ;
        } else if (myProfile->width == 1920 && myProfile->height == 1080 && myProfile->frame_rate_num == 24 && myProfile->frame_rate_den == 1
                        && myProfile->progressive == 1) {
                info.fmt = &FMT_1080p24;
-       } else if (myProfile->width == 1920 && myProfile->height == 1080 && myProfile->frame_rate_num == 24000 && myProfile->frame_rate_den == 1001
-                       && myProfile->progressive == 1) {
+               sdi_frame_mode = SDIVIDEO_CTL_SMPTE_274M_1080P_24HZ;
+       } else if (myProfile->width == 1920 && myProfile->height == 1080 && myProfile->frame_rate_num == 24000 && myProfile->frame_rate_den
+                       == 1001 && myProfile->progressive == 1) {
                info.fmt = &FMT_1080p2398;
+               sdi_frame_mode = SDIVIDEO_CTL_SMPTE_274M_1080P_23_98HZ;
        } else if (myProfile->width == 1280 && myProfile->height == 720 && myProfile->frame_rate_num == 60 && myProfile->frame_rate_den == 1
                        && myProfile->progressive == 1) {
                info.fmt = &FMT_720p60;
-       } else if (myProfile->width == 1280 && myProfile->height == 720 && myProfile->frame_rate_num == 60000 && myProfile->frame_rate_den == 1001
-                       && myProfile->progressive == 1) {
+               sdi_frame_mode = SDIVIDEO_CTL_SMPTE_296M_720P_60HZ;
+       } else if (myProfile->width == 1280 && myProfile->height == 720 && myProfile->frame_rate_num == 60000 && myProfile->frame_rate_den
+                       == 1001 && myProfile->progressive == 1) {
                info.fmt = &FMT_720p5994;
+               sdi_frame_mode = SDIVIDEO_CTL_SMPTE_296M_720P_59_94HZ;
        } else if (myProfile->width == 1280 && myProfile->height == 720 && myProfile->frame_rate_num == 50 && myProfile->frame_rate_den == 1
                        && myProfile->progressive == 1) {
                info.fmt = &FMT_720p50;
+               sdi_frame_mode = SDIVIDEO_CTL_SMPTE_296M_720P_50HZ;
        } else if (myProfile->width == 1280 && myProfile->height == 720 && myProfile->frame_rate_num == 30 && myProfile->frame_rate_den == 1
                        && myProfile->progressive == 1) {
                info.fmt = &FMT_720p30;
-       } else if (myProfile->width == 1280 && myProfile->height == 720 && myProfile->frame_rate_num == 30000 && myProfile->frame_rate_den == 1001
-                       && myProfile->progressive == 1) {
+               sdi_frame_mode = SDIVIDEO_CTL_SMPTE_296M_720P_30HZ;
+       } else if (myProfile->width == 1280 && myProfile->height == 720 && myProfile->frame_rate_num == 30000 && myProfile->frame_rate_den
+                       == 1001 && myProfile->progressive == 1) {
                info.fmt = &FMT_720p2997;
+               sdi_frame_mode = SDIVIDEO_CTL_SMPTE_296M_720P_29_97HZ;
        } else if (myProfile->width == 1280 && myProfile->height == 720 && myProfile->frame_rate_num == 25 && myProfile->frame_rate_den == 1
                        && myProfile->progressive == 1) {
                info.fmt = &FMT_720p25;
+               sdi_frame_mode = SDIVIDEO_CTL_SMPTE_296M_720P_25HZ;
        } else if (myProfile->width == 1280 && myProfile->height == 720 && myProfile->frame_rate_num == 24 && myProfile->frame_rate_den == 1
                        && myProfile->progressive == 1) {
                info.fmt = &FMT_720p24;
-       } else if (myProfile->width == 1280 && myProfile->height == 720 && myProfile->frame_rate_num == 24000 && myProfile->frame_rate_den == 1001
-                       && myProfile->progressive == 1) {
+               sdi_frame_mode = SDIVIDEO_CTL_SMPTE_296M_720P_24HZ;
+       } else if (myProfile->width == 1280 && myProfile->height == 720 && myProfile->frame_rate_num == 24000 && myProfile->frame_rate_den
+                       == 1001 && myProfile->progressive == 1) {
                info.fmt = &FMT_720p2398;
+               sdi_frame_mode = SDIVIDEO_CTL_SMPTE_296M_720P_23_98HZ;
        } else if (myProfile->width == 720 && myProfile->height == 576 && myProfile->frame_rate_num == 25 && myProfile->frame_rate_den == 1
                        && myProfile->progressive == 0) {
                info.fmt = &FMT_576i50;
-       } else if (myProfile->width == 720 && myProfile->height == 480 && myProfile->frame_rate_num == 30000 && myProfile->frame_rate_den == 1001
-                       && myProfile->progressive == 0) {
+               sdi_frame_mode = SDIVIDEO_CTL_BT_601_576I_50HZ;
+       } else if (myProfile->width == 720 && myProfile->height == 486 && myProfile->frame_rate_num == 30000 && myProfile->frame_rate_den
+                       == 1001 && myProfile->progressive == 0) {
+               info.fmt = &FMT_486i5994;
+               sdi_frame_mode = SDIVIDEO_CTL_SMPTE_125M_486I_59_94HZ;
+       } else if (myProfile->width == 720 && myProfile->height == 480 && myProfile->frame_rate_num == 30000 && myProfile->frame_rate_den
+                       == 1001 && myProfile->progressive == 0) {
                info.fmt = &FMT_480i5994;
+               sdi_frame_mode = SDIVIDEO_CTL_SMPTE_125M_486I_59_94HZ;
        } else {
-               printf("Consumer gets unknown format: %s", myProfile->description);
+               printf("Consumer got unknown format: %s", myProfile->description);
                info.fmt = &FMT_576i50;
+               sdi_frame_mode = SDIVIDEO_CTL_BT_601_576I_50HZ;
        }
 
-       printf("Consumer use format: %s\nProfile: %i %i %i %i %i\n", myProfile->description, myProfile->width, myProfile->height, myProfile->frame_rate_num,
-                       myProfile->frame_rate_den, myProfile->progressive);
+       printf("Consumer use format: %s\nProfile: %i %i %i %i %i\n", myProfile->description, myProfile->width, myProfile->height,
+                       myProfile->frame_rate_num, myProfile->frame_rate_den, myProfile->progressive);
 
-       // Check if the format support own blanking (note: model 193 support currently only active video at the video device file)
+       // Check if the format supports own blanking (note: model 193 supports currently only active video at the video device file)
        if (info.blanking && info.fmt != &FMT_576i50) {
-               printf("SDI consumer doesn't support blanking(HANC) for this configurred SD board and SDI format. Try arguemnt: blanking=false\n");
+               printf("SDI consumer doesn't support blanking(HANC) for the configured SD board and SDI format. Try argument: blanking=false\n");
                return EXIT_FAILURE;
        }
 
-       if (device_file_video != NULL) {
-               // open file handler for SDI(video) output
-               if ((fh_sdi_video = open(device_file_video, O_WRONLY)) == -1) {
-                       perror(NULL);
-                       printf("\ncould not open video output destination: %s\n", device_file_video);
-               }
-               printf("SDI consumer use video device file: %s\n", device_file_video);
-       }
-
-       // Check if seperat device file for audio must use
-       if (device_file_audio != NULL) {
-               // open file handler for audio output
-               if ((fh_sdi_audio = open(device_file_audio, O_WRONLY | O_CREAT, 0777)) == -1) {
-                       perror(NULL);
-                       printf("\ncould not open audio output destination: %s\n", device_file_audio);
-                       return EXIT_FAILURE;
-               }
-               printf("SDI consumer use audio device file: %s\n", device_file_audio);
-       }
-
        // if we write our own HANC we need an AES channel status bit array
        if (info.blanking) {
 
@@ -248,7 +252,7 @@ static int sdi_init(char *device_video, char *device_audio, uint8_t blanking, ml
                        AESChannelStatusBitArray[i] = 0;
 
                /**
-                * Professionel Format - Channel Status Bits
+                * Professional Format - Channel Status Bits
                 **/
                ////// Byte 0 //////
                AESChannelStatusBitArray[0] = 1; // professional format
@@ -261,7 +265,7 @@ static int sdi_init(char *device_video, char *device_audio, uint8_t blanking, ml
 
                AESChannelStatusBitArray[5] = 0; // locked
 
-               AESChannelStatusBitArray[6] = 0; // sample frequncy Fs: [01]48kHz, [10]44kHz, [11]32kHz
+               AESChannelStatusBitArray[6] = 0; // sample frequency Fs: [01]48kHz, [10]44kHz, [11]32kHz
                AESChannelStatusBitArray[7] = 1; // ^
                ////// Byte 1 //////
                AESChannelStatusBitArray[8] = 0; // channel mode: [0000] not indicated, [0001]2channels, [0010]1channel mono, ...
@@ -303,7 +307,7 @@ static int sdi_init(char *device_video, char *device_audio, uint8_t blanking, ml
        line_buffer = (uint16_t*) calloc(info.fmt->samples_per_line, sizeof(uint16_t));
 
        // calculate and set buffer for the complete SDI frame
-       if (info.fmt != &FMT_576i50 && info.fmt != &FMT_480i5994) {
+       if (info.fmt != &FMT_576i50 && info.fmt != &FMT_486i5994) {
                if (info.blanking) {
                        if (pack == pack_v210) {
                                samples = (info.fmt->samples_per_line / 96 * 48) + ((info.fmt->samples_per_line % 96) ? 48 : 0);
@@ -339,13 +343,114 @@ static int sdi_init(char *device_video, char *device_audio, uint8_t blanking, ml
                }
        }
 
-       // hack/overwrite because we use default the pack_v210() not as befor the pack10()
-       //(*10/8 because we store (TOTAL_SAMPLES*TOTAL_LINES) words with 10 bit in this 8 bit array) )
+       // (*10/8 because we store (TOTAL_SAMPLES*TOTAL_LINES) words with 10 bit in this 8 bit array) )
        if (info.fmt == &FMT_576i50 && info.blanking) {
                sdi_frame_size = info.fmt->samples_per_line * 10 / 8 * info.fmt->lines_per_frame;
        }
 
-       printf("SDI frame size:%li\n", sdi_frame_size);
+       if (info.blanking) {
+               printf("SDI frame size: %"PRIu64"\n", sdi_frame_size);
+       } else {
+               printf("Frame size for active video: %"PRIu64"\n", sdi_frame_size);
+       }
+
+       /**
+        * Setup HD-SDI Master device (vidport):
+        *
+        * if device_file_video available then
+        *      if vidport available
+        *              1. setup
+        *      end
+        *      1. open device file handler
+        *
+        *      if device_file_audio available then
+        *              1. setup
+        *              2. open device file handler
+        *      end
+        * end
+        **/
+       if (device_file_video != NULL) {
+
+               // If we use a Linsys HD board with active video (without blanking) setup the board for the used mode
+               if (strstr(device_file_video, "sdivideotx") != NULL && !info.blanking) {
+
+                       char * value;
+
+                       // Buffer size
+                       value = itoa(sdi_frame_size);
+                       setSDIVideoProperties(SETTING_BUFFER_SIZE_VIDEO, value, device_video);
+                       free(value);
+
+                       // Frame Mode
+                       value = itoa(sdi_frame_mode);
+                       setSDIVideoProperties(SETTING_FRAME_MODE, value, device_video);
+                       free(value);
+
+                       // Data Mode
+                       if (pack == pack8)
+                               setSDIVideoProperties(SETTING_DATA_MODE, "0", device_video);
+                       else if (pack == pack_v210)
+                               setSDIVideoProperties(SETTING_DATA_MODE, "1", device_video);
+               }
+
+               // open file handle for SDI(video) output
+               if ((fh_sdi_video = open(device_file_video, O_WRONLY)) == -1) {
+                       perror(NULL);
+                       printf("\ncould not open video output destination: %s\n", device_file_video);
+                       return EXIT_FAILURE;
+               }
+               printf("SDI consumer uses video device file: %s\n", device_file_video);
+
+               // Check if we have to use a separate device file for audio
+               if (device_file_audio != NULL) {
+
+                       // set settings for audio device file
+                       if (strstr(device_file_audio, "sdiaudiotx") != NULL && !info.blanking) {
+
+                               char * value;
+
+                               /**
+                                * prepare sample size
+                                * MLT suports: 16bit, 32bit
+                                * LINSYS SDI boards supports: 16bit, 24bit, 32bit
+                                * we set 16bit as default
+                                **/
+                               uint8_t sample_size = audio_format->aformat == mlt_audio_s32 ? 32 : 16;
+
+                               // Buffer size
+                               // audio buffer per frame (Bytes) = sample rate / frame rate * ( sample size / 1Byte ) x channels
+                               value = itoa(
+                                               (uint64_t) audio_format->sample_rate / ( (uint64_t) myProfile->frame_rate_num / (uint64_t) myProfile->frame_rate_den) * (uint64_t) sample_size / 8
+                                                               * (uint64_t) audio_format->channels);
+                               setSDIAudioProperties(SETTING_BUFFER_SIZE_AUDIO, value, device_audio);
+                               free(value);
+
+                               // channels
+                               value = itoa(audio_format->channels);
+                               setSDIAudioProperties(SETTING_CHANNELS, value, device_audio);
+                               free(value);
+
+                               // sample rate
+                               value = itoa(audio_format->sample_rate);
+                               setSDIAudioProperties(SETTING_SAMPEL_RATE, value, device_audio);
+                               free(value);
+
+                               // sample size
+                               value = itoa(sample_size);
+                               setSDIAudioProperties(SETTING_SAMPLE_SIZE, value, device_audio);
+                               free(value);
+                       }
+
+                       // open file handle for audio output
+                       if ((fh_sdi_audio = open(device_file_audio, O_WRONLY)) == -1) {
+                               perror(NULL);
+                               printf("\nCould not open audio output destination: %s\n", device_file_audio);
+                               return EXIT_FAILURE;
+                       }
+                       printf("SDI consumer uses audio device file: %s\n", device_file_audio);
+               }
+
+       }
 
        // set buffer for the complete SDI frame
        data = (uint8_t*) calloc(sdi_frame_size, sizeof(uint8_t));
@@ -361,8 +466,8 @@ static int sdi_init(char *device_video, char *device_audio, uint8_t blanking, ml
  * @param audio_streams: number of audio streams which have content in aBuffer (available 0-8)
  * @return current DBN (data block number of SDI frame)
  **/
-static int sdi_playout(uint8_t *vBuffer, int16_t aBuffer[MAX_AUDIO_STREAMS][MAX_AUDIO_SAMPLES], const struct audio_format * audio_format, int audio_streams,
-               int my_DBN) {
+static int sdi_playout(uint8_t *vBuffer, int16_t aBuffer[MAX_AUDIO_STREAMS][MAX_AUDIO_SAMPLES], const struct audio_format * audio_format,
+               int audio_streams, int my_DBN) {
 
        // Pointer to the start of data. This is used to fill data line by line
        uint8_t *p = data;
@@ -414,8 +519,8 @@ static int sdi_playout(uint8_t *vBuffer, int16_t aBuffer[MAX_AUDIO_STREAMS][MAX_
                info.xyz = &FIELD_1_ACTIVE;
                int f1counter = 1; // only odd lines
                for (i = 23; i <= 310; i++) {
-                       create_SD_SDI_Line(line_buffer, &info, FIELD_1, ACTIVE_VIDEO, vBuffer, aBuffer, i, f1counter, getDBN(my_DBN++), AudioGroupCounter,
-                                       getNumberOfAudioGroups2Write(i), audio_streams);
+                       create_SD_SDI_Line(line_buffer, &info, FIELD_1, ACTIVE_VIDEO, vBuffer, aBuffer, i, f1counter, getDBN(my_DBN++),
+                                       AudioGroupCounter, getNumberOfAudioGroups2Write(i), audio_streams);
                        AudioGroupCounter += getNumberOfAudioGroups2Write(i);
                        p = pack10(p, line_buffer, info.fmt->samples_per_line);
                        f1counter += 2;
@@ -487,8 +592,8 @@ static int sdi_playout(uint8_t *vBuffer, int16_t aBuffer[MAX_AUDIO_STREAMS][MAX_
                int f2counter = 2; // only even Lines
                for (i = 336; i <= 623; i++) {
 
-                       create_SD_SDI_Line(line_buffer, &info, FIELD_2, ACTIVE_VIDEO, vBuffer, aBuffer, i, f2counter, getDBN(my_DBN++), AudioGroupCounter,
-                                       getNumberOfAudioGroups2Write(i), audio_streams);
+                       create_SD_SDI_Line(line_buffer, &info, FIELD_2, ACTIVE_VIDEO, vBuffer, aBuffer, i, f2counter, getDBN(my_DBN++),
+                                       AudioGroupCounter, getNumberOfAudioGroups2Write(i), audio_streams);
                        AudioGroupCounter += getNumberOfAudioGroups2Write(i);
                        p = pack10(p, line_buffer, info.fmt->samples_per_line);
                        f2counter += 2;
@@ -638,7 +743,22 @@ static int sdi_playout(uint8_t *vBuffer, int16_t aBuffer[MAX_AUDIO_STREAMS][MAX_
 
                                /**
                                 *  Generate an SDI NTSC frame
+                                *
+                                *
+                                *   16 lines   VERT_BLANKING   FIELD_1_VERT_BLANKING
+                                *    1 lines   VERT_BLANKING   FIELD_1_ACTIVE
+                                *    3 lines   ACTIVE_VIDEO    FIELD_1_ACTIVE                  (opt. video data)
+                                *  240 lines   ACTIVE_VIDEO    FIELD_1_ACTIVE
+                                *    2 lines   VERT_BLANKING   FIELD_1_VERT_BLANKING
+                                *
+                                *    8 lines   VERT_BLANKING   FIELD_2_VERT_BLANKING
+                                *    9 lines   VERT_BLANKING   FIELD_2_VERT_BLANKING
+                                *    3 lines   ACTIVE_VIDEO    FIELD_2_ACTIVE                  (opt. video data)
+                                *  240 lines   ACTIVE_VIDEO    FIELD_2_ACTIVE
+                                *    4 lines   VERT_BLANKING   FIELD_2_VERT_BLANKING
+                                *
                                 **/
+
                                elements = info.fmt->active_samples_per_line;
 
                                active_video_line = 1;
@@ -657,29 +777,42 @@ static int sdi_playout(uint8_t *vBuffer, int16_t aBuffer[MAX_AUDIO_STREAMS][MAX_
                                }
 
                                info.xyz = &FIELD_1_ACTIVE;
-                               // 3 lines opt. video data
-                               for (info.ln = 17; info.ln <= 19; info.ln++) {
-                                       mkline(line_buffer, &info, BLACK);
-                                       p = pack(p, line_buffer, elements);
-                               }
-                               for (info.ln = 20; info.ln <= 259; info.ln++) {
-                                       create_HD_SDI_Line(line_buffer, &info, active_video_line, ACTIVE_VIDEO, vBuffer);
-                                       p = pack(p, line_buffer, elements);
-                                       active_video_line += 2;
+
+                               // 480 or 486 lines
+                               if (info.fmt == &FMT_480i5994) {
+                                       // 3 lines opt. video data
+                                       for (info.ln = 17; info.ln <= 19; info.ln++) {
+                                               mkline(line_buffer, &info, BLACK);
+                                               p = pack(p, line_buffer, elements);
+                                       }
+                                       // 240 lines
+                                       for (info.ln = 20; info.ln <= 259; info.ln++) {
+                                               create_HD_SDI_Line(line_buffer, &info, active_video_line, ACTIVE_VIDEO, vBuffer);
+                                               p = pack(p, line_buffer, elements);
+                                               active_video_line += 2;
+                                       }
+                               } else {
+                                       // 243 lines
+                                       for (info.ln = 17; info.ln <= 259; info.ln++) {
+                                               create_HD_SDI_Line(line_buffer, &info, active_video_line, ACTIVE_VIDEO, vBuffer);
+                                               p = pack(p, line_buffer, elements);
+                                               active_video_line += 2;
+                                       }
                                }
                                if (info.blanking) {
+                                       // 2 lines vertical data
                                        info.xyz = &FIELD_1_VERT_BLANKING;
                                        for (info.ln = 260; info.ln <= 261; info.ln++) {
                                                create_HD_SDI_Line(line_buffer, &info, 0, VERT_BLANKING, vBuffer);
                                                p = pack(p, line_buffer, elements);
                                        }
+                                       // 8 lines vertical data
                                        info.xyz = &FIELD_2_VERT_BLANKING;
-                                       // 7 lines vertical data
                                        for (info.ln = 262; info.ln <= 269; info.ln++) {
                                                create_HD_SDI_Line(line_buffer, &info, 0, VERT_BLANKING, vBuffer);
                                                p = pack(p, line_buffer, elements);
                                        }
-                                       // 9 lines opt. video data ?? // TODO have look to SMPTE
+                                       // 9 lines
                                        for (info.ln = 270; info.ln <= 278; info.ln++) {
                                                create_HD_SDI_Line(line_buffer, &info, 0, VERT_BLANKING, vBuffer);
                                                p = pack(p, line_buffer, elements);
@@ -688,17 +821,30 @@ static int sdi_playout(uint8_t *vBuffer, int16_t aBuffer[MAX_AUDIO_STREAMS][MAX_
                                }
 
                                active_video_line = 0;
-                               // 3 lines opt. video data
-                               info.xyz = &FIELD_2_ACTIVE;
-                               for (info.ln = 279; info.ln <= 281; info.ln++) {
-                                       mkline(line_buffer, &info, BLACK);
-                                       p = pack(p, line_buffer, elements);
-                               }
-                               for (info.ln = 282; info.ln <= 521; info.ln++) {
-                                       create_HD_SDI_Line(line_buffer, &info, active_video_line, ACTIVE_VIDEO, vBuffer);
-                                       p = pack(p, line_buffer, elements);
-                                       active_video_line += 2;
+
+                               // 480 or 486 lines
+                               if (info.fmt == &FMT_480i5994) {
+                                       // 3 lines opt. video data
+                                       info.xyz = &FIELD_2_ACTIVE;
+                                       for (info.ln = 279; info.ln <= 281; info.ln++) {
+                                               mkline(line_buffer, &info, BLACK);
+                                               p = pack(p, line_buffer, elements);
+                                       }
+                                       // 240 lines
+                                       for (info.ln = 282; info.ln <= 521; info.ln++) {
+                                               create_HD_SDI_Line(line_buffer, &info, active_video_line, ACTIVE_VIDEO, vBuffer);
+                                               p = pack(p, line_buffer, elements);
+                                               active_video_line += 2;
+                                       }
+                               } else {
+                                       // 243 lines
+                                       for (info.ln = 279; info.ln <= 521; info.ln++) {
+                                               create_HD_SDI_Line(line_buffer, &info, active_video_line, ACTIVE_VIDEO, vBuffer);
+                                               p = pack(p, line_buffer, elements);
+                                               active_video_line += 2;
+                                       }
                                }
+                               // 4 lines vertical data
                                if (info.blanking) {
                                        info.xyz = &FIELD_2_VERT_BLANKING;
                                        for (info.ln = 522; info.ln <= 525; info.ln++) {
@@ -784,27 +930,28 @@ static int sdi_playout(uint8_t *vBuffer, int16_t aBuffer[MAX_AUDIO_STREAMS][MAX_
                        return -1;
                }
                bytes += written_bytes;
+       }
 
-               // Check for events of the SDI board
-               unsigned int val;
-               if (ioctl(fh_sdi_video, SDI_IOC_TXGETEVENTS, &val) < 0) {
-                       // Maybe this is not an SDI device...
-                       fprintf(stderr, "SDI VIDEO output:");
-                       perror("unable to get the transmitter event flags");
-               } else if (val) {
-                       if (val & SDI_EVENT_TX_BUFFER) {
-                               printf("SDI VIDEO driver transmit buffer queue underrun "
-                                       "detected.\n");
-                       }
-                       if (val & SDI_EVENT_TX_FIFO) {
-                               printf("SDI VIDEO onboard transmit FIFO underrun detected.\n");
-                               // TODO react
-                       }
-                       if (val & SDI_EVENT_TX_DATA) {
-                               printf("SDI VIDEO transmit data change detected.\n");
-                       }
+       // Check for events of the SDI board
+       unsigned int val;
+       if (ioctl(fh_sdi_video, SDI_IOC_TXGETEVENTS, &val) < 0) {
+               // Maybe this is not an SDI device...
+               //fprintf(stderr, "SDI VIDEO output:");
+               //perror("unable to get the transmitter event flags");
+       } else if (val) {
+               if (val & SDI_EVENT_TX_BUFFER) {
+                       printf("SDI VIDEO driver transmit buffer queue underrun "
+                               "detected.\n");
+                       fflush(stdout);
+               }
+               if (val & SDI_EVENT_TX_FIFO) {
+                       printf("SDI VIDEO onboard transmit FIFO underrun detected.\n");
+                       fflush(stdout);
+               }
+               if (val & SDI_EVENT_TX_DATA) {
+                       printf("SDI VIDEO transmit data change detected.\n");
+                       fflush(stdout);
                }
-               fflush(stdout);
        }
 
        // if available write audio data
@@ -814,7 +961,6 @@ static int sdi_playout(uint8_t *vBuffer, int16_t aBuffer[MAX_AUDIO_STREAMS][MAX_
                written_bytes = 0;
 
                // set number of samples and cut by 1600 if NTSC (handle problem of real time encoding of NTSC frequencies)
-               //size_t samples_total_per_track = audio_format->samples == 1601 || audio_format->samples == 1602 ? 1600 : audio_format->samples; // TODO buffer underrun by NTSC frequencs because of 3/2 pull down
                size_t samples_total_per_track = audio_format->samples;
                uint16_t sample_number = 0;
                size_t channels_per_track_total = 2;
@@ -828,7 +974,7 @@ static int sdi_playout(uint8_t *vBuffer, int16_t aBuffer[MAX_AUDIO_STREAMS][MAX_
                // set total bytes per session
                size_t bytes_total = 0;
                bytes_total = audio_format->aformat == mlt_audio_s16 ? channels_per_track_total * sizeof(int16_t) : bytes_total;
-               bytes_total = audio_format->aformat == mlt_audio_s32 ? channels_per_track_total * sizeof(int32_t) : bytes_total; // TODO sdi board must be pre-configured for 32bit samples!!!!
+               bytes_total = audio_format->aformat == mlt_audio_s32 ? channels_per_track_total * sizeof(int32_t) : bytes_total;
 
                // write all samples of all streams interleaved
                /**
@@ -873,8 +1019,8 @@ static int sdi_playout(uint8_t *vBuffer, int16_t aBuffer[MAX_AUDIO_STREAMS][MAX_
                                // n = number of channels per stream
                                written_bytes = 0;
                                while (written_bytes < bytes_total) {
-                                       written_bytes += write(fh_sdi_audio, (uint8_t *) aBuffer[stream_number] + sample_number * bytes_total + written_bytes, bytes_total
-                                                       - written_bytes);
+                                       written_bytes += write(fh_sdi_audio, (uint8_t *) aBuffer[stream_number] + sample_number * bytes_total + written_bytes,
+                                                       bytes_total - written_bytes);
                                }
                                sum_written_bytes += written_bytes;
                                sum_written_bytes_a += written_bytes;
@@ -883,14 +1029,15 @@ static int sdi_playout(uint8_t *vBuffer, int16_t aBuffer[MAX_AUDIO_STREAMS][MAX_
                        }
 
                        // write pseudo tracks
-                       // now fill rest of audio tracks with NULL or copy of first track
-                       while (stream_number < 4) { // TODO linsys board model 193 have a limit to 4 AES groups (=4streams,8channels)
+                       // now fill rest of audio tracks(AES frames) with NULL or copy of first track
+                       while (stream_number < audio_format->channels / 2) {
 
                                // write for every stream n samples
                                // n = number of channels per stream
                                written_bytes = 0;
                                while (written_bytes < bytes_total) {
-                                       written_bytes += write(fh_sdi_audio, (uint8_t *) aBuffer[0] + sample_number * bytes_total + written_bytes, bytes_total - written_bytes);
+                                       written_bytes += write(fh_sdi_audio, (uint8_t *) aBuffer[0] + sample_number * bytes_total + written_bytes,
+                                                       bytes_total - written_bytes);
                                }
                                sum_written_bytes += written_bytes;
                                sum_written_bytes_b += written_bytes;
@@ -900,25 +1047,24 @@ static int sdi_playout(uint8_t *vBuffer, int16_t aBuffer[MAX_AUDIO_STREAMS][MAX_
 
                        sample_number++;
 
-//                     // Check for events of the SDI board (only firmware 0.9)
-//                     unsigned int val;
-//                     if (ioctl(fh_sdi_audio, SDI_IOC_TXGETEVENTS, &val) < 0) {
-//                             //Maybe this is not an SDI device...
-//                             fprintf(stderr, "SDI AUDIO output:");
-//                             perror("unable to get the transmitter event flags");
-//                     } else if (val) {
-//                             if (val & SDI_EVENT_TX_BUFFER) {
-//                                     printf("SDI AUDIO driver transmit buffer queue underrun "
-//                                             "detected.\n");
-//                             }
-//                             if (val & SDI_EVENT_TX_FIFO) {
-//                                     printf("SDI AUDIO onboard transmit FIFO underrun detected.\n");
-//                                     //TODO react
-//                             }
-//                             if (val & SDI_EVENT_TX_DATA) {
-//                                     printf("SDI AUDIO transmit data change detected.\n");
-//                             }
-//                     }
+                       // Check for events of the SDI audio device
+                       unsigned int val;
+                       if (ioctl(fh_sdi_audio, SDIAUDIO_IOC_TXGETEVENTS, &val) < 0) {
+                               //Maybe this is not an SDI device...
+                               //                              fprintf(stderr, "SDI AUDIO output:");
+                               //                              perror("unable to get the transmitter event flags");
+                       } else if (val) {
+                               if (val & SDIAUDIO_EVENT_TX_BUFFER) {
+                                       printf("SDI AUDIO driver transmit buffer queue underrun "
+                                               "detected.\n");
+                               }
+                               if (val & SDIAUDIO_EVENT_TX_FIFO) {
+                                       printf("SDI AUDIO onboard transmit FIFO underrun detected.\n");
+                               }
+                               if (val & SDIAUDIO_EVENT_TX_DATA) {
+                                       printf("SDI AUDIO transmit data change detected.\n");
+                               }
+                       }
                }
        }
 
@@ -943,8 +1089,8 @@ static int sdi_playout(uint8_t *vBuffer, int16_t aBuffer[MAX_AUDIO_STREAMS][MAX_
  * @param audio_streams: number of audio streams to integrate
  */
 static inline int create_SD_SDI_Line(uint16_t *buf, const struct line_info *info, int field, int active, uint8_t *video_buffer,
-               int16_t audio_buffer[MAX_AUDIO_STREAMS][MAX_AUDIO_SAMPLES], int linenumber_sdiframe, int active_video_line, int my_DBN, int16_t AudioGroupCounter,
-               int16_t AudioGroups2Write, int audio_streams) {
+               int16_t audio_buffer[MAX_AUDIO_STREAMS][MAX_AUDIO_SAMPLES], int linenumber_sdiframe, int active_video_line, int my_DBN,
+               int16_t AudioGroupCounter, int16_t AudioGroups2Write, int audio_streams) {
 
        // write line with TRS(EAV) ANC(audio) TRS(SAV) activeVideo(CbY1CrY2)
        //                                      *************************************************************************
@@ -1039,6 +1185,14 @@ static inline int create_SD_SDI_Line(uint16_t *buf, const struct line_info *info
        *p++ = info->xyz->sav;
        //#########################################################################################
 
+
+       // Because we skip the first line of video, it can happen that we read too far in the buffer
+       if (active_video_line >= info->fmt->active_lines_per_frame) {
+               active_video_line = info->fmt->active_lines_per_frame - 1; // in SD PAL was set 575
+       }
+       //Index of the start of the current line in the video_buffer
+       int start_of_current_line = active_video_line * info->fmt->active_samples_per_line;
+
        // If VBlank then fill the line with 0x200 and 0x040 (total black)
        switch (active) {
        default:
@@ -1055,30 +1209,25 @@ static inline int create_SD_SDI_Line(uint16_t *buf, const struct line_info *info
 
                        // shift "<< 2" because 8 bit data in 10 bit word
 
-                       // Because we skip the first line of video, it can happen that we read too far in the buffer
-                       if (active_video_line >= info->fmt->active_lines_per_frame) {
-                               active_video_line = info->fmt->active_lines_per_frame - 1; // in SD PAL was set 575
-                       }
-
-                       *p = video_buffer[(active_video_line * 1440) + ((p - 288) - buf) + 1] << 2; // Cb
+                       *p = video_buffer[start_of_current_line + ((p - 288) - buf) + 1] << 2; // Cb
                        p++;
                        if (*(p - 1) < 0x040)
                                *(p - 1) = 0x040; // check values
                        if (*(p - 1) > 0x3c0)
                                *(p - 1) = 0x3c0;
-                       *p = video_buffer[(active_video_line * 1440) + ((p - 288) - buf) - 1] << 2; // Y1
+                       *p = video_buffer[start_of_current_line + ((p - 288) - buf) - 1] << 2; // Y1
                        p++;
                        if (*(p - 1) < 0x040)
                                *(p - 1) = 0x040;
                        if (*(p - 1) > 0x3ac)
                                *(p - 1) = 0x3ac;
-                       *p = video_buffer[(active_video_line * 1440) + ((p - 288) - buf) + 1] << 2; // Cr
+                       *p = video_buffer[start_of_current_line + ((p - 288) - buf) + 1] << 2; // Cr
                        p++;
                        if (*(p - 1) < 0x040)
                                *(p - 1) = 0x040;
                        if (*(p - 1) > 0x3c0)
                                *(p - 1) = 0x3c0;
-                       *p = video_buffer[(active_video_line * 1440) + ((p - 288) - buf) - 1] << 2; // Y2
+                       *p = video_buffer[start_of_current_line + ((p - 288) - buf) - 1] << 2; // Y2
                        p++;
                        if (*(p - 1) < 0x040)
                                *(p - 1) = 0x040;
@@ -1101,10 +1250,17 @@ static inline int create_SD_SDI_Line(uint16_t *buf, const struct line_info *info
  *
  * Returns a negative error code on failure and zero on success.
  **/
-static inline int create_HD_SDI_Line(uint16_t *buf, const struct line_info *info, uint16_t active_video_line, unsigned int active, uint8_t *video_buffer) {
+static inline int create_HD_SDI_Line(uint16_t *buf, const struct line_info *info, uint16_t active_video_line, unsigned int active,
+               uint8_t *video_buffer) {
        uint16_t *p = buf, *endp, ln;
        uint16_t samples = info->blanking ? info->fmt->samples_per_line : info->fmt->active_samples_per_line;
 
+       if (active_video_line >= info->fmt->active_lines_per_frame) {
+               active_video_line = info->fmt->active_lines_per_frame - 1;
+       }
+
+       int start_of_current_line = active_video_line * info->fmt->active_samples_per_line;
+
        if (info->blanking) {
 
                // write line with TRS(EAV) ANC(audio) TRS(SAV) activeVideo(CbY1CrY2)
@@ -1199,42 +1355,29 @@ static inline int create_HD_SDI_Line(uint16_t *buf, const struct line_info *info
 
                while (p < (buf + samples)) {
 
-                       if (active_video_line >= info->fmt->active_lines_per_frame) {
-                               active_video_line = info->fmt->active_lines_per_frame - 1;
-                       }
-
-                       //                      sample = (active_video_line * info->fmt->active_samples_per_line) + (p - buf) + 1;
-                       //                      *p++ = sample > 1440 ? 735 : (video_buffer[sample] << 2);
-                       //                      sample = (active_video_line * info->fmt->active_samples_per_line) + (p - buf) - 1;
-                       //                      *p++ = sample > 1440 ? 335 : (video_buffer[sample] << 2);
-                       //                      sample = (active_video_line * info->fmt->active_samples_per_line) + (p - buf) + 1;
-                       //                      *p++ = sample > 1440 ? 793 : (video_buffer[sample] << 2);
-                       //                      sample = (active_video_line * info->fmt->active_samples_per_line) + (p - buf) - 1;
-                       //                      *p++ = sample > 1440 ? 335 : (video_buffer[sample] << 2);
-
-                       *p = video_buffer[(active_video_line * info->fmt->active_samples_per_line) + (p - buf) + 1] << 2; // Cb
+                       *p = video_buffer[start_of_current_line + (p - buf) + 1] << 2; // Cb
                        p++;
-                       // check values, but need manny resources
+                       //check values, this needs a lot of resources
                        //                      if (*(p - 1) < 0x040)
                        //                              *(p - 1) = 0x040;
                        //                      if (*(p - 1) > 0x3c0)
                        //                              *(p - 1) = 0x3c0;
                        //
-                       *p = video_buffer[(active_video_line * info->fmt->active_samples_per_line) + (p - buf) - 1] << 2; // Y1
+                       *p = video_buffer[start_of_current_line + (p - buf) - 1] << 2; // Y1
                        p++;
                        //                      if (*(p - 1) < 0x040)
                        //                              *(p - 1) = 0x040;
                        //                      if (*(p - 1) > 0x3ac)
                        //                              *(p - 1) = 0x3ac;
                        //
-                       *p = video_buffer[(active_video_line * info->fmt->active_samples_per_line) + (p - buf) + 1] << 2; // Cr
+                       *p = video_buffer[start_of_current_line + (p - buf) + 1] << 2; // Cr
                        p++;
                        //                      if (*(p - 1) < 0x040)
                        //                              *(p - 1) = 0x040;
                        //                      if (*(p - 1) > 0x3c0)
                        //                              *(p - 1) = 0x3c0;
                        //
-                       *p = video_buffer[(active_video_line * info->fmt->active_samples_per_line) + (p - buf) - 1] << 2; // Y2
+                       *p = video_buffer[start_of_current_line + (p - buf) - 1] << 2; // Y2
                        p++;
                        //                      if (*(p - 1) < 0x040)
                        //                              *(p - 1) = 0x040;
@@ -1247,8 +1390,8 @@ static inline int create_HD_SDI_Line(uint16_t *buf, const struct line_info *info
        return 0;
 }
 
-static int writeANC(uint16_t *p, int videoline_sdiframe, uint16_t DID, int my_DBN, int16_t *audio_buffer_A, int16_t *audio_buffer_B, int16_t AudioGroupCounter,
-               int16_t AudioGroups2Write) {
+static int writeANC(uint16_t *p, int videoline_sdiframe, uint16_t DID, int my_DBN, int16_t *audio_buffer_A, int16_t *audio_buffer_B,
+               int16_t AudioGroupCounter, int16_t AudioGroups2Write) {
 
        /**
         * ANC Ancillary Data (vgl. SMPTE 291-M page 6 )
@@ -1317,20 +1460,21 @@ static int writeANC(uint16_t *p, int videoline_sdiframe, uint16_t DID, int my_DB
 
                // 1 DC         (Data Counter)
                // number of UDW = AudioGroups2Write x 2AESFrames x 2channesl x 3words(X,X+1,X+2)
-               buffer = AudioGroups2Write * 2* 2* 3 ; parity_counter= 0;
+               buffer = AudioGroups2Write * 2 * 2 * 3;
+               parity_counter = 0;
                // count binary ones for parity
-               for (i=0; i<8; i++) {
+               for (i = 0; i < 8; i++) {
                        if (buffer & (1 << i))
-                       parity_counter++;
+                               parity_counter++;
                }
-               if ((parity_counter%2)==0) { //else leave the 0
-                       buffer+= 512; // 10 0000 0000 // set bit8 = even parity bit and bit9 = !bit8
+               if ((parity_counter % 2) == 0) { //else leave the 0
+                       buffer += 512; // 10 0000 0000 // set bit8 = even parity bit and bit9 = !bit8
                } else {
-                       buffer+= 256; // 01 0000 0000 // set bit8 = even parity bit and bit9 = !bit8
+                       buffer += 256; // 01 0000 0000 // set bit8 = even parity bit and bit9 = !bit8
                }
                *p++ = buffer;
 
-               int16_t sample_number=0;
+               int16_t sample_number = 0;
                int16_t counter = 0;
                // write subframes:
                // = n x 1 AudioGroup
@@ -1338,33 +1482,29 @@ static int writeANC(uint16_t *p, int videoline_sdiframe, uint16_t DID, int my_DB
                // = n x 2 x 2samples
                // = 4 samples
                // = 4 x 3words
-               while (counter < AudioGroups2Write*2) { /* 4:3 */
+               while (counter < AudioGroups2Write * 2) { /* 4:3 */
 
                        // write one Audio Group with 4 x AES subframes
                        // ( samples for ch01,ch02,ch03,ch04 or ch05,ch06,ch07,ch08 or ch09,ch10,ch11,ch12 or ch13,ch14,ch15,ch16)
                        // and use audio_buffer_A(stereo) and audio_buffer_B(stereo)
                        // `pack_AES_subframe()` write 3 ANC words (3*10bit), also 1 sample
 
-                       sample_number=(AudioGroupCounter*2)+ counter;
-                       pack_AES_subframe(p, getChannelStatusBit(sample_number/2, 1),
-                                       getZBit(sample_number/2), 0, &audio_buffer_A[sample_number]); // left
-                       p+=3; // step 3 words
+                       sample_number = (AudioGroupCounter * 2) + counter;
+                       pack_AES_subframe(p, getChannelStatusBit(sample_number / 2, 1), getZBit(sample_number / 2), 0, &audio_buffer_A[sample_number]); // left
+                       p += 3; // step 3 words
 
-                       sample_number=(AudioGroupCounter*2)+ counter+1;
-                       pack_AES_subframe(p, getChannelStatusBit(sample_number/2, 2),
-                                       getZBit(sample_number/2), 1, &audio_buffer_A[sample_number]); // right
-                       p+=3;
+                       sample_number = (AudioGroupCounter * 2) + counter + 1;
+                       pack_AES_subframe(p, getChannelStatusBit(sample_number / 2, 2), getZBit(sample_number / 2), 1, &audio_buffer_A[sample_number]); // right
+                       p += 3;
 
-                       sample_number=(AudioGroupCounter*2)+ counter;
-                       pack_AES_subframe(p, getChannelStatusBit(sample_number/2, 3),
-                                       getZBit(sample_number/2), 2, &audio_buffer_B[sample_number]); // left
-                       p+=3;
+                       sample_number = (AudioGroupCounter * 2) + counter;
+                       pack_AES_subframe(p, getChannelStatusBit(sample_number / 2, 3), getZBit(sample_number / 2), 2, &audio_buffer_B[sample_number]); // left
+                       p += 3;
 
-                       sample_number=(AudioGroupCounter*2)+ counter+1;
-                       pack_AES_subframe(p, getChannelStatusBit(sample_number/2, 4),
-                                       getZBit(sample_number/2), 3, &audio_buffer_B[sample_number]); // right
-                       p+=3;
-                       counter+=2;
+                       sample_number = (AudioGroupCounter * 2) + counter + 1;
+                       pack_AES_subframe(p, getChannelStatusBit(sample_number / 2, 4), getZBit(sample_number / 2), 3, &audio_buffer_B[sample_number]); // right
+                       p += 3;
+                       counter += 2;
                }
 
                // 1 CS         (Checksum from DID - UDW)
@@ -1374,7 +1514,7 @@ static int writeANC(uint16_t *p, int videoline_sdiframe, uint16_t DID, int my_DB
                // rest until end of `ANCILLARY_DATA_SAMPLES` will be fill in a loop after call this function
                *p++ = 0x040;
        }
-       return p-pp;
+       return p - pp;
 }
 
 // calculate checksumm of ANC (SMPTE 272-M 15.3 Checksum (CS))
@@ -1781,7 +1921,7 @@ static int mkline(unsigned short int *buf, const struct line_info *info, unsigne
                        *p++ = 0x040;
                }
                break;
-       case BLACK:
+       case BLACK: /* black line (filler for FMT_480i5994 ) */
                while (p < (buf + samples)) {
                        *p++ = 0x200;
                        *p++ = 0x040;
@@ -1789,6 +1929,14 @@ static int mkline(unsigned short int *buf, const struct line_info *info, unsigne
                        *p++ = 0x040;
                }
                break;
+       case GREEN: /* green line for test purpose */
+               while (p < (buf + samples)) {
+                       *p++ = 289;
+                       *p++ = 450;
+                       *p++ = 231;
+                       *p++ = 450;
+               }
+               break;
        case MAIN_SET:
                /* 75% gray */
                endp += b + 1;
@@ -1971,3 +2119,295 @@ static int mkline(unsigned short int *buf, const struct line_info *info, unsigne
        }
        return 0;
 }
+
+static int setSDIVideoProperties(enum sdi_setting_video_e setting, char * value, char * device) {
+
+       const char fmt[] = "/sys/class/sdivideo/sdivideo%cx%i/%s";
+       struct stat buf;
+       int num;
+       char type, name[256], data[256];
+       char *endptr;
+
+       /* Get the sysfs info */
+       memset(&buf, 0, sizeof(buf));
+
+       /**
+        * Stat the file, fills the structure with info about the file
+        * Get the major number from device node
+        **/
+       if (stat(device, &buf) < 0) {
+               fprintf(stderr, "%s: ", device);
+               perror("unable to get the file status");
+               return -1;
+       }
+
+       /* Check if it is a character device or not */
+       if (!S_ISCHR (buf.st_mode)) {
+               fprintf(stderr, "%s: not a character device\n", device);
+               return -1;
+       }
+
+       /* Check the minor number to determine if it is a receive or transmit device */
+       type = (buf.st_rdev & 0x0080) ? 'r' : 't';
+
+       /* Get the receiver or transmitter number */
+       num = buf.st_rdev & 0x007f;
+
+       /* Build the path to sysfs file */
+       snprintf(name, sizeof(name), fmt, type, num, "dev");
+       memset(data, 0, sizeof(data));
+
+       /* Read sysfs file (dev) */
+       if (util_read(name, data, sizeof(data)) < 0) {
+               fprintf(stderr, "%s: ", device);
+               perror("unable to get the device number");
+               return -1;
+       }
+       /* Compare the major number taken from sysfs file to the one taken from device node */
+       if (strtoul(data, &endptr, 0) != (buf.st_rdev >> 8)) {
+               fprintf(stderr, "%s: not a SMPTE 292M/SMPTE 259M-C device\n", device);
+               return -1;
+       }
+       if (*endptr != ':') {
+               fprintf(stderr, "%s: error reading %s\n", device, name);
+               return -1;
+       }
+
+       // Which setting do we write
+       if (setting == SETTING_BUFFER_NUMBER_VIDEO) {
+               snprintf(name, sizeof(name), fmt, type, num, "buffers");
+               snprintf(data, sizeof(data), "%s\n", value);
+               if (util_write(name, data, sizeof(data)) < 0) {
+                       fprintf(stderr, "%s: ", device);
+                       perror("unable to set the number of buffers");
+                       return -1;
+               }
+               printf("\tSet number of buffers = %s\n", value);
+       } else if (setting == SETTING_BUFFER_SIZE_VIDEO) {
+               snprintf(name, sizeof(name), fmt, type, num, "bufsize");
+               snprintf(data, sizeof(data), "%s\n", value);
+               if (util_write(name, data, sizeof(data)) < 0) {
+                       fprintf(stderr, "%s: ", device);
+                       perror("unable to set the buffer size");
+                       return -1;
+               }
+               printf("\tSet buffer size = %s Bytes\n", value);
+       } else if (setting == SETTING_CLOCK_SOURCE) {
+               snprintf(name, sizeof(name), fmt, type, num, "clock_source");
+               snprintf(data, sizeof(data), "%s\n", value);
+               if (util_write(name, data, sizeof(data)) < 0) {
+                       fprintf(stderr, "%s: ", device);
+                       perror("unable to set the clock source");
+                       return -1;
+               }
+               printf("\tSet clock source = %s\n", value);
+       } else if (setting == SETTING_DATA_MODE) {
+               snprintf(name, sizeof(name), fmt, type, num, "mode");
+               snprintf(data, sizeof(data), "%s\n", value);
+               if (util_write(name, data, sizeof(data)) < 0) {
+                       fprintf(stderr, "%s: ", device);
+                       perror("unable to set the interface operating mode");
+                       return -1;
+               }
+               printf("\tSet data mode = %s\n", value);
+       } else if (setting == SETTING_FRAME_MODE) {
+               snprintf(name, sizeof(name), fmt, type, num, "frame_mode");
+               snprintf(data, sizeof(data), "%s\n", value);
+               if (util_write(name, data, sizeof(data)) < 0) {
+                       fprintf(stderr, "%s: ", device);
+                       perror("unable to set the interface frame mode");
+                       return -1;
+               }
+               printf("\tSet frame mode = %s\n", value);
+       }
+
+       return 0;
+
+}
+
+static int setSDIAudioProperties(enum sdi_setting_audio_e setting, char * value, char * device) {
+       const char fmt[] = "/sys/class/sdiaudio/sdiaudio%cx%i/%s";
+       struct stat buf;
+       int num;
+       char type, name[256], data[256];
+       char *endptr;
+
+       /* Get the sysfs info */
+       memset(&buf, 0, sizeof(buf));
+       if (stat(device, &buf) < 0) {
+               fprintf(stderr, "%s: ", device);
+               perror("unable to get the file status");
+               return -1;
+       }
+       if (!S_ISCHR (buf.st_mode)) {
+               fprintf(stderr, "%s: not a character device\n", device);
+               return -1;
+       }
+       type = (buf.st_rdev & 0x0080) ? 'r' : 't';
+       num = buf.st_rdev & 0x007f;
+       snprintf(name, sizeof(name), fmt, type, num, "dev");
+       memset(data, 0, sizeof(data));
+       if (util_read(name, data, sizeof(data)) < 0) {
+               fprintf(stderr, "%s: ", device);
+               perror("unable to get the device number");
+               return -1;
+       }
+
+       if (strtoul(data, &endptr, 0) != (buf.st_rdev >> 8)) {
+               fprintf(stderr, "%s: not an audio device\n", device);
+               return -1;
+       }
+       if (*endptr != ':') {
+               fprintf(stderr, "%s: error reading %s\n", device, name);
+               return -1;
+       }
+
+       if (setting == SETTING_BUFFER_NUMBER_AUDIO) {
+               snprintf(name, sizeof(name), fmt, type, num, "buffers");
+               snprintf(data, sizeof(data), "%s\n", value);
+
+               if (util_write(name, data, sizeof(data)) < 0) {
+                       fprintf(stderr, "%s: ", device);
+                       perror("unable to set the number of buffers");
+                       return -1;
+               }
+               printf("\tSet number of buffers = %s\n", value);
+       } else if (setting == SETTING_BUFFER_SIZE_AUDIO) {
+               snprintf(name, sizeof(name), fmt, type, num, "bufsize");
+               snprintf(data, sizeof(data), "%s\n", value);
+               if (util_write(name, data, sizeof(data)) < 0) {
+                       fprintf(stderr, "%s: ", device);
+                       perror("unable to set the buffer size");
+                       return -1;
+               }
+               printf("\tSet buffer size = %s Bytes\n", value);
+       } else if (setting == SETTING_SAMPLE_SIZE) {
+               snprintf(name, sizeof(name), fmt, type, num, "sample_size");
+               snprintf(data, sizeof(data), "%s\n", value);
+               if (util_write(name, data, sizeof(data)) < 0) {
+                       fprintf(stderr, "%s: ", device);
+                       perror("unable to set the interface audio sample size");
+                       return -1;
+               }
+               switch (atol(value)) {
+               case SDIAUDIO_CTL_AUDSAMP_SZ_16:
+                       printf("\tAssuming 16-bit audio.\n");
+                       break;
+               case SDIAUDIO_CTL_AUDSAMP_SZ_24:
+                       printf("\tAssuming 24-bit audio.\n");
+                       break;
+               case SDIAUDIO_CTL_AUDSAMP_SZ_32:
+                       printf("\tAssuming 32-bit audio.\n");
+                       break;
+               default:
+                       printf("\tSet audio sample size = %lu.\n", atol(value));
+                       break;
+               }
+       } else if (setting == SETTING_SAMPEL_RATE) {
+               snprintf(name, sizeof(name), fmt, type, num, "sample_rate");
+               snprintf(data, sizeof(data), "%lu\n", atol(value));
+               if (util_write(name, data, sizeof(data)) < 0) {
+                       fprintf(stderr, "%s: ", device);
+                       perror("unable to set the interface audio sample rate");
+                       return -1;
+               }
+               switch (atoi(value)) {
+               case 32000:
+                       printf("\tAssuming 32 kHz audio.\n");
+                       break;
+               case 44100:
+                       printf("\tAssuming 44.1 kHz audio.\n");
+                       break;
+               case 48000:
+                       printf("\tAssuming 48 kHz audio.\n");
+                       break;
+               default:
+                       printf("\tSet audio sample rate = %lu.\n", atol(value));
+                       break;
+               }
+       } else if (setting == SETTING_CHANNELS) {
+               snprintf(name, sizeof(name), fmt, type, num, "channels");
+               snprintf(data, sizeof(data), "%lu\n", atol(value));
+               if (util_write(name, data, sizeof(data)) < 0) {
+                       fprintf(stderr, "%s: ", device);
+                       perror("unable to set "
+                               "the interface audio channel enable");
+                       return -1;
+               }
+               switch (atol(value)) {
+               case SDIAUDIO_CTL_AUDCH_EN_0:
+                       printf("\tDisabling audio.\n");
+                       break;
+               case SDIAUDIO_CTL_AUDCH_EN_2:
+                       printf("\tAssuming 2 channels of audio.\n");
+                       break;
+               case SDIAUDIO_CTL_AUDCH_EN_4:
+                       printf("\tAssuming 4 channels of audio.\n");
+                       break;
+               case SDIAUDIO_CTL_AUDCH_EN_6:
+                       printf("\tAssuming 6 channels of audio.\n");
+                       break;
+               case SDIAUDIO_CTL_AUDCH_EN_8:
+                       printf("\tAssuming 8 channels of audio.\n");
+                       break;
+               default:
+                       printf("\tSet audio channel enable = %lu.\n", atol(value));
+                       break;
+               }
+       } else if (setting == SETTING_NON_AUDIO) {
+               snprintf(name, sizeof(name), fmt, type, num, "non_audio");
+               snprintf(data, sizeof(data), "0x%04lX\n", atol(value));
+               if (util_write(name, data, sizeof(data)) < 0) {
+                       fprintf(stderr, "%s: ", device);
+                       perror("unable to set "
+                               "the interface non-audio");
+                       return -1;
+               }
+               switch (atol(value)) {
+               case 0x0000:
+                       printf("\tPassing PCM audio.\n");
+                       break;
+               case 0x00ff:
+                       printf("\tPassing non-audio.\n");
+                       break;
+               default:
+                       printf("\tSet non-audio = 0x%04lX.\n", atol(value));
+                       break;
+               }
+       }
+
+       return 0;
+}
+
+static ssize_t util_read(const char *name, char *buf, size_t count) {
+       ssize_t fd, ret;
+
+       if ((fd = open(name, O_RDONLY)) < 0) {
+               return fd;
+       }
+       ret = read(fd, buf, count);
+       close(fd);
+       return ret;
+}
+
+static ssize_t util_write(const char *name, const char *buf, size_t count) {
+       ssize_t fd, ret;
+
+       if ((fd = open(name, O_WRONLY)) < 0) {
+               return fd;
+       }
+       ret = write(fd, buf, count);
+       close(fd);
+       return ret;
+}
+
+static char * itoa(uint64_t i) {
+
+       if (i == 0)
+               return strdup("0");
+
+       char * mystring = (char *) malloc(50);
+       sprintf(mystring, "%"PRIu64, i);
+
+       return mystring;
+}