Statistics
| Branch: | Revision:

ffmpeg / libavformat / rtpdec.c @ 45aa9080

History | View | Annotate | Download (18.5 KB)

1 8eb793c4 Luca Abeni
/*
2
 * RTP input format
3 406792e7 Diego Biurrun
 * Copyright (c) 2002 Fabrice Bellard
4 8eb793c4 Luca Abeni
 *
5
 * This file is part of FFmpeg.
6
 *
7
 * FFmpeg is free software; you can redistribute it and/or
8
 * modify it under the terms of the GNU Lesser General Public
9
 * License as published by the Free Software Foundation; either
10
 * version 2.1 of the License, or (at your option) any later version.
11
 *
12
 * FFmpeg is distributed in the hope that it will be useful,
13
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
15
 * Lesser General Public License for more details.
16
 *
17
 * You should have received a copy of the GNU Lesser General Public
18
 * License along with FFmpeg; if not, write to the Free Software
19
 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
20
 */
21 245976da Diego Biurrun
22 7246177d Aurelien Jacobs
/* needed for gethostname() */
23 d0feff2a Diego Biurrun
#define _XOPEN_SOURCE 600
24 7246177d Aurelien Jacobs
25 9106a698 Stefano Sabatini
#include "libavcodec/get_bits.h"
26 8eb793c4 Luca Abeni
#include "avformat.h"
27
#include "mpegts.h"
28
29
#include <unistd.h>
30
#include "network.h"
31
32 302879cb Luca Abeni
#include "rtpdec.h"
33 e9fce261 Ronald S. Bultje
#include "rtp_asf.h"
34 8eb793c4 Luca Abeni
#include "rtp_h264.h"
35 e6327fba Ronald S. Bultje
#include "rtp_vorbis.h"
36 45aa9080 Ronald S. Bultje
#include "rtpdec_h263.h"
37 8eb793c4 Luca Abeni
38
//#define DEBUG
39
40
/* TODO: - add RTCP statistics reporting (should be optional).
41

42
         - add support for h263/mpeg4 packetized output : IDEA: send a
43
         buffer to 'rtp_write_packet' contains all the packets for ONE
44
         frame. Each packet should have a four byte header containing
45
         the length in big endian format (same trick as
46
         'url_open_dyn_packet_buf')
47
*/
48
49
/* statistics functions */
50
RTPDynamicProtocolHandler *RTPFirstDynamicPayloadHandler= NULL;
51
52
static RTPDynamicProtocolHandler mp4v_es_handler= {"MP4V-ES", CODEC_TYPE_VIDEO, CODEC_ID_MPEG4};
53
static RTPDynamicProtocolHandler mpeg4_generic_handler= {"mpeg4-generic", CODEC_TYPE_AUDIO, CODEC_ID_AAC};
54
55 0369d2b0 Ronald S. Bultje
void ff_register_dynamic_payload_handler(RTPDynamicProtocolHandler *handler)
56 8eb793c4 Luca Abeni
{
57
    handler->next= RTPFirstDynamicPayloadHandler;
58
    RTPFirstDynamicPayloadHandler= handler;
59
}
60
61
void av_register_rtp_dynamic_payload_handlers(void)
62
{
63 0369d2b0 Ronald S. Bultje
    ff_register_dynamic_payload_handler(&mp4v_es_handler);
64
    ff_register_dynamic_payload_handler(&mpeg4_generic_handler);
65 45aa9080 Ronald S. Bultje
    ff_register_dynamic_payload_handler(&ff_h263_1998_dynamic_handler);
66
    ff_register_dynamic_payload_handler(&ff_h263_2000_dynamic_handler);
67 0369d2b0 Ronald S. Bultje
    ff_register_dynamic_payload_handler(&ff_h264_dynamic_handler);
68 e6327fba Ronald S. Bultje
    ff_register_dynamic_payload_handler(&ff_vorbis_dynamic_handler);
69 e9fce261 Ronald S. Bultje
70
    ff_register_dynamic_payload_handler(&ff_ms_rtp_asf_pfv_handler);
71
    ff_register_dynamic_payload_handler(&ff_ms_rtp_asf_pfa_handler);
72 8eb793c4 Luca Abeni
}
73
74
static int rtcp_parse_packet(RTPDemuxContext *s, const unsigned char *buf, int len)
75
{
76
    if (buf[1] != 200)
77
        return -1;
78
    s->last_rtcp_ntp_time = AV_RB64(buf + 8);
79
    if (s->first_rtcp_ntp_time == AV_NOPTS_VALUE)
80
        s->first_rtcp_ntp_time = s->last_rtcp_ntp_time;
81
    s->last_rtcp_timestamp = AV_RB32(buf + 16);
82
    return 0;
83
}
84
85
#define RTP_SEQ_MOD (1<<16)
86
87
/**
88
* called on parse open packet
89
*/
90
static void rtp_init_statistics(RTPStatistics *s, uint16_t base_sequence) // called on parse open packet.
91
{
92
    memset(s, 0, sizeof(RTPStatistics));
93
    s->max_seq= base_sequence;
94
    s->probation= 1;
95
}
96
97
/**
98
* called whenever there is a large jump in sequence numbers, or when they get out of probation...
99
*/
100
static void rtp_init_sequence(RTPStatistics *s, uint16_t seq)
101
{
102
    s->max_seq= seq;
103
    s->cycles= 0;
104
    s->base_seq= seq -1;
105
    s->bad_seq= RTP_SEQ_MOD + 1;
106
    s->received= 0;
107
    s->expected_prior= 0;
108
    s->received_prior= 0;
109
    s->jitter= 0;
110
    s->transit= 0;
111
}
112
113
/**
114
* returns 1 if we should handle this packet.
115
*/
116
static int rtp_valid_packet_in_sequence(RTPStatistics *s, uint16_t seq)
117
{
118
    uint16_t udelta= seq - s->max_seq;
119
    const int MAX_DROPOUT= 3000;
120
    const int MAX_MISORDER = 100;
121
    const int MIN_SEQUENTIAL = 2;
122
123
    /* source not valid until MIN_SEQUENTIAL packets with sequence seq. numbers have been received */
124
    if(s->probation)
125
    {
126
        if(seq==s->max_seq + 1) {
127
            s->probation--;
128
            s->max_seq= seq;
129
            if(s->probation==0) {
130
                rtp_init_sequence(s, seq);
131
                s->received++;
132
                return 1;
133
            }
134
        } else {
135
            s->probation= MIN_SEQUENTIAL - 1;
136
            s->max_seq = seq;
137
        }
138
    } else if (udelta < MAX_DROPOUT) {
139
        // in order, with permissible gap
140
        if(seq < s->max_seq) {
141
            //sequence number wrapped; count antother 64k cycles
142
            s->cycles += RTP_SEQ_MOD;
143
        }
144
        s->max_seq= seq;
145
    } else if (udelta <= RTP_SEQ_MOD - MAX_MISORDER) {
146
        // sequence made a large jump...
147
        if(seq==s->bad_seq) {
148
            // two sequential packets-- assume that the other side restarted without telling us; just resync.
149
            rtp_init_sequence(s, seq);
150
        } else {
151
            s->bad_seq= (seq + 1) & (RTP_SEQ_MOD-1);
152
            return 0;
153
        }
154
    } else {
155
        // duplicate or reordered packet...
156
    }
157
    s->received++;
158
    return 1;
159
}
160
161
#if 0
162
/**
163
* This function is currently unused; without a valid local ntp time, I don't see how we could calculate the
164
* difference between the arrival and sent timestamp.  As a result, the jitter and transit statistics values
165
* never change.  I left this in in case someone else can see a way. (rdm)
166
*/
167
static void rtcp_update_jitter(RTPStatistics *s, uint32_t sent_timestamp, uint32_t arrival_timestamp)
168
{
169
    uint32_t transit= arrival_timestamp - sent_timestamp;
170
    int d;
171
    s->transit= transit;
172
    d= FFABS(transit - s->transit);
173
    s->jitter += d - ((s->jitter + 8)>>4);
174
}
175
#endif
176
177
int rtp_check_and_send_back_rr(RTPDemuxContext *s, int count)
178
{
179
    ByteIOContext *pb;
180
    uint8_t *buf;
181
    int len;
182
    int rtcp_bytes;
183
    RTPStatistics *stats= &s->statistics;
184
    uint32_t lost;
185
    uint32_t extended_max;
186
    uint32_t expected_interval;
187
    uint32_t received_interval;
188
    uint32_t lost_interval;
189
    uint32_t expected;
190
    uint32_t fraction;
191
    uint64_t ntp_time= s->last_rtcp_ntp_time; // TODO: Get local ntp time?
192
193
    if (!s->rtp_ctx || (count < 1))
194
        return -1;
195
196
    /* TODO: I think this is way too often; RFC 1889 has algorithm for this */
197
    /* XXX: mpeg pts hardcoded. RTCP send every 0.5 seconds */
198
    s->octet_count += count;
199
    rtcp_bytes = ((s->octet_count - s->last_octet_count) * RTCP_TX_RATIO_NUM) /
200
        RTCP_TX_RATIO_DEN;
201
    rtcp_bytes /= 50; // mmu_man: that's enough for me... VLC sends much less btw !?
202
    if (rtcp_bytes < 28)
203
        return -1;
204
    s->last_octet_count = s->octet_count;
205
206
    if (url_open_dyn_buf(&pb) < 0)
207
        return -1;
208
209
    // Receiver Report
210
    put_byte(pb, (RTP_VERSION << 6) + 1); /* 1 report block */
211
    put_byte(pb, 201);
212
    put_be16(pb, 7); /* length in words - 1 */
213
    put_be32(pb, s->ssrc); // our own SSRC
214
    put_be32(pb, s->ssrc); // XXX: should be the server's here!
215
    // some placeholders we should really fill...
216
    // RFC 1889/p64
217
    extended_max= stats->cycles + stats->max_seq;
218
    expected= extended_max - stats->base_seq + 1;
219
    lost= expected - stats->received;
220
    lost= FFMIN(lost, 0xffffff); // clamp it since it's only 24 bits...
221
    expected_interval= expected - stats->expected_prior;
222
    stats->expected_prior= expected;
223
    received_interval= stats->received - stats->received_prior;
224
    stats->received_prior= stats->received;
225
    lost_interval= expected_interval - received_interval;
226
    if (expected_interval==0 || lost_interval<=0) fraction= 0;
227
    else fraction = (lost_interval<<8)/expected_interval;
228
229
    fraction= (fraction<<24) | lost;
230
231
    put_be32(pb, fraction); /* 8 bits of fraction, 24 bits of total packets lost */
232
    put_be32(pb, extended_max); /* max sequence received */
233
    put_be32(pb, stats->jitter>>4); /* jitter */
234
235
    if(s->last_rtcp_ntp_time==AV_NOPTS_VALUE)
236
    {
237
        put_be32(pb, 0); /* last SR timestamp */
238
        put_be32(pb, 0); /* delay since last SR */
239
    } else {
240
        uint32_t middle_32_bits= s->last_rtcp_ntp_time>>16; // this is valid, right? do we need to handle 64 bit values special?
241
        uint32_t delay_since_last= ntp_time - s->last_rtcp_ntp_time;
242
243
        put_be32(pb, middle_32_bits); /* last SR timestamp */
244
        put_be32(pb, delay_since_last); /* delay since last SR */
245
    }
246
247
    // CNAME
248
    put_byte(pb, (RTP_VERSION << 6) + 1); /* 1 report block */
249
    put_byte(pb, 202);
250
    len = strlen(s->hostname);
251
    put_be16(pb, (6 + len + 3) / 4); /* length in words - 1 */
252
    put_be32(pb, s->ssrc);
253
    put_byte(pb, 0x01);
254
    put_byte(pb, len);
255
    put_buffer(pb, s->hostname, len);
256
    // padding
257
    for (len = (6 + len) % 4; len % 4; len++) {
258
        put_byte(pb, 0);
259
    }
260
261
    put_flush_packet(pb);
262
    len = url_close_dyn_buf(pb, &buf);
263
    if ((len > 0) && buf) {
264
        int result;
265 e8420626 Måns Rullgård
        dprintf(s->ic, "sending %d bytes of RR\n", len);
266 8eb793c4 Luca Abeni
        result= url_write(s->rtp_ctx, buf, len);
267 e8420626 Måns Rullgård
        dprintf(s->ic, "result from url_write: %d\n", result);
268 8eb793c4 Luca Abeni
        av_free(buf);
269
    }
270
    return 0;
271
}
272
273
/**
274
 * open a new RTP parse context for stream 'st'. 'st' can be NULL for
275
 * MPEG2TS streams to indicate that they should be demuxed inside the
276
 * rtp demux (otherwise CODEC_ID_MPEG2TS packets are returned)
277
 * TODO: change this to not take rtp_payload data, and use the new dynamic payload system.
278
 */
