rmdec.c 45.3 KB
Newer Older
Fabrice Bellard's avatar
Fabrice Bellard committed
1
/*
2
 * "Real" compatible demuxer.
3
 * Copyright (c) 2000, 2001 Fabrice Bellard
Fabrice Bellard's avatar
Fabrice Bellard committed
4
 *
5 6 7
 * This file is part of FFmpeg.
 *
 * FFmpeg is free software; you can redistribute it and/or
8 9
 * modify it under the terms of the GNU Lesser General Public
 * License as published by the Free Software Foundation; either
10
 * version 2.1 of the License, or (at your option) any later version.
Fabrice Bellard's avatar
Fabrice Bellard committed
11
 *
12
 * FFmpeg is distributed in the hope that it will be useful,
Fabrice Bellard's avatar
Fabrice Bellard committed
13
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 15
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 * Lesser General Public License for more details.
Fabrice Bellard's avatar
Fabrice Bellard committed
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
Fabrice Bellard's avatar
Fabrice Bellard committed
20
 */
21

22 23
#include <inttypes.h>

24
#include "libavutil/avassert.h"
25
#include "libavutil/avstring.h"
26
#include "libavutil/channel_layout.h"
27
#include "libavutil/internal.h"
28
#include "libavutil/intreadwrite.h"
29
#include "libavutil/dict.h"
Fabrice Bellard's avatar
Fabrice Bellard committed
30
#include "avformat.h"
31
#include "avio_internal.h"
32
#include "internal.h"
33
#include "rmsipr.h"
34
#include "rm.h"
35

36
#define DEINT_ID_GENR MKTAG('g', 'e', 'n', 'r') ///< interleaving for Cooker/ATRAC
37 38 39 40 41 42
#define DEINT_ID_INT0 MKTAG('I', 'n', 't', '0') ///< no interleaving needed
#define DEINT_ID_INT4 MKTAG('I', 'n', 't', '4') ///< interleaving for 28.8
#define DEINT_ID_SIPR MKTAG('s', 'i', 'p', 'r') ///< interleaving for Sipro
#define DEINT_ID_VBRF MKTAG('v', 'b', 'r', 'f') ///< VBR case for AAC
#define DEINT_ID_VBRS MKTAG('v', 'b', 'r', 's') ///< VBR case for AAC

43
struct RMStream {
44
    AVPacket pkt;      ///< place to store merged video frame / reordered audio data
45 46 47 48 49 50 51 52 53
    int videobufsize;  ///< current assembled frame size
    int videobufpos;   ///< position for the next slice in the video buffer
    int curpic_num;    ///< picture number of current frame
    int cur_slice, slices;
    int64_t pktpos;    ///< first slice position in file
    /// Audio descrambling matrix parameters
    int64_t audiotimestamp; ///< Audio packet timestamp
    int sub_packet_cnt; // Subpacket counter, used while reading
    int sub_packet_size, sub_packet_h, coded_framesize; ///< Descrambling parameters from container
54 55
    int audio_framesize; /// Audio frame size from container
    int sub_packet_lengths[16]; /// Length of each subpacket
56
    int32_t deint_id;  ///< deinterleaver used in audio stream
57 58
};

59
typedef struct RMDemuxContext {
60 61 62 63
    int nb_packets;
    int old_format;
    int current_stream;
    int remaining_len;
64 65
    int audio_stream_num; ///< Stream number for audio packets
    int audio_pkt_cnt; ///< Output packet counter
66
    int data_end;
67
} RMDemuxContext;
Fabrice Bellard's avatar
Fabrice Bellard committed
68

69 70
static int rm_read_close(AVFormatContext *s);

71
static inline void get_strl(AVIOContext *pb, char *buf, int buf_size, int len)
Fabrice Bellard's avatar
Fabrice Bellard committed
72
{
73
    int i;
74
    char *q, r;
Fabrice Bellard's avatar
Fabrice Bellard committed
75 76 77

    q = buf;
    for(i=0;i<len;i++) {
78
        r = avio_r8(pb);
Fabrice Bellard's avatar
Fabrice Bellard committed
79
        if (i < buf_size - 1)
80
            *q++ = r;
Fabrice Bellard's avatar
Fabrice Bellard committed
81
    }
82
    if (buf_size > 0) *q = '\0';
Fabrice Bellard's avatar
Fabrice Bellard committed
83 84
}

85
static void get_str8(AVIOContext *pb, char *buf, int buf_size)
86
{
87
    get_strl(pb, buf, buf_size, avio_r8(pb));
Fabrice Bellard's avatar
Fabrice Bellard committed
88 89
}

90
static int rm_read_extradata(AVFormatContext *s, AVIOContext *pb, AVCodecParameters *par, unsigned size)
91
{
92
    if (size >= 1<<24) {
93
        av_log(s, AV_LOG_ERROR, "extradata size %u too large\n", size);
94
        return -1;
95
    }
96
    if (ff_get_extradata(s, par, pb, size) < 0)
97
        return AVERROR(ENOMEM);
98 99 100
    return 0;
}

101
static void rm_read_metadata(AVFormatContext *s, AVIOContext *pb, int wide)
102 103 104
{
    char buf[1024];
    int i;
105

106
    for (i=0; i<FF_ARRAY_ELEMS(ff_rm_metadata); i++) {
107 108
        int len = wide ? avio_rb16(pb) : avio_r8(pb);
        get_strl(pb, buf, sizeof(buf), len);
109
        av_dict_set(&s->metadata, ff_rm_metadata[i], buf, 0);
110 111 112
    }
}

113 114 115
RMStream *ff_rm_alloc_rmstream (void)
{
    RMStream *rms = av_mallocz(sizeof(RMStream));
116 117
    if (!rms)
        return NULL;
118 119 120 121 122 123
    rms->curpic_num = -1;
    return rms;
}

void ff_rm_free_rmstream (RMStream *rms)
{
124
    av_packet_unref(&rms->pkt);
125 126
}

127
static int rm_read_audio_stream_info(AVFormatContext *s, AVIOContext *pb,
128
                                     AVStream *st, RMStream *ast, int read_all)
