FreeCalypso > hg > gsm-codec-lib
comparison libgsmhr1/rtp_in_direct.c @ 510:5bf71b091323
libgsmhr1: add direct conversion from RTP input to decoder params
author | Mychaela Falconia <falcon@freecalypso.org> |
---|---|
date | Sun, 25 Aug 2024 02:19:37 +0000 |
parents | |
children |
comparison
equal
deleted
inserted
replaced
509:b7ddcb178ef6 | 510:5bf71b091323 |
---|---|
1 /* | |
2 * The function implemented in this module takes whatever HRv1 payload format | |
3 * came in from RTP (can be RFC 5993 with or without TW-TS-002 extensions, | |
4 * can be bare TS 101 318, can be zero-length or missing payload) and turns it | |
5 * into the internal input form for the HRv1 decoder. It is logically | |
6 * equivalent to calling gsmhr_rtp_in_preen() followed by | |
7 * gsmhr_decoder_twts002_in(), but is more efficient by avoiding the extra | |
8 * intermediate buffer and copying. | |
9 */ | |
10 | |
11 #include <stdint.h> | |
12 #include <string.h> | |
13 #include "tw_gsmhr.h" | |
14 | |
15 static void emit_bfi_nodata(int16_t *params) | |
16 { | |
17 memset(params, 0, sizeof(int16_t) * GSMHR_NUM_PARAMS); | |
18 params[18] = 2; /* BFI with no data */ | |
19 params[19] = 0; /* UFI */ | |
20 params[20] = 0; /* SID */ | |
21 params[21] = 0; /* TAF */ | |
22 } | |
23 | |
24 int gsmhr_rtp_in_direct(const uint8_t *rtp_in, unsigned rtp_in_len, | |
25 int16_t *params) | |
26 { | |
27 int ft; | |
28 | |
29 switch (rtp_in_len) { | |
30 case 0: | |
31 /* BFI-no-data, but not an invalid RTP input per se */ | |
32 emit_bfi_nodata(params); | |
33 return 0; | |
34 case 1: | |
35 /* | |
36 * This length is valid only if the payload is in | |
37 * RFC 5993 or TW-TS-002 format with FT=1 or FT=7. | |
38 */ | |
39 if (rtp_in[0] & 0x80) | |
40 goto bad_rtp_input; | |
41 ft = rtp_in[0] >> 4; | |
42 if (ft == 1 || ft == 7) { | |
43 gsmhr_decoder_twts002_in(rtp_in, params); | |
44 return 0; | |
45 } else | |
46 goto bad_rtp_input; | |
47 case GSMHR_FRAME_LEN_RPF: | |
48 /* | |
49 * The length is that of a TS 101 318 payload. | |
50 * No further checks can be done: every possible | |
51 * bit pattern is a valid payload in this format. | |
52 * But we do need to check for a perfect SID | |
53 * (the only kind of SID this format allows) | |
54 * and mark it accordingly in the output. | |
55 */ | |
56 gsmhr_unpack_ts101318(rtp_in, params); | |
57 params[18] = 0; /* BFI */ | |
58 params[19] = 0; /* UFI */ | |
59 params[20] = gsmhr_ts101318_is_perfect_sid(rtp_in); | |
60 params[21] = 0; /* TAF */ | |
61 return 0; | |
62 case GSMHR_FRAME_LEN_5993: | |
63 /* | |
64 * This length is valid only if the payload is in | |
65 * RFC 5993 or TW-TS-002 format with FT=0, FT=2 or FT=6. | |
66 */ | |
67 if (rtp_in[0] & 0x80) | |
68 goto bad_rtp_input; | |
69 ft = rtp_in[0] >> 4; | |
70 if (ft == 0 || ft == 2 || ft == 6) { | |
71 gsmhr_decoder_twts002_in(rtp_in, params); | |
72 return 0; | |
73 } else | |
74 goto bad_rtp_input; | |
75 default: | |
76 bad_rtp_input: | |
77 /* | |
78 * Treat it like BFI-no-data, and tell the caller | |
79 * that we received an invalid RTP payload. | |
80 */ | |
81 emit_bfi_nodata(params); | |
82 return -1; | |
83 } | |
84 } |