3 * RTP decoding routines for Wireshark.
4 * Copied from ui/gtk/rtp_player.c
6 * Copyright 2006, Alejandro Vaquero <alejandrovaquero@yahoo.com>
8 * Wireshark - Network traffic analyzer
9 * By Gerald Combs <gerald@wireshark.org>
10 * Copyright 1999 Gerald Combs
12 * SPDX-License-Identifier: GPL-2.0-or-later
17 #include <wsutil/codecs.h>
18 #include <wsutil/wslog.h>
20 #include <epan/rtp_pt.h>
21 #include <epan/dissectors/packet-rtp.h>
22 #include <epan/dissectors/packet-iuup.h>
23 #include <epan/dissectors/packet-amr.h>
25 #include <ui/rtp_media.h>
27 /****************************************************************************/
29 /****************************************************************************/
31 typedef struct _rtp_decoder_t
{
32 codec_handle_t handle
;
33 codec_context_t
*context
;
36 /****************************************************************************/
38 * Return rtp_decoder_t for packet
41 static inline rtp_decoder_t
*
42 decode_rtp_find_decoder(uint8_t payload_type
, GHashTable
*decoders_hash
)
44 /* Look for registered codecs */
45 return (rtp_decoder_t
*)g_hash_table_lookup(decoders_hash
, GUINT_TO_POINTER(payload_type
));
48 static rtp_decoder_t
*
49 decode_rtp_create_decoder(uint8_t payload_type
, const char *payload_type_str
, int payload_rate
,
50 int payload_channels
, wmem_map_t
*payload_fmtp_map
, GHashTable
*decoders_hash
)
52 rtp_decoder_t
*decoder
;
53 /* Put either valid or empty decoder into the hash table */
54 decoder
= g_new(rtp_decoder_t
, 1);
55 decoder
->handle
= NULL
;
56 decoder
->context
= g_new(codec_context_t
, 1);
57 decoder
->context
->sample_rate
= payload_rate
;
58 decoder
->context
->channels
= payload_channels
;
59 decoder
->context
->fmtp_map
= payload_fmtp_map
;
60 decoder
->context
->priv
= NULL
;
63 decoder
->handle
= find_codec(payload_type_str
);
64 if (!decoder
->handle
) {
65 const char *p
= try_val_to_str_ext(payload_type
, &rtp_payload_type_short_vals_ext
);
67 decoder
->handle
= find_codec(p
);
71 decoder
->context
->priv
= codec_init(decoder
->handle
, decoder
->context
);
73 g_hash_table_insert(decoders_hash
, GUINT_TO_POINTER(payload_type
), decoder
);
77 static rtp_decoder_t
*
78 decode_rtp_find_or_create_decoder(uint8_t payload_type
, const char *payload_type_str
, int payload_rate
,
79 int payload_channels
, wmem_map_t
*payload_fmtp_map
, GHashTable
*decoders_hash
)
81 rtp_decoder_t
*decoder
;
83 /* Look for registered codecs */
84 decoder
= decode_rtp_find_decoder(payload_type
, decoders_hash
);
86 decoder
= decode_rtp_create_decoder(payload_type
, payload_type_str
, payload_rate
,
87 payload_channels
, payload_fmtp_map
, decoders_hash
);
92 /****************************************************************************/
93 /** Decode payload from an RTP packet
94 * For RTP packets with dynamic payload types, the payload name, clock rate,
95 * and number of audio channels (e.g., from the SDP) can be provided.
96 * Note that the output sample rate and number of channels might not be the
97 * same as that of the input.
99 * @param decoder RTP decoder used to decode the audio in the RTP payload.
100 * @param payload_data Payload
101 * @param payload_len Length of payload
102 * @param out_buff Output audio samples.
103 * @param channels_ptr If non-NULL, receives the number of channels in the sample.
104 * @param sample_rate_ptr If non-NULL, receives the sample rate.
105 * @return The number of decoded bytes on success, 0 on failure.
109 decode_rtp_packet_payload(rtp_decoder_t
*decoder
, uint8_t *payload_data
, size_t payload_len
,
110 SAMPLE
**out_buff
, unsigned *channels_ptr
, unsigned *sample_rate_ptr
)
112 SAMPLE
*tmp_buff
= NULL
;
114 size_t decoded_bytes
= 0;
116 if (!decoder
->handle
) {
121 /* Decode with registered codec */
122 /* if output == NULL and outputSizeBytes == NULL => ask for expected size of the buffer */
123 tmp_buff_len
= codec_decode(decoder
->handle
, decoder
->context
, payload_data
, payload_len
, NULL
, NULL
);
124 tmp_buff
= (SAMPLE
*)g_malloc(tmp_buff_len
);
125 decoded_bytes
= codec_decode(decoder
->handle
, decoder
->context
, payload_data
, payload_len
, tmp_buff
, &tmp_buff_len
);
126 *out_buff
= tmp_buff
;
129 *channels_ptr
= codec_get_channels(decoder
->handle
, decoder
->context
);
132 if (sample_rate_ptr
) {
133 *sample_rate_ptr
= codec_get_frequency(decoder
->handle
, decoder
->context
);
136 return decoded_bytes
;
139 /****************************************************************************/
140 /** Prepend an AMR NB Octet-Aligned header (2 bytes) to the AMR payload.
141 * A new buffer is allocated, filled and returned. The caller is responsible of freeing it.
143 * @return The callee-allocated buffer containing the AMR OA header + payload
146 prepend_amr_oa_hdr(uint8_t amr_ft
, uint8_t amr_q
, const uint8_t *amr_payload
, uint8_t amr_payload_len
)
150 amr_hdr
= (uint8_t *)g_malloc(AMR_NB_OA_HDR_LEN
+ amr_payload_len
);
151 amr_hdr
[0] = 0xf0; /* CMR = 15 = "no change" */
152 amr_hdr
[1] = (0 << 7) | /* F=0 */
153 ((amr_ft
& 0x0f) << 3) |
154 (amr_q
&& 0x01) << 2;
155 memcpy(amr_hdr
+ AMR_NB_OA_HDR_LEN
, amr_payload
, amr_payload_len
);
159 /****************************************************************************/
160 /** Parse IuUP header to obtain the AMR payload, generate a octet-aligned AMR
161 * buffer which the AMR decoder can digest and decode it.
163 * @return Number of decoded bytes
167 decode_iuup_packet(rtp_packet_t
*rp
, SAMPLE
**out_buff
, GHashTable
*decoders_hash
, unsigned *channels_ptr
,
168 unsigned *sample_rate_ptr
)
170 uint8_t iuup_pdu_type
;
171 uint8_t iuup_frame_nr
;
173 uint8_t iuup_hdr_len
;
174 uint8_t *iuup_payload
;
175 uint8_t iuup_payload_len
;
178 rtp_decoder_t
*decoder
;
179 size_t decoded_bytes
;
181 if (rp
->info
->info_payload_len
< 1)
184 /* Parse the IuUP header into struct iuup_decoded dt: */
185 iuup_pdu_type
= rp
->payload_data
[0] >> 4;
186 switch (iuup_pdu_type
) {
187 case PDUTYPE_DATA_WITH_CRC
:
188 iuup_hdr_len
= PDUTYPE_DATA_WITH_CRC_HDR_LEN
;
190 case PDUTYPE_DATA_NO_CRC
:
191 iuup_hdr_len
= PDUTYPE_DATA_NO_CRC_HDR_LEN
;
197 if (rp
->info
->info_payload_len
< iuup_hdr_len
)
200 iuup_frame_nr
= rp
->payload_data
[0] & 0x0f;
201 iuup_fqc
= rp
->payload_data
[1] >> 6;
202 iuup_payload
= rp
->payload_data
+ iuup_hdr_len
;
203 iuup_payload_len
= rp
->info
->info_payload_len
- iuup_hdr_len
;
204 ws_assert(rp
->info
->info_payload_len
- iuup_hdr_len
< sizeof(uint8_t));
206 /* Figure out AMR FT from size: */
207 amr_ft
= amr_nb_bytes_to_ft(iuup_payload_len
);
209 ws_log(LOG_DOMAIN_QTUI
, LOG_LEVEL_MESSAGE
,
210 "#%u: IuUP with unknown AMR payload format: frame_nr=%u bytes=%u\n",
211 rp
->frame_num
, iuup_frame_nr
, iuup_payload_len
);
215 /* Prepend an octet-aligned header to the AMR payload, so that the decoder can digest it: */
216 amr_hdr
= prepend_amr_oa_hdr(amr_ft
, !iuup_fqc
, iuup_payload
, iuup_payload_len
);
218 /* Look for registered codecs */
219 decoder
= decode_rtp_find_decoder(rp
->info
->info_payload_type
, decoders_hash
);
221 wmem_map_t
*iuup_decode_amr_fmtp
= wmem_map_new(wmem_epan_scope(), wmem_str_hash
, g_str_equal
);
222 wmem_map_insert(iuup_decode_amr_fmtp
, "octet-align", "1");
223 decoder
= decode_rtp_create_decoder(rp
->info
->info_payload_type
,
225 rp
->info
->info_payload_rate
,
226 rp
->info
->info_payload_channels
,
227 iuup_decode_amr_fmtp
,
231 decoded_bytes
= decode_rtp_packet_payload(decoder
, amr_hdr
, AMR_NB_OA_HDR_LEN
+ iuup_payload_len
,
232 out_buff
, channels_ptr
, sample_rate_ptr
);
234 return decoded_bytes
;
241 /****************************************************************************/
243 * @return Number of decoded bytes
247 decode_rtp_packet(rtp_packet_t
*rp
, SAMPLE
**out_buff
, GHashTable
*decoders_hash
, unsigned *channels_ptr
,
248 unsigned *sample_rate_ptr
)
250 rtp_decoder_t
*decoder
;
252 if ((rp
->payload_data
== NULL
) || (rp
->info
->info_payload_len
== 0) ) {
256 if (rp
->info
->info_is_iuup
)
257 return decode_iuup_packet(rp
, out_buff
, decoders_hash
, channels_ptr
, sample_rate_ptr
);
259 /* Look for registered codecs */
260 decoder
= decode_rtp_find_or_create_decoder(rp
->info
->info_payload_type
,
261 rp
->info
->info_payload_type_str
,
262 rp
->info
->info_payload_rate
,
263 rp
->info
->info_payload_channels
,
264 rp
->info
->info_payload_fmtp_map
,
266 return decode_rtp_packet_payload(decoder
,
267 rp
->payload_data
, rp
->info
->info_payload_len
,
268 out_buff
, channels_ptr
, sample_rate_ptr
);
271 /****************************************************************************/
273 rtp_decoder_value_destroy(void *dec_arg
)
275 rtp_decoder_t
*dec
= (rtp_decoder_t
*)dec_arg
;
278 codec_release(dec
->handle
, dec
->context
);
279 g_free(dec
->context
);
284 GHashTable
*rtp_decoder_hash_table_new(void)
286 return g_hash_table_new_full(g_direct_hash
, g_direct_equal
, NULL
, rtp_decoder_value_destroy
);