129
{
130
    char buf[256];
131
    uint32_t version;
132
    int ret;
133 134

    /* ra type header */
135
    version = avio_rb16(pb); /* version */
136
    if (version == 3) {
137
        unsigned bytes_per_minute;
138
        int header_size = avio_rb16(pb);
139
        int64_t startpos = avio_tell(pb);
140 141 142
        avio_skip(pb, 8);
        bytes_per_minute = avio_rb16(pb);
        avio_skip(pb, 4);
143
        rm_read_metadata(s, pb, 0);
144
        if ((startpos + header_size) >= avio_tell(pb) + 2) {
Ronald S. Bultje's avatar
Ronald S. Bultje committed
145
            // fourcc (should always be "lpcJ")
146
            avio_r8(pb);
Ronald S. Bultje's avatar
Ronald S. Bultje committed
147
            get_str8(pb, buf, sizeof(buf));
148 149
        }
        // Skip extra header crap (this should never happen)
150
        if ((startpos + header_size) > avio_tell(pb))
151
            avio_skip(pb, header_size + startpos - avio_tell(pb));
152
        if (bytes_per_minute)
153
            st->codecpar->bit_rate = 8LL * bytes_per_minute / 60;
154 155 156 157 158
        st->codecpar->sample_rate = 8000;
        st->codecpar->channels = 1;
        st->codecpar->channel_layout = AV_CH_LAYOUT_MONO;
        st->codecpar->codec_type = AVMEDIA_TYPE_AUDIO;
        st->codecpar->codec_id = AV_CODEC_ID_RA_144;
159
        ast->deint_id = DEINT_ID_INT0;
160
    } else {
161
        int flavor, sub_packet_h, coded_framesize, sub_packet_size;
162
        int codecdata_length;
163
        unsigned bytes_per_minute;
164
        /* old version (4) */
165
        avio_skip(pb, 2); /* unused */
166 167 168 169 170 171 172
        avio_rb32(pb); /* .ra4 */
        avio_rb32(pb); /* data size */
        avio_rb16(pb); /* version2 */
        avio_rb32(pb); /* header size */
        flavor= avio_rb16(pb); /* add codec info / flavor */
        ast->coded_framesize = coded_framesize = avio_rb32(pb); /* coded frame size */
        avio_rb32(pb); /* ??? */
173 174 175
        bytes_per_minute = avio_rb32(pb);
        if (version == 4) {
            if (bytes_per_minute)
176
                st->codecpar->bit_rate = 8LL * bytes_per_minute / 60;
177
        }
178 179
        avio_rb32(pb); /* ??? */
        ast->sub_packet_h = sub_packet_h = avio_rb16(pb); /* 1 */
180
        st->codecpar->block_align= avio_rb16(pb); /* frame size */
181 182
        ast->sub_packet_size = sub_packet_size = avio_rb16(pb); /* sub packet size */
        avio_rb16(pb); /* ??? */
183
        if (version == 5) {
184
            avio_rb16(pb); avio_rb16(pb); avio_rb16(pb);
185
        }
186
        st->codecpar->sample_rate = avio_rb16(pb);
187
        avio_rb32(pb);
188
        st->codecpar->channels = avio_rb16(pb);
189
        if (version == 5) {
190
            ast->deint_id = avio_rl32(pb);
191
            avio_read(pb, buf, 4);
192 193
            buf[4] = 0;
        } else {
194
            AV_WL32(buf, 0);
195
            get_str8(pb, buf, sizeof(buf)); /* desc */
196
            ast->deint_id = AV_RL32(buf);
197
            get_str8(pb, buf, sizeof(buf)); /* desc */
198
        }
199 200 201 202
        st->codecpar->codec_type = AVMEDIA_TYPE_AUDIO;
        st->codecpar->codec_tag  = AV_RL32(buf);
        st->codecpar->codec_id   = ff_codec_get_id(ff_rm_codec_tags,
                                                   st->codecpar->codec_tag);
203

204
        switch (st->codecpar->codec_id) {
205
        case AV_CODEC_ID_AC3:
206
            st->need_parsing = AVSTREAM_PARSE_FULL;
207
            break;
208
        case AV_CODEC_ID_RA_288:
209
            st->codecpar->extradata_size= 0;
210
            av_freep(&st->codecpar->extradata);
211 212
            ast->audio_framesize = st->codecpar->block_align;
            st->codecpar->block_align = coded_framesize;
213
            break;
214
        case AV_CODEC_ID_COOK:
215
            st->need_parsing = AVSTREAM_PARSE_HEADERS;
216 217
        case AV_CODEC_ID_ATRAC3:
        case AV_CODEC_ID_SIPR:
218 219 220
            if (read_all) {
                codecdata_length = 0;
            } else {
221 222 223 224
                avio_rb16(pb); avio_r8(pb);
                if (version == 5)
                    avio_r8(pb);
                codecdata_length = avio_rb32(pb);
225
                if(codecdata_length + AV_INPUT_BUFFER_PADDING_SIZE <= (unsigned)codecdata_length){
226 227 228
                    av_log(s, AV_LOG_ERROR, "codecdata_length too large\n");
                    return -1;
                }
229
            }
230

231 232
            ast->audio_framesize = st->codecpar->block_align;
            if (st->codecpar->codec_id == AV_CODEC_ID_SIPR) {
233 234 235 236 237
                if (flavor > 3) {
                    av_log(s, AV_LOG_ERROR, "bad SIPR file flavor %d\n",
                           flavor);
                    return -1;
                }
238
                st->codecpar->block_align = ff_sipr_subpk_size[flavor];
239
                st->need_parsing = AVSTREAM_PARSE_FULL_RAW;
240 241 242 243 244
            } else {
                if(sub_packet_size <= 0){
                    av_log(s, AV_LOG_ERROR, "sub_packet_size is invalid\n");
                    return -1;
                }
245
                st->codecpar->block_align = ast->sub_packet_size;
246
            }
247
            if ((ret = rm_read_extradata(s, pb, st->codecpar, codecdata_length)) < 0)
248
                return ret;
249

250
            break;
251
        case AV_CODEC_ID_AAC:
252
            avio_rb16(pb); avio_r8(pb);
253
            if (version == 5)
254 255
                avio_r8(pb);
            codecdata_length = avio_rb32(pb);
256
            if(codecdata_length + AV_INPUT_BUFFER_PADDING_SIZE <= (unsigned)codecdata_length){
257 258 259
                av_log(s, AV_LOG_ERROR, "codecdata_length too large\n");
                return -1;
            }
260
            if (codecdata_length >= 1) {
261
                avio_r8(pb);
262
                if ((ret = rm_read_extradata(s, pb, st->codecpar, codecdata_length - 1)) < 0)
263
                    return ret;
264
            }
265
            break;
266
        }
267 268 269
        switch (ast->deint_id) {
        case DEINT_ID_INT4:
            if (ast->coded_framesize > ast->audio_framesize ||
270
                sub_packet_h <= 1 ||
271 272
                ast->coded_framesize * sub_packet_h > (2 + (sub_packet_h & 1)) * ast->audio_framesize)
                return AVERROR_INVALIDDATA;
273 274 275 276
            if (ast->coded_framesize * sub_packet_h != 2*ast->audio_framesize) {
                avpriv_request_sample(s, "mismatching interleaver parameters");
                return AVERROR_INVALIDDATA;
            }
277 278 279 280 281
            break;
        case DEINT_ID_GENR:
            if (ast->sub_packet_size <= 0 ||
                ast->sub_packet_size > ast->audio_framesize)
                return AVERROR_INVALIDDATA;
282 283
            if (ast->audio_framesize % ast->sub_packet_size)
                return AVERROR_INVALIDDATA;
284 285 286 287 288 289 290
            break;
        case DEINT_ID_SIPR:
        case DEINT_ID_INT0:
        case DEINT_ID_VBRS:
        case DEINT_ID_VBRF:
            break;
        default:
291
            av_log(s, AV_LOG_ERROR ,"Unknown interleaver %"PRIX32"\n", ast->deint_id);
292 293
            return AVERROR_INVALIDDATA;
        }
294 295 296
        if (ast->deint_id == DEINT_ID_INT4 ||
            ast->deint_id == DEINT_ID_GENR ||
            ast->deint_id == DEINT_ID_SIPR) {
297
            if (st->codecpar->block_align <= 0 ||
298
                ast->audio_framesize * sub_packet_h > (unsigned)INT_MAX ||
299
                ast->audio_framesize * sub_packet_h < st->codecpar->block_align)
300 301 302 303
                return AVERROR_INVALIDDATA;
            if (av_new_packet(&ast->pkt, ast->audio_framesize * sub_packet_h) < 0)
                return AVERROR(ENOMEM);
        }
304

305
        if (read_all) {
306 307 308
            avio_r8(pb);
            avio_r8(pb);
            avio_r8(pb);
309
            rm_read_metadata(s, pb, 0);
310 311
        }
    }
312
    return 0;
313 314
}

315 316
int ff_rm_read_mdpr_codecdata(AVFormatContext *s, AVIOContext *pb,
                              AVStream *st, RMStream *rst,
317
                              unsigned int codec_data_size, const uint8_t *mime)
