5 #include <framework/mlt_frame.h>
6 #include <framework/mlt_profile.h>
14 #include <sys/ioctl.h>
15 #include <sys/types.h>
23 #ifndef SDI_GENERATOR_H_
24 #define SDI_GENERATOR_H_
26 // definitions are only for SD NTSC (mkline funktion for test pattern)
27 #define VERT_BLANKING 0
34 // defines for SD SDI with blanking
35 #define ANCILLARY_DATA_SAMPLES 280
38 #define VERT_BLANKING 0
39 #define ACTIVE_VIDEO 1
42 #define SDI_IOC_MAGIC '='
43 #define SDI_IOC_TXGETEVENTS _IOR(SDI_IOC_MAGIC, 2, unsigned int)
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)
53 // part of the linsys sdiaudio.h
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)
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)
70 // Filehandler for sdi output
71 static int fh_sdi_video;
72 static int fh_sdi_audio;
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)
80 * 23.98Hz = fix:{2002}
83 * 29.97Hz = varies:{1601,1602,1602}
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;
100 mlt_audio_format aformat; // default: mlt_audio_pcm
101 uint16_t samples; // default 2*1920
102 uint16_t sample_rate; // default 48000
104 * 0 channels = audio disabled, transmit only
105 * 2 channels (stereo)
110 int channels; // default 2 (stereo)
114 * SDI DEVICE FILE SETTINGS AND MODES
116 enum sdi_setting_video_e {
118 SETTING_BUFFER_NUMBER_VIDEO = 0, SETTING_BUFFER_SIZE_VIDEO = 1, SETTING_CLOCK_SOURCE = 2, SETTING_DATA_MODE = 3, SETTING_FRAME_MODE = 4
120 enum sdi_setting_audio_e {
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
130 static int sdi_frame_mode = 0;
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
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 */
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 */
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);
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 };
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 };
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 };
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 };
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 };
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 };
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 };
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 };
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 };
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 };
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 };
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 };
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 };
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 };
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 };
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 };
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 };
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 };
236 // SD NTSC; 480 video lines, 6 lines opt. video data
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)
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 };
245 unsigned short int sav;
246 unsigned short int eav;
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 };
255 const struct source_format *fmt;
257 const struct trs *xyz;
268 // 192bit for AESChannelStatusBits
269 uint8_t AESChannelStatusBitArray[192]; // beta array
270 //uint8_t AESChannelStatusBitArray[24]; // TODO better way for 24x8bit !!!
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
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;
289 static int sdi_init(char *device_video, char *device_audio, uint8_t blanking, mlt_profile myProfile, const struct audio_format * audio_format);
291 static int sdimaster_close();
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,
296 static int mkline(unsigned short int *buf, const struct line_info *info, unsigned int pattern);
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);
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);
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);
311 static uint8_t getDBN(int my_DBN);
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);
317 static int pack_AES_subframe(uint16_t *p, int8_t c, int8_t z, int8_t ch, int16_t *audio_sample);
319 #endif /* SDI_GENERATOR_H_ */