279 be73a544 Luca Abeni
RTPDemuxContext *rtp_parse_open(AVFormatContext *s1, AVStream *st, URLContext *rtpc, int payload_type, RTPPayloadData *rtp_payload_data)
280 8eb793c4 Luca Abeni
{
281
    RTPDemuxContext *s;
282
283
    s = av_mallocz(sizeof(RTPDemuxContext));
284
    if (!s)
285
        return NULL;
286
    s->payload_type = payload_type;
287
    s->last_rtcp_ntp_time = AV_NOPTS_VALUE;
288
    s->first_rtcp_ntp_time = AV_NOPTS_VALUE;
289
    s->ic = s1;
290
    s->st = st;
291
    s->rtp_payload_data = rtp_payload_data;
292
    rtp_init_statistics(&s->statistics, 0); // do we know the initial sequence from sdp?
293
    if (!strcmp(ff_rtp_enc_name(payload_type), "MP2T")) {
294
        s->ts = mpegts_parse_open(s->ic);
295
        if (s->ts == NULL) {
296
            av_free(s);
297
            return NULL;
298
        }
299
    } else {
300 26efefc5 Luca Abeni
        av_set_pts_info(st, 32, 1, 90000);
301 8eb793c4 Luca Abeni
        switch(st->codec->codec_id) {
302
        case CODEC_ID_MPEG1VIDEO:
303
        case CODEC_ID_MPEG2VIDEO:
304
        case CODEC_ID_MP2:
305
        case CODEC_ID_MP3:
306
        case CODEC_ID_MPEG4:
307 45aa9080 Ronald S. Bultje
        case CODEC_ID_H263:
308 8eb793c4 Luca Abeni
        case CODEC_ID_H264:
309
            st->need_parsing = AVSTREAM_PARSE_FULL;
310
            break;
311
        default:
312 d6b9e57a Luca Abeni
            if (st->codec->codec_type == CODEC_TYPE_AUDIO) {
313
                av_set_pts_info(st, 32, 1, st->codec->sample_rate);
314
            }
315 8eb793c4 Luca Abeni
            break;
316
        }
317
    }
318
    // needed to send back RTCP RR in RTSP sessions
319
    s->rtp_ctx = rtpc;
320
    gethostname(s->hostname, sizeof(s->hostname));
321
    return s;
322
}
323
324 99a1d191 Ronald S. Bultje
void
325
rtp_parse_set_dynamic_protocol(RTPDemuxContext *s, PayloadContext *ctx,
326
                               RTPDynamicProtocolHandler *handler)