318 319
{
    unsigned int v;
320
    int size;
321
    int64_t codec_pos;
322
    int ret;
323

324
    if (codec_data_size > INT_MAX)
325
        return AVERROR_INVALIDDATA;
326 327
    if (codec_data_size == 0)
        return 0;
328

329
    avpriv_set_pts_info(st, 64, 1, 1000);
330
    codec_pos = avio_tell(pb);
331
    v = avio_rb32(pb);
332

333 334
    if (v == MKTAG(0xfd, 'a', 'r', '.')) {
        /* ra type header */
335
        if (rm_read_audio_stream_info(s, pb, st, rst, 0))
336
            return -1;
337 338
    } else if (v == MKBETAG('L', 'S', 'D', ':')) {
        avio_seek(pb, -4, SEEK_CUR);
339
        if ((ret = rm_read_extradata(s, pb, st->codecpar, codec_data_size)) < 0)
340 341
            return ret;

342 343 344
        st->codecpar->codec_type = AVMEDIA_TYPE_AUDIO;
        st->codecpar->codec_tag  = AV_RL32(st->codecpar->extradata);
        st->codecpar->codec_id   = ff_codec_get_id(ff_rm_codec_tags,
345
                                                st->codecpar->codec_tag);
346
    } else if(mime && !strcmp(mime, "logical-fileinfo")){
347
        int stream_count, rule_count, property_count, i;
348 349 350 351 352 353 354 355 356 357 358 359 360 361 362 363 364 365 366 367 368 369 370 371 372
        ff_free_stream(s, st);
        if (avio_rb16(pb) != 0) {
            av_log(s, AV_LOG_WARNING, "Unsupported version\n");
            goto skip;
        }
        stream_count = avio_rb16(pb);
        avio_skip(pb, 6*stream_count);
        rule_count = avio_rb16(pb);
        avio_skip(pb, 2*rule_count);
        property_count = avio_rb16(pb);
        for(i=0; i<property_count; i++){
            uint8_t name[128], val[128];
            avio_rb32(pb);
            if (avio_rb16(pb) != 0) {
                av_log(s, AV_LOG_WARNING, "Unsupported Name value property version\n");
                goto skip; //FIXME skip just this one
            }
            get_str8(pb, name, sizeof(name));
            switch(avio_rb32(pb)) {
            case 2: get_strl(pb, val, sizeof(val), avio_rb16(pb));
                av_dict_set(&s->metadata, name, val, 0);
                break;
            default: avio_skip(pb, avio_rb16(pb));
            }
        }
373
    } else {
Mans Rullgard's avatar
Mans Rullgard committed
374
        int fps;
375
        if (avio_rl32(pb) != MKTAG('V', 'I', 'D', 'O')) {
376
        fail1:
377
            av_log(s, AV_LOG_WARNING, "Unsupported stream type %08x\n", v);
378 379
            goto skip;
        }
380 381 382
        st->codecpar->codec_tag = avio_rl32(pb);
        st->codecpar->codec_id  = ff_codec_get_id(ff_rm_codec_tags,
                                                  st->codecpar->codec_tag);
383 384
        av_log(s, AV_LOG_TRACE, "%"PRIX32" %X\n",
               st->codecpar->codec_tag, MKTAG('R', 'V', '2', '0'));
385
        if (st->codecpar->codec_id == AV_CODEC_ID_NONE)
386
            goto fail1;
387 388
        st->codecpar->width  = avio_rb16(pb);
        st->codecpar->height = avio_rb16(pb);
389 390
        avio_skip(pb, 2); // looks like bits per sample
        avio_skip(pb, 4); // always zero?
391
        st->codecpar->codec_type = AVMEDIA_TYPE_VIDEO;
392
        st->need_parsing = AVSTREAM_PARSE_TIMESTAMPS;
393
        fps = avio_rb32(pb);
394

395
        if ((ret = rm_read_extradata(s, pb, st->codecpar, codec_data_size - (avio_tell(pb) - codec_pos))) < 0)
396
            return ret;
397

398 399 400
        if (fps > 0) {
            av_reduce(&st->avg_frame_rate.den, &st->avg_frame_rate.num,
                      0x10000, fps, (1 << 30) - 1);
401
#if FF_API_R_FRAME_RATE
402
            st->r_frame_rate = st->avg_frame_rate;
403
#endif
404 405 406 407
        } else if (s->error_recognition & AV_EF_EXPLODE) {
            av_log(s, AV_LOG_ERROR, "Invalid framerate\n");
            return AVERROR_INVALIDDATA;
        }
408 409 410 411
    }

skip:
    /* skip codec info */
412
    size = avio_tell(pb) - codec_pos;
413 414 415 416 417
    if (codec_data_size >= size) {
        avio_skip(pb, codec_data_size - size);
    } else {
        av_log(s, AV_LOG_WARNING, "codec_data_size %u < size %d\n", codec_data_size, size);
    }
418

419
    return 0;
420 421
}

422 423 424 425
/** this function assumes that the demuxer has already seeked to the start
 * of the INDX chunk, and will bail out if not. */
static int rm_read_index(AVFormatContext *s)
{
426
    AVIOContext *pb = s->pb;
427 428 429 430
    unsigned int size, n_pkts, str_id, next_off, n, pos, pts;
    AVStream *st;

    do {
431
        if (avio_rl32(pb) != MKTAG('I','N','D','X'))
432
            return -1;
433
        size     = avio_rb32(pb);
434 435
        if (size < 20)
            return -1;
436
        avio_skip(pb, 2);
437 438 439
        n_pkts   = avio_rb32(pb);
        str_id   = avio_rb16(pb);
        next_off = avio_rb32(pb);
440 441 442 443 444
        for (n = 0; n < s->nb_streams; n++)
            if (s->streams[n]->id == str_id) {
                st = s->streams[n];
                break;
            }
445 446 447 448
        if (n == s->nb_streams) {
            av_log(s, AV_LOG_ERROR,
                   "Invalid stream index %d for index at pos %"PRId64"\n",
                   str_id, avio_tell(pb));
449
            goto skip;
450 451 452
        } else if ((avio_size(pb) - avio_tell(pb)) / 14 < n_pkts) {
            av_log(s, AV_LOG_ERROR,
                   "Nr. of packets in packet index for stream index %d "
453
                   "exceeds filesize (%"PRId64" at %"PRId64" = %"PRId64")\n",
454 455 456 457
                   str_id, avio_size(pb), avio_tell(pb),
                   (avio_size(pb) - avio_tell(pb)) / 14);
            goto skip;
        }
458 459

        for (n = 0; n < n_pkts; n++) {
460
            avio_skip(pb, 2);
461 462
            pts = avio_rb32(pb);
            pos = avio_rb32(pb);
463
            avio_skip(pb, 4); /* packet no. */
464 465 466 467 468

            av_add_index_entry(st, pos, pts, 0, 0, AVINDEX_KEYFRAME);
        }

skip:
469 470 471 472
        if (next_off && avio_tell(pb) < next_off &&
            avio_seek(pb, next_off, SEEK_SET) < 0) {
            av_log(s, AV_LOG_ERROR,
                   "Non-linear index detected, not supported\n");
473
            return -1;
474
        }
475 476 477 478
    } while (next_off);

    return 0;
}
479

480
static int rm_read_header_old(AVFormatContext *s)
481
{
482
    RMDemuxContext *rm = s->priv_data;
483 484 485
    AVStream *st;

    rm->old_format = 1;
486
    st = avformat_new_stream(s, NULL);
487
    if (!st)
488
        return -1;
489
    st->priv_data = ff_rm_alloc_rmstream();
490 491
    if (!st->priv_data)
        return AVERROR(ENOMEM);
492
    return rm_read_audio_stream_info(s, s->pb, st, st->priv_data, 1);
493 494
}

495 496 497 498 499 500 501 502 503 504 505 506 507 508 509 510 511 512 513 514 515 516
static int rm_read_multi(AVFormatContext *s, AVIOContext *pb,
                         AVStream *st, char *mime)
{
    int number_of_streams = avio_rb16(pb);
    int number_of_mdpr;
    int i, ret;
    unsigned size2;
    for (i = 0; i<number_of_streams; i++)
        avio_rb16(pb);
    number_of_mdpr = avio_rb16(pb);
    if (number_of_mdpr != 1) {
        avpriv_request_sample(s, "MLTI with multiple (%d) MDPR", number_of_mdpr);
    }
    for (i = 0; i < number_of_mdpr; i++) {
        AVStream *st2;
        if (i > 0) {
            st2 = avformat_new_stream(s, NULL);
            if (!st2) {
                ret = AVERROR(ENOMEM);
                return ret;
            }
            st2->id = st->id + (i<<16);
517
            st2->codecpar->bit_rate = st->codecpar->bit_rate;
518 519
            st2->start_time = st->start_time;
            st2->duration   = st->duration;
520
            st2->codecpar->codec_type = AVMEDIA_TYPE_DATA;
521 522 523 524 525 526 527 528 529 530 531 532 533 534 535
            st2->priv_data = ff_rm_alloc_rmstream();
            if (!st2->priv_data)
                return AVERROR(ENOMEM);
        } else
            st2 = st;

        size2 = avio_rb32(pb);
        ret = ff_rm_read_mdpr_codecdata(s, s->pb, st2, st2->priv_data,
                                        size2, mime);
        if (ret < 0)
            return ret;
    }
    return 0;
}

