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 }