327
{
328
    s->dynamic_protocol_context = ctx;
329
    s->parse_packet = handler->parse_packet;
330
}
331
332 8eb793c4 Luca Abeni
static int rtp_parse_mp4_au(RTPDemuxContext *s, const uint8_t *buf)
333
{
334
    int au_headers_length, au_header_size, i;
335
    GetBitContext getbitcontext;
336 be73a544 Luca Abeni
    RTPPayloadData *infos;
337 8eb793c4 Luca Abeni
338
    infos = s->rtp_payload_data;
339
340
    if (infos == NULL)
341
        return -1;
342
343 bd107136 Diego Biurrun
    /* decode the first 2 bytes where the AUHeader sections are stored
344 8eb793c4 Luca Abeni
       length in bits */
345
    au_headers_length = AV_RB16(buf);
346
347
    if (au_headers_length > RTP_MAX_PACKET_LENGTH)
348
      return -1;
349
350
    infos->au_headers_length_bytes = (au_headers_length + 7) / 8;
351
352
    /* skip AU headers length section (2 bytes) */
353
    buf += 2;
354
355
    init_get_bits(&getbitcontext, buf, infos->au_headers_length_bytes * 8);
356
357
    /* XXX: Wrong if optionnal additional sections are present (cts, dts etc...) */
358
    au_header_size = infos->sizelength + infos->indexlength;
359
    if (au_header_size <= 0 || (au_headers_length % au_header_size != 0))
360
        return -1;
361
362
    infos->nb_au_headers = au_headers_length / au_header_size;
363
    infos->au_headers = av_malloc(sizeof(struct AUHeaders) * infos->nb_au_headers);
364
365
    /* XXX: We handle multiple AU Section as only one (need to fix this for interleaving)
366
       In my test, the FAAD decoder does not behave correctly when sending each AU one by one
367
       but does when sending the whole as one big packet...  */
368
    infos->au_headers[0].size = 0;
369
    infos->au_headers[0].index = 0;
370
    for (i = 0; i < infos->nb_au_headers; ++i) {
371
        infos->au_headers[0].size += get_bits_long(&getbitcontext, infos->sizelength);
372
        infos->au_headers[0].index = get_bits_long(&getbitcontext, infos->indexlength);
373
    }
374
375
    infos->nb_au_headers = 1;
376
377
    return 0;
378
}
379
380
/**
381
 * This was the second switch in rtp_parse packet.  Normalizes time, if required, sets stream_index, etc.
382
 */