536
static int rm_read_header(AVFormatContext *s)
Fabrice Bellard's avatar
Fabrice Bellard committed
537
{
538
    RMDemuxContext *rm = s->priv_data;
Fabrice Bellard's avatar
Fabrice Bellard committed
539
    AVStream *st;
540
    AVIOContext *pb = s->pb;
541
    unsigned int tag;
542
    int tag_size;
543
    unsigned int start_time, duration;
544
    unsigned int data_off = 0, indx_off = 0;
545
    char buf[128], mime[128];
546
    int flags = 0;
547
    int ret = -1;
548
    unsigned size, v;
549
    int64_t codec_pos;
Fabrice Bellard's avatar
Fabrice Bellard committed
550

551
    tag = avio_rl32(pb);
552 553
    if (tag == MKTAG('.', 'r', 'a', 0xfd)) {
        /* very old .ra format */
554
        return rm_read_header_old(s);
555
    } else if (tag != MKTAG('.', 'R', 'M', 'F')) {
556
        return AVERROR(EIO);
557
    }
Fabrice Bellard's avatar
Fabrice Bellard committed
558

559 560
    tag_size = avio_rb32(pb);
    avio_skip(pb, tag_size - 8);
561

Fabrice Bellard's avatar
Fabrice Bellard committed
562
    for(;;) {
563
        if (avio_feof(pb))
564
            goto fail;
565 566 567
        tag = avio_rl32(pb);
        tag_size = avio_rb32(pb);
        avio_rb16(pb);
568 569
        av_log(s, AV_LOG_TRACE, "tag=%s size=%d\n",
               av_fourcc2str(tag), tag_size);
570
        if (tag_size < 10 && tag != MKTAG('D', 'A', 'T', 'A'))
571
            goto fail;
Fabrice Bellard's avatar
Fabrice Bellard committed
572 573 574
        switch(tag) {
        case MKTAG('P', 'R', 'O', 'P'):
            /* file header */
575 576 577 578 579
            avio_rb32(pb); /* max bit rate */
            avio_rb32(pb); /* avg bit rate */
            avio_rb32(pb); /* max packet size */
            avio_rb32(pb); /* avg packet size */
            avio_rb32(pb); /* nb packets */
580 581
            duration = avio_rb32(pb); /* duration */
            s->duration = av_rescale(duration, AV_TIME_BASE, 1000);
582 583 584 585 586
            avio_rb32(pb); /* preroll */
            indx_off = avio_rb32(pb); /* index offset */
            data_off = avio_rb32(pb); /* data offset */
            avio_rb16(pb); /* nb streams */
            flags = avio_rb16(pb); /* flags */
Fabrice Bellard's avatar
Fabrice Bellard committed
587 588
            break;
        case MKTAG('C', 'O', 'N', 'T'):
589
            rm_read_metadata(s, pb, 1);
Fabrice Bellard's avatar
Fabrice Bellard committed
590 591
            break;
        case MKTAG('M', 'D', 'P', 'R'):
592
            st = avformat_new_stream(s, NULL);
593 594 595 596
            if (!st) {
                ret = AVERROR(ENOMEM);
                goto fail;
            }
597 598
            st->id = avio_rb16(pb);
            avio_rb32(pb); /* max bit rate */
599
            st->codecpar->bit_rate = avio_rb32(pb); /* bit rate */
600 601 602 603 604
            avio_rb32(pb); /* max packet size */
            avio_rb32(pb); /* avg packet size */
            start_time = avio_rb32(pb); /* start time */
            avio_rb32(pb); /* preroll */
            duration = avio_rb32(pb); /* duration */
605 606
            st->start_time = start_time;
            st->duration = duration;
607 608
            if(duration>0)
                s->duration = AV_NOPTS_VALUE;
Fabrice Bellard's avatar
Fabrice Bellard committed
609
            get_str8(pb, buf, sizeof(buf)); /* desc */
610
            get_str8(pb, mime, sizeof(mime)); /* mimetype */
611
            st->codecpar->codec_type = AVMEDIA_TYPE_DATA;
612
            st->priv_data = ff_rm_alloc_rmstream();
613 614
            if (!st->priv_data)
                return AVERROR(ENOMEM);
615 616

            size = avio_rb32(pb);
617
            codec_pos = avio_tell(pb);
618 619 620 621

            ffio_ensure_seekback(pb, 4);
            v = avio_rb32(pb);
            if (v == MKBETAG('M', 'L', 'T', 'I')) {
622 623 624
                ret = rm_read_multi(s, s->pb, st, mime);
                if (ret < 0)
                    goto fail;
625 626
                avio_seek(pb, codec_pos + size, SEEK_SET);
            } else {
627
                avio_skip(pb, -4);
628 629 630 631
                if (ff_rm_read_mdpr_codecdata(s, s->pb, st, st->priv_data,
                                              size, mime) < 0)
                    goto fail;
            }
632

Fabrice Bellard's avatar
Fabrice Bellard committed
633 634 635 636 637
            break;
        case MKTAG('D', 'A', 'T', 'A'):
            goto header_end;
        default:
            /* unknown tag: skip it */
638
            avio_skip(pb, tag_size - 10);
Fabrice Bellard's avatar
Fabrice Bellard committed
639 640 641 642
            break;
        }
    }
 header_end:
643
    rm->nb_packets = avio_rb32(pb); /* number of packets */
644 645
    if (!rm->nb_packets && (flags & 4))
        rm->nb_packets = 3600 * 25;
646
    avio_rb32(pb); /* next data header */
647 648

    if (!data_off)
649
        data_off = avio_tell(pb) - 18;
650 651
    if (indx_off && (pb->seekable & AVIO_SEEKABLE_NORMAL) &&
        !(s->flags & AVFMT_FLAG_IGNIDX) &&
652
        avio_seek(pb, indx_off, SEEK_SET) >= 0) {
653
        rm_read_index(s);
654
        avio_seek(pb, data_off + 18, SEEK_SET);
655 656
    }

Fabrice Bellard's avatar
Fabrice Bellard committed
657
    return 0;
658 659 660 661

fail:
    rm_read_close(s);
    return ret;
Fabrice Bellard's avatar
Fabrice Bellard committed
662 663
}

664
static int get_num(AVIOContext *pb, int *len)
665 666 667
{
    int n, n1;

668
    n = avio_rb16(pb);
669
    (*len)-=2;
670
    n &= 0x7FFF;
671 672 673
    if (n >= 0x4000) {
        return n - 0x4000;
    } else {
674
        n1 = avio_rb16(pb);
675 676 677 678 679
        (*len)-=2;
        return (n << 16) | n1;
    }
}

680 681 682
/* multiple of 20 bytes for ra144 (ugly) */
#define RAW_PACKET_SIZE 1000

