]> git.sesse.net Git - mlt/blob - src/modules/linsys/sdi_generator.h
Fix compile error on Windows.
[mlt] / src / modules / linsys / sdi_generator.h
1 /**
2  * sdi_generator.h
3  **/
4
5 #include <framework/mlt_frame.h>
6 #include <framework/mlt_profile.h>
7 #include <stdio.h>
8 #include <stdlib.h>
9 #include <signal.h>
10 #include <stdint.h>
11 #include <string.h>
12 #include <unistd.h>
13 #include <fcntl.h>
14 #include <sys/ioctl.h>
15 #include <sys/types.h>
16 #include <sys/stat.h>
17
18 #include <pthread.h>
19
20 #include <signal.h>
21 #include <math.h>
22
23 #ifndef SDI_GENERATOR_H_
24 #define SDI_GENERATOR_H_
25
26 // definitions are only for SD NTSC (mkline funktion for test pattern)
27 #define VERT_BLANKING 0
28 #define MAIN_SET 1
29 #define CHROMA_SET 2
30 #define BLACK_SET 3
31 #define BLACK 4
32 #define GREEN 5
33
34 // defines for SD SDI with blanking
35 #define ANCILLARY_DATA_SAMPLES 280
36 #define FIELD_1 1
37 #define FIELD_2 2
38 #define VERT_BLANKING 0
39 #define ACTIVE_VIDEO 1
40
41 // Master SDI device
42 #define SDI_IOC_MAGIC '='
43 #define SDI_IOC_TXGETEVENTS     _IOR(SDI_IOC_MAGIC, 2, unsigned int)
44
45 // Transmitter event flag bit locations
46 #define SDI_EVENT_TX_BUFFER_ORDER       0
47 #define SDI_EVENT_TX_BUFFER             (1 << SDI_EVENT_TX_BUFFER_ORDER)
48 #define SDI_EVENT_TX_FIFO_ORDER         1
49 #define SDI_EVENT_TX_FIFO               (1 << SDI_EVENT_TX_FIFO_ORDER)
50 #define SDI_EVENT_TX_DATA_ORDER         2
51 #define SDI_EVENT_TX_DATA               (1 << SDI_EVENT_TX_DATA_ORDER)
52
53 // part of the linsys sdiaudio.h
54
55 #define SDIAUDIO_IOC_TXGETCAP                   _IOR(SDIAUDIO_IOC_MAGIC, 1, unsigned int)
56 #define SDIAUDIO_IOC_TXGETEVENTS                _IOR(SDIAUDIO_IOC_MAGIC, 2, unsigned int)
57 #define SDIAUDIO_IOC_TXGETBUFLEVEL              _IOR(SDIAUDIO_IOC_MAGIC, 3, unsigned int)
58 #define SDIAUDIO_IOC_TXGETTXD                   _IOR(SDIAUDIO_IOC_MAGIC, 4, int)
59
60 #define SDIAUDIO_IOC_MAGIC '~' /* This ioctl magic number is currently free. See
61                            * /usr/src/linux/Documentation/ioctl-number.txt */
62 /* Transmitter event flag bit locations */
63 #define SDIAUDIO_EVENT_TX_BUFFER_ORDER  0
64 #define SDIAUDIO_EVENT_TX_BUFFER        (1 << SDIAUDIO_EVENT_TX_BUFFER_ORDER)
65 #define SDIAUDIO_EVENT_TX_FIFO_ORDER    1
66 #define SDIAUDIO_EVENT_TX_FIFO          (1 << SDIAUDIO_EVENT_TX_FIFO_ORDER)
67 #define SDIAUDIO_EVENT_TX_DATA_ORDER    2
68 #define SDIAUDIO_EVENT_TX_DATA          (1 << SDIAUDIO_EVENT_TX_DATA_ORDER)
69
70 // Filehandler for sdi output
71 static int fh_sdi_video;
72 static int fh_sdi_audio;
73
74 #define MAX_SAMPLES_PER_LINE (2*2750)
75 #define MAX_LINES_PER_FRAME 1125
76 #define MAX_AUDIO_STREAMS (8)
77 // max. audio samples per frame
78 #define MAX_AUDIO_SAMPLES (2002*2)
79 /**
80  * 23.98Hz = fix:{2002}
81  * 24Hz = fix:{2000}
82  * 25Hz = fix:{1920}
83  * 29.97Hz = varies:{1601,1602,1602}
84  * 30Hz = fix:{1600}
85  **/
86
87 #define MAX_SDI_HEIGHT 1125                     // HD-SDI
88 #define MAX_SDI_WIDTH 2750                      // HD-SDI (FMT_1080p24 has up to 2750)
89 #define MAX_SDI_FRAMESIZE (MAX_SDI_HEIGHT*MAX_SDI_WIDTH*2) // SDI frame size, (2 Pixels are represented by 4 bytes, yuyv422)
90 struct source_format {
91         unsigned int lines_per_frame;
92         unsigned int active_lines_per_frame;
93         unsigned int samples_per_line;
94         unsigned int active_samples_per_line;
95         unsigned int interlaced;
96 };
97
98 struct audio_format {
99
100         mlt_audio_format aformat; // default: mlt_audio_pcm
101         uint16_t samples; // default 2*1920
102         uint16_t sample_rate; // default 48000
103         /**
104          * 0 channels = audio disabled, transmit only
105          * 2 channels (stereo)
106          * 4 channels
107          * 6 channels
108          * 8 channels
109          **/
110         int channels; // default 2 (stereo)
111 };
112
113 /**
114  * SDI DEVICE FILE SETTINGS AND MODES
115  **/
116 enum sdi_setting_video_e {
117
118         SETTING_BUFFER_NUMBER_VIDEO = 0, SETTING_BUFFER_SIZE_VIDEO = 1, SETTING_CLOCK_SOURCE = 2, SETTING_DATA_MODE = 3, SETTING_FRAME_MODE = 4
119 };
120 enum sdi_setting_audio_e {
121
122         SETTING_BUFFER_NUMBER_AUDIO = 0,
123         SETTING_BUFFER_SIZE_AUDIO = 1,
124         SETTING_SAMPLE_SIZE = 2,
125         SETTING_CHANNELS = 3,
126         SETTING_SAMPEL_RATE = 4,
127         SETTING_NON_AUDIO = 5
128 };
129
130 static int sdi_frame_mode = 0;
131
132 /* Frame mode settings */
133 #define SDIVIDEO_CTL_UNLOCKED                    0
134 #define SDIVIDEO_CTL_SMPTE_125M_486I_59_94HZ     1
135 #define SDIVIDEO_CTL_BT_601_576I_50HZ            2
136 #define SDIVIDEO_CTL_SMPTE_260M_1035I_60HZ       5
137 #define SDIVIDEO_CTL_SMPTE_260M_1035I_59_94HZ    6
138 #define SDIVIDEO_CTL_SMPTE_295M_1080I_50HZ       7
139 #define SDIVIDEO_CTL_SMPTE_274M_1080I_60HZ       8
140 #define SDIVIDEO_CTL_SMPTE_274M_1080PSF_30HZ     9
141 #define SDIVIDEO_CTL_SMPTE_274M_1080I_59_94HZ   10
142 #define SDIVIDEO_CTL_SMPTE_274M_1080PSF_29_97HZ 11
143 #define SDIVIDEO_CTL_SMPTE_274M_1080I_50HZ      12
144 #define SDIVIDEO_CTL_SMPTE_274M_1080PSF_25HZ    13
145 #define SDIVIDEO_CTL_SMPTE_274M_1080PSF_24HZ    14
146 #define SDIVIDEO_CTL_SMPTE_274M_1080PSF_23_98HZ 15
147 #define SDIVIDEO_CTL_SMPTE_274M_1080P_30HZ      16
148 #define SDIVIDEO_CTL_SMPTE_274M_1080P_29_97HZ   17
149 #define SDIVIDEO_CTL_SMPTE_274M_1080P_25HZ      18
150 #define SDIVIDEO_CTL_SMPTE_274M_1080P_24HZ      19
151 #define SDIVIDEO_CTL_SMPTE_274M_1080P_23_98HZ   20
152 #define SDIVIDEO_CTL_SMPTE_296M_720P_60HZ       21
153 #define SDIVIDEO_CTL_SMPTE_296M_720P_59_94HZ    22
154 #define SDIVIDEO_CTL_SMPTE_296M_720P_50HZ       23
155 #define SDIVIDEO_CTL_SMPTE_296M_720P_30HZ       24
156 #define SDIVIDEO_CTL_SMPTE_296M_720P_29_97HZ    25
157 #define SDIVIDEO_CTL_SMPTE_296M_720P_25HZ       26
158 #define SDIVIDEO_CTL_SMPTE_296M_720P_24HZ       27
159 #define SDIVIDEO_CTL_SMPTE_296M_720P_23_98HZ    28
160
161 /* Audio sample size */
162 #define SDIAUDIO_CTL_AUDSAMP_SZ_16      16 /* 16 bit */
163 #define SDIAUDIO_CTL_AUDSAMP_SZ_24      24 /* 24 bit */
164 #define SDIAUDIO_CTL_AUDSAMP_SZ_32      32 /* 32 bit */
165
166 /* Audio channel enable */
167 #define SDIAUDIO_CTL_AUDCH_EN_0         0 /* 0 channel/disable audio */
168 #define SDIAUDIO_CTL_AUDCH_EN_2         2 /* 2 channel */
169 #define SDIAUDIO_CTL_AUDCH_EN_4         4 /* 4 channel */
170 #define SDIAUDIO_CTL_AUDCH_EN_6         6 /* 6 channel */
171 #define SDIAUDIO_CTL_AUDCH_EN_8         8 /* 8 channel */
172
173 static char * itoa(uint64_t i);
174 static ssize_t util_read(const char *name, char *buf, size_t count);
175 static ssize_t util_write(const char *name, const char *buf, size_t count);
176 static int setSDIVideoProperties(enum sdi_setting_video_e setting, char * value, char * device);
177 static int setSDIAudioProperties(enum sdi_setting_audio_e setting, char * value, char * device);
178
179 // HD
180 static const struct source_format FMT_1080i60 = { .lines_per_frame = 1125, .active_lines_per_frame = 1080, .samples_per_line = 2*2200,
181                 .active_samples_per_line = 2*1920, .interlaced = 1 };
182
183 static const struct source_format FMT_1080i5994 = { .lines_per_frame = 1125, .active_lines_per_frame = 1080, .samples_per_line = 2*2200,
184                 .active_samples_per_line = 2*1920, .interlaced = 1 };
185
186 static const struct source_format FMT_1080i50 = { .lines_per_frame = 1125, .active_lines_per_frame = 1080, .samples_per_line = 2*2640,
187                 .active_samples_per_line = 2*1920, .interlaced = 1 };
188
189 static const struct source_format FMT_1080p30 = { .lines_per_frame = 1125, .active_lines_per_frame = 1080, .samples_per_line = 2*2200,
190                 .active_samples_per_line = 2*1920, .interlaced = 0 };
191
192 static const struct source_format FMT_1080p2997 = { .lines_per_frame = 1125, .active_lines_per_frame = 1080, .samples_per_line = 2*2200,
193                 .active_samples_per_line = 2*1920, .interlaced = 0 };
194
195 static const struct source_format FMT_1080p25 = { .lines_per_frame = 1125, .active_lines_per_frame = 1080, .samples_per_line = 2*2640,
196                 .active_samples_per_line = 2*1920, .interlaced = 0 };
197
198 static const struct source_format FMT_1080p24 = { .lines_per_frame = 1125, .active_lines_per_frame = 1080, .samples_per_line = 2*2750,
199                 .active_samples_per_line = 2*1920, .interlaced = 0 };
200
201 static const struct source_format FMT_1080p2398 = { .lines_per_frame = 1125, .active_lines_per_frame = 1080, .samples_per_line = 2*2750,
202                 .active_samples_per_line = 2*1920, .interlaced = 0 };
203
204 static const struct source_format FMT_720p60 = { .lines_per_frame = 750, .active_lines_per_frame = 720, .samples_per_line = 2*1650,
205                 .active_samples_per_line = 2*1280, .interlaced = 0 };
206
207 static const struct source_format FMT_720p5994 = { .lines_per_frame = 750, .active_lines_per_frame = 720, .samples_per_line = 2*1650,
208                 .active_samples_per_line = 2*1280, .interlaced = 0 };
209
210 static const struct source_format FMT_720p50 = { .lines_per_frame = 750, .active_lines_per_frame = 720, .samples_per_line = 2*1980,
211                 .active_samples_per_line = 2*1280, .interlaced = 0 };
212
213 static const struct source_format FMT_720p30 = { .lines_per_frame = 750, .active_lines_per_frame = 720, .samples_per_line = 2*3300,
214                 .active_samples_per_line = 2*1280, .interlaced = 0 };
215
216 static const struct source_format FMT_720p2997 = { .lines_per_frame = 750, .active_lines_per_frame = 720, .samples_per_line = 2*3300,
217                 .active_samples_per_line = 2*1280, .interlaced = 0 };
218
219 static const struct source_format FMT_720p25 = { .lines_per_frame = 750, .active_lines_per_frame = 720, .samples_per_line = 2*3960,
220                 .active_samples_per_line = 2*1280, .interlaced = 0 };
221
222 static const struct source_format FMT_720p24 = { .lines_per_frame = 750, .active_lines_per_frame = 720, .samples_per_line = 2*4125,
223                 .active_samples_per_line = 2*1280, .interlaced = 0 };
224
225 static const struct source_format FMT_720p2398 = { .lines_per_frame = 750, .active_lines_per_frame = 720, .samples_per_line = 2*4125,
226                 .active_samples_per_line = 2*1280, .interlaced = 0 };
227
228 // SD PAL
229 static const struct source_format FMT_576i50 = { .lines_per_frame = 625, .active_lines_per_frame = 576, .samples_per_line = 2*864 /*1728*/,
230                 .active_samples_per_line = 2*720 /* 720xY, 360xCb, 360xCr */, .interlaced = 1 };
231
232 // SD NTSC; 486 video lines
233 static const struct source_format FMT_486i5994 = { .lines_per_frame = 525, .active_lines_per_frame = 486, .samples_per_line = 2*858 /*1716*/,
234                 .active_samples_per_line = 2*720 /* 720xY, 360xCb, 360xCr */, .interlaced = 1 };
235
236 // SD NTSC; 480 video lines, 6 lines opt. video data
237 /**
238  * sames as FMT_486i5994 but the first 6 lines will be filled with SDI-BLACK
239  * or can be used for opt. video data (s.SMPTE)
240  */
241 static const struct source_format FMT_480i5994 = { .lines_per_frame = 525, .active_lines_per_frame = 486, .samples_per_line = 2*858 /*1716*/,
242                 .active_samples_per_line = 2*720 /* 720xY, 360xCb, 360xCr */, .interlaced = 1 };
243
244 struct trs {
245         unsigned short int sav;
246         unsigned short int eav;
247 };
248
249 static const struct trs FIELD_1_ACTIVE = { .sav = 0x200, .eav = 0x274 };
250 static const struct trs FIELD_1_VERT_BLANKING = { .sav = 0x2ac, .eav = 0x2d8 };
251 static const struct trs FIELD_2_ACTIVE = { .sav = 0x31c, .eav = 0x368 };
252 static const struct trs FIELD_2_VERT_BLANKING = { .sav = 0x3b0, .eav = 0x3c4 };
253
254 struct line_info {
255         const struct source_format *fmt;
256         unsigned int ln;
257         const struct trs *xyz;
258         uint8_t blanking;
259 };
260
261 struct SDI_atr {
262         int status;
263         int *fh;
264         uint8_t *data;
265         size_t framesize;
266 } SDI_atr;
267
268 // 192bit for AESChannelStatusBits
269 uint8_t AESChannelStatusBitArray[192]; // beta array
270 //uint8_t AESChannelStatusBitArray[24]; // TODO better way for 24x8bit !!!
271
272 // buffer for one sdi line
273 uint16_t * line_buffer;
274 // counter for active line number
275 uint16_t active_video_line;
276 // buffer for sdi frame size
277 uint64_t sdi_frame_size;
278 // buffer for the complete SDI frame
279 uint8_t * data;
280
281 static char * device_file_video;
282 static char * device_file_audio;
283 static struct line_info info;
284 static uint8_t *(*pack)(uint8_t *outbuf, unsigned short int *inbuf, size_t count);
285 static size_t elements;
286 static unsigned int samples;
287
288 // functions
289 static int sdi_init(char *device_video, char *device_audio, uint8_t blanking, mlt_profile myProfile, const struct audio_format * audio_format);
290
291 static int sdimaster_close();
292
293 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,
294                 int my_DBN);
295
296 static int mkline(unsigned short int *buf, const struct line_info *info, unsigned int pattern);
297
298 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);
299 static inline int create_SD_SDI_Line(uint16_t *buf, const struct line_info *info, int field, int active, uint8_t *video_buffer,
300                 int16_t audio_buffer[MAX_AUDIO_STREAMS][MAX_AUDIO_SAMPLES], int linenumber_sdiframe, int active_video_line, int my_DBN, int16_t AudioGroupCounter,
301                 int16_t AudioGroups2Write, int audio_streams);
302
303 static int writeANC(uint16_t *p, int linenumber_sdiframe, uint16_t DID, int my_DBN, int16_t *audio_buffer_A, int16_t *audio_buffer_B,
304                 int16_t AudioDataPacketCounter, int16_t AudioGroups2Write);
305 static uint16_t checker(uint16_t *DID_pointer);
306
307 static uint8_t getZBit(int sample_number);
308 static uint8_t getChannelStatusBit(uint16_t sample_number, uint8_t ch);
309 static int16_t getNumberOfAudioGroups2Write(int linenuber);
310
311 static uint8_t getDBN(int my_DBN);
312
313 static inline uint8_t *pack8(uint8_t *outbuf, uint16_t *inbuf, size_t count); // alias 'pack_uyvy()'
314 static inline uint8_t *pack10(uint8_t *outbuf, uint16_t *inbuf, size_t count);
315 static inline uint8_t *pack_v210(uint8_t *outbuf, uint16_t *inbuf, size_t count);
316
317 static int pack_AES_subframe(uint16_t *p, int8_t c, int8_t z, int8_t ch, int16_t *audio_sample);
318
319 #endif /* SDI_GENERATOR_H_ */