rmdec.c 45.8 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 240 241 242 243
            } else {
                if(sub_packet_size <= 0){
                    av_log(s, AV_LOG_ERROR, "sub_packet_size is invalid\n");
                    return -1;
                }
244
                st->codecpar->block_align = ast->sub_packet_size;
245
            }
246
            if ((ret = rm_read_extradata(s, pb, st->codecpar, codecdata_length)) < 0)
247
                return ret;
248

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

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

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

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

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

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

341 342 343
        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,
344
                                                st->codecpar->codec_tag);
345
    } else if(mime && !strcmp(mime, "logical-fileinfo")){
346
        int stream_count, rule_count, property_count, i;
347 348 349 350 351 352 353 354 355 356 357 358 359 360 361 362 363 364 365 366 367 368 369 370 371
        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));
            }
        }
372
    } else {
Mans Rullgard's avatar
Mans Rullgard committed
373
        int fps;
374
        if (avio_rl32(pb) != MKTAG('V', 'I', 'D', 'O')) {
375
        fail1:
376
            av_log(s, AV_LOG_WARNING, "Unsupported stream type %08x\n", v);
377 378
            goto skip;
        }
379 380 381 382 383
        st->codecpar->codec_tag = avio_rl32(pb);
        st->codecpar->codec_id  = ff_codec_get_id(ff_rm_codec_tags,
                                                  st->codecpar->codec_tag);
        av_log(s, AV_LOG_TRACE, "%X %X\n", st->codecpar->codec_tag, MKTAG('R', 'V', '2', '0'));
        if (st->codecpar->codec_id == AV_CODEC_ID_NONE)
384
            goto fail1;
385 386
        st->codecpar->width  = avio_rb16(pb);
        st->codecpar->height = avio_rb16(pb);
387 388
        avio_skip(pb, 2); // looks like bits per sample
        avio_skip(pb, 4); // always zero?
389
        st->codecpar->codec_type = AVMEDIA_TYPE_VIDEO;
390
        st->need_parsing = AVSTREAM_PARSE_TIMESTAMPS;
391
        fps = avio_rb32(pb);
392

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

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

skip:
    /* skip codec info */
410
    size = avio_tell(pb) - codec_pos;
411 412 413 414 415
    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);
    }
416

417
    return 0;
418 419
}

