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