383
static void finalize_packet(RTPDemuxContext *s, AVPacket *pkt, uint32_t timestamp)
384
{
385 fba7815d Luca Abeni
    if (s->last_rtcp_ntp_time != AV_NOPTS_VALUE) {
386
        int64_t addend;
387
        int delta_timestamp;
388
389
        /* compute pts from timestamp with received ntp_time */
390
        delta_timestamp = timestamp - s->last_rtcp_timestamp;
391
        /* convert to the PTS timebase */
392
        addend = av_rescale(s->last_rtcp_ntp_time - s->first_rtcp_ntp_time, s->st->time_base.den, (uint64_t)s->st->time_base.num << 32);
393
        pkt->pts = addend + delta_timestamp;
394
    }
395 8eb793c4 Luca Abeni
}
396
397
/**
398
 * Parse an RTP or RTCP packet directly sent as a buffer.
399
 * @param s RTP parse context.
400
 * @param pkt returned packet
401
 * @param buf input buffer or NULL to read the next packets
402
 * @param len buffer len
403
 * @return 0 if a packet is returned, 1 if a packet is returned and more can follow
404
 * (use buf as NULL to read the next). -1 if no packet (error or no more packet).
405
 */
406
int rtp_parse_packet(RTPDemuxContext *s, AVPacket *pkt,
407
                     const uint8_t *buf, int len)
