purple: work around broken dbus-server.h
[siplcs.git] / src / core / sipe-msrtp.c
blobd342f23d42dc5e8f7aa891e349f359d99baaa8cd
1 /**
2 * @file sipe-msrtp.c
4 * pidgin-sipe
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
23 #include <string.h>
25 #include <glib.h>
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); \
38 where += 2;
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); \
45 where += 4;
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); \
56 where += 8;
58 enum
60 VSR_FLAG_NONE = 0,
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
67 enum
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,
77 enum
79 VSR_FPS_7_5 = 1,
80 VSR_FPS_12_5 = 2,
81 VSR_FPS_15 = 4,
82 VSR_FPS_25 = 8,
83 VSR_FPS_30 = 16,
84 VSR_FPS_50 = 32,
85 VSR_FPS_60 = 64
88 enum
90 NAL_UNIT_TYPE_SEI = 6,
91 NAL_UNIT_TYPE_PACSI = 30
94 enum
96 MS_LD_FPS_IDX_7_5 = 0,
97 MS_LD_FPS_IDX_12_5 = 1,
98 MS_LD_FPS_IDX_15 = 2,
99 MS_LD_FPS_IDX_25 = 3,
100 MS_LD_FPS_IDX_30 = 4,
101 MS_LD_FPS_IDX_50 = 5,
102 MS_LD_FPS_IDX_60 = 6
105 void
106 sipe_core_msrtp_write_video_source_request(guint8 *buffer,
107 guint8 payload_type)
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 */
119 /* Header */
121 SIPE_WRITE_UINT16_BE(buffer, 0x1); // AFB Type
122 // Length
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
135 /* Entry */
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
159 static void
160 write_nal_unit_header(guint8 *dest, gboolean f_bit, guint8 nal_ref_idc,
161 guint8 type)
163 *dest = f_bit ? 0x80 : 0x00;
164 *dest |= nal_ref_idc << 5;
165 *dest |= type;
168 static void
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;
186 ++buffer;
188 *buffer = prid << 2;
189 *buffer |= (constrained_baseline ? 1 : 0) << 1;
192 gsize
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
215 ++ptr;
217 *ptr = 1 << 7; // No Inter Layer Prediction = True
218 *ptr |= 0 << 4; // Dependency ID = 0
219 *ptr |= 0; // Quality ID
220 ++ptr;
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
227 ++ptr;
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,
253 TRUE, 0, TRUE);
254 ptr += 16;
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);
274 return ptr - buffer;
278 Local Variables:
279 mode: c
280 c-file-style: "bsd"
281 indent-tabs-mode: t
282 tab-width: 8
283 End: