6 * Copyright (C) 2016 SIPE Project <http://sipe.sourceforge.net/>
8 * This program is free software; you can redistribute it and/or modify
9 * it under the terms of the GNU General Public License as published by
10 * the Free Software Foundation; either version 2 of the License, or
11 * (at your option) any later version.
13 * This program is distributed in the hope that it will be useful,
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 * GNU General Public License for more details.
18 * You should have received a copy of the GNU General Public License
19 * along with this program; if not, write to the Free Software
20 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
27 #include "sipe-core.h"
29 #define _SIPE_WRITE(where, idx, size, shift, value) \
30 ((guint8 *) where)[idx] = (((guint##size)value) >> shift) & 0xff
32 #define SIPE_WRITE_UINT8(where, value) \
33 _SIPE_WRITE(where++, 0, 8, 0, value);
35 #define SIPE_WRITE_UINT16_BE(where, value) \
36 _SIPE_WRITE(where, 0, 16, 8, value); \
37 _SIPE_WRITE(where, 1, 16, 0, value); \
40 #define SIPE_WRITE_UINT32_BE(where, value) \
41 _SIPE_WRITE(where, 0, 32, 24, value); \
42 _SIPE_WRITE(where, 1, 32, 16, value); \
43 _SIPE_WRITE(where, 2, 32, 8, value); \
44 _SIPE_WRITE(where, 3, 32, 0, value); \
47 #define SIPE_WRITE_UINT64_BE(where, value) \
48 _SIPE_WRITE(where, 0, 64, 56, value); \
49 _SIPE_WRITE(where, 1, 64, 48, value); \
50 _SIPE_WRITE(where, 2, 64, 40, value); \
51 _SIPE_WRITE(where, 3, 64, 32, value); \
52 _SIPE_WRITE(where, 4, 64, 24, value); \
53 _SIPE_WRITE(where, 5, 64, 16, value); \
54 _SIPE_WRITE(where, 6, 64, 8, value); \
55 _SIPE_WRITE(where, 7, 64, 0, value); \
61 VSR_FLAG_H264_CGS_REWRITE
= 1,
62 VSR_FLAG_H264_CONSTRAINED_PROFILE_ONLY
= 2,
63 VSR_FLAG_RT_NO_SP_FRAMES
= 4,
64 VSR_FLAG_H264_NO_SEAMLESS_RESOLUTION_CHANGE
= 8
69 VSR_ASPECT_4_BY_3
= 1,
70 VSR_ASPECT_16_BY_9
= 2,
71 VSR_ASPECT_1_BY_1
= 4,
72 VSR_ASPECT_3_BY_4
= 8,
73 VSR_ASPECT_9_BY_16
= 16,
74 VSR_ASPECT_20_BY_3
= 32,
90 NAL_UNIT_TYPE_SEI
= 6,
91 NAL_UNIT_TYPE_PACSI
= 30
96 MS_LD_FPS_IDX_7_5
= 0,
97 MS_LD_FPS_IDX_12_5
= 1,
100 MS_LD_FPS_IDX_30
= 4,
101 MS_LD_FPS_IDX_50
= 5,
106 sipe_core_msrtp_write_video_source_request(guint8
*buffer
,
109 static guint8 bit_rate_histogram
[] = {
110 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
113 static guint8 quality_report_histogram
[] = {
114 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
117 /* VSR FCI field - from [MS-RTP] 2.2.12.2 */
121 SIPE_WRITE_UINT16_BE(buffer
, 0x1); // AFB Type
123 SIPE_WRITE_UINT16_BE(buffer
, SIPE_MSRTP_VSR_HEADER_LEN
+
124 SIPE_MSRTP_VSR_ENTRY_LEN
);
125 // Requested Media Source ID
126 SIPE_WRITE_UINT32_BE(buffer
, SIPE_MSRTP_VSR_SOURCE_ANY
);
127 SIPE_WRITE_UINT16_BE(buffer
, 1); // Request Id
128 SIPE_WRITE_UINT16_BE(buffer
, 0); // Reserve1
129 SIPE_WRITE_UINT8(buffer
, 0); // Version
130 SIPE_WRITE_UINT8(buffer
, 0 << 7); // Keyframe (1bit) + Reserve2
131 SIPE_WRITE_UINT8(buffer
, 1); // Number of Entries
132 SIPE_WRITE_UINT8(buffer
, SIPE_MSRTP_VSR_ENTRY_LEN
); // Entry Length
133 SIPE_WRITE_UINT32_BE(buffer
, 0x0); // Reserve3
137 SIPE_WRITE_UINT8(buffer
, payload_type
); // Payload Type
138 SIPE_WRITE_UINT8(buffer
, 1); // UCConfig Mode
139 SIPE_WRITE_UINT8(buffer
, VSR_FLAG_NONE
); // Flags
140 SIPE_WRITE_UINT8(buffer
, VSR_ASPECT_4_BY_3
); // Aspect Ratio Bit Mask
141 SIPE_WRITE_UINT16_BE(buffer
, 432); // Maximum Width
142 SIPE_WRITE_UINT16_BE(buffer
, 432); // Maximum Height
143 SIPE_WRITE_UINT32_BE(buffer
, 350000); // Minimum bit rate
144 SIPE_WRITE_UINT32_BE(buffer
, 0); // Reserve
145 SIPE_WRITE_UINT32_BE(buffer
, 10000); // Bit rate per level
146 // Bit rate Histogram
147 memcpy(buffer
, bit_rate_histogram
, sizeof (bit_rate_histogram
));
148 buffer
+= sizeof (bit_rate_histogram
);
149 SIPE_WRITE_UINT32_BE(buffer
, VSR_FPS_15
); // Frame rate bit mask
150 SIPE_WRITE_UINT16_BE(buffer
, 0); // Number of MUST instances
151 SIPE_WRITE_UINT16_BE(buffer
, 1); // Number of MAY instances
152 // Quality Report Histogram
153 memcpy(buffer
, quality_report_histogram
,
154 sizeof (quality_report_histogram
));
155 buffer
+= sizeof (quality_report_histogram
);
156 SIPE_WRITE_UINT32_BE(buffer
, 103680); // Maximum number of pixels
160 write_nal_unit_header(guint8
*dest
, gboolean f_bit
, guint8 nal_ref_idc
,
163 *dest
= f_bit
? 0x80 : 0x00;
164 *dest
|= nal_ref_idc
<< 5;
169 write_ms_layer_description(guint8
*buffer
, guint16 width
, guint16 height
,
170 guint32 bitrate
, guint8 framerate_idx
,
171 gboolean base_layer
, guint16 prid
,
172 gboolean constrained_baseline
)
174 // Coded width and height
175 SIPE_WRITE_UINT16_BE(buffer
, width
);
176 SIPE_WRITE_UINT16_BE(buffer
, height
);
178 // Display width and height
179 SIPE_WRITE_UINT16_BE(buffer
, width
);
180 SIPE_WRITE_UINT16_BE(buffer
, height
);
182 SIPE_WRITE_UINT32_BE(buffer
, bitrate
);
184 *buffer
= framerate_idx
<< 3;
185 *buffer
|= base_layer
? 0 : 1;
189 *buffer
|= (constrained_baseline
? 1 : 0) << 1;
193 sipe_core_msrtp_write_video_scalability_info(guint8
*buffer
, guint8 nal_count
)
195 static const guint8 MS_STREAM_LAYOUT_SEI_UUID
[] = {
196 0x13, 0x9f, 0xb1, 0xa9, 0x44, 0x6a, 0x4d, 0xec, 0x8c, 0xbf,
197 0x65, 0xb1, 0xe1, 0x2d, 0x2c, 0xfd
200 static const guint8 MS_BITSTREAM_INFO_SEI_UUID
[] = {
201 0x05, 0xfb, 0xc6, 0xb9, 0x5a, 0x80, 0x40, 0xe5, 0xa2, 0x2a,
202 0xab, 0x40, 0x20, 0x26, 0x7e, 0x26
205 guint8
*ptr
= buffer
;
207 // Write PACSI (RFC6190 section 4.9)
208 SIPE_WRITE_UINT32_BE(ptr
, 77); // Length of the NAL
210 write_nal_unit_header(ptr
++, FALSE
, 3, NAL_UNIT_TYPE_PACSI
);
212 *ptr
= 1 << 7; // Reserved bit = 1
213 *ptr
|= 1 << 6; // I-bit = 1 if any aggregated unit has it set to 1
214 *ptr
|= 0; // Priority = 0
217 *ptr
= 1 << 7; // No Inter Layer Prediction = True
218 *ptr
|= 0 << 4; // Dependency ID = 0
219 *ptr
|= 0; // Quality ID
222 *ptr
= 0; // Temporal ID
223 *ptr
|= 0 << 4; // Use Ref Base Picture = False
224 *ptr
|= 0 << 3; // Discardable = False
225 *ptr
|= 1 << 2; // Output = True
226 *ptr
|= 3; // Reserved
229 // X|Y|T|A|P|C|S|E flags: DONC & First NAL = True
230 SIPE_WRITE_UINT8(ptr
, 0x22);
232 SIPE_WRITE_UINT16_BE(ptr
, 1); // Cross Session Decoder Order Number
234 // Stream Layout SEI Message (MS-H264PF section 2.2.5)
235 SIPE_WRITE_UINT16_BE(ptr
, 45); // Size of the NAL
237 write_nal_unit_header(ptr
++, FALSE
, 0, NAL_UNIT_TYPE_SEI
);
239 SIPE_WRITE_UINT8(ptr
, 5); // Payload type (user data unregistered)
240 SIPE_WRITE_UINT8(ptr
, 42); // Payload size
242 memcpy(ptr
, MS_STREAM_LAYOUT_SEI_UUID
,
243 sizeof (MS_STREAM_LAYOUT_SEI_UUID
));
244 ptr
+= sizeof (MS_STREAM_LAYOUT_SEI_UUID
);
246 // Layer Presence - layer with PRID 0 present
247 SIPE_WRITE_UINT64_BE(ptr
, 0x0100000000000000);
249 SIPE_WRITE_UINT8(ptr
, 1); // Layer Description Present = True
250 SIPE_WRITE_UINT8(ptr
, 16); // Layer Description Size
252 write_ms_layer_description(ptr
, 212, 160, 50250, MS_LD_FPS_IDX_7_5
,
256 // MS Bitstream Info SEI Message ([MS-H264PF] section 2.2.7)
257 SIPE_WRITE_UINT16_BE(ptr
, 21); // Size of the NAL
259 write_nal_unit_header(ptr
++, FALSE
, 0, NAL_UNIT_TYPE_SEI
);
261 SIPE_WRITE_UINT8(ptr
, 5); // Payload type (user data unregistered)
262 SIPE_WRITE_UINT8(ptr
, 18); // Payload size
264 memcpy(ptr
, MS_BITSTREAM_INFO_SEI_UUID
,
265 sizeof (MS_BITSTREAM_INFO_SEI_UUID
));
266 ptr
+= sizeof (MS_BITSTREAM_INFO_SEI_UUID
);
268 /* Reference frame count. This should increment with each reference
269 * frame, but clients apparently don't care about the value. */
270 SIPE_WRITE_UINT8(ptr
, 1);
271 // Number of NAL units described by this PACSI NAL unit.
272 SIPE_WRITE_UINT8(ptr
, nal_count
);