Line data Source code
1 : /******************************************************************************************************
2 :
3 : (C) 2022-2025 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB,
4 : Fraunhofer-Gesellschaft zur Foerderung der angewandten Forschung e.V., Huawei Technologies Co. LTD.,
5 : Koninklijke Philips N.V., Nippon Telegraph and Telephone Corporation, Nokia Technologies Oy, Orange,
6 : Panasonic Holdings Corporation, Qualcomm Technologies, Inc., VoiceAge Corporation, and other
7 : contributors to this repository. All Rights Reserved.
8 :
9 : This software is protected by copyright law and by international treaties.
10 : The IVAS codec Public Collaboration consisting of Dolby International AB, Ericsson AB,
11 : Fraunhofer-Gesellschaft zur Foerderung der angewandten Forschung e.V., Huawei Technologies Co. LTD.,
12 : Koninklijke Philips N.V., Nippon Telegraph and Telephone Corporation, Nokia Technologies Oy, Orange,
13 : Panasonic Holdings Corporation, Qualcomm Technologies, Inc., VoiceAge Corporation, and other
14 : contributors to this repository retain full ownership rights in their respective contributions in
15 : the software. This notice grants no license of any kind, including but not limited to patent
16 : license, nor is any license granted by implication, estoppel or otherwise.
17 :
18 : Contributors are required to enter into the IVAS codec Public Collaboration agreement before making
19 : contributions.
20 :
21 : This software is provided "AS IS", without any express or implied warranties. The software is in the
22 : development stage. It is intended exclusively for experts who have experience with such software and
23 : solely for the purpose of inspection. All implied warranties of non-infringement, merchantability
24 : and fitness for a particular purpose are hereby disclaimed and excluded.
25 :
26 : Any dispute, controversy or claim arising under or in relation to providing this software shall be
27 : submitted to and settled by the final, binding jurisdiction of the courts of Munich, Germany in
28 : accordance with the laws of the Federal Republic of Germany excluding its conflict of law rules and
29 : the United Nations Convention on Contracts on the International Sales of Goods.
30 :
31 : *******************************************************************************************************/
32 :
33 : #include <stdbool.h>
34 : #include <assert.h>
35 : #include <string.h>
36 : #include "isar_lc3plus_payload.h"
37 : #include "options.h"
38 :
39 :
40 : /*-------------------------------------------------------------------------
41 : * Local functions
42 : *------------------------------------------------------------------------*/
43 :
44 0 : static LC3PLUS_RTP_ERR s_frame_duration_ms_from_fdi(
45 : int32_t *frame_duration_us,
46 : const LC3PLUS_RTP_FTD_FDI fdi )
47 : {
48 0 : if ( NULL == frame_duration_us )
49 : {
50 0 : return LC3PLUS_RTP_ERR_NULL_PTR;
51 : }
52 0 : switch ( fdi )
53 : {
54 0 : case LC3PLUS_RTP_FTD_FDI_2500_US:
55 0 : *frame_duration_us = 2500;
56 0 : break;
57 0 : case LC3PLUS_RTP_FTD_FDI_5000_US:
58 0 : *frame_duration_us = 5000;
59 0 : break;
60 0 : case LC3PLUS_RTP_FTD_FDI_10000_US:
61 0 : *frame_duration_us = 10000;
62 0 : break;
63 0 : case LC3PLUS_RTP_FTD_FDI_RESERVED:
64 : default:
65 0 : return LC3PLUS_RTP_ERR_INVALID_PARAMETERS;
66 : }
67 :
68 0 : return LC3PLUS_RTP_ERR_NO_ERROR;
69 : }
70 :
71 :
72 0 : static LC3PLUS_RTP_ERR s_sampling_rate_hz_from_bwr(
73 : int32_t *sample_rate_hz,
74 : const LC3PLUS_RTP_FTD_BWR bwr )
75 : {
76 0 : if ( NULL == sample_rate_hz )
77 : {
78 0 : return LC3PLUS_RTP_ERR_NULL_PTR;
79 : }
80 0 : switch ( bwr )
81 : {
82 0 : case LC3PLUS_RTP_FTD_BWR_NB:
83 0 : *sample_rate_hz = 8000;
84 0 : break;
85 0 : case LC3PLUS_RTP_FTD_BWR_WB:
86 0 : *sample_rate_hz = 16000;
87 0 : break;
88 0 : case LC3PLUS_RTP_FTD_BWR_SSWB:
89 0 : *sample_rate_hz = 24000;
90 0 : break;
91 0 : case LC3PLUS_RTP_FTD_BWR_SWB:
92 0 : *sample_rate_hz = 32000;
93 0 : break;
94 0 : case LC3PLUS_RTP_FTD_BWR_FBCD:
95 0 : *sample_rate_hz = 44100;
96 0 : break;
97 0 : case LC3PLUS_RTP_FTD_BWR_FB:
98 0 : *sample_rate_hz = 48000;
99 0 : break;
100 0 : case LC3PLUS_RTP_FTD_BWR_FBHR:
101 0 : *sample_rate_hz = 48000;
102 0 : break;
103 0 : case LC3PLUS_RTP_FTD_BWR_UBHR:
104 0 : *sample_rate_hz = 96000;
105 0 : break;
106 0 : default:
107 0 : return LC3PLUS_RTP_ERR_INVALID_PARAMETERS;
108 : }
109 :
110 0 : return LC3PLUS_RTP_ERR_NO_ERROR;
111 : }
112 :
113 :
114 0 : static LC3PLUS_RTP_ERR s_high_resolution_flag_from_bwr(
115 : int16_t *high_resolution_flag,
116 : const LC3PLUS_RTP_FTD_BWR bwr )
117 : {
118 0 : if ( NULL == high_resolution_flag )
119 : {
120 0 : return LC3PLUS_RTP_ERR_NULL_PTR;
121 : }
122 0 : switch ( bwr )
123 : {
124 0 : case LC3PLUS_RTP_FTD_BWR_NB:
125 0 : *high_resolution_flag = 0;
126 0 : break;
127 0 : case LC3PLUS_RTP_FTD_BWR_WB:
128 0 : *high_resolution_flag = 0;
129 0 : break;
130 0 : case LC3PLUS_RTP_FTD_BWR_SSWB:
131 0 : *high_resolution_flag = 0;
132 0 : break;
133 0 : case LC3PLUS_RTP_FTD_BWR_SWB:
134 0 : *high_resolution_flag = 0;
135 0 : break;
136 0 : case LC3PLUS_RTP_FTD_BWR_FBCD:
137 0 : *high_resolution_flag = 0;
138 0 : break;
139 0 : case LC3PLUS_RTP_FTD_BWR_FB:
140 0 : *high_resolution_flag = 0;
141 0 : break;
142 0 : case LC3PLUS_RTP_FTD_BWR_FBHR:
143 0 : *high_resolution_flag = 1;
144 0 : break;
145 0 : case LC3PLUS_RTP_FTD_BWR_UBHR:
146 0 : *high_resolution_flag = 1;
147 0 : break;
148 0 : default:
149 0 : return LC3PLUS_RTP_ERR_INVALID_PARAMETERS;
150 : }
151 :
152 0 : return LC3PLUS_RTP_ERR_NO_ERROR;
153 : }
154 :
155 :
156 : /*-------------------------------------------------------------------------
157 : * LC3PLUS_RTP_frame_data_length_get_size()
158 : *
159 : *
160 : *------------------------------------------------------------------------*/
161 :
162 0 : LC3PLUS_RTP_ERR LC3PLUS_RTP_frame_data_length_get_size(
163 : int32_t *length,
164 : const LC3PLUS_RTP_FDL frameDataLengthValue )
165 : {
166 0 : if ( frameDataLengthValue == LC3PLUS_RTP_FDL_NO_REQ_OR_NO_DATA || frameDataLengthValue == LC3PLUS_RTP_FDL_SPEECH_BAD || frameDataLengthValue == LC3PLUS_RTP_FDL_SPEECH_SID )
167 : {
168 0 : *length = 1;
169 : }
170 0 : else if ( frameDataLengthValue >= LC3PLUS_RTP_FDL_LENGTH_1_MIN && frameDataLengthValue <= LC3PLUS_RTP_FDL_LENGTH_1_MAX )
171 : {
172 0 : *length = 1;
173 : }
174 0 : else if ( frameDataLengthValue >= LC3PLUS_RTP_FDL_LENGTH_2_MIN && frameDataLengthValue <= LC3PLUS_RTP_FDL_LENGTH_2_MAX )
175 : {
176 0 : *length = 2;
177 : }
178 0 : else if ( frameDataLengthValue >= LC3PLUS_RTP_FDL_LENGTH_3_MIN && frameDataLengthValue <= LC3PLUS_RTP_FDL_LENGTH_3_MAX )
179 : {
180 0 : *length = 3;
181 : }
182 : else
183 : {
184 0 : return LC3PLUS_RTP_ERR_INVALID_PARAMETERS;
185 : }
186 :
187 0 : return LC3PLUS_RTP_ERR_NO_ERROR;
188 : }
189 :
190 :
191 0 : static LC3PLUS_RTP_ERR s_frame_data_length_pack(
192 : const LC3PLUS_RTP_FDL frameDataLengthValue,
193 : uint8_t *dst )
194 : {
195 : int32_t frame_data_length_size;
196 : LC3PLUS_RTP_ERR err;
197 :
198 0 : if ( NULL == dst )
199 : {
200 0 : return LC3PLUS_RTP_ERR_NULL_PTR;
201 : }
202 :
203 0 : err = LC3PLUS_RTP_frame_data_length_get_size( &frame_data_length_size, frameDataLengthValue );
204 0 : if ( err != LC3PLUS_RTP_ERR_NO_ERROR )
205 : {
206 0 : return err;
207 : }
208 0 : if ( 1 == frame_data_length_size )
209 : {
210 0 : *dst++ = frameDataLengthValue >> 0 & LC3PLUS_RTP_FDL_EXTENSION_VALUE;
211 : }
212 0 : else if ( 2 == frame_data_length_size )
213 : {
214 0 : const int32_t frameDataLengthValueToWrite = frameDataLengthValue - LC3PLUS_RTP_FDL_EXTENSION_VALUE;
215 0 : *dst++ = LC3PLUS_RTP_FDL_EXTENSION_VALUE;
216 0 : *dst = frameDataLengthValueToWrite >> 0 & LC3PLUS_RTP_FDL_EXTENSION_VALUE;
217 : }
218 0 : else if ( 3 == frame_data_length_size )
219 : {
220 0 : const int32_t frameDataLengthValueToWrite = frameDataLengthValue - ( 2 * LC3PLUS_RTP_FDL_EXTENSION_VALUE );
221 0 : *dst++ = LC3PLUS_RTP_FDL_EXTENSION_VALUE;
222 0 : *dst++ = LC3PLUS_RTP_FDL_EXTENSION_VALUE;
223 0 : *dst = frameDataLengthValueToWrite >> 0 & LC3PLUS_RTP_FDL_EXTENSION_VALUE;
224 : }
225 :
226 0 : return LC3PLUS_RTP_ERR_NO_ERROR;
227 : }
228 :
229 :
230 0 : static int32_t s_get_size_from_fdl(
231 : const LC3PLUS_RTP_FDL fdl )
232 : {
233 0 : if ( fdl >= LC3PLUS_RTP_FDL_LENGTH_1_MIN && fdl <= LC3PLUS_RTP_FDL_LENGTH_3_MAX )
234 : {
235 0 : return fdl;
236 : }
237 :
238 0 : return 0;
239 : }
240 :
241 :
242 0 : static bool s_fdl_is_magic_value(
243 : const LC3PLUS_RTP_FDL fdl )
244 : {
245 0 : if ( fdl == LC3PLUS_RTP_FDL_NO_REQ_OR_NO_DATA || fdl == LC3PLUS_RTP_FDL_SPEECH_SID || fdl == LC3PLUS_RTP_FDL_SPEECH_BAD )
246 : {
247 0 : return true;
248 : }
249 :
250 0 : return false;
251 : }
252 :
253 :
254 0 : static bool s_fdl_value_is_valid_request(
255 : const LC3PLUS_RTP_FDL fdl_request )
256 : {
257 : /* LC3PLUS_RTP_FDL_SPEECH_SID && LC3PLUS_RTP_FDL_SPEECH_SID are not valid values for the FDL request */
258 0 : if ( fdl_request == LC3PLUS_RTP_FDL_NO_REQ_OR_NO_DATA || ( fdl_request >= LC3PLUS_RTP_FDL_LENGTH_1_MIN && fdl_request <= LC3PLUS_RTP_FDL_LENGTH_3_MAX ) )
259 : {
260 0 : return true;
261 : }
262 :
263 0 : return false;
264 : }
265 :
266 :
267 0 : static LC3PLUS_RTP_ERR s_frame_data_length_parse(
268 : LC3PLUS_RTP_FDL *frame_data_length_value,
269 : const uint8_t *src,
270 : const size_t remaining_capacity )
271 : {
272 : int32_t frame_data_length_size;
273 : LC3PLUS_RTP_ERR err;
274 :
275 0 : if ( NULL == src || NULL == frame_data_length_value || remaining_capacity < 1 )
276 : {
277 0 : return LC3PLUS_RTP_ERR_NULL_PTR;
278 : }
279 :
280 0 : if ( remaining_capacity > 2 && LC3PLUS_RTP_FDL_EXTENSION_VALUE == *src && LC3PLUS_RTP_FDL_EXTENSION_VALUE == *( src + 1 ) )
281 : {
282 0 : *frame_data_length_value = *( src + 2 ) + 2 * LC3PLUS_RTP_FDL_EXTENSION_VALUE;
283 : }
284 0 : else if ( remaining_capacity > 1 && LC3PLUS_RTP_FDL_EXTENSION_VALUE == *src )
285 : {
286 0 : *frame_data_length_value = *( src + 1 ) + 1 * LC3PLUS_RTP_FDL_EXTENSION_VALUE;
287 : }
288 0 : else if ( remaining_capacity > 0 )
289 : {
290 0 : *frame_data_length_value = *src << 0;
291 : }
292 : else
293 : {
294 0 : return LC3PLUS_RTP_ERR_INVALID_BITSTREAM_SIZE;
295 : }
296 :
297 : /* sanity check */
298 0 : err = LC3PLUS_RTP_frame_data_length_get_size( &frame_data_length_size, *frame_data_length_value );
299 0 : if ( err != LC3PLUS_RTP_ERR_NO_ERROR )
300 : {
301 0 : return err;
302 : }
303 :
304 0 : return LC3PLUS_RTP_ERR_NO_ERROR;
305 : }
306 :
307 :
308 0 : static LC3PLUS_RTP_ERR s_parse_ftd(
309 : const uint8_t *p_read,
310 : LC3PLUS_RTP_FTD *receiver_ftd,
311 : int32_t *num_bytes_read,
312 : const size_t remaining_capacity )
313 : {
314 : int32_t frame_data_block_size;
315 : LC3PLUS_RTP_FDL fdl;
316 : LC3PLUS_RTP_ERR err;
317 :
318 0 : if ( NULL == p_read || NULL == receiver_ftd || NULL == num_bytes_read || remaining_capacity < LC3PLUS_RTP_FTD_MIN_SIZE )
319 : {
320 0 : return LC3PLUS_RTP_ERR_NULL_PTR;
321 : }
322 :
323 0 : *num_bytes_read = 0;
324 0 : receiver_ftd->fc = 0;
325 0 : receiver_ftd->fdi = 0;
326 0 : receiver_ftd->bwr = 0;
327 0 : receiver_ftd->h = 0;
328 0 : receiver_ftd->fc |= *p_read & LC3PLUS_RTP_FTD_FC_MASK;
329 0 : receiver_ftd->fdi |= ( *p_read & LC3PLUS_RTP_FTD_FDI_MASK );
330 0 : receiver_ftd->bwr |= ( *p_read & LC3PLUS_RTP_FTD_BWR_MASK );
331 0 : receiver_ftd->h |= ( *p_read & LC3PLUS_RTP_FTD_H_MASK );
332 0 : p_read++;
333 0 : *num_bytes_read = 1;
334 :
335 0 : err = s_frame_data_length_parse( &fdl, p_read, remaining_capacity - *num_bytes_read );
336 0 : if ( LC3PLUS_RTP_ERR_NO_ERROR != err )
337 : {
338 0 : return err;
339 : }
340 0 : frame_data_block_size = s_get_size_from_fdl( fdl );
341 :
342 0 : receiver_ftd->frame_data_length = frame_data_block_size;
343 : int32_t length_field_size;
344 0 : err = LC3PLUS_RTP_frame_data_length_get_size( &length_field_size, receiver_ftd->frame_data_length );
345 0 : if ( LC3PLUS_RTP_ERR_NO_ERROR != err )
346 : {
347 0 : return err;
348 : }
349 0 : *num_bytes_read += length_field_size;
350 :
351 0 : return LC3PLUS_RTP_ERR_NO_ERROR;
352 : }
353 :
354 :
355 : /*-------------------------------------------------------------------------
356 : * LC3PLUS_RTP_payload_serialize()
357 : *
358 : *
359 : *------------------------------------------------------------------------*/
360 :
361 0 : LC3PLUS_RTP_ERR LC3PLUS_RTP_payload_serialize(
362 : uint8_t *serialized_buffer,
363 : const size_t serialized_buffer_capacity,
364 : size_t *packed_buffer_actual_size,
365 : const LC3PLUS_RTP_FDL fdl_request,
366 : LC3PLUS_RTP_FTD *sender_ftds,
367 : const size_t sender_ftds_num )
368 : {
369 : LC3PLUS_RTP_ERR err;
370 0 : uint8_t *p_write = serialized_buffer;
371 : uint32_t i;
372 0 : int32_t bytes_written = 0;
373 : int32_t lc3plus_frame_size_sum;
374 : uint8_t *p_frame_data;
375 : int32_t fdl_request_length;
376 :
377 0 : if ( NULL == serialized_buffer || NULL == packed_buffer_actual_size || NULL == sender_ftds )
378 : {
379 0 : return LC3PLUS_RTP_ERR_NULL_PTR;
380 : }
381 :
382 0 : *packed_buffer_actual_size = 0;
383 0 : err = LC3PLUS_RTP_frame_data_length_get_size( &fdl_request_length, fdl_request );
384 0 : if ( LC3PLUS_RTP_ERR_NO_ERROR != err )
385 : {
386 0 : return err;
387 : }
388 0 : if ( !s_fdl_value_is_valid_request( fdl_request ) )
389 : {
390 0 : return LC3PLUS_RTP_ERR_INVALID_FDL_REQUEST;
391 : }
392 0 : if ( (int32_t) serialized_buffer_capacity < bytes_written + fdl_request_length )
393 : {
394 0 : return LC3PLUS_RTP_ERR_INVALID_BITSTREAM_SIZE;
395 : }
396 0 : err = s_frame_data_length_pack( fdl_request, p_write );
397 0 : if ( LC3PLUS_RTP_ERR_NO_ERROR != err )
398 : {
399 0 : return err;
400 : }
401 0 : bytes_written += fdl_request_length;
402 0 : p_write += bytes_written;
403 :
404 0 : for ( i = 0; i < sender_ftds_num; ++i )
405 : {
406 : /* only the last ftd may have the LC3PLUS_RTP_FTD_FC_LAST_OVERALL value */
407 0 : if ( sender_ftds[i].fc == LC3PLUS_RTP_FTD_FC_LAST_OVERALL && i != ( sender_ftds_num - 1 ) )
408 : {
409 0 : return LC3PLUS_RTP_ERR_INVALID_PARAMETERS;
410 : }
411 : /* the last ftd must have the LC3PLUS_RTP_FTD_FC_LAST_OVERALL value */
412 0 : if ( sender_ftds[i].fc != LC3PLUS_RTP_FTD_FC_LAST_OVERALL && i == ( sender_ftds_num - 1 ) )
413 : {
414 0 : return LC3PLUS_RTP_ERR_INVALID_PARAMETERS;
415 : }
416 0 : if ( (int32_t) serialized_buffer_capacity < bytes_written + LC3PLUS_RTP_FTD_LENGTH_EXCLUDING_FDL )
417 : {
418 0 : return LC3PLUS_RTP_ERR_INVALID_BITSTREAM_SIZE;
419 : }
420 0 : *p_write = 0x00;
421 0 : *p_write |= LC3PLUS_RTP_FTD_FC_MASK & (uint8_t) sender_ftds[i].fc;
422 0 : *p_write |= LC3PLUS_RTP_FTD_FDI_MASK & (uint8_t) sender_ftds[i].fdi;
423 0 : *p_write |= LC3PLUS_RTP_FTD_BWR_MASK & (uint8_t) sender_ftds[i].bwr;
424 0 : *p_write |= LC3PLUS_RTP_FTD_H_MASK & (uint8_t) sender_ftds[i].h;
425 0 : p_write++;
426 0 : bytes_written += LC3PLUS_RTP_FTD_LENGTH_EXCLUDING_FDL;
427 :
428 : int32_t fdl_length;
429 0 : err = LC3PLUS_RTP_frame_data_length_get_size( &fdl_length, sender_ftds[i].frame_data_length );
430 0 : if ( LC3PLUS_RTP_ERR_NO_ERROR != err )
431 : {
432 0 : return err;
433 : }
434 0 : if ( (int32_t) serialized_buffer_capacity < bytes_written + fdl_length )
435 : {
436 0 : return LC3PLUS_RTP_ERR_INVALID_BITSTREAM_SIZE;
437 : }
438 0 : err = s_frame_data_length_pack( sender_ftds[i].frame_data_length, p_write );
439 0 : if ( LC3PLUS_RTP_ERR_NO_ERROR != err )
440 : {
441 0 : return err;
442 : }
443 0 : p_write += fdl_length;
444 0 : bytes_written += fdl_length;
445 : }
446 :
447 0 : lc3plus_frame_size_sum = 0;
448 0 : p_frame_data = serialized_buffer + bytes_written;
449 0 : for ( i = 0; i < sender_ftds_num; ++i )
450 : {
451 0 : sender_ftds[i].frame_data = p_frame_data;
452 0 : p_frame_data += sender_ftds[i].frame_data_length;
453 0 : lc3plus_frame_size_sum += sender_ftds[i].frame_data_length;
454 : }
455 0 : *packed_buffer_actual_size = bytes_written + lc3plus_frame_size_sum;
456 0 : assert( *packed_buffer_actual_size <= serialized_buffer_capacity );
457 :
458 0 : return LC3PLUS_RTP_ERR_NO_ERROR;
459 : }
460 :
461 :
462 0 : static LC3PLUS_RTP_ERR s_ftds_parse(
463 : LC3PLUS_RTP_FTD *receiver_ftds,
464 : const int32_t receiver_ftds_num_max,
465 : int16_t *receiver_ftds_num,
466 : uint8_t *serialized_buffer,
467 : const size_t serialized_buffer_size )
468 : {
469 : int32_t diff;
470 : uint8_t *p_read;
471 0 : uint32_t ftds_offset_sum = 0;
472 : int16_t i;
473 : LC3PLUS_RTP_ERR error;
474 : int32_t frame_offset_counter;
475 : int32_t size;
476 :
477 0 : p_read = serialized_buffer;
478 0 : if ( NULL == receiver_ftds || NULL == receiver_ftds_num || NULL == serialized_buffer )
479 : {
480 0 : return LC3PLUS_RTP_ERR_NULL_PTR;
481 : }
482 0 : if ( 0 == serialized_buffer_size )
483 : {
484 0 : return LC3PLUS_RTP_ERR_EMPTY_TOC;
485 : }
486 0 : if ( receiver_ftds_num_max <= 0 )
487 : {
488 0 : return LC3PLUS_RTP_ERR_INVALID_PARAMETERS;
489 : }
490 :
491 : {
492 0 : int32_t num_bytes_read_sum = 0;
493 0 : const int32_t min_num_bytes_per_ftd = 2;
494 0 : int16_t receiver_ftds_index = 0;
495 0 : bool another_ftd = true;
496 : int32_t num_bytes_read_per_ftd;
497 :
498 0 : while ( another_ftd )
499 : {
500 0 : if ( (int32_t) serialized_buffer_size < min_num_bytes_per_ftd )
501 : {
502 0 : return LC3PLUS_RTP_ERR_INVALID_BITSTREAM_SIZE;
503 : }
504 0 : if ( num_bytes_read_sum >= (int32_t) serialized_buffer_size - min_num_bytes_per_ftd )
505 : {
506 0 : return LC3PLUS_RTP_ERR_INVALID_BITSTREAM_SIZE;
507 : }
508 0 : num_bytes_read_per_ftd = 0;
509 0 : error = s_parse_ftd( p_read, &receiver_ftds[receiver_ftds_index], &num_bytes_read_per_ftd, serialized_buffer_size - num_bytes_read_sum );
510 0 : if ( LC3PLUS_RTP_ERR_NO_ERROR != error )
511 : {
512 0 : return error;
513 : }
514 0 : p_read += num_bytes_read_per_ftd;
515 0 : num_bytes_read_sum += num_bytes_read_per_ftd;
516 :
517 0 : if ( receiver_ftds[receiver_ftds_index].fc == LC3PLUS_RTP_FTD_FC_RESERVED )
518 : {
519 0 : return LC3PLUS_RTP_ERR_INVALID_BITSTREAM;
520 : }
521 0 : else if ( receiver_ftds[receiver_ftds_index].fc == LC3PLUS_RTP_FTD_FC_LAST_OVERALL )
522 : {
523 0 : another_ftd = false;
524 : }
525 :
526 0 : if ( another_ftd )
527 : {
528 0 : if ( receiver_ftds_index >= receiver_ftds_num_max )
529 : {
530 0 : return LC3PLUS_RTP_ERR_NOT_ENOUGH_FTDS_ALLOCATED;
531 : }
532 0 : ( receiver_ftds_index )++;
533 : }
534 : }
535 0 : *receiver_ftds_num = receiver_ftds_index + 1;
536 : }
537 :
538 : /* set frame-data pointers into serialized_buffer */
539 0 : for ( i = 0; i < *receiver_ftds_num; ++i )
540 : {
541 0 : error = LC3PLUS_RTP_frame_data_length_get_size( &size, receiver_ftds[i].frame_data_length );
542 0 : if ( error != LC3PLUS_RTP_ERR_NO_ERROR )
543 : {
544 0 : return error;
545 : }
546 0 : ftds_offset_sum += LC3PLUS_RTP_FTD_LENGTH_EXCLUDING_FDL + size;
547 : }
548 :
549 0 : frame_offset_counter = 0;
550 0 : for ( i = 0; i < *receiver_ftds_num; ++i )
551 : {
552 0 : if ( s_fdl_is_magic_value( receiver_ftds[i].frame_data_length ) )
553 : {
554 0 : receiver_ftds[i].frame_data = NULL;
555 : }
556 : else
557 : {
558 0 : receiver_ftds[i].frame_data = serialized_buffer + ftds_offset_sum + frame_offset_counter;
559 0 : frame_offset_counter += receiver_ftds[i].frame_data_length;
560 : }
561 : }
562 :
563 0 : if ( ftds_offset_sum + frame_offset_counter != serialized_buffer_size )
564 : {
565 : /* parsed content & size n bytes of input buffer do not line up */
566 : /* if the buffer capacity is larger and the remaining bytes are zero, we don't treat this as an error since it's due to the IVAS-Split rendering zero padding */
567 0 : diff = serialized_buffer_size - ( ftds_offset_sum + frame_offset_counter );
568 0 : if ( diff < 0 )
569 : {
570 0 : return LC3PLUS_RTP_ERR_INVALID_BITSTREAM_SIZE;
571 : }
572 : /* verify that all bytes are zero */
573 0 : p_read += frame_offset_counter;
574 0 : for ( i = 0; i < diff; ++i )
575 : {
576 0 : if ( *p_read != 0 )
577 : {
578 : /* non-zero byte in padding region */
579 0 : return LC3PLUS_RTP_ERR_NONZERO_PADDING_BYTES;
580 : }
581 0 : p_read++;
582 : }
583 : }
584 :
585 0 : return LC3PLUS_RTP_ERR_NO_ERROR;
586 : }
587 :
588 :
589 : /*-------------------------------------------------------------------------
590 : * LC3PLUS_RTP_payload_deserialize()
591 : *
592 : *
593 : *------------------------------------------------------------------------*/
594 :
595 0 : LC3PLUS_RTP_ERR LC3PLUS_RTP_payload_deserialize(
596 : LC3PLUS_RTP_PAYLOAD *payload,
597 : uint8_t *serialized_buffer,
598 : const size_t serialized_buffer_size )
599 : {
600 : int32_t new_frame_duration_us;
601 : int32_t new_sampling_rate_hz;
602 : int16_t new_high_resolution_flag;
603 0 : int16_t i = 0;
604 0 : int16_t channel_id = 0;
605 0 : int16_t media_time_id = 0;
606 0 : const int16_t invalid_value = -1;
607 : int16_t media_times_per_channel[LC3PLUS_RTP_PAYLOAD_MAX_NUM_CHANNELS];
608 : int16_t channels_per_media_time[LC3PLUS_RTP_PAYLOAD_MAX_NUM_MEDIA_TIMES];
609 : LC3PLUS_RTP_ERR err;
610 :
611 0 : if ( NULL == payload || NULL == serialized_buffer )
612 : {
613 0 : return LC3PLUS_RTP_ERR_NULL_PTR;
614 : }
615 0 : if ( 0 == serialized_buffer_size )
616 : {
617 0 : return LC3PLUS_RTP_ERR_INVALID_PARAMETERS;
618 : }
619 :
620 0 : for ( media_time_id = 0; media_time_id < LC3PLUS_RTP_PAYLOAD_MAX_NUM_MEDIA_TIMES; ++media_time_id )
621 : {
622 0 : channels_per_media_time[media_time_id] = invalid_value;
623 : }
624 0 : media_time_id = 0;
625 0 : for ( channel_id = 0; channel_id < LC3PLUS_RTP_PAYLOAD_MAX_NUM_CHANNELS; ++channel_id )
626 : {
627 0 : media_times_per_channel[channel_id] = invalid_value;
628 : }
629 0 : channel_id = 0;
630 :
631 0 : err = s_frame_data_length_parse( &payload->fdl_request, serialized_buffer, serialized_buffer_size );
632 0 : if ( LC3PLUS_RTP_ERR_NO_ERROR != err )
633 : {
634 0 : return err;
635 : }
636 : int32_t fdl_request_length;
637 0 : err = LC3PLUS_RTP_frame_data_length_get_size( &fdl_request_length, payload->fdl_request );
638 0 : if ( LC3PLUS_RTP_ERR_NO_ERROR != err )
639 : {
640 0 : return err;
641 : }
642 0 : if ( !s_fdl_value_is_valid_request( payload->fdl_request ) )
643 : {
644 0 : return LC3PLUS_RTP_ERR_INVALID_FDL_REQUEST;
645 : }
646 :
647 0 : err = s_ftds_parse( payload->ftds, sizeof( payload->ftds ) / sizeof( LC3PLUS_RTP_FTD ), &payload->num_ftds, serialized_buffer + fdl_request_length, serialized_buffer_size - fdl_request_length );
648 0 : if ( LC3PLUS_RTP_ERR_NO_ERROR != err )
649 : {
650 0 : return err;
651 : }
652 0 : if ( 0 == payload->num_ftds )
653 : {
654 0 : return LC3PLUS_RTP_ERR_GENERIC_ERROR;
655 : }
656 : /* verify shared setting between all FTDs [samplerate, frame_duration, channel count] */
657 :
658 : /* initialize on the first FTD, use this as reference */
659 0 : err = s_frame_duration_ms_from_fdi( &payload->frame_duration_us, payload->ftds[0].fdi );
660 0 : if ( LC3PLUS_RTP_ERR_NO_ERROR != err )
661 : {
662 0 : return err;
663 : }
664 0 : err = s_sampling_rate_hz_from_bwr( &payload->sampling_rate_hz, payload->ftds[0].bwr );
665 0 : if ( LC3PLUS_RTP_ERR_NO_ERROR != err )
666 : {
667 0 : return err;
668 : }
669 0 : err = s_high_resolution_flag_from_bwr( &payload->high_resolution_enabled, payload->ftds[0].bwr );
670 0 : if ( LC3PLUS_RTP_ERR_NO_ERROR != err )
671 : {
672 0 : return err;
673 : }
674 0 : payload->num_channels = 0;
675 0 : payload->num_media_times = 0;
676 0 : for ( i = 0; i < payload->num_ftds; ++i )
677 : {
678 0 : if ( payload->ftds[i].h != LC3PLUS_RTP_FTD_H_PRIMARY )
679 : {
680 : /* not implemented */
681 0 : return LC3PLUS_RTP_ERR_NOT_IMPLEMENTED;
682 : }
683 :
684 0 : err = s_frame_duration_ms_from_fdi( &new_frame_duration_us, payload->ftds[i].fdi );
685 0 : if ( LC3PLUS_RTP_ERR_NO_ERROR != err )
686 : {
687 0 : return err;
688 : }
689 0 : if ( payload->frame_duration_us != new_frame_duration_us )
690 : {
691 : /* mixed frame durations not supported */
692 0 : return LC3PLUS_RTP_ERR_UNSUPPORTED_CONFIGURATION;
693 : }
694 :
695 0 : err = s_sampling_rate_hz_from_bwr( &new_sampling_rate_hz, payload->ftds[i].bwr );
696 0 : if ( LC3PLUS_RTP_ERR_NO_ERROR != err )
697 : {
698 0 : return err;
699 : }
700 0 : if ( payload->sampling_rate_hz != new_sampling_rate_hz )
701 : {
702 : /* mixed sampling frequencies not supported */
703 0 : return LC3PLUS_RTP_ERR_UNSUPPORTED_CONFIGURATION;
704 : }
705 :
706 :
707 0 : err = s_high_resolution_flag_from_bwr( &new_high_resolution_flag, payload->ftds[i].bwr );
708 0 : if ( LC3PLUS_RTP_ERR_NO_ERROR != err )
709 : {
710 0 : return err;
711 : }
712 0 : if ( payload->high_resolution_enabled != new_high_resolution_flag )
713 : {
714 : /* mixed high resolution mode not supported */
715 0 : return LC3PLUS_RTP_ERR_UNSUPPORTED_CONFIGURATION;
716 : }
717 :
718 0 : switch ( payload->ftds[i].fc )
719 : {
720 0 : case LC3PLUS_RTP_FTD_FC_LAST_OVERALL:
721 0 : channels_per_media_time[media_time_id]++;
722 0 : media_times_per_channel[channel_id]++;
723 0 : channel_id = 0;
724 0 : media_time_id = 0;
725 0 : break;
726 0 : case LC3PLUS_RTP_FTD_FC_SUBSEQUENT_CHANNEL:
727 0 : media_times_per_channel[channel_id]++;
728 0 : channels_per_media_time[media_time_id]++;
729 0 : channel_id++;
730 0 : break;
731 0 : case LC3PLUS_RTP_FTD_FC_LAST_IN_MEDIATIME:
732 0 : media_times_per_channel[channel_id]++;
733 0 : channels_per_media_time[media_time_id]++;
734 0 : channel_id = 0;
735 0 : media_time_id++;
736 0 : break;
737 0 : case LC3PLUS_RTP_FTD_FC_RESERVED:
738 : default:
739 0 : return LC3PLUS_RTP_ERR_INVALID_BITSTREAM;
740 : }
741 : }
742 :
743 : {
744 : int32_t valid_num_media_times_per_channel;
745 : int32_t iCh;
746 : /* check whether all channels exist for each media time */
747 0 : if ( media_times_per_channel[0] == invalid_value )
748 : {
749 0 : return LC3PLUS_RTP_ERR_NOT_IMPLEMENTED;
750 : }
751 0 : valid_num_media_times_per_channel = media_times_per_channel[0];
752 0 : for ( iCh = 0; iCh < LC3PLUS_RTP_PAYLOAD_MAX_NUM_CHANNELS; ++iCh )
753 : {
754 0 : if ( media_times_per_channel[iCh] == invalid_value )
755 : {
756 0 : break;
757 : }
758 0 : if ( valid_num_media_times_per_channel != media_times_per_channel[iCh] )
759 : {
760 0 : return LC3PLUS_RTP_ERR_NOT_IMPLEMENTED;
761 : }
762 : }
763 : }
764 : {
765 : /* whether all media times exist for each channel */
766 : int32_t iMediaTime;
767 : int32_t valid_num_channels_per_media_time;
768 0 : if ( channels_per_media_time[0] == invalid_value )
769 : {
770 0 : return LC3PLUS_RTP_ERR_NOT_IMPLEMENTED;
771 : }
772 0 : valid_num_channels_per_media_time = channels_per_media_time[0];
773 0 : for ( iMediaTime = 0; iMediaTime < LC3PLUS_RTP_PAYLOAD_MAX_NUM_MEDIA_TIMES; ++iMediaTime )
774 : {
775 0 : if ( channels_per_media_time[iMediaTime] == invalid_value )
776 : {
777 0 : break;
778 : }
779 0 : if ( valid_num_channels_per_media_time != channels_per_media_time[iMediaTime] )
780 : {
781 0 : return LC3PLUS_RTP_ERR_NOT_IMPLEMENTED;
782 : }
783 : }
784 : }
785 :
786 : /* convert zero-index to count */
787 0 : payload->num_channels = channels_per_media_time[0] + 1;
788 0 : payload->num_media_times = media_times_per_channel[0] + 1;
789 :
790 : /* verify that all media times have the same number of channels, partial packets are not supported */
791 0 : if ( payload->num_ftds != payload->num_channels * payload->num_media_times )
792 : {
793 0 : return LC3PLUS_RTP_ERR_GENERIC_ERROR;
794 : }
795 :
796 0 : return LC3PLUS_RTP_ERR_NO_ERROR;
797 : }
798 :
799 :
800 : /*-------------------------------------------------------------------------
801 : * LC3PLUS_RTP_ftd_bwr_from_samplerate()
802 : *
803 : *
804 : *------------------------------------------------------------------------*/
805 :
806 0 : LC3PLUS_RTP_ERR LC3PLUS_RTP_ftd_bwr_from_samplerate(
807 : LC3PLUS_RTP_FTD_BWR *bwr,
808 : const int32_t sampling_rate,
809 : const int32_t high_res_enabled )
810 : {
811 0 : if ( NULL == bwr )
812 : {
813 0 : return LC3PLUS_RTP_ERR_NULL_PTR;
814 : }
815 0 : switch ( sampling_rate )
816 : {
817 0 : case 8000:
818 0 : if ( high_res_enabled )
819 : {
820 0 : return LC3PLUS_RTP_ERR_INVALID_PARAMETERS;
821 : }
822 0 : *bwr = LC3PLUS_RTP_FTD_BWR_NB;
823 0 : return LC3PLUS_RTP_ERR_NO_ERROR;
824 0 : case 16000:
825 0 : if ( high_res_enabled )
826 : {
827 0 : return LC3PLUS_RTP_ERR_INVALID_PARAMETERS;
828 : }
829 0 : *bwr = LC3PLUS_RTP_FTD_BWR_WB;
830 0 : return LC3PLUS_RTP_ERR_NO_ERROR;
831 0 : case 24000:
832 0 : if ( high_res_enabled )
833 : {
834 0 : return LC3PLUS_RTP_ERR_INVALID_PARAMETERS;
835 : }
836 0 : *bwr = LC3PLUS_RTP_FTD_BWR_SSWB;
837 0 : return LC3PLUS_RTP_ERR_NO_ERROR;
838 0 : case 32000:
839 0 : if ( high_res_enabled )
840 : {
841 0 : return LC3PLUS_RTP_ERR_INVALID_PARAMETERS;
842 : }
843 0 : *bwr = LC3PLUS_RTP_FTD_BWR_SWB;
844 0 : return LC3PLUS_RTP_ERR_NO_ERROR;
845 0 : case 44100:
846 0 : if ( high_res_enabled )
847 : {
848 0 : return LC3PLUS_RTP_ERR_INVALID_PARAMETERS;
849 : }
850 0 : *bwr = LC3PLUS_RTP_FTD_BWR_FBCD;
851 0 : return LC3PLUS_RTP_ERR_NO_ERROR;
852 0 : case 48000:
853 0 : if ( 0 == high_res_enabled )
854 : {
855 0 : *bwr = LC3PLUS_RTP_FTD_BWR_FB;
856 0 : return LC3PLUS_RTP_ERR_NO_ERROR;
857 : }
858 : else
859 : {
860 0 : *bwr = LC3PLUS_RTP_FTD_BWR_FBHR;
861 0 : return LC3PLUS_RTP_ERR_NO_ERROR;
862 : }
863 0 : case 96000:
864 0 : if ( 0 == high_res_enabled )
865 : {
866 0 : return LC3PLUS_RTP_ERR_INVALID_PARAMETERS;
867 : }
868 0 : *bwr = LC3PLUS_RTP_FTD_BWR_UBHR;
869 0 : return LC3PLUS_RTP_ERR_NO_ERROR;
870 0 : default:
871 0 : break;
872 : }
873 :
874 0 : return LC3PLUS_RTP_ERR_INVALID_PARAMETERS;
875 : }
876 :
877 :
878 : /*-------------------------------------------------------------------------
879 : * LC3PLUS_RTP_ftd_fdi_from_frame_duration_us()
880 : *
881 : *
882 : *------------------------------------------------------------------------*/
883 :
884 0 : LC3PLUS_RTP_ERR LC3PLUS_RTP_ftd_fdi_from_frame_duration_us(
885 : LC3PLUS_RTP_FTD_FDI *fdi,
886 : const int32_t frame_duration_us )
887 : {
888 0 : if ( NULL == fdi )
889 : {
890 0 : return LC3PLUS_RTP_ERR_NULL_PTR;
891 : }
892 0 : switch ( frame_duration_us )
893 : {
894 0 : case 2500:
895 0 : *fdi = LC3PLUS_RTP_FTD_FDI_2500_US;
896 0 : return LC3PLUS_RTP_ERR_NO_ERROR;
897 0 : case 5000:
898 0 : *fdi = LC3PLUS_RTP_FTD_FDI_5000_US;
899 0 : return LC3PLUS_RTP_ERR_NO_ERROR;
900 0 : case 10000:
901 0 : *fdi = LC3PLUS_RTP_FTD_FDI_10000_US;
902 0 : return LC3PLUS_RTP_ERR_NO_ERROR;
903 0 : default:
904 0 : break;
905 : }
906 :
907 0 : return LC3PLUS_RTP_ERR_INVALID_PARAMETERS;
908 : }
|