420 421 422 423
/** 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)
{
424
    AVIOContext *pb = s->pb;
425 426 427 428
    unsigned int size, n_pkts, str_id, next_off, n, pos, pts;
    AVStream *st;

    do {
429
        if (avio_rl32(pb) != MKTAG('I','N','D','X'))
430
            return -1;
431
        size     = avio_rb32(pb);
432 433
        if (size < 20)
            return -1;
434
        avio_skip(pb, 2);
435 436 437
        n_pkts   = avio_rb32(pb);
        str_id   = avio_rb16(pb);
        next_off = avio_rb32(pb);
438 439 440 441 442
        for (n = 0; n < s->nb_streams; n++)
            if (s->streams[n]->id == str_id) {
                st = s->streams[n];
                break;
            }
443 444 445 446
        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));
447
            goto skip;
448 449 450
        } 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 "
451
                   "exceeds filesize (%"PRId64" at %"PRId64" = %"PRId64")\n",
452 453 454 455
                   str_id, avio_size(pb), avio_tell(pb),
                   (avio_size(pb) - avio_tell(pb)) / 14);
            goto skip;
        }
456 457

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

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

skip:
467 468 469 470
        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");
471
            return -1;
472
        }
473 474 475 476
    } while (next_off);

    return 0;
}
477

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

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

493 494 495 496 497 498 499 500 501 502 503 504 505 506 507 508 509 510 511 512 513 514
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);
515
            st2->codecpar->bit_rate = st->codecpar->bit_rate;
516 517
            st2->start_time = st->start_time;
            st2->duration   = st->duration;
518
            st2->codecpar->codec_type = AVMEDIA_TYPE_DATA;
519 520 521 522 523 524 525 526 527 528 529 530 531 532 533
            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;
}

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

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

557 558
    tag_size = avio_rb32(pb);
    avio_skip(pb, tag_size - 8);
559

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

            size = avio_rb32(pb);
620
            codec_pos = avio_tell(pb);
621 622 623 624

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

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

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

Fabrice Bellard's avatar
Fabrice Bellard committed
659
    return 0;
660 661 662 663

fail:
    rm_read_close(s);
    return ret;
Fabrice Bellard's avatar
Fabrice Bellard committed
664 665
}

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

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

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

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

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

Michael Niedermayer's avatar
Michael Niedermayer committed
704
            if(state == MKBETAG('I', 'N', 'D', 'X')){
705
                int n_pkts, expected_len;
706
                len = avio_rb32(pb);
707
                avio_skip(pb, 2);
708
                n_pkts = avio_rb32(pb);
709 710 711 712 713 714 715 716 717
                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
718 719 720
                if(len<0)
                    continue;
                goto skip;
721 722 723
            } 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
724
            }
725

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

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

Michael Niedermayer's avatar
Michael Niedermayer committed
751 752 753 754 755
        return len;
    }
    return -1;
}

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

766
    hdr = avio_r8(pb); len--;
767
    type = hdr >> 6;
768 769

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

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

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

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

    return 1;
}

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

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

877 878 879 880 881 882 883 884 885 886
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;
}

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

895
    if (st->codecpar->codec_type == AVMEDIA_TYPE_VIDEO) {
896
        rm->current_stream= st->id;
897 898
        ret = rm_assemble_video_frame(s, pb, rm, ast, pkt, len, seq, &timestamp);
        if(ret)
899
            return ret < 0 ? ret : -1; //got partial frame or error
900
    } else if (st->codecpar->codec_type == AVMEDIA_TYPE_AUDIO) {
901 902 903
        if ((ast->deint_id == DEINT_ID_GENR) ||
            (ast->deint_id == DEINT_ID_INT4) ||
            (ast->deint_id == DEINT_ID_SIPR)) {
904
            int x;
905 906 907 908 909
            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;
910

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

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

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

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

    pkt->stream_index = st->index;

#if 0
967 968
    if (st->codecpar->codec_type == AVMEDIA_TYPE_VIDEO) {
        if(st->codecpar->codec_id == AV_CODEC_ID_RV20){
969
            int seq= 128*(pkt->data[2]&0x7F) + (pkt->data[3]>>1);
970
            av_log(s, AV_LOG_DEBUG, "%d %"PRId64" %d\n", *timestamp, *timestamp*512LL/25, seq);
971

972 973 974
            seq |= (timestamp&~0x3FFF);
            if(seq - timestamp >  0x2000) seq -= 0x4000;
            if(seq - timestamp < -0x2000) seq += 0x4000;
975 976 977 978
        }
    }
#endif

979
    pkt->pts = timestamp;
980
    if (flags & 2)
981
        pkt->flags |= AV_PKT_FLAG_KEY;
982

983
    return st->codecpar->codec_type == AVMEDIA_TYPE_AUDIO ? rm->audio_pkt_cnt : 0;
984 985
}

986
int
987
ff_rm_retrieve_cache (AVFormatContext *s, AVIOContext *pb,
988
                      AVStream *st, RMStream *ast, AVPacket *pkt)
989
{
990
    RMDemuxContext *rm = s->priv_data;
991

992
    av_assert0 (rm->audio_pkt_cnt > 0);
993

994
    if (ast->deint_id == DEINT_ID_VBRF ||
995 996 997 998 999
        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 {
1000
        int ret = av_new_packet(pkt, st->codecpar->block_align);
1001 1002
        if (ret < 0)
            return ret;
1003 1004 1005
        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);
1006 1007
    }
    rm->audio_pkt_cnt--;
1008 1009
    if ((pkt->pts = ast->audiotimestamp) != AV_NOPTS_VALUE) {
        ast->audiotimestamp = AV_NOPTS_VALUE;
1010
        pkt->flags = AV_PKT_FLAG_KEY;
1011
    } else
1012
        pkt->flags = 0;
1013
    pkt->stream_index = st->index;
1014 1015

    return rm->audio_pkt_cnt;
1016 1017
}

Fabrice Bellard's avatar
Fabrice Bellard committed
1018 1019
static int rm_read_packet(AVFormatContext *s, AVPacket *pkt)
{
1020
    RMDemuxContext *rm = s->priv_data;
1021
    AVStream *st = NULL; // init to silence compiler warning
1022
    int i, len, res, seq = 1;
1023
    int64_t timestamp, pos;
1024
    int flags;
Fabrice Bellard's avatar
Fabrice Bellard committed
1025

1026
    for (;;) {
1027 1028 1029
        if (rm->audio_pkt_cnt) {
            // If there are queued audio packet return them first
            st = s->streams[rm->audio_stream_num];
1030 1031 1032
            res = ff_rm_retrieve_cache(s, s->pb, st, st->priv_data, pkt);
            if(res < 0)
                return res;
1033
            flags = 0;
1034 1035
        } else {
            if (rm->old_format) {
1036
                RMStream *ast;
Ronald S. Bultje's avatar
Ronald S. Bultje committed
1037

1038 1039
                st = s->streams[0];
                ast = st->priv_data;
1040 1041 1042 1043
                timestamp = AV_NOPTS_VALUE;
                len = !ast->audio_framesize ? RAW_PACKET_SIZE :
                    ast->coded_framesize * ast->sub_packet_h / 2;
                flags = (seq++ == 1) ? 2 : 0;
1044
                pos = avio_tell(s->pb);
1045
            } else {
1046
                len = rm_sync(s, &timestamp, &flags, &i, &pos);
1047 1048
                if (len > 0)
                    st = s->streams[i];
1049 1050
            }

1051 1052 1053
            if (avio_feof(s->pb))
                return AVERROR_EOF;
            if (len <= 0)
1054
                return AVERROR(EIO);
Michael Niedermayer's avatar
Michael Niedermayer committed
1055

1056
            res = ff_rm_parse_packet (s, s->pb, st, st->priv_data, len, pkt,
1057
                                      &seq, flags, timestamp);
1058 1059
            if (res < -1)
                return res;
1060
            if((flags&2) && (seq&0x7F) == 1)
1061
                av_add_index_entry(st, pos, timestamp, 0, 0, AVINDEX_KEYFRAME);
1062 1063 1064
            if (res)
                continue;
        }
Michael Niedermayer's avatar
Michael Niedermayer committed
1065

1066 1067
        if(  (st->discard >= AVDISCARD_NONKEY && !(flags&2))
           || st->discard >= AVDISCARD_ALL){
1068
            av_packet_unref(pkt);
1069 1070
        } else
            break;
1071 1072
    }

Fabrice Bellard's avatar
Fabrice Bellard committed
1073 1074 1075 1076 1077
    return 0;
}

static int rm_read_close(AVFormatContext *s)
{
1078 1079 1080 1081
    int i;

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

Fabrice Bellard's avatar
Fabrice Bellard committed
1083 1084 1085
    return 0;
}

Fabrice Bellard's avatar
Fabrice Bellard committed
1086 1087 1088
static int rm_probe(AVProbeData *p)
{
    /* check file header */