683
static int rm_sync(AVFormatContext *s, int64_t *timestamp, int *flags, int *stream_index, int64_t *pos){
684
    RMDemuxContext *rm = s->priv_data;
685
    AVIOContext *pb = s->pb;
Michael Niedermayer's avatar
Michael Niedermayer committed
686
    AVStream *st;
Michael Niedermayer's avatar
Michael Niedermayer committed
687
    uint32_t state=0xFFFFFFFF;
Michael Niedermayer's avatar
Michael Niedermayer committed
688

689
    while(!avio_feof(pb)){
690
        int len, num, i;
691
        int mlti_id;
692
        *pos= avio_tell(pb) - 3;
Michael Niedermayer's avatar
Michael Niedermayer committed
693 694
        if(rm->remaining_len > 0){
            num= rm->current_stream;
695
            mlti_id = 0;
Michael Niedermayer's avatar
Michael Niedermayer committed
696 697 698 699
            len= rm->remaining_len;
            *timestamp = AV_NOPTS_VALUE;
            *flags= 0;
        }else{
700
            state= (state<<8) + avio_r8(pb);
701

Michael Niedermayer's avatar
Michael Niedermayer committed
702
            if(state == MKBETAG('I', 'N', 'D', 'X')){
703
                int n_pkts, expected_len;
704
                len = avio_rb32(pb);
705
                avio_skip(pb, 2);
706
                n_pkts = avio_rb32(pb);
707 708 709 710 711 712 713 714 715
                expected_len = 20 + n_pkts * 14;
                if (len == 20)
                    /* some files don't add index entries to chunk size... */
                    len = expected_len;
                else if (len != expected_len)
                    av_log(s, AV_LOG_WARNING,
                           "Index size %d (%d pkts) is wrong, should be %d.\n",
                           len, n_pkts, expected_len);
                len -= 14; // we already read part of the index header
Michael Niedermayer's avatar
Michael Niedermayer committed
716 717 718
                if(len<0)
                    continue;
                goto skip;
719 720 721
            } else if (state == MKBETAG('D','A','T','A')) {
                av_log(s, AV_LOG_WARNING,
                       "DATA tag in middle of chunk, file may be broken.\n");
Michael Niedermayer's avatar
Michael Niedermayer committed
722
            }
723

724
            if(state > (unsigned)0xFFFF || state <= 12)
Michael Niedermayer's avatar
Michael Niedermayer committed
725
                continue;
726
            len=state - 12;
Michael Niedermayer's avatar
Michael Niedermayer committed
727 728
            state= 0xFFFFFFFF;

729 730
            num = avio_rb16(pb);
            *timestamp = avio_rb32(pb);
731 732
            mlti_id = (avio_r8(pb)>>1)-1<<16;
            mlti_id = FFMAX(mlti_id, 0);
733
            *flags = avio_r8(pb); /* flags */
Michael Niedermayer's avatar
Michael Niedermayer committed
734 735 736
        }
        for(i=0;i<s->nb_streams;i++) {
            st = s->streams[i];
737
            if (mlti_id + num == st->id)
Michael Niedermayer's avatar
Michael Niedermayer committed
738 739 740
                break;
        }
        if (i == s->nb_streams) {
Michael Niedermayer's avatar
Michael Niedermayer committed
741
skip:
Michael Niedermayer's avatar
Michael Niedermayer committed
742
            /* skip packet if unknown number */
743
            avio_skip(pb, len);
744
            rm->remaining_len = 0;
Michael Niedermayer's avatar
Michael Niedermayer committed
745 746 747
            continue;
        }
        *stream_index= i;
748

Michael Niedermayer's avatar
Michael Niedermayer committed
749 750 751 752 753
        return len;
    }
    return -1;
}

754
static int rm_assemble_video_frame(AVFormatContext *s, AVIOContext *pb,
755
                                   RMDemuxContext *rm, RMStream *vst,
756 757
                                   AVPacket *pkt, int len, int *pseq,
                                   int64_t *timestamp)
758
{
759
    int hdr;
760
    int seq = 0, pic_num = 0, len2 = 0, pos = 0; //init to silence compiler warning
761
    int type;
762
    int ret;
763

764
    hdr = avio_r8(pb); len--;
765
    type = hdr >> 6;
766 767

    if(type != 3){  // not frame as a part of packet
768
        seq = avio_r8(pb); len--;
769 770
    }
    if(type != 1){  // not whole frame
771
        len2 = get_num(pb, &len);
772
        pos  = get_num(pb, &len);
773
        pic_num = avio_r8(pb); len--;
774
    }
775
    if(len<0) {
776
        av_log(s, AV_LOG_ERROR, "Insufficient data\n");
777
        return -1;
778
    }
779 780
    rm->remaining_len = len;
    if(type&1){     // frame, not slice
781
        if(type == 3){  // frame as a part of packet
782
            len= len2;
783 784
            *timestamp = pos;
        }
785
        if(rm->remaining_len < len) {
786
            av_log(s, AV_LOG_ERROR, "Insufficient remaining len\n");
787
            return -1;
788
        }
789
        rm->remaining_len -= len;
790 791 792 793 794
        if(av_new_packet(pkt, len + 9) < 0)
            return AVERROR(EIO);
        pkt->data[0] = 0;
        AV_WL32(pkt->data + 1, 1);
        AV_WL32(pkt->data + 5, 0);
795
        if ((ret = avio_read(pb, pkt->data + 9, len)) != len) {
796
            av_packet_unref(pkt);
797
            av_log(s, AV_LOG_ERROR, "Failed to read %d bytes\n", len);
798 799
            return ret < 0 ? ret : AVERROR(EIO);
        }
800 801 802 803
        return 0;
    }
    //now we have to deal with single slice

804
    *pseq = seq;
805
    if((seq & 0x7F) == 1 || vst->curpic_num != pic_num){
806 807 808 809
        if (len2 > ffio_limit(pb, len2)) {
            av_log(s, AV_LOG_ERROR, "Impossibly sized packet\n");
            return AVERROR_INVALIDDATA;
        }
810 811
        vst->slices = ((hdr & 0x3F) << 1) + 1;
        vst->videobufsize = len2 + 8*vst->slices + 1;
812
        av_packet_unref(&vst->pkt); //FIXME this should be output.
813
        if(av_new_packet(&vst->pkt, vst->videobufsize) < 0)
814
            return AVERROR(ENOMEM);
815
        memset(vst->pkt.data, 0, vst->pkt.size);
816 817 818
        vst->videobufpos = 8*vst->slices + 1;
        vst->cur_slice = 0;
        vst->curpic_num = pic_num;
819
        vst->pktpos = avio_tell(pb);
820
    }
Roberto Togni's avatar
Roberto Togni committed
821
    if(type == 2)
822 823
        len = FFMIN(len, pos);

824 825
    if(++vst->cur_slice > vst->slices) {
        av_log(s, AV_LOG_ERROR, "cur slice %d, too large\n", vst->cur_slice);
826
        return 1;
827
    }
828 829
    if(!vst->pkt.data)
        return AVERROR(ENOMEM);
830 831
    AV_WL32(vst->pkt.data - 7 + 8*vst->cur_slice, 1);
    AV_WL32(vst->pkt.data - 3 + 8*vst->cur_slice, vst->videobufpos - 8*vst->slices - 1);
832 833
    if(vst->videobufpos + len > vst->videobufsize) {
        av_log(s, AV_LOG_ERROR, "outside videobufsize\n");
834
        return 1;
835
    }
836
    if (avio_read(pb, vst->pkt.data + vst->videobufpos, len) != len)
837
        return AVERROR(EIO);
838
    vst->videobufpos += len;
839 840
    rm->remaining_len-= len;

841
    if (type == 2 || vst->videobufpos == vst->videobufsize) {
842 843
        vst->pkt.data[0] = vst->cur_slice-1;
        *pkt= vst->pkt;
844
        vst->pkt.data= NULL;
845
        vst->pkt.size= 0;
846
        vst->pkt.buf = NULL;
847
        if(vst->slices != vst->cur_slice) //FIXME find out how to set slices correct from the begin
848
            memmove(pkt->data + 1 + 8*vst->cur_slice, pkt->data + 1 + 8*vst->slices,
849
                vst->videobufpos - 1 - 8*vst->slices);
850
        pkt->size = vst->videobufpos + 8*(vst->cur_slice - vst->slices);
851 852
        pkt->pts = AV_NOPTS_VALUE;
        pkt->pos = vst->pktpos;
853
        vst->slices = 0;
854
        return 0;
855 856 857 858 859
    }

    return 1;
}