408
{
409
    unsigned int ssrc, h;
410 f841a0fc Ronald S. Bultje
    int payload_type, seq, ret, flags = 0;
411 8eb793c4 Luca Abeni
    AVStream *st;
412
    uint32_t timestamp;
413
    int rv= 0;
414
415
    if (!buf) {
416
        /* return the next packets, if any */
417
        if(s->st && s->parse_packet) {
418
            timestamp= 0; ///< Should not be used if buf is NULL, but should be set to the timestamp of the packet returned....
419 1a45a9f4 Ronald S. Bultje
            rv= s->parse_packet(s->ic, s->dynamic_protocol_context,
420 9b932b8a Ronald S. Bultje
                                s->st, pkt, &timestamp, NULL, 0, flags);
421 8eb793c4 Luca Abeni
            finalize_packet(s, pkt, timestamp);
422
            return rv;
423
        } else {
424
            // TODO: Move to a dynamic packet handler (like above)
425
            if (s->read_buf_index >= s->read_buf_size)
426
                return -1;
427
            ret = mpegts_parse_packet(s->ts, pkt, s->buf + s->read_buf_index,
428
                                      s->read_buf_size - s->read_buf_index);
429
            if (ret < 0)
430
                return -1;
431
            s->read_buf_index += ret;
432
            if (s->read_buf_index < s->read_buf_size)
433
                return 1;
434
            else
435
                return 0;
436
        }
437
    }
438
439
    if (len < 12)
440
        return -1;
441
442
    if ((buf[0] & 0xc0) != (RTP_VERSION << 6))
443
        return -1;
444
    if (buf[1] >= 200 && buf[1] <= 204) {
445
        rtcp_parse_packet(s, buf, len);
446
        return -1;
447
    }
448
    payload_type = buf[1] & 0x7f;
449 144ae29d Ronald S. Bultje
    if (buf[1] & 0x80)
450
        flags |= RTP_FLAG_MARKER;
451 8eb793c4 Luca Abeni
    seq  = AV_RB16(buf + 2);
452
    timestamp = AV_RB32(buf + 4);
453
    ssrc = AV_RB32(buf + 8);
454
    /* store the ssrc in the RTPDemuxContext */
455
    s->ssrc = ssrc;
456
457
    /* NOTE: we can handle only one payload type */
458
    if (s->payload_type != payload_type)
459
        return -1;
460
461
    st = s->st;
462
    // only do something with this if all the rtp checks pass...
463
    if(!rtp_valid_packet_in_sequence(&s->statistics, seq))
464
    {
465
        av_log(st?st->codec:NULL, AV_LOG_ERROR, "RTP: PT=%02x: bad cseq %04x expected=%04x\n",
466
               payload_type, seq, ((s->seq + 1) & 0xffff));
467
        return -1;
468
    }
469
470
    s->seq = seq;
471
    len -= 12;
472
    buf += 12;
473
474
    if (!st) {
475
        /* specific MPEG2TS demux support */
476
        ret = mpegts_parse_packet(s->ts, pkt, buf, len);
477
        if (ret < 0)
478
            return -1;
479
        if (ret < len) {
480
            s->read_buf_size = len - ret;
481
            memcpy(s->buf, buf + ret, s->read_buf_size);
482
            s->read_buf_index = 0;
483
            return 1;
484
        }
485 f3e71942 Ronald S. Bultje
        return 0;
486 b4e3330c Ronald S. Bultje
    } else if (s->parse_packet) {
487 1a45a9f4 Ronald S. Bultje
        rv = s->parse_packet(s->ic, s->dynamic_protocol_context,
488 9b932b8a Ronald S. Bultje
                             s->st, pkt, &timestamp, buf, len, flags);
489 8eb793c4 Luca Abeni
    } else {
490
        // at this point, the RTP header has been stripped;  This is ASSUMING that there is only 1 CSRC, which in't wise.
491
        switch(st->codec->codec_id) {
492
        case CODEC_ID_MP2:
493 76faff6e Luca Abeni
        case CODEC_ID_MP3:
494 8eb793c4 Luca Abeni
            /* better than nothing: skip mpeg audio RTP header */
495
            if (len <= 4)
496
                return -1;
497
            h = AV_RB32(buf);
498
            len -= 4;
499
            buf += 4;
500
            av_new_packet(pkt, len);
501
            memcpy(pkt->data, buf, len);
502
            break;
503
        case CODEC_ID_MPEG1VIDEO:
504
        case CODEC_ID_MPEG2VIDEO:
505
            /* better than nothing: skip mpeg video RTP header */
506
            if (len <= 4)
507
                return -1;
508
            h = AV_RB32(buf);
509
            buf += 4;
510
            len -= 4;
511
            if (h & (1 << 26)) {
512
                /* mpeg2 */
513
                if (len <= 4)
514
                    return -1;
515
                buf += 4;
516
                len -= 4;
517
            }
518
            av_new_packet(pkt, len);
519
            memcpy(pkt->data, buf, len);
520
            break;
521
            // moved from below, verbatim.  this is because this section handles packets, and the lower switch handles
522
            // timestamps.
523
            // TODO: Put this into a dynamic packet handler...
524
        case CODEC_ID_AAC:
525
            if (rtp_parse_mp4_au(s, buf))
526
                return -1;
527
            {
528 be73a544 Luca Abeni
                RTPPayloadData *infos = s->rtp_payload_data;
529 8eb793c4 Luca Abeni
                if (infos == NULL)
530
                    return -1;
531
                buf += infos->au_headers_length_bytes + 2;
532
                len -= infos->au_headers_length_bytes + 2;
533
534
                /* XXX: Fixme we only handle the case where rtp_parse_mp4_au define
535
                    one au_header */
536
                av_new_packet(pkt, infos->au_headers[0].size);
537
                memcpy(pkt->data, buf, infos->au_headers[0].size);
538
                buf += infos->au_headers[0].size;
539
                len -= infos->au_headers[0].size;
540
            }
541
            s->read_buf_size = len;
542
            rv= 0;
543
            break;
544
        default:
545 f739b36d Ronald S. Bultje
            av_new_packet(pkt, len);
546
            memcpy(pkt->data, buf, len);
547 8eb793c4 Luca Abeni
            break;
548
        }
549 eafb17d1 Ronald S. Bultje
550
        pkt->stream_index = st->index;
551 f3e71942 Ronald S. Bultje
    }
552 8eb793c4 Luca Abeni
553 95f03cf3 Ronald S. Bultje
    // now perform timestamp things....
554
    finalize_packet(s, pkt, timestamp);
555 f3e71942 Ronald S. Bultje
556 8eb793c4 Luca Abeni
    return rv;
557
}
558
559
void rtp_parse_close(RTPDemuxContext *s)
560
{
561
    // TODO: fold this into the protocol specific data fields.
562
    if (!strcmp(ff_rtp_enc_name(s->payload_type), "MP2T")) {
563
        mpegts_parse_close(s->ts);
564
    }
565
    av_free(s);
566
}