1089 1090 1091 1092 1093
    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
1094 1095 1096 1097 1098
        return AVPROBE_SCORE_MAX;
    else
        return 0;
}

1099
static int64_t rm_read_dts(AVFormatContext *s, int stream_index,
Michael Niedermayer's avatar
Michael Niedermayer committed
1100 1101
                               int64_t *ppos, int64_t pos_limit)
{
1102
    RMDemuxContext *rm = s->priv_data;
Michael Niedermayer's avatar
Michael Niedermayer committed
1103
    int64_t pos, dts;
1104
    int stream_index2, flags, len, h;
Michael Niedermayer's avatar
Michael Niedermayer committed
1105 1106

    pos = *ppos;
1107

Michael Niedermayer's avatar
Michael Niedermayer committed
1108 1109 1110
    if(rm->old_format)
        return AV_NOPTS_VALUE;

1111 1112 1113
    if (avio_seek(s->pb, pos, SEEK_SET) < 0)
        return AV_NOPTS_VALUE;

Michael Niedermayer's avatar
Michael Niedermayer committed
1114 1115
    rm->remaining_len=0;
    for(;;){
1116 1117 1118
        int seq=1;
        AVStream *st;

1119
        len = rm_sync(s, &dts, &flags, &stream_index2, &pos);
Michael Niedermayer's avatar
Michael Niedermayer committed
1120 1121
        if(len<0)
            return AV_NOPTS_VALUE;
1122 1123

        st = s->streams[stream_index2];
1124
        if (st->codecpar->codec_type == AVMEDIA_TYPE_VIDEO) {
1125
            h= avio_r8(s->pb); len--;
1126
            if(!(h & 0x40)){
1127
                seq = avio_r8(s->pb); len--;
Michael Niedermayer's avatar
Michael Niedermayer committed
1128 1129
            }
        }
1130

1131
        if((flags&2) && (seq&0x7F) == 1){
1132
            av_log(s, AV_LOG_TRACE, "%d %d-%d %"PRId64" %d\n",
1133
                    flags, stream_index2, stream_index, dts, seq);
1134
            av_add_index_entry(st, pos, dts, 0, 0, AVINDEX_KEYFRAME);
1135 1136 1137 1138
            if(stream_index2 == stream_index)
                break;
        }

1139
        avio_skip(s->pb, len);
Michael Niedermayer's avatar
Michael Niedermayer committed
1140 1141 1142 1143 1144
    }
    *ppos = pos;
    return dts;
}