860 861 862 863 864 865
static inline void
rm_ac3_swap_bytes (AVStream *st, AVPacket *pkt)
{
    uint8_t *ptr;
    int j;

866
    if (st->codecpar->codec_id == AV_CODEC_ID_AC3) {
867 868 869 870 871 872 873 874
        ptr = pkt->data;
        for (j=0;j<pkt->size;j+=2) {
            FFSWAP(int, ptr[0], ptr[1]);
            ptr += 2;
        }
    }
}

875 876 877 878 879 880 881 882 883 884
static int readfull(AVFormatContext *s, AVIOContext *pb, uint8_t *dst, int n) {
    int ret = avio_read(pb, dst, n);
    if (ret != n) {
        if (ret >= 0) memset(dst + ret, 0, n - ret);
        else          memset(dst      , 0, n);
        av_log(s, AV_LOG_ERROR, "Failed to fully read block\n");
    }
    return ret;
}

885
int
886
ff_rm_parse_packet (AVFormatContext *s, AVIOContext *pb,
887
                    AVStream *st, RMStream *ast, int len, AVPacket *pkt,
888
                    int *seq, int flags, int64_t timestamp)
889
{
890
    RMDemuxContext *rm = s->priv_data;
891
    int ret;
892

893
    if (st->codecpar->codec_type == AVMEDIA_TYPE_VIDEO) {
894
        rm->current_stream= st->id;
895 896
        ret = rm_assemble_video_frame(s, pb, rm, ast, pkt, len, seq, &timestamp);
        if(ret)
897
            return ret < 0 ? ret : -1; //got partial frame or error
898
    } else if (st->codecpar->codec_type == AVMEDIA_TYPE_AUDIO) {
899 900 901
        if ((ast->deint_id == DEINT_ID_GENR) ||
            (ast->deint_id == DEINT_ID_INT4) ||
            (ast->deint_id == DEINT_ID_SIPR)) {
902
            int x;
903 904 905 906 907
            int sps = ast->sub_packet_size;
            int cfs = ast->coded_framesize;
            int h = ast->sub_packet_h;
            int y = ast->sub_packet_cnt;
            int w = ast->audio_framesize;
908

909
            if (flags & 2)
910
                y = ast->sub_packet_cnt = 0;
911
            if (!y)
912
                ast->audiotimestamp = timestamp;
913

914 915
            switch (ast->deint_id) {
                case DEINT_ID_INT4:
916
                    for (x = 0; x < h/2; x++)
917
                        readfull(s, pb, ast->pkt.data+x*2*w+y*cfs, cfs);
918
                    break;
919
                case DEINT_ID_GENR:
920
                    for (x = 0; x < w/sps; x++)
921
                        readfull(s, pb, ast->pkt.data+sps*(h*x+((h+1)/2)*(y&1)+(y>>1)), sps);
922
                    break;
923
                case DEINT_ID_SIPR:
924
                    readfull(s, pb, ast->pkt.data + y * w, w);
925
                    break;
926 927
            }

928
            if (++(ast->sub_packet_cnt) < h)
929
                return -1;
930
            if (ast->deint_id == DEINT_ID_SIPR)
931
                ff_rm_reorder_sipr_data(ast->pkt.data, h, w);
932

933 934
             ast->sub_packet_cnt = 0;
             rm->audio_stream_num = st->index;
935 936 937 938
            if (st->codecpar->block_align <= 0) {
                av_log(s, AV_LOG_ERROR, "Invalid block alignment %d\n", st->codecpar->block_align);
                return AVERROR_INVALIDDATA;
            }
939
             rm->audio_pkt_cnt = h * w / st->codecpar->block_align;
940 941
        } else if ((ast->deint_id == DEINT_ID_VBRF) ||
                   (ast->deint_id == DEINT_ID_VBRS)) {
942 943
            int x;
            rm->audio_stream_num = st->index;
944
            ast->sub_packet_cnt = (avio_rb16(pb) & 0xf0) >> 4;
945 946
            if (ast->sub_packet_cnt) {
                for (x = 0; x < ast->sub_packet_cnt; x++)
947
                    ast->sub_packet_lengths[x] = avio_rb16(pb);
948
                rm->audio_pkt_cnt = ast->sub_packet_cnt;
949
                ast->audiotimestamp = timestamp;
950 951
            } else
                return -1;
952
        } else {
953 954
            if ((ret = av_get_packet(pb, pkt, len)) < 0)
                return ret;
955
            rm_ac3_swap_bytes(st, pkt);
956
        }
957 958 959 960
    } else {
        if ((ret = av_get_packet(pb, pkt, len)) < 0)
            return ret;
    }
961 962 963

    pkt->stream_index = st->index;

964
    pkt->pts = timestamp;
965
    if (flags & 2)
966
        pkt->flags |= AV_PKT_FLAG_KEY;
967

968
    return st->codecpar->codec_type == AVMEDIA_TYPE_AUDIO ? rm->audio_pkt_cnt : 0;
969 970
}

971
int
972
ff_rm_retrieve_cache (AVFormatContext *s, AVIOContext *pb,
973
                      AVStream *st, RMStream *ast, AVPacket *pkt)
974
{
975
    RMDemuxContext *rm = s->priv_data;
976

977
    av_assert0 (rm->audio_pkt_cnt > 0);
978

979
    if (ast->deint_id == DEINT_ID_VBRF ||
980 981 982 983 984
        ast->deint_id == DEINT_ID_VBRS) {
        int ret = av_get_packet(pb, pkt, ast->sub_packet_lengths[ast->sub_packet_cnt - rm->audio_pkt_cnt]);
        if (ret < 0)
            return ret;
    } else {
985
        int ret = av_new_packet(pkt, st->codecpar->block_align);
986 987
        if (ret < 0)
            return ret;
988 989 990
        memcpy(pkt->data, ast->pkt.data + st->codecpar->block_align * //FIXME avoid this
               (ast->sub_packet_h * ast->audio_framesize / st->codecpar->block_align - rm->audio_pkt_cnt),
               st->codecpar->block_align);
991 992
    }
    rm->audio_pkt_cnt--;
993 994
    if ((pkt->pts = ast->audiotimestamp) != AV_NOPTS_VALUE) {
        ast->audiotimestamp = AV_NOPTS_VALUE;
995
        pkt->flags = AV_PKT_FLAG_KEY;
996
    } else
997
        pkt->flags = 0;
998
    pkt->stream_index = st->index;
999 1000

    return rm->audio_pkt_cnt;
1001 1002
}

Fabrice Bellard's avatar
Fabrice Bellard committed
1003 1004
static int rm_read_packet(AVFormatContext *s, AVPacket *pkt)
{
1005
    RMDemuxContext *rm = s->priv_data;
1006
    AVStream *st = NULL; // init to silence compiler warning
1007
    int i, len, res, seq = 1;
1008
    int64_t timestamp, pos;
1009
    int flags;
Fabrice Bellard's avatar
Fabrice Bellard committed
1010

1011
    for (;;) {
1012 1013 1014
        if (rm->audio_pkt_cnt) {
            // If there are queued audio packet return them first
            st = s->streams[rm->audio_stream_num];
1015 1016 1017
            res = ff_rm_retrieve_cache(s, s->pb, st, st->priv_data, pkt);
            if(res < 0)
                return res;
1018
            flags = 0;
1019 1020
        } else {
            if (rm->old_format) {
1021
                RMStream *ast;
Ronald S. Bultje's avatar
Ronald S. Bultje committed
1022

1023 1024
                st = s->streams[0];
                ast = st->priv_data;
1025 1026 1027 1028
                timestamp = AV_NOPTS_VALUE;
                len = !ast->audio_framesize ? RAW_PACKET_SIZE :
                    ast->coded_framesize * ast->sub_packet_h / 2;
                flags = (seq++ == 1) ? 2 : 0;
1029
                pos = avio_tell(s->pb);
1030
            } else {
1031
                len = rm_sync(s, &timestamp, &flags, &i, &pos);
1032 1033
                if (len > 0)
                    st = s->streams[i];
1034 1035
            }

1036 1037 1038
            if (avio_feof(s->pb))
                return AVERROR_EOF;
            if (len <= 0)
1039
                return AVERROR(EIO);
Michael Niedermayer's avatar
Michael Niedermayer committed
1040

1041
            res = ff_rm_parse_packet (s, s->pb, st, st->priv_data, len, pkt,
1042
                                      &seq, flags, timestamp);
1043 1044
            if (res < -1)
                return res;
1045
            if((flags&2) && (seq&0x7F) == 1)
1046
                av_add_index_entry(st, pos, timestamp, 0, 0, AVINDEX_KEYFRAME);
1047 1048 1049
            if (res)
                continue;
        }
Michael Niedermayer's avatar
Michael Niedermayer committed
1050

1051 1052
        if(  (st->discard >= AVDISCARD_NONKEY && !(flags&2))
           || st->discard >= AVDISCARD_ALL){
1053
            av_packet_unref(pkt);
1054 1055
        } else
            break;
1056 1057
    }

Fabrice Bellard's avatar
Fabrice Bellard committed
1058 1059 1060 1061 1062
    return 0;
}

