1 /*
2 Copyright (c) 2012, Broadcom Europe Ltd
3 All rights reserved.
4 
5 Redistribution and use in source and binary forms, with or without
6 modification, are permitted provided that the following conditions are met:
7     * Redistributions of source code must retain the above copyright
8       notice, this list of conditions and the following disclaimer.
9     * Redistributions in binary form must reproduce the above copyright
10       notice, this list of conditions and the following disclaimer in the
11       documentation and/or other materials provided with the distribution.
12     * Neither the name of the copyright holder nor the
13       names of its contributors may be used to endorse or promote products
14       derived from this software without specific prior written permission.
15 
16 THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
17 ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
18 WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
19 DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY
20 DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
21 (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
22 LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
23 ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
24 (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
25 SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
26 */
27 #include <stdlib.h>
28 #include <stdio.h>
29 #include <string.h>
30 
31 #define CONTAINER_IS_BIG_ENDIAN
32 //#define ENABLE_CONTAINERS_LOG_FORMAT
33 //#define ENABLE_CONTAINERS_LOG_FORMAT_VERBOSE
34 #define CONTAINER_HELPER_LOG_INDENT(a) 0
35 #include "containers/core/containers_private.h"
36 #include "containers/core/containers_io_helpers.h"
37 #include "containers/core/containers_utils.h"
38 #include "containers/core/containers_uri.h"
39 #include "containers/core/containers_logging.h"
40 #include "containers/core/containers_bits.h"
41 #include "containers/core/containers_list.h"
42 
43 #include "rtp_priv.h"
44 #include "rtp_mpeg4.h"
45 #include "rtp_h264.h"
46 
47 #ifdef _DEBUG
48 /* Validates static sorted lists are correctly constructed */
49 #define RTP_DEBUG 1
50 #endif
51 
52 /******************************************************************************
53 Configurable defines and constants.
54 ******************************************************************************/
55 
56 /** Maximum size of an RTP packet */
57 #define MAXIMUM_PACKET_SIZE   2048
58 
59 /** Maximum number of RTP packets that can be missed without restarting. */
60 #define MAX_DROPOUT           3000
61 /** Maximum number of out of sequence RTP packets that are accepted. */
62 #define MAX_MISORDER          0
63 /** Minimum number of sequential packets required for an acceptable connection
64  * when restarting. */
65 #define MIN_SEQUENTIAL        2
66 
67 /******************************************************************************
68 Defines and constants.
69 ******************************************************************************/
70 
71 #define RTP_SCHEME                     "rtp:"
72 
73 /** The RTP PKT scheme is used with test pkt files */
74 #define RTP_PKT_SCHEME                     "rtppkt:"
75 
76 /** \name RTP URI parameter names
77  * @{ */
78 #define PAYLOAD_TYPE_NAME              "rtppt"
79 #define MIME_TYPE_NAME                 "mime-type"
80 #define CHANNELS_NAME                  "channels"
81 #define RATE_NAME                      "rate"
82 #define SSRC_NAME                      "ssrc"
83 #define SEQ_NAME                       "seq"
84 /* @} */
85 
86 /** A sentinel codec that is not supported */
87 #define UNSUPPORTED_CODEC              VC_FOURCC(0,0,0,0)
88 
89 /** Evaluates to true if the given payload type is in the supported static audio range. */
90 #define IS_STATIC_AUDIO_TYPE(PT)       ((PT) < countof(static_audio_payload_types))
91 
92 /** Payload type number for the first static video type */
93 #define FIRST_STATIC_VIDEO_TYPE   24
94 /** Evaluates to true if the given payload type is in the supported static video range. */
95 #define IS_STATIC_VIDEO_TYPE(PT)       ((PT) >= FIRST_STATIC_VIDEO_TYPE && \
96                                         (PT) < (FIRST_STATIC_VIDEO_TYPE + countof(static_video_payload_types)))
97 
98 /** Evaluates to true if the given payload type is in the dynamic range. */
99 #define IS_DYNAMIC_TYPE(PT)            ((PT) >= 96 && (PT) < 128)
100 
101 /** All sequence numbers are modulo this value. */
102 #define RTP_SEQ_MOD                    (1 << 16)
103 
104 /** All the static video payload types use a 90kHz timestamp clock */
105 #define STATIC_VIDEO_TIMESTAMP_CLOCK   90000
106 
107 /** Number of microseconds in a second, used to convert RTP timestamps to microseconds */
108 #define MICROSECONDS_PER_SECOND        1000000
109 
110 /******************************************************************************
111 Type definitions
112 ******************************************************************************/
113 
114 /** \name MIME type parameter handlers
115  * Function prototypes for payload parameter handlers */
116 /* @{ */
117 static VC_CONTAINER_STATUS_T audio_parameter_handler(VC_CONTAINER_T *p_ctx, VC_CONTAINER_TRACK_T *track, const VC_CONTAINERS_LIST_T *params);
118 static VC_CONTAINER_STATUS_T l8_parameter_handler(VC_CONTAINER_T *p_ctx, VC_CONTAINER_TRACK_T *track, const VC_CONTAINERS_LIST_T *params);
119 static VC_CONTAINER_STATUS_T l16_parameter_handler(VC_CONTAINER_T *p_ctx, VC_CONTAINER_TRACK_T *track, const VC_CONTAINERS_LIST_T *params);
120 /* @} */
121 
122 /** \name MIME type payload handlers */
123 /* @{ */
124 static VC_CONTAINER_STATUS_T l16_payload_handler(VC_CONTAINER_T *p_ctx, VC_CONTAINER_TRACK_T *track,
125       VC_CONTAINER_PACKET_T *p_packet, uint32_t flags);
126 /* @} */
127 
128 /** Static audio payload type data */
129 typedef struct audio_payload_type_data_tag
130 {
131    VC_CONTAINER_FOURCC_T codec;        /**< FourCC codec for this payload type */
132    uint32_t channels;                  /**< Number of audio channels */
133    uint32_t sample_rate;               /**< Sample rate */
134    uint32_t bits_per_sample;           /**< Bits per sample, or 1 if not applicable */
135    PARAMETER_HANDLER_T param_handler;  /**< Optional parameter handler */
136    PAYLOAD_HANDLER_T payload_handler;  /**< Optional payload handler */
137 } AUDIO_PAYLOAD_TYPE_DATA_T;
138 
139 /** The details for the statically defined audio payload types from RFC3551 */
140 static AUDIO_PAYLOAD_TYPE_DATA_T static_audio_payload_types[] =
141 {
142    { VC_CONTAINER_CODEC_MULAW, 1, 8000,  8,  audio_parameter_handler, NULL },                /*  0 - PCMU */
143    { UNSUPPORTED_CODEC },                                                                    /*  1 - reserved */
144    { UNSUPPORTED_CODEC },                                                                    /*  2 - reserved */
145    { UNSUPPORTED_CODEC,        1, 8000,  1,  NULL,                    NULL },                /*  3 - GSM */
146    { UNSUPPORTED_CODEC,        1, 8000,  1,  NULL,                    NULL },                /*  4 - G723 */
147    { UNSUPPORTED_CODEC,        1, 8000,  4,  NULL,                    NULL },                /*  5 - DVI4 */
148    { UNSUPPORTED_CODEC,        1, 16000, 4,  NULL,                    NULL },                /*  6 - DVI4 */
149    { UNSUPPORTED_CODEC,        1, 8000,  1,  NULL,                    NULL },                /*  7 - LPC */
150    { VC_CONTAINER_CODEC_ALAW,  1, 8000,  8,  audio_parameter_handler, NULL },                /*  8 - PCMA */
151    { UNSUPPORTED_CODEC,        1, 8000,  8,  NULL,                    NULL },                /*  9 - G722 */
152    { VC_CONTAINER_CODEC_PCM_SIGNED,   2, 44100, 16, audio_parameter_handler, l16_payload_handler }, /* 10 - L16 */
153    { VC_CONTAINER_CODEC_PCM_SIGNED,   1, 44100, 16, audio_parameter_handler, l16_payload_handler }, /* 11 - L16 */
154    { VC_CONTAINER_CODEC_QCELP, 1, 8000,  16, NULL,                    NULL },                /* 12 - QCELP */
155    { UNSUPPORTED_CODEC,        1, 8000,  1,  NULL,                    NULL },                /* 13 - CN */
156    { VC_CONTAINER_CODEC_MPGA,  1, 90000, 1,  NULL,                    NULL },                /* 14 - MPA */
157    { UNSUPPORTED_CODEC,        1, 8000,  1,  NULL,                    NULL },                /* 15 - G728 */
158    { UNSUPPORTED_CODEC,        1, 11025, 4,  NULL,                    NULL },                /* 16 - DVI4 */
159    { UNSUPPORTED_CODEC,        1, 22050, 4,  NULL,                    NULL },                /* 17 - DVI4 */
160    { UNSUPPORTED_CODEC,        1, 8000,  1,  NULL,                    NULL },                /* 18 - G729 */
161 };
162 
163 /** Static video payload type data */
164 typedef struct video_payload_type_data_tag
165 {
166    VC_CONTAINER_FOURCC_T codec;        /**< FourCC codec for this payload type */
167    PARAMETER_HANDLER_T param_handler;  /**< Optional parameter handler */
168    PAYLOAD_HANDLER_T payload_handler;  /**< Optional payload handler */
169 } VIDEO_PAYLOAD_TYPE_DATA_T;
170 
171 /** The details for the statically defined video payload types from RFC3551 */
172 static VIDEO_PAYLOAD_TYPE_DATA_T static_video_payload_types[] =
173 {
174    { UNSUPPORTED_CODEC },                    /* 24 - unassigned */
175    { UNSUPPORTED_CODEC },                    /* 25 - CelB */
176    { UNSUPPORTED_CODEC },                    /* 26 - JPEG */
177    { UNSUPPORTED_CODEC },                    /* 27 - unassigned */
178    { UNSUPPORTED_CODEC },                    /* 28 - nv */
179    { UNSUPPORTED_CODEC },                    /* 29 - unassigned */
180    { UNSUPPORTED_CODEC },                    /* 30 - unassigned */
181    { UNSUPPORTED_CODEC },                    /* 31 - H261 */
182    { VC_CONTAINER_CODEC_MP2V, NULL, NULL },  /* 32 - MPV */
183    { UNSUPPORTED_CODEC },                    /* 33 - MP2T */
184    { VC_CONTAINER_CODEC_H263, NULL, NULL }   /* 34 - H263 */
185 };
186 
187 /** MIME type details */
188 typedef struct mime_type_data_tag
189 {
190    const char *name;                   /**< Name of MIME type */
191    VC_CONTAINER_ES_TYPE_T es_type;     /**< Elementary stream type */
192    VC_CONTAINER_FOURCC_T codec;        /**< Codec to be used */
193    PARAMETER_HANDLER_T param_handler;  /**< Parameter handler for this MIME type */
194 } MIME_TYPE_DATA_T;
195 
196 /** Comparator for MIME type details. */
197 static int mime_type_data_comparator(const MIME_TYPE_DATA_T *a, const MIME_TYPE_DATA_T *b);
198 
199 /** Dynamic audio payload details
200  * Note: case-insensitive sort by name */
201 static MIME_TYPE_DATA_T dynamic_mime_details[] = {
202    { "audio/l16", VC_CONTAINER_ES_TYPE_AUDIO, VC_CONTAINER_CODEC_PCM_SIGNED, l16_parameter_handler },
203    { "audio/l8", VC_CONTAINER_ES_TYPE_AUDIO, VC_CONTAINER_CODEC_PCM_SIGNED, l8_parameter_handler },
204    { "audio/mpeg4-generic", VC_CONTAINER_ES_TYPE_AUDIO, VC_CONTAINER_CODEC_MP4A, mp4_parameter_handler },
205    { "video/h264", VC_CONTAINER_ES_TYPE_VIDEO, VC_CONTAINER_CODEC_H264, h264_parameter_handler },
206    { "video/mpeg4-generic", VC_CONTAINER_ES_TYPE_VIDEO, VC_CONTAINER_CODEC_MP4V, mp4_parameter_handler },
207 };
208 
209 /** Sorted list of dynamic MIME type details */
210 VC_CONTAINERS_STATIC_LIST(dynamic_mime, dynamic_mime_details, mime_type_data_comparator);
211 
212 /** RTP reader data. */
213 typedef struct VC_CONTAINER_MODULE_T
214 {
215    VC_CONTAINER_TRACK_T *track;
216 } VC_CONTAINER_MODULE_T;
217 
218 /******************************************************************************
219 Function prototypes
220 ******************************************************************************/
221 VC_CONTAINER_STATUS_T rtp_reader_open( VC_CONTAINER_T * );
222 
223 /******************************************************************************
224 Local Functions
225 ******************************************************************************/
226 
227 /**************************************************************************//**
228  * Parameter comparison function.
229  * Compare two parameter structures and return whether the first is less than,
230  * equal to or greater than the second.
231  *
232  * @param first   The first structure to be compared.
233  * @param second  The second structure to be compared.
234  * @return  Negative if first is less than second, positive if first is greater
235  *          and zero if they are equal.
236  */
parameter_comparator(const PARAMETER_T * first,const PARAMETER_T * second)237 static int parameter_comparator(const PARAMETER_T *first, const PARAMETER_T *second)
238 {
239    return strcasecmp(first->name, second->name);
240 }
241 
242 /**************************************************************************//**
243  * Creates and populates a parameter list from a URI structure.
244  * The list does not copy the parameter strings themselves, so the URI structure
245  * must be retained (and its parameters unmodified) while the list is in use.
246  *
247  * @param uri  The URI containing the parameters.
248  * @return  List created from the parameters of the URI, or NULL on error.
249  */
fill_parameter_list(VC_URI_PARTS_T * uri)250 static VC_CONTAINERS_LIST_T *fill_parameter_list(VC_URI_PARTS_T *uri)
251 {
252    uint32_t num_parameters = vc_uri_num_queries(uri);
253    VC_CONTAINERS_LIST_T *parameters;
254    uint32_t ii;
255 
256    parameters = vc_containers_list_create(num_parameters, sizeof(PARAMETER_T), (VC_CONTAINERS_LIST_COMPARATOR_T)parameter_comparator);
257    if (!parameters)
258       return NULL;
259 
260    for (ii = 0; ii < num_parameters; ii++)
261    {
262       PARAMETER_T param;
263 
264       vc_uri_query(uri, ii, &param.name, &param.value);
265       if (!vc_containers_list_insert(parameters, &param, false))
266       {
267          vc_containers_list_destroy(parameters);
268          return NULL;
269       }
270    }
271 
272 #ifdef RTP_DEBUG
273    vc_containers_list_validate(parameters);
274 #endif
275 
276    return parameters;
277 }
278 
279 /**************************************************************************//**
280  * Decodes a static audio payload type into track information.
281  * The static parameters may be overridden by URI parameters.
282  *
283  * @param p_ctx         The reader context.
284  * @param track         The track to be populated.
285  * @param param_list    The URI parameter list.
286  * @param payload_type  The static payload type.
287  * @return  The resulting status of the function.
288  */
decode_static_audio_type(VC_CONTAINER_T * p_ctx,VC_CONTAINER_TRACK_T * track,const VC_CONTAINERS_LIST_T * param_list,uint32_t payload_type)289 static VC_CONTAINER_STATUS_T decode_static_audio_type(VC_CONTAINER_T *p_ctx,
290       VC_CONTAINER_TRACK_T *track,
291       const VC_CONTAINERS_LIST_T *param_list,
292       uint32_t payload_type)
293 {
294    VC_CONTAINER_ES_FORMAT_T *format = track->format;
295    AUDIO_PAYLOAD_TYPE_DATA_T *data = &static_audio_payload_types[payload_type];
296 
297    VC_CONTAINER_PARAM_UNUSED(p_ctx);
298    VC_CONTAINER_PARAM_UNUSED(param_list);
299 
300    vc_container_assert(payload_type < countof(static_audio_payload_types));
301 
302    if (data->codec == UNSUPPORTED_CODEC)
303       return VC_CONTAINER_ERROR_FORMAT_NOT_SUPPORTED;
304 
305    format->es_type = VC_CONTAINER_ES_TYPE_AUDIO;
306    format->codec = data->codec;
307    format->type->audio.channels = data->channels;
308    format->type->audio.sample_rate = data->sample_rate;
309    format->type->audio.bits_per_sample = data->bits_per_sample;
310    format->type->audio.block_align = data->channels * BITS_TO_BYTES(data->bits_per_sample);
311    track->priv->module->timestamp_clock = format->type->audio.sample_rate;
312    track->priv->module->payload_handler = data->payload_handler;
313 
314    if (data->param_handler)
315       data->param_handler(p_ctx, track, param_list);
316 
317    return VC_CONTAINER_SUCCESS;
318 }
319 
320 /**************************************************************************//**
321  * Decodes a static video payload type into track information.
322  * The static parameters may be overridden by URI parameters.
323  *
324  * @param p_ctx         The reader context.
325  * @param track         The track to be populated.
326  * @param param_list    The URI parameter list.
327  * @param payload_type  The static payload type.
328  * @return  The resulting status of the function.
329  */
decode_static_video_type(VC_CONTAINER_T * p_ctx,VC_CONTAINER_TRACK_T * track,const VC_CONTAINERS_LIST_T * param_list,uint32_t payload_type)330 static VC_CONTAINER_STATUS_T decode_static_video_type(VC_CONTAINER_T *p_ctx,
331       VC_CONTAINER_TRACK_T *track,
332       const VC_CONTAINERS_LIST_T *param_list,
333       uint32_t payload_type)
334 {
335    VC_CONTAINER_ES_FORMAT_T *format = track->format;
336    VIDEO_PAYLOAD_TYPE_DATA_T *data = &static_video_payload_types[payload_type - FIRST_STATIC_VIDEO_TYPE];
337 
338    VC_CONTAINER_PARAM_UNUSED(p_ctx);
339    VC_CONTAINER_PARAM_UNUSED(param_list);
340 
341    vc_container_assert(payload_type >= FIRST_STATIC_VIDEO_TYPE);
342    vc_container_assert(payload_type < FIRST_STATIC_VIDEO_TYPE + countof(static_video_payload_types));
343 
344    if (data->codec == UNSUPPORTED_CODEC)
345       return VC_CONTAINER_ERROR_FORMAT_NOT_SUPPORTED;
346 
347    format->es_type = VC_CONTAINER_ES_TYPE_VIDEO;
348    format->codec = data->codec;
349    track->priv->module->timestamp_clock = STATIC_VIDEO_TIMESTAMP_CLOCK;
350    track->priv->module->payload_handler = data->payload_handler;
351 
352    if (data->param_handler)
353       data->param_handler(p_ctx, track, param_list);
354 
355    return VC_CONTAINER_SUCCESS;
356 }
357 
358 /**************************************************************************//**
359  * Compare two MIME type structures and return whether the first is less than,
360  * equal to or greater than the second.
361  *
362  * @param a The first parameter structure to be compared.
363  * @param b The second parameter structure to be compared.
364  * @return  Negative if a is less than b, positive if a is greater and zero if
365  *          they are equal.
366  */
mime_type_data_comparator(const MIME_TYPE_DATA_T * a,const MIME_TYPE_DATA_T * b)367 static int mime_type_data_comparator(const MIME_TYPE_DATA_T *a, const MIME_TYPE_DATA_T *b)
368 {
369    return strcasecmp(a->name, b->name);
370 }
371 
372 /**************************************************************************//**
373  * Generic audio parameter handler.
374  * Updates the track information with generic audio parameters, such as "rate"
375  * and "channels".
376  *
377  * @param p_ctx   The reader context.
378  * @param track   The track to be updated.
379  * @param params  The URI parameter list.
380  * @return  The resulting status of the function.
381  */
audio_parameter_handler(VC_CONTAINER_T * p_ctx,VC_CONTAINER_TRACK_T * track,const VC_CONTAINERS_LIST_T * params)382 static VC_CONTAINER_STATUS_T audio_parameter_handler(VC_CONTAINER_T *p_ctx,
383       VC_CONTAINER_TRACK_T *track,
384       const VC_CONTAINERS_LIST_T *params)
385 {
386    VC_CONTAINER_AUDIO_FORMAT_T *audio = &track->format->type->audio;
387 
388    VC_CONTAINER_PARAM_UNUSED(p_ctx);
389 
390    /* See RFC3555. Generic audio parameters that can override static payload
391     * type defaults. */
392    if (rtp_get_parameter_u32(params, RATE_NAME, &audio->sample_rate))
393       track->priv->module->timestamp_clock = audio->sample_rate;
394    if (rtp_get_parameter_u32(params, CHANNELS_NAME, &audio->channels))
395       audio->block_align = audio->channels * BITS_TO_BYTES(audio->bits_per_sample);
396 
397    return VC_CONTAINER_SUCCESS;
398 }
399 
400 /**************************************************************************//**
401  * L8 specific audio parameter handler.
402  * Updates the track information with audio parameters needed by the audio/L8
403  * MIME type. For example, the "rate" parameter is mandatory.
404  *
405  * @param p_ctx   The reader context.
406  * @param track   The track to be updated.
407  * @param params  The URI parameter list.
408  * @return  The resulting status of the function.
409  */
l8_parameter_handler(VC_CONTAINER_T * p_ctx,VC_CONTAINER_TRACK_T * track,const VC_CONTAINERS_LIST_T * params)410 static VC_CONTAINER_STATUS_T l8_parameter_handler(VC_CONTAINER_T *p_ctx,
411       VC_CONTAINER_TRACK_T *track,
412       const VC_CONTAINERS_LIST_T *params)
413 {
414    VC_CONTAINER_AUDIO_FORMAT_T *audio = &track->format->type->audio;
415 
416    VC_CONTAINER_PARAM_UNUSED(p_ctx);
417 
418    /* See RFC3555, section 4.1.14, for parameter names and details. */
419    if (!rtp_get_parameter_u32(params, RATE_NAME, &audio->sample_rate))
420       return VC_CONTAINER_ERROR_FORMAT_INVALID;
421    if (!rtp_get_parameter_u32(params, CHANNELS_NAME, &audio->channels))
422       audio->channels = 1;
423    audio->bits_per_sample = 8;
424    audio->block_align = audio->channels;
425    track->priv->module->timestamp_clock = audio->sample_rate;
426 
427    return VC_CONTAINER_SUCCESS;
428 }
429 
430 /**************************************************************************//**
431  * L16 specific audio parameter handler.
432  * Updates the track information with audio parameters needed by the audio/L16
433  * MIME type. For example, the "rate" parameter is mandatory.
434  *
435  * @param p_ctx   The reader context.
436  * @param track   The track to be updated.
437  * @param params  The URI parameter list.
438  * @return  The resulting status of the function.
439  */
l16_parameter_handler(VC_CONTAINER_T * p_ctx,VC_CONTAINER_TRACK_T * track,const VC_CONTAINERS_LIST_T * params)440 static VC_CONTAINER_STATUS_T l16_parameter_handler(VC_CONTAINER_T *p_ctx,
441       VC_CONTAINER_TRACK_T *track,
442       const VC_CONTAINERS_LIST_T *params)
443 {
444    VC_CONTAINER_AUDIO_FORMAT_T *audio = &track->format->type->audio;
445 
446    VC_CONTAINER_PARAM_UNUSED(p_ctx);
447 
448    /* See RFC3555, section 4.1.15, for parameter names and details. */
449    if (!rtp_get_parameter_u32(params, RATE_NAME, &audio->sample_rate))
450       return VC_CONTAINER_ERROR_FORMAT_INVALID;
451    if (!rtp_get_parameter_u32(params, CHANNELS_NAME, &audio->channels))
452       audio->channels = 1;
453    audio->bits_per_sample = 16;
454    audio->block_align = audio->channels * 2;
455    track->priv->module->timestamp_clock = audio->sample_rate;
456    track->priv->module->payload_handler = l16_payload_handler;
457 
458    /* TODO: add support for "channel-order" to set channel mapping */
459 
460    return VC_CONTAINER_SUCCESS;
461 }
462 
463 /**************************************************************************//**
464  * Decode a dynamic payload type from parameters.
465  * Populates the track information with data for supported dynamic media types.
466  *
467  * @param p_ctx      The reader context.
468  * @param track      The track to be updated.
469  * @param param_list The URI parameter list.
470  * @return  The resulting status of the function.
471  */
decode_dynamic_type(VC_CONTAINER_T * p_ctx,VC_CONTAINER_TRACK_T * track,const VC_CONTAINERS_LIST_T * param_list)472 static VC_CONTAINER_STATUS_T decode_dynamic_type(VC_CONTAINER_T *p_ctx,
473       VC_CONTAINER_TRACK_T *track,
474       const VC_CONTAINERS_LIST_T *param_list)
475 {
476    VC_CONTAINER_ES_FORMAT_T *format = track->format;
477    VC_CONTAINER_STATUS_T status = VC_CONTAINER_SUCCESS;
478    PARAMETER_T mime_type;
479    MIME_TYPE_DATA_T mime_details;
480 
481    /* Get MIME type parameter */
482    mime_type.name = MIME_TYPE_NAME;
483    if (!vc_containers_list_find_entry(param_list, &mime_type))
484       return VC_CONTAINER_ERROR_FORMAT_INVALID;
485 
486 #ifdef RTP_DEBUG
487    vc_containers_list_validate(&dynamic_mime);
488 #endif
489 
490    /* Look up MIME type to see if it can be handled */
491    mime_details.name = mime_type.value;
492    if (!vc_containers_list_find_entry(&dynamic_mime, &mime_details))
493       return VC_CONTAINER_ERROR_FORMAT_NOT_SUPPORTED;
494 
495    format->codec = mime_details.codec;
496    format->es_type = mime_details.es_type;
497 
498    /* Default number of channels for audio is one */
499    if (mime_details.es_type == VC_CONTAINER_ES_TYPE_AUDIO)
500       format->type->audio.channels = 1;
501 
502    /* Lete MIME type specific parameter handler deal with any other parameters */
503    status = mime_details.param_handler(p_ctx, track, param_list);
504 
505    /* Ensure that the sample rate has been set for audio formats */
506    if (mime_details.es_type == VC_CONTAINER_ES_TYPE_AUDIO && !format->type->audio.sample_rate)
507       return VC_CONTAINER_ERROR_FORMAT_INVALID;
508 
509    return status;
510 }
511 
512 /**************************************************************************//**
513  * Decode the RTP payload type.
514  * Populates track information with data from static tables and the URI
515  * parameter list, according to the payload and MIME types.
516  *
517  * @param p_ctx   The reader context.
518  * @param track   The track to be updated.
519  * @param params  The URI parameter list.
520  * @return  The resulting status of the function.
521  */
decode_payload_type(VC_CONTAINER_T * p_ctx,VC_CONTAINER_TRACK_T * track,const VC_CONTAINERS_LIST_T * param_list,uint32_t payload_type)522 static VC_CONTAINER_STATUS_T  decode_payload_type(VC_CONTAINER_T *p_ctx,
523       VC_CONTAINER_TRACK_T *track,
524       const VC_CONTAINERS_LIST_T *param_list,
525       uint32_t payload_type)
526 {
527    VC_CONTAINER_TRACK_MODULE_T *module = track->priv->module;
528    VC_CONTAINER_STATUS_T status;
529 
530    if (IS_STATIC_AUDIO_TYPE(payload_type))
531       status = decode_static_audio_type(p_ctx, track, param_list, payload_type);
532    else if (IS_STATIC_VIDEO_TYPE(payload_type))
533       status = decode_static_video_type(p_ctx, track, param_list, payload_type);
534    else if (IS_DYNAMIC_TYPE(payload_type))
535       status = decode_dynamic_type(p_ctx, track, param_list);
536    else
537       status = VC_CONTAINER_ERROR_FORMAT_NOT_SUPPORTED;
538 
539    module->payload_type = (uint8_t)payload_type;
540 
541    return status;
542 }
543 
544 /**************************************************************************//**
545  * Initialises the RTP sequence number algorithm with a new sequence number.
546  *
547  * @param t_module   The track module.
548  * @param seq        The new sequence number.
549  */
init_sequence_number(VC_CONTAINER_TRACK_MODULE_T * t_module,uint16_t seq)550 static void init_sequence_number(VC_CONTAINER_TRACK_MODULE_T *t_module,
551       uint16_t seq)
552 {
553    t_module->base_seq = seq;
554    t_module->max_seq_num = seq;
555    t_module->bad_seq = RTP_SEQ_MOD + 1;   /* so seq == bad_seq is false */
556    t_module->received = 0;
557 }
558 
559 /**************************************************************************//**
560  * Checks whether the sequence number for a packet is acceptable or not.
561  * The packet will be unacceptable if it is out of sequence by some degree, or
562  * if the packet sequence is still being established.
563  *
564  * @param t_module   The track module.
565  * @param seq        The new sequence number.
566  * @return  True if the sequence number indicates the packet is acceptable
567  */
update_sequence_number(VC_CONTAINER_TRACK_MODULE_T * t_module,uint16_t seq)568 static bool update_sequence_number(VC_CONTAINER_TRACK_MODULE_T *t_module,
569       uint16_t seq)
570 {
571    uint16_t udelta = seq - t_module->max_seq_num;
572 
573    /* NOTE: This source is derived from the example code in RFC3550, section A.1 */
574 
575    /* Source is not valid until MIN_SEQUENTIAL packets with
576     * sequential sequence numbers have been received. */
577    if (t_module->probation)
578    {
579       /* packet is in sequence */
580       if (seq == t_module->max_seq_num + 1)
581       {
582          t_module->probation--;
583          t_module->max_seq_num = seq;
584          LOG_INFO(0, "RTP: Probation, %u more packet(s) to go at 0x%4.4hx", t_module->probation, seq);
585 
586          if (!t_module->probation)
587          {
588             init_sequence_number(t_module, seq);
589             t_module->received++;
590             return 1;
591          }
592       } else {
593          t_module->probation = MIN_SEQUENTIAL - 1;
594          t_module->max_seq_num = seq;
595          LOG_INFO(0, "RTP: Probation reset, wait for %u packet(s) at 0x%4.4hx", t_module->probation, seq);
596       }
597       return 0;
598    } else if (udelta < MAX_DROPOUT)
599    {
600       if (!udelta)
601       {
602          /* Duplicate packet, drop it */
603          LOG_INFO(0, "RTP: Drop duplicate packet at 0x%4.4hx", seq);
604          return 0;
605       }
606       if (udelta > 1)
607       {
608          LOG_INFO(0, "RTP: Jumped by %hu packets to 0x%4.4hx", udelta, seq);
609       }
610       /* in order, with permissible gap */
611       t_module->max_seq_num = seq;
612    } else
613 #if (MAX_MISORDER != 0)
614       /* When MAX_MISORDER is zero, always treat as out of order */
615       if (udelta <= RTP_SEQ_MOD - MAX_MISORDER)
616 #endif
617       {
618          /* the sequence number made a very large jump */
619          if (seq == t_module->bad_seq)
620          {
621             LOG_INFO(0, "RTP: Misorder restart at 0x%4.4hx", seq);
622             /* Two sequential packets -- assume that the other side
623              * restarted without telling us so just re-sync
624              * (i.e., pretend this was the first packet). */
625             init_sequence_number(t_module, seq);
626          } else {
627             LOG_INFO(0, "RTP: Misorder at 0x%4.4hx, expected 0x%4.4hx", seq, t_module->max_seq_num);
628             t_module->bad_seq = (seq + 1) & (RTP_SEQ_MOD-1);
629             return 0;
630          }
631       }
632 #if (MAX_MISORDER != 0)
633    else {
634       /* duplicate or reordered packet */
635 
636       /* TODO: handle out of order packets */
637    }
638 #endif
639    t_module->received++;
640    return 1;
641 }
642 
643 /**************************************************************************//**
644  * Extract the fields of an RTP packet and validate it.
645  *
646  * @param p_ctx      The reader context.
647  * @param t_module   The track module.
648  * @return  True if successful, false if there were not enough bits in the
649  *          packet or the packet was invalid.
650  */
decode_rtp_packet_header(VC_CONTAINER_T * p_ctx,VC_CONTAINER_TRACK_MODULE_T * t_module)651 static void decode_rtp_packet_header(VC_CONTAINER_T *p_ctx,
652       VC_CONTAINER_TRACK_MODULE_T *t_module)
653 {
654    VC_CONTAINER_BITS_T *payload = &t_module->payload;
655    uint32_t version, has_padding, has_extension, csrc_count, has_marker;
656    uint32_t payload_type, ssrc;
657    uint16_t seq_num;
658 
659    /* Break down fixed header area into component parts */
660    version              = BITS_READ_U32(p_ctx, payload, 2, "Version");
661    has_padding          = BITS_READ_U32(p_ctx, payload, 1, "Has padding");
662    has_extension        = BITS_READ_U32(p_ctx, payload, 1, "Has extension");
663    csrc_count           = BITS_READ_U32(p_ctx, payload, 4, "CSRC count");
664    has_marker           = BITS_READ_U32(p_ctx, payload, 1, "Has marker");
665    payload_type         = BITS_READ_U32(p_ctx, payload, 7, "Payload type");
666    seq_num              = BITS_READ_U16(p_ctx, payload, 16, "Sequence number");
667    t_module->timestamp  = BITS_READ_U32(p_ctx, payload, 32, "Timestamp");
668    ssrc                 = BITS_READ_U32(p_ctx, payload, 32, "SSRC");
669 
670    /* If there was only a partial header, abort immediately */
671    if (!BITS_VALID(p_ctx, payload))
672       return;
673 
674    /* Validate version, payload type, sequence number and SSRC, if set */
675    if (version != 2 || payload_type != t_module->payload_type)
676    {
677       BITS_INVALIDATE(p_ctx, payload);
678       return;
679    }
680    if (BIT_IS_SET(t_module->flags, TRACK_SSRC_SET) && (ssrc != t_module->expected_ssrc))
681    {
682       LOG_DEBUG(p_ctx, "RTP: Unexpected SSRC (0x%8.8X)", ssrc);
683       BITS_INVALIDATE(p_ctx, payload);
684       return;
685    }
686 
687    /* Check sequence number indicates packet is usable */
688    if (!update_sequence_number(t_module, seq_num))
689    {
690       BITS_INVALIDATE(p_ctx, payload);
691       return;
692    }
693 
694    /* Adjust to account for padding, CSRCs and extension */
695    if (has_padding)
696    {
697       VC_CONTAINER_BITS_T bit_stream;
698       uint32_t available = BITS_BYTES_AVAILABLE(p_ctx, payload);
699       uint8_t padding;
700 
701       BITS_COPY_STREAM(p_ctx, &bit_stream, payload);
702       /* The last byte of the payload is the number of padding bytes, including itself */
703       BITS_SKIP_BYTES(p_ctx, &bit_stream, available - 1, "Skip to padding length");
704       padding = BITS_READ_U8(p_ctx, &bit_stream, 8, "Padding length");
705 
706       BITS_REDUCE_BYTES(p_ctx, payload, padding, "Remove padding");
707    }
708 
709    /* Each CSRC is 32 bits, so shift count up to skip the right number of bits */
710    BITS_SKIP(p_ctx, payload, csrc_count << 5, "CSRC section");
711 
712    if (has_extension)
713    {
714       uint32_t extension_bits;
715 
716       /* Extension header is 16-bit ID (which isn't needed), then 16-bit length in 32-bit words */
717       BITS_SKIP(p_ctx, payload, 16, "Extension ID");
718       extension_bits = BITS_READ_U32(p_ctx, payload, 16, "Extension length") << 5;
719       BITS_SKIP(p_ctx, payload, extension_bits, "Extension data");
720    }
721 
722    /* Record whether or not this RTP packet had the marker bit set */
723    if (has_marker)
724       SET_BIT(t_module->flags, TRACK_HAS_MARKER);
725    else
726       CLEAR_BIT(t_module->flags, TRACK_HAS_MARKER);
727 
728    /* If it hasn't been set independently, use the first timestamp as a baseline */
729    if (!t_module->timestamp_base)
730       t_module->timestamp_base = t_module->timestamp;
731    t_module->timestamp -= t_module->timestamp_base;
732 }
733 
734 /**************************************************************************//**
735  * Generic payload handler.
736  * Copies/skips data verbatim from the packet payload.
737  *
738  * @param p_ctx      The reader context.
739  * @param track      The track being read.
740  * @param p_packet   The container packet information, or NULL.
741  * @param flags      The container read flags.
742  * @return  The resulting status of the function.
743  */
generic_payload_handler(VC_CONTAINER_T * p_ctx,VC_CONTAINER_TRACK_T * track,VC_CONTAINER_PACKET_T * p_packet,uint32_t flags)744 static VC_CONTAINER_STATUS_T generic_payload_handler(VC_CONTAINER_T *p_ctx,
745       VC_CONTAINER_TRACK_T *track,
746       VC_CONTAINER_PACKET_T *p_packet,
747       uint32_t flags)
748 {
749    VC_CONTAINER_TRACK_MODULE_T *t_module = track->priv->module;
750    VC_CONTAINER_BITS_T *payload = &t_module->payload;
751    uint32_t size;
752 
753    VC_CONTAINER_PARAM_UNUSED(p_ctx);
754 
755    if (!p_packet)
756    {
757       /* Skip the rest of this RTP packet */
758       BITS_INVALIDATE(p_ctx, payload);
759       return VC_CONTAINER_SUCCESS;
760    }
761 
762    /* Copy as much as possible into the client packet buffer */
763    size = BITS_BYTES_AVAILABLE(p_ctx, payload);
764 
765    if (flags & VC_CONTAINER_READ_FLAG_SKIP)
766       BITS_SKIP_BYTES(p_ctx, payload, size, "Packet data");
767    else {
768       if (!(flags & VC_CONTAINER_READ_FLAG_INFO))
769       {
770          if (size > p_packet->buffer_size)
771             size = p_packet->buffer_size;
772 
773          BITS_COPY_BYTES(p_ctx, payload, size, p_packet->data, "Packet data");
774       }
775       p_packet->size = size;
776    }
777 
778    return VC_CONTAINER_SUCCESS;
779 }
780 
781 /**************************************************************************//**
782  * L16 payload handler.
783  * Copies/skips data from the packet payload. On copy, swaps consecutive bytes
784  * in the data in order to get expected byte order.
785  *
786  * @param p_ctx      The reader context.
787  * @param track      The track being read.
788  * @param p_packet   The container packet information, or NULL.
789  * @param flags      The container read flags.
790  * @return  The resulting status of the function.
791  */
l16_payload_handler(VC_CONTAINER_T * p_ctx,VC_CONTAINER_TRACK_T * track,VC_CONTAINER_PACKET_T * p_packet,uint32_t flags)792 static VC_CONTAINER_STATUS_T l16_payload_handler(VC_CONTAINER_T *p_ctx,
793       VC_CONTAINER_TRACK_T *track,
794       VC_CONTAINER_PACKET_T *p_packet,
795       uint32_t flags)
796 {
797    VC_CONTAINER_STATUS_T status;
798 
799    /* Most aspects are handled adequately by the generic handler */
800    status = generic_payload_handler(p_ctx, track, p_packet, flags);
801    if (status != VC_CONTAINER_SUCCESS)
802       return status;
803 
804    if (p_packet && !(flags & (VC_CONTAINER_READ_FLAG_SKIP | VC_CONTAINER_READ_FLAG_INFO)))
805    {
806       uint8_t *ptr, *end_ptr;
807 
808       /* Ensure packet size is even */
809       p_packet->size &= ~1;
810 
811       /* Swap bytes of each sample, to get host order instead of network order */
812       for (ptr = p_packet->data, end_ptr = ptr + p_packet->size; ptr < end_ptr; ptr += 2)
813       {
814          uint8_t high_byte = ptr[0];
815          ptr[0] = ptr[1];
816          ptr[1] = high_byte;
817       }
818    }
819 
820    return status;
821 }
822 
823 /*****************************************************************************
824 Utility functions for use by RTP payload handlers
825  *****************************************************************************/
826 
827 /**************************************************************************//**
828  * Gets the value of a parameter as an unsigned 32-bit decimal integer.
829  *
830  * @param param_list The URI parameter list.
831  * @param name       The name of the parameter.
832  * @param value      Pointer to the variable to receive the value.
833  * @return  True if the parameter value was read and stored correctly, false
834  *          otherwise.
835  */
rtp_get_parameter_u32(const VC_CONTAINERS_LIST_T * param_list,const char * name,uint32_t * value)836 bool rtp_get_parameter_u32(const VC_CONTAINERS_LIST_T *param_list,
837       const char *name,
838       uint32_t *value)
839 {
840    PARAMETER_T param;
841 
842    param.name = name;
843    if (vc_containers_list_find_entry(param_list, &param) && param.value)
844    {
845       char *end;
846 
847       *value = strtoul(param.value, &end, 10);
848       return (end != param.value) && (*end == '\0');
849    }
850 
851    return false;
852 }
853 
854 /**************************************************************************//**
855  * Gets the value of a parameter as an unsigned 32-bit hexadecimal integer.
856  *
857  * @param param_list The URI parameter list.
858  * @param name       The name of the parameter.
859  * @param value      Pointer to the variable to receive the value.
860  * @return  True if the parameter value was read and stored correctly, false
861  *          otherwise.
862  */
rtp_get_parameter_x32(const VC_CONTAINERS_LIST_T * param_list,const char * name,uint32_t * value)863 bool rtp_get_parameter_x32(const VC_CONTAINERS_LIST_T *param_list,
864       const char *name,
865       uint32_t *value)
866 {
867    PARAMETER_T param;
868 
869    param.name = name;
870    if (vc_containers_list_find_entry(param_list, &param) && param.value)
871    {
872       char *end;
873 
874       *value = strtoul(param.value, &end, 16);
875       return (end != param.value) && (*end == '\0');
876    }
877 
878    return false;
879 }
880 
881 /*****************************************************************************
882 Functions exported as part of the Container Module API
883  *****************************************************************************/
884 
885 /**************************************************************************//**
886  * Read/skip data from the container.
887  * Can also be used to query information about the next block of data.
888  *
889  * @param p_ctx      The reader context.
890  * @param p_packet   The container packet information, or NULL.
891  * @param flags      The container read flags.
892  * @return  The resulting status of the function.
893  */
rtp_reader_read(VC_CONTAINER_T * p_ctx,VC_CONTAINER_PACKET_T * p_packet,uint32_t flags)894 static VC_CONTAINER_STATUS_T rtp_reader_read( VC_CONTAINER_T *p_ctx,
895                                                VC_CONTAINER_PACKET_T *p_packet,
896                                                uint32_t flags )
897 {
898    VC_CONTAINER_TRACK_T *track;
899    VC_CONTAINER_TRACK_MODULE_T *t_module;
900    VC_CONTAINER_STATUS_T status;
901 
902    if((flags & VC_CONTAINER_READ_FLAG_FORCE_TRACK) && p_packet->track)
903       return VC_CONTAINER_ERROR_INVALID_ARGUMENT;
904 
905    track = p_ctx->tracks[0];
906    t_module = track->priv->module;
907 
908    CLEAR_BIT(t_module->flags, TRACK_NEW_PACKET);
909 
910    while (!BITS_AVAILABLE(p_ctx, &t_module->payload))
911    {
912       uint32_t bytes_read;
913 
914       /* No data left from last RTP packet, get another one */
915       bytes_read = READ_BYTES(p_ctx, t_module->buffer, MAXIMUM_PACKET_SIZE);
916       if (!bytes_read)
917          return STREAM_STATUS(p_ctx);
918 
919       BITS_INIT(p_ctx, &t_module->payload, t_module->buffer, bytes_read);
920 
921       decode_rtp_packet_header(p_ctx, t_module);
922       SET_BIT(t_module->flags, TRACK_NEW_PACKET);
923    }
924 
925    if (p_packet)
926    {
927       uint32_t timestamp_top = t_module->timestamp >> 30;
928 
929       /* Determine whether timestamp has wrapped forwards or backwards around zero */
930       if ((timestamp_top == 0) && (t_module->last_timestamp_top == 3))
931          t_module->timestamp_wraps++;
932       else if ((timestamp_top == 3) && (t_module->last_timestamp_top == 0))
933          t_module->timestamp_wraps--;
934       t_module->last_timestamp_top = timestamp_top;
935 
936       p_packet->dts = p_packet->pts = ((int64_t)t_module->timestamp_wraps << 32) | t_module->timestamp;
937       p_packet->track = 0;
938       p_packet->flags = 0;
939    }
940 
941    status = t_module->payload_handler(p_ctx, track, p_packet, flags);
942    if (p_packet && status == VC_CONTAINER_SUCCESS)
943    {
944       /* Adjust timestamps from RTP clock rate to microseconds */
945       p_packet->pts = p_packet->pts * MICROSECONDS_PER_SECOND / t_module->timestamp_clock;
946       p_packet->dts = p_packet->dts * MICROSECONDS_PER_SECOND / t_module->timestamp_clock;
947    }
948 
949    STREAM_STATUS(p_ctx) = status;
950    return status;
951 }
952 
953 /**************************************************************************//**
954  * Seek over data in the container.
955  *
956  * @param p_ctx      The reader context.
957  * @param p_offset   The seek offset.
958  * @param mode       The seek mode.
959  * @param flags      The seek flags.
960  * @return  The resulting status of the function.
961  */
rtp_reader_seek(VC_CONTAINER_T * p_ctx,int64_t * p_offset,VC_CONTAINER_SEEK_MODE_T mode,VC_CONTAINER_SEEK_FLAGS_T flags)962 static VC_CONTAINER_STATUS_T rtp_reader_seek( VC_CONTAINER_T *p_ctx,
963                                                int64_t *p_offset,
964                                                VC_CONTAINER_SEEK_MODE_T mode,
965                                                VC_CONTAINER_SEEK_FLAGS_T flags)
966 {
967    VC_CONTAINER_PARAM_UNUSED(p_ctx);
968    VC_CONTAINER_PARAM_UNUSED(p_offset);
969    VC_CONTAINER_PARAM_UNUSED(mode);
970    VC_CONTAINER_PARAM_UNUSED(flags);
971 
972    /* RTP is a non-seekable container */
973    return VC_CONTAINER_ERROR_UNSUPPORTED_OPERATION;
974 }
975 
976 /**************************************************************************//**
977  * Apply a control operation to the container.
978  *
979  * @param p_ctx      The reader context.
980  * @param operation  The control operation.
981  * @param args       Optional additional arguments for the operation.
982  * @return  The resulting status of the function.
983  */
rtp_reader_control(VC_CONTAINER_T * p_ctx,VC_CONTAINER_CONTROL_T operation,va_list args)984 static VC_CONTAINER_STATUS_T rtp_reader_control( VC_CONTAINER_T *p_ctx,
985                                                 VC_CONTAINER_CONTROL_T operation,
986                                                 va_list args)
987 {
988    VC_CONTAINER_STATUS_T status;
989    VC_CONTAINER_TRACK_MODULE_T *t_module = p_ctx->tracks[0]->priv->module;
990 
991    switch (operation)
992    {
993    case VC_CONTAINER_CONTROL_SET_TIMESTAMP_BASE:
994       {
995          t_module->timestamp_base = va_arg(args, uint32_t);
996          if (!t_module->timestamp_base)
997             t_module->timestamp_base = 1;    /* Zero is used to mean "not set" */
998          status = VC_CONTAINER_SUCCESS;
999       }
1000       break;
1001    case VC_CONTAINER_CONTROL_SET_NEXT_SEQUENCE_NUMBER:
1002       {
1003          init_sequence_number(t_module, (uint16_t)va_arg(args, uint32_t));
1004          t_module->probation = 0;
1005          status = VC_CONTAINER_SUCCESS;
1006       }
1007       break;
1008    case VC_CONTAINER_CONTROL_SET_SOURCE_ID:
1009       {
1010          t_module->expected_ssrc = va_arg(args, uint32_t);
1011          SET_BIT(t_module->flags, TRACK_SSRC_SET);
1012          status = VC_CONTAINER_SUCCESS;
1013       }
1014       break;
1015    default:
1016       status = VC_CONTAINER_ERROR_UNSUPPORTED_OPERATION;
1017    }
1018 
1019    return status;
1020 }
1021 
1022 /**************************************************************************//**
1023  * Close the container.
1024  *
1025  * @param p_ctx   The reader context.
1026  * @return  The resulting status of the function.
1027  */
rtp_reader_close(VC_CONTAINER_T * p_ctx)1028 static VC_CONTAINER_STATUS_T rtp_reader_close( VC_CONTAINER_T *p_ctx )
1029 {
1030    VC_CONTAINER_MODULE_T *module = p_ctx->priv->module;
1031 
1032    vc_container_assert(p_ctx->tracks_num < 2);
1033 
1034    if (p_ctx->tracks_num)
1035    {
1036       void *payload_extra;
1037 
1038       vc_container_assert(module);
1039       vc_container_assert(module->track);
1040       vc_container_assert(module->track->priv);
1041       vc_container_assert(module->track->priv->module);
1042 
1043       payload_extra = module->track->priv->module->extra;
1044       if (payload_extra)
1045          free(payload_extra);
1046       vc_container_free_track(p_ctx, module->track);
1047    }
1048    p_ctx->tracks = NULL;
1049    p_ctx->tracks_num = 0;
1050    if (module) free(module);
1051    p_ctx->priv->module = 0;
1052    return VC_CONTAINER_SUCCESS;
1053 }
1054 
1055 /**************************************************************************//**
1056  * Open the container.
1057  * Uses the I/O URI and/or data to configure the container.
1058  *
1059  * @param p_ctx   The reader context.
1060  * @return  The resulting status of the function.
1061  */
rtp_reader_open(VC_CONTAINER_T * p_ctx)1062 VC_CONTAINER_STATUS_T rtp_reader_open( VC_CONTAINER_T *p_ctx )
1063 {
1064    VC_CONTAINER_MODULE_T *module = 0;
1065    VC_CONTAINER_TRACK_T *track = 0;
1066    VC_CONTAINER_TRACK_MODULE_T *t_module = 0;
1067    VC_CONTAINER_STATUS_T status = VC_CONTAINER_SUCCESS;
1068    VC_CONTAINERS_LIST_T *parameters = NULL;
1069    uint32_t payload_type;
1070    uint32_t initial_seq_num;
1071 
1072    /* Check the URI scheme looks valid */
1073    if (!vc_uri_scheme(p_ctx->priv->uri) ||
1074        (strcasecmp(vc_uri_scheme(p_ctx->priv->uri), RTP_SCHEME) &&
1075         strcasecmp(vc_uri_scheme(p_ctx->priv->uri), RTP_PKT_SCHEME)))
1076       return VC_CONTAINER_ERROR_FORMAT_NOT_SUPPORTED;
1077 
1078    /* Make the query/parameter list more easily searchable */
1079    parameters = fill_parameter_list(p_ctx->priv->uri);
1080    if (!parameters) { status = VC_CONTAINER_ERROR_OUT_OF_MEMORY; goto error; }
1081 
1082    /* Payload type parameter is mandatory and must fit in 7 bits */
1083    if (!rtp_get_parameter_u32(parameters, PAYLOAD_TYPE_NAME, &payload_type) || payload_type > 127)
1084    {
1085       status = VC_CONTAINER_ERROR_FORMAT_INVALID;
1086       goto error;
1087    }
1088 
1089    /* Allocate our context */
1090    module = (VC_CONTAINER_MODULE_T *)malloc(sizeof(VC_CONTAINER_MODULE_T));
1091    if (!module) { status = VC_CONTAINER_ERROR_OUT_OF_MEMORY; goto error; }
1092 
1093    memset(module, 0, sizeof(*module));
1094    p_ctx->priv->module = module;
1095    p_ctx->tracks = &module->track;
1096 
1097    /* Allocate the track, including space for reading an RTP packet on the end */
1098    track = vc_container_allocate_track(p_ctx, sizeof(VC_CONTAINER_TRACK_MODULE_T) + MAXIMUM_PACKET_SIZE);
1099    if (!track)
1100    {
1101       status = VC_CONTAINER_ERROR_OUT_OF_MEMORY;
1102       goto error;
1103    }
1104    module->track = track;
1105    p_ctx->tracks_num = 1;
1106    t_module = track->priv->module;
1107 
1108    /* Initialise the track data */
1109    t_module->buffer = (uint8_t *)(t_module + 1);
1110    status = decode_payload_type(p_ctx, track, parameters, payload_type);
1111    if (status != VC_CONTAINER_SUCCESS)
1112       goto error;
1113 
1114    vc_container_assert(t_module->timestamp_clock != 0);
1115 
1116    /* Default to a generic, unstructured payload handler */
1117    if (!t_module->payload_handler)
1118       t_module->payload_handler = generic_payload_handler;
1119 
1120    if (rtp_get_parameter_x32(parameters, SSRC_NAME, &t_module->expected_ssrc))
1121       SET_BIT(t_module->flags, TRACK_SSRC_SET);
1122 
1123    t_module->probation = MIN_SEQUENTIAL;
1124    if (rtp_get_parameter_u32(parameters, SEQ_NAME, &initial_seq_num))
1125    {
1126       /* If an initial sequence number is provided, avoid probation period */
1127       t_module->max_seq_num = (uint16_t)initial_seq_num;
1128       t_module->probation = 0;
1129    }
1130 
1131    track->is_enabled = true;
1132 
1133    vc_containers_list_destroy(parameters);
1134 
1135    p_ctx->priv->pf_close = rtp_reader_close;
1136    p_ctx->priv->pf_read = rtp_reader_read;
1137    p_ctx->priv->pf_seek = rtp_reader_seek;
1138    p_ctx->priv->pf_control = rtp_reader_control;
1139 
1140    return VC_CONTAINER_SUCCESS;
1141 
1142 error:
1143    if (parameters) vc_containers_list_destroy(parameters);
1144    if(status == VC_CONTAINER_SUCCESS || status == VC_CONTAINER_ERROR_EOS)
1145       status = VC_CONTAINER_ERROR_FORMAT_INVALID;
1146    LOG_DEBUG(p_ctx, "error opening RTP (%i)", status);
1147    rtp_reader_close(p_ctx);
1148    return status;
1149 }
1150 
1151 /********************************************************************************
1152  Entrypoint function
1153  ********************************************************************************/
1154 
1155 #if !defined(ENABLE_CONTAINERS_STANDALONE) && defined(__HIGHC__)
1156 # pragma weak reader_open rtp_reader_open
1157 #endif
1158