1145 1146 1147 1148 1149 1150 1151 1152 1153 1154 1155 1156
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;
}


1157
AVInputFormat ff_rm_demuxer = {
1158
    .name           = "rm",
1159
    .long_name      = NULL_IF_CONFIG_SMALL("RealMedia"),
1160 1161 1162 1163 1164 1165
    .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,
1166
    .read_seek      = rm_read_seek,
Fabrice Bellard's avatar
Fabrice Bellard committed
1167
};
1168

1169
AVInputFormat ff_rdt_demuxer = {
1170 1171 1172 1173
    .name           = "rdt",
    .long_name      = NULL_IF_CONFIG_SMALL("RDT demuxer"),
    .priv_data_size = sizeof(RMDemuxContext),
    .read_close     = rm_read_close,
1174
    .flags          = AVFMT_NOFILE,
1175
};
1176 1177 1178 1179 1180 1181 1182 1183 1184 1185 1186 1187 1188

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;
1189
    int i, j, n, count, nb_streams = 0, ret;
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 1352 1353 1354 1355 1356 1357 1358 1359 1360 1361 1362 1363 1364 1365 1366
    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);

1367
                if (size < 1 || size > INT_MAX/4) {
1368
                    av_log(s, AV_LOG_ERROR, "size %u is invalid\n", size);
1369 1370 1371
                    return AVERROR_INVALIDDATA;
                }

1372 1373 1374 1375 1376 1377 1378 1379 1380 1381 1382 1383 1384 1385 1386 1387 1388 1389 1390
                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 {
1391
                av_log(s, AV_LOG_ERROR, "Unsupported opcode=%d at %"PRIX64"\n", opcode, avio_tell(pb) - 1);
1392 1393 1394 1395 1396 1397 1398 1399 1400 1401 1402 1403 1404 1405 1406 1407 1408
                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,
1409
    .read_close     = rm_read_close,
1410 1411
    .extensions     = "ivr",
};