static int rm_read_close(AVFormatContext *s)
{
1063 1064 1065 1066
    int i;

    for (i=0;i<s->nb_streams;i++)
        ff_rm_free_rmstream(s->streams[i]->priv_data);
1067

Fabrice Bellard's avatar
Fabrice Bellard committed
1068 1069 1070
    return 0;
}

Fabrice Bellard's avatar
Fabrice Bellard committed
1071 1072 1073
static int rm_probe(AVProbeData *p)
{
    /* check file header */
1074 1075 1076 1077 1078
    if ((p->buf[0] == '.' && p->buf[1] == 'R' &&
         p->buf[2] == 'M' && p->buf[3] == 'F' &&
         p->buf[4] == 0 && p->buf[5] == 0) ||
        (p->buf[0] == '.' && p->buf[1] == 'r' &&
         p->buf[2] == 'a' && p->buf[3] == 0xfd))
Fabrice Bellard's avatar
Fabrice Bellard committed
1079 1080 1081 1082 1083
        return AVPROBE_SCORE_MAX;
    else
        return 0;
}

1084
static int64_t rm_read_dts(AVFormatContext *s, int stream_index,
Michael Niedermayer's avatar
Michael Niedermayer committed
1085 1086
                               int64_t *ppos, int64_t pos_limit)
{
1087
    RMDemuxContext *rm = s->priv_data;
Michael Niedermayer's avatar
Michael Niedermayer committed
1088
    int64_t pos, dts;
1089
    int stream_index2, flags, len, h;
Michael Niedermayer's avatar
Michael Niedermayer committed
1090 1091

    pos = *ppos;
1092

Michael Niedermayer's avatar
Michael Niedermayer committed
1093 1094 1095
    if(rm->old_format)
        return AV_NOPTS_VALUE;

1096 1097 1098
    if (avio_seek(s->pb, pos, SEEK_SET) < 0)
        return AV_NOPTS_VALUE;

Michael Niedermayer's avatar
Michael Niedermayer committed
1099 1100
    rm->remaining_len=0;
    for(;;){
1101 1102 1103
        int seq=1;
        AVStream *st;

1104
        len = rm_sync(s, &dts, &flags, &stream_index2, &pos);
Michael Niedermayer's avatar
Michael Niedermayer committed
1105 1106
        if(len<0)
            return AV_NOPTS_VALUE;
1107 1108

        st = s->streams[stream_index2];
1109
        if (st->codecpar->codec_type == AVMEDIA_TYPE_VIDEO) {
1110
            h= avio_r8(s->pb); len--;
1111
            if(!(h & 0x40)){
1112
                seq = avio_r8(s->pb); len--;
Michael Niedermayer's avatar
Michael Niedermayer committed
1113 1114
            }
        }
1115

1116
        if((flags&2) && (seq&0x7F) == 1){
1117
            av_log(s, AV_LOG_TRACE, "%d %d-%d %"PRId64" %d\n",
1118
                    flags, stream_index2, stream_index, dts, seq);
1119
            av_add_index_entry(st, pos, dts, 0, 0, AVINDEX_KEYFRAME);
1120 1121 1122 1123
            if(stream_index2 == stream_index)
                break;
        }

1124
        avio_skip(s->pb, len);
Michael Niedermayer's avatar
Michael Niedermayer committed
1125 1126 1127 1128 1129
    }
    *ppos = pos;
    return dts;
}

1130 1131 1132 1133 1134 1135 1136 1137 1138 1139 1140 1141
static int rm_read_seek(AVFormatContext *s, int stream_index,
                        int64_t pts, int flags)
{
    RMDemuxContext *rm = s->priv_data;

    if (ff_seek_frame_binary(s, stream_index, pts, flags) < 0)
        return -1;
    rm->audio_pkt_cnt = 0;
    return 0;
}


1142
AVInputFormat ff_rm_demuxer = {
1143
    .name           = "rm",
1144
    .long_name      = NULL_IF_CONFIG_SMALL("RealMedia"),
1145 1146 1147 1148 1149 1150
    .priv_data_size = sizeof(RMDemuxContext),
    .read_probe     = rm_probe,
    .read_header    = rm_read_header,
    .read_packet    = rm_read_packet,
    .read_close     = rm_read_close,
    .read_timestamp = rm_read_dts,
1151
    .read_seek      = rm_read_seek,
Fabrice Bellard's avatar
Fabrice Bellard committed
1152
};
1153

1154
AVInputFormat ff_rdt_demuxer = {
1155 1156 1157 1158
    .name           = "rdt",
    .long_name      = NULL_IF_CONFIG_SMALL("RDT demuxer"),
    .priv_data_size = sizeof(RMDemuxContext),
    .read_close     = rm_read_close,
1159
    .flags          = AVFMT_NOFILE,
1160
};
1161 1162 1163 1164 1165 1166 1167 1168 1169 1170 1171 1172 1173

static int ivr_probe(AVProbeData *p)
{
    if (memcmp(p->buf, ".R1M\x0\x1\x1", 7) &&
        memcmp(p->buf, ".REC", 4))
        return 0;

    return AVPROBE_SCORE_MAX;
}

