77
78
ff_rdt_parse_close(RDTDemuxContext *s)
81
for (i = 1; i < s->n_streams; i++)
82
s->streams[i]->priv_data = NULL;
87
83
struct PayloadContext {
88
84
AVFormatContext *rmctx;
89
RMStream *rmst[MAX_STREAMS];
90
87
uint8_t *mlti_data;
91
88
unsigned int mlti_data_size;
92
89
char buffer[RTP_MAX_PACKET_LENGTH + FF_INPUT_BUFFER_PADDING_SIZE];
101
98
unsigned char zres[16],
102
99
buf[64] = { 0xa1, 0xe9, 0x14, 0x9d, 0x0e, 0x6b, 0x3b, 0x59 };
103
100
#define XOR_TABLE_SIZE 37
104
const unsigned char xor_table[XOR_TABLE_SIZE] = {
101
static const unsigned char xor_table[XOR_TABLE_SIZE] = {
105
102
0x05, 0x18, 0x74, 0xd0, 0x0d, 0x09, 0x02, 0x53,
106
103
0xc0, 0x01, 0x05, 0x05, 0x67, 0x03, 0x19, 0x70,
107
104
0x08, 0x27, 0x66, 0x10, 0x10, 0x72, 0x08, 0x09,
135
132
rdt_load_mdpr (PayloadContext *rdt, AVStream *st, int rule_nr)
142
139
* Layout of the MLTI chunk:
144
* 2:<number of streams>
141
* 2: number of streams
145
142
* Then for each stream ([number_of_streams] times):
147
* 2:<number of mdpr chunks>
144
* 2: number of mdpr chunks
148
145
* Then for each mdpr chunk ([number_of_mdpr_chunks] times):
151
148
* we skip MDPR chunks until we reach the one of the stream
152
149
* we're interested in, and forward that ([size]+[data]) to
153
150
* the RM demuxer to parse the stream-specific header data.
155
152
if (!rdt->mlti_data)
157
init_put_byte(&pb, rdt->mlti_data, rdt->mlti_data_size, 0,
154
ffio_init_context(&pb, rdt->mlti_data, rdt->mlti_data_size, 0,
158
155
NULL, NULL, NULL, NULL);
156
tag = avio_rl32(&pb);
160
157
if (tag == MKTAG('M', 'L', 'T', 'I')) {
161
158
int num, chunk_nr;
163
160
/* read index of MDPR chunk numbers */
161
num = avio_rb16(&pb);
165
162
if (rule_nr < 0 || rule_nr >= num)
167
url_fskip(&pb, rule_nr * 2);
168
chunk_nr = get_be16(&pb);
169
url_fskip(&pb, (num - 1 - rule_nr) * 2);
164
avio_skip(&pb, rule_nr * 2);
165
chunk_nr = avio_rb16(&pb);
166
avio_skip(&pb, (num - 1 - rule_nr) * 2);
171
168
/* read MDPR chunks */
169
num = avio_rb16(&pb);
173
170
if (chunk_nr >= num)
175
172
while (chunk_nr--)
176
url_fskip(&pb, get_be32(&pb));
177
size = get_be32(&pb);
173
avio_skip(&pb, avio_rb32(&pb));
174
size = avio_rb32(&pb);
179
176
size = rdt->mlti_data_size;
180
url_fseek(&pb, 0, SEEK_SET);
177
avio_seek(&pb, 0, SEEK_SET);
182
if (ff_rm_read_mdpr_codecdata(rdt->rmctx, &pb, st, rdt->rmst[st->index], size) < 0)
179
if (ff_rm_read_mdpr_codecdata(rdt->rmctx, &pb, st, rdt->rmst[st->index], size, NULL) < 0)
297
294
rdt_parse_packet (AVFormatContext *ctx, PayloadContext *rdt, AVStream *st,
298
295
AVPacket *pkt, uint32_t *timestamp,
299
const uint8_t *buf, int len, int flags)
296
const uint8_t *buf, int len, uint16_t rtp_seq, int flags)
301
298
int seq = 1, res;
304
301
if (rdt->audio_pkt_cnt == 0) {
307
init_put_byte(&pb, buf, len, 0, NULL, NULL, NULL, NULL);
304
ffio_init_context(&pb, (uint8_t *)buf, len, 0, NULL, NULL, NULL, NULL);
308
305
flags = (flags & RTP_FLAG_KEY) ? 2 : 0;
309
306
res = ff_rm_parse_packet (rdt->rmctx, &pb, st, rdt->rmst[st->index], len, pkt,
310
307
&seq, flags, *timestamp);
311
pos = url_ftell(&pb);
308
pos = avio_tell(&pb);
315
if (st->codec->codec_id == CODEC_ID_AAC) {
312
if (st->codec->codec_id == AV_CODEC_ID_AAC) {
316
313
memcpy (rdt->buffer, buf + pos, len - pos);
317
rdt->rmctx->pb = av_alloc_put_byte (rdt->buffer, len - pos, 0,
314
rdt->rmctx->pb = avio_alloc_context (rdt->buffer, len - pos, 0,
318
315
NULL, NULL, NULL, NULL);
325
322
ff_rm_retrieve_cache (rdt->rmctx, rdt->rmctx->pb,
326
323
st, rdt->rmst[st->index], pkt);
327
324
if (rdt->audio_pkt_cnt == 0 &&
328
st->codec->codec_id == CODEC_ID_AAC)
325
st->codec->codec_id == AV_CODEC_ID_AAC)
329
326
av_freep(&rdt->rmctx->pb);
331
328
pkt->stream_index = st->index;
338
335
ff_rdt_parse_packet(RDTDemuxContext *s, AVPacket *pkt,
339
const uint8_t *buf, int len)
336
uint8_t **bufptr, int len)
338
uint8_t *buf = bufptr ? *bufptr : NULL;
341
339
int seq_no, flags = 0, stream_id, set_id, is_keyframe;
342
340
uint32_t timestamp;
350
348
timestamp= 0; ///< Should not be used if buf is NULL, but should be set to the timestamp of the packet returned....
351
349
rv= s->parse_packet(s->ic, s->dynamic_protocol_context,
352
350
s->streams[s->prev_stream_id],
353
pkt, ×tamp, NULL, 0, flags);
351
pkt, ×tamp, NULL, 0, 0, flags);
378
376
rv = s->parse_packet(s->ic, s->dynamic_protocol_context,
379
377
s->streams[s->prev_stream_id],
380
pkt, ×tamp, buf, len, flags);
378
pkt, ×tamp, buf, len, 0, flags);
420
420
int n, first = -1;
422
422
for (n = 0; n < s->nb_streams; n++)
423
if (s->streams[n]->priv_data == stream->priv_data) {
423
if (s->streams[n]->id == stream->id) {
424
int count = s->streams[n]->index + 1, err;
424
425
if (first == -1) first = n;
426
if (rdt->nb_rmst < count) {
427
if ((err = av_reallocp(&rdt->rmst,
428
count * sizeof(*rdt->rmst))) < 0) {
432
memset(rdt->rmst + rdt->nb_rmst, 0,
433
(count - rdt->nb_rmst) * sizeof(*rdt->rmst));
434
rdt->nb_rmst = count;
425
436
rdt->rmst[s->streams[n]->index] = ff_rm_alloc_rmstream();
426
437
rdt_load_mdpr(rdt, s->streams[n], (n - first) * 2);
428
if (s->streams[n]->codec->codec_id == CODEC_ID_AAC)
429
s->streams[n]->codec->frame_size = 1; // FIXME
454
if (!(st = av_new_stream(s, 0)))
462
if (!(st = avformat_new_stream(s, NULL)))
464
st->id = orig_st->id;
456
465
st->codec->codec_type = orig_st->codec->codec_type;
457
st->priv_data = orig_st->priv_data;
458
466
st->first_dts = orig_st->first_dts;
476
484
* is set and once for if it isn't. We only read the first because we
477
485
* don't care much (that's what the "odd" variable is for).
478
486
* Each rule contains a set of one or more statements, optionally
479
* preceeded by a single condition. If there's a condition, the rule
487
* preceded by a single condition. If there's a condition, the rule
480
488
* starts with a '#'. Multiple conditions are merged between brackets,
481
489
* so there are never multiple conditions spread out over separate
482
490
* statements. Generally, these conditions are bitrate limits (min/max)
483
491
* for multi-bitrate streams.
485
493
if (*p == '\"') p++;
486
for (n_rules = 0; s->nb_streams < MAX_STREAMS;) {
487
495
if (!(end = strchr(p, ';')))
489
497
if (!odd && end != p) {
513
523
rdt_new_context (void)
515
525
PayloadContext *rdt = av_mallocz(sizeof(PayloadContext));
517
av_open_input_stream(&rdt->rmctx, NULL, "", &rdt_demuxer, NULL);
529
ret = avformat_open_input(&rdt->rmctx, "", &ff_rdt_demuxer, NULL);
527
for (i = 0; i < MAX_STREAMS; i++)
543
for (i = 0; i < rdt->nb_rmst; i++)
528
544
if (rdt->rmst[i]) {
529
545
ff_rm_free_rmstream(rdt->rmst[i]);
530
546
av_freep(&rdt->rmst[i]);
533
av_close_input_stream(rdt->rmctx);
549
avformat_close_input(&rdt->rmctx);
534
550
av_freep(&rdt->mlti_data);
551
av_freep(&rdt->rmst);
538
555
#define RDT_HANDLER(n, s, t) \
539
static RTPDynamicProtocolHandler ff_rdt_ ## n ## _handler = { \
556
static RTPDynamicProtocolHandler rdt_ ## n ## _handler = { \
541
558
.codec_type = t, \
542
.codec_id = CODEC_ID_NONE, \
559
.codec_id = AV_CODEC_ID_NONE, \
543
560
.parse_sdp_a_line = rdt_parse_sdp_line, \
544
.open = rdt_new_context, \
545
.close = rdt_free_context, \
561
.alloc = rdt_new_context, \
562
.free = rdt_free_context, \
546
563
.parse_packet = rdt_parse_packet \
549
566
RDT_HANDLER(live_video, "x-pn-multirate-realvideo-live", AVMEDIA_TYPE_VIDEO);
550
567
RDT_HANDLER(live_audio, "x-pn-multirate-realaudio-live", AVMEDIA_TYPE_AUDIO);
551
568
RDT_HANDLER(video, "x-pn-realvideo", AVMEDIA_TYPE_VIDEO);
552
569
RDT_HANDLER(audio, "x-pn-realaudio", AVMEDIA_TYPE_AUDIO);
554
void av_register_rdt_dynamic_payload_handlers(void)
571
void ff_register_rdt_dynamic_payload_handlers(void)
556
ff_register_dynamic_payload_handler(&ff_rdt_video_handler);
557
ff_register_dynamic_payload_handler(&ff_rdt_audio_handler);
558
ff_register_dynamic_payload_handler(&ff_rdt_live_video_handler);
559
ff_register_dynamic_payload_handler(&ff_rdt_live_audio_handler);
573
ff_register_dynamic_payload_handler(&rdt_video_handler);
574
ff_register_dynamic_payload_handler(&rdt_audio_handler);
575
ff_register_dynamic_payload_handler(&rdt_live_video_handler);
576
ff_register_dynamic_payload_handler(&rdt_live_audio_handler);