static int ivr_read_header(AVFormatContext *s)
{
    unsigned tag, type, len, tlen, value;
1174
    int i, j, n, count, nb_streams = 0, ret;
1175 1176 1177 1178 1179 1180 1181 1182 1183 1184 1185 1186 1187 1188 1189 1190 1191 1192 1193 1194 1195 1196 1197 1198 1199 1200 1201 1202 1203 1204 1205 1206 1207 1208 1209 1210 1211 1212 1213 1214 1215 1216 1217 1218 1219 1220 1221 1222 1223 1224 1225 1226 1227 1228 1229 1230 1231 1232 1233 1234 1235 1236 1237 1238 1239 1240 1241 1242 1243 1244 1245 1246 1247 1248 1249 1250 1251 1252 1253 1254 1255 1256 1257 1258 1259 1260 1261 1262 1263 1264 1265 1266 1267 1268 1269 1270 1271 1272 1273 1274 1275 1276 1277 1278 1279 1280 1281 1282 1283 1284 1285 1286 1287 1288 1289 1290 1291 1292 1293 1294 1295 1296 1297 1298 1299 1300 1301 1302 1303 1304 1305 1306 1307 1308 1309 1310 1311 1312 1313 1314 1315 1316 1317 1318 1319 1320 1321 1322 1323 1324 1325 1326 1327 1328 1329 1330 1331 1332 1333 1334 1335 1336 1337 1338 1339 1340 1341 1342 1343 1344 1345 1346 1347 1348 1349 1350 1351
    uint8_t key[256], val[256];
    AVIOContext *pb = s->pb;
    AVStream *st;
    int64_t pos, offset, temp;

    pos = avio_tell(pb);
    tag = avio_rl32(pb);
    if (tag == MKTAG('.','R','1','M')) {
        if (avio_rb16(pb) != 1)
            return AVERROR_INVALIDDATA;
        if (avio_r8(pb) != 1)
            return AVERROR_INVALIDDATA;
        len = avio_rb32(pb);
        avio_skip(pb, len);
        avio_skip(pb, 5);
        temp = avio_rb64(pb);
        while (!avio_feof(pb) && temp) {
            offset = temp;
            temp = avio_rb64(pb);
        }
        avio_skip(pb, offset - avio_tell(pb));
        if (avio_r8(pb) != 1)
            return AVERROR_INVALIDDATA;
        len = avio_rb32(pb);
        avio_skip(pb, len);
        if (avio_r8(pb) != 2)
            return AVERROR_INVALIDDATA;
        avio_skip(pb, 16);
        pos = avio_tell(pb);
        tag = avio_rl32(pb);
    }

    if (tag != MKTAG('.','R','E','C'))
        return AVERROR_INVALIDDATA;

    if (avio_r8(pb) != 0)
        return AVERROR_INVALIDDATA;
    count = avio_rb32(pb);
    for (i = 0; i < count; i++) {
        if (avio_feof(pb))
            return AVERROR_INVALIDDATA;

        type = avio_r8(pb);
        tlen = avio_rb32(pb);
        avio_get_str(pb, tlen, key, sizeof(key));
        len = avio_rb32(pb);
        if (type == 5) {
            avio_get_str(pb, len, val, sizeof(val));
            av_log(s, AV_LOG_DEBUG, "%s = '%s'\n", key, val);
        } else if (type == 4) {
            av_log(s, AV_LOG_DEBUG, "%s = '0x", key);
            for (j = 0; j < len; j++)
                av_log(s, AV_LOG_DEBUG, "%X", avio_r8(pb));
            av_log(s, AV_LOG_DEBUG, "'\n");
        } else if (len == 4 && type == 3 && !strncmp(key, "StreamCount", tlen)) {
            nb_streams = value = avio_rb32(pb);
        } else if (len == 4 && type == 3) {
            value = avio_rb32(pb);
            av_log(s, AV_LOG_DEBUG, "%s = %d\n", key, value);
        } else {
            av_log(s, AV_LOG_DEBUG, "Skipping unsupported key: %s\n", key);
            avio_skip(pb, len);
        }
    }

    for (n = 0; n < nb_streams; n++) {
        st = avformat_new_stream(s, NULL);
        if (!st)
            return AVERROR(ENOMEM);
        st->priv_data = ff_rm_alloc_rmstream();
        if (!st->priv_data)
            return AVERROR(ENOMEM);

        if (avio_r8(pb) != 1)
            return AVERROR_INVALIDDATA;

        count = avio_rb32(pb);
        for (i = 0; i < count; i++) {
            if (avio_feof(pb))
                return AVERROR_INVALIDDATA;

            type = avio_r8(pb);
            tlen  = avio_rb32(pb);
            avio_get_str(pb, tlen, key, sizeof(key));
            len  = avio_rb32(pb);
            if (type == 5) {
                avio_get_str(pb, len, val, sizeof(val));
                av_log(s, AV_LOG_DEBUG, "%s = '%s'\n", key, val);
            } else if (type == 4 && !strncmp(key, "OpaqueData", tlen)) {
                ret = ffio_ensure_seekback(pb, 4);
                if (ret < 0)
                    return ret;
                if (avio_rb32(pb) == MKBETAG('M', 'L', 'T', 'I')) {
                    ret = rm_read_multi(s, pb, st, NULL);
                } else {
                    avio_seek(pb, -4, SEEK_CUR);
                    ret = ff_rm_read_mdpr_codecdata(s, pb, st, st->priv_data, len, NULL);
                }

                if (ret < 0)
                    return ret;
            } else if (type == 4) {
                int j;

                av_log(s, AV_LOG_DEBUG, "%s = '0x", key);
                for (j = 0; j < len; j++)
                    av_log(s, AV_LOG_DEBUG, "%X", avio_r8(pb));
                av_log(s, AV_LOG_DEBUG, "'\n");
            } else if (len == 4 && type == 3 && !strncmp(key, "Duration", tlen)) {
                st->duration = avio_rb32(pb);
            } else if (len == 4 && type == 3) {
                value = avio_rb32(pb);
                av_log(s, AV_LOG_DEBUG, "%s = %d\n", key, value);
            } else {
                av_log(s, AV_LOG_DEBUG, "Skipping unsupported key: %s\n", key);
                avio_skip(pb, len);
            }
        }
    }

    if (avio_r8(pb) != 6)
        return AVERROR_INVALIDDATA;
    avio_skip(pb, 12);
    avio_skip(pb, avio_rb64(pb) + pos - avio_tell(s->pb));
    if (avio_r8(pb) != 8)
        return AVERROR_INVALIDDATA;
    avio_skip(pb, 8);

    return 0;
}

static int ivr_read_packet(AVFormatContext *s, AVPacket *pkt)
{
    RMDemuxContext *rm = s->priv_data;
    int ret = AVERROR_EOF, opcode;
    AVIOContext *pb = s->pb;
    unsigned size, index;
    int64_t pos, pts;

    if (avio_feof(pb) || rm->data_end)
        return AVERROR_EOF;

    pos = avio_tell(pb);

    for (;;) {
        if (rm->audio_pkt_cnt) {
            // If there are queued audio packet return them first
            AVStream *st;

            st = s->streams[rm->audio_stream_num];
            ret = ff_rm_retrieve_cache(s, pb, st, st->priv_data, pkt);
            if (ret < 0) {
                return ret;
            }
        } else {
            if (rm->remaining_len) {
                avio_skip(pb, rm->remaining_len);
                rm->remaining_len = 0;
            }

            if (avio_feof(pb))
                return AVERROR_EOF;

            opcode = avio_r8(pb);
            if (opcode == 2) {
                AVStream *st;
                int seq = 1;

                pts = avio_rb32(pb);
                index = avio_rb16(pb);
                if (index >= s->nb_streams)
                    return AVERROR_INVALIDDATA;

                avio_skip(pb, 4);
                size = avio_rb32(pb);
                avio_skip(pb, 4);

1352
                if (size < 1 || size > INT_MAX/4) {
1353
                    av_log(s, AV_LOG_ERROR, "size %u is invalid\n", size);
1354 1355 1356
                    return AVERROR_INVALIDDATA;
                }

1357 1358 1359 1360 1361 1362 1363 1364 1365 1366 1367 1368 1369 1370 1371 1372 1373 1374 1375
                st = s->streams[index];
                ret = ff_rm_parse_packet(s, pb, st, st->priv_data, size, pkt,
                                         &seq, 0, pts);
                if (ret < -1) {
                    return ret;
                } else if (ret) {
                    continue;
                }

                pkt->pos = pos;
                pkt->pts = pts;
                pkt->stream_index = index;
            } else if (opcode == 7) {
                pos = avio_rb64(pb);
                if (!pos) {
                    rm->data_end = 1;
                    return AVERROR_EOF;
                }
            } else {
1376
                av_log(s, AV_LOG_ERROR, "Unsupported opcode=%d at %"PRIX64"\n", opcode, avio_tell(pb) - 1);
1377 1378 1379 1380 1381 1382 1383 1384 1385 1386 1387 1388 1389 1390 1391 1392 1393
                return AVERROR(EIO);
            }
        }

        break;
    }

    return ret;
}

AVInputFormat ff_ivr_demuxer = {
    .name           = "ivr",
    .long_name      = NULL_IF_CONFIG_SMALL("IVR (Internet Video Recording)"),
    .priv_data_size = sizeof(RMDemuxContext),
    .read_probe     = ivr_probe,
    .read_header    = ivr_read_header,
    .read_packet    = ivr_read_packet,
1394
    .read_close     = rm_read_close,
1395 1396
    .extensions     = "ivr",
};