rmdec.c 45.5 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 read = avio_get_str(pb, len, buf, buf_size);
Fabrice Bellard's avatar
Fabrice Bellard committed
74

75 76
    if (read > 0)
        avio_skip(pb, len - read);
Fabrice Bellard's avatar
Fabrice Bellard committed
77 78
}

79
static void get_str8(AVIOContext *pb, char *buf, int buf_size)
80
{
81
    get_strl(pb, buf, buf_size, avio_r8(pb));
Fabrice Bellard's avatar
Fabrice Bellard committed
82 83
}

84
static int rm_read_extradata(AVFormatContext *s, AVIOContext *pb, AVCodecParameters *par, unsigned size)
85
{
86
    if (size >= 1<<24) {
87
        av_log(s, AV_LOG_ERROR, "extradata size %u too large\n", size);
88
        return -1;
89
    }
90
    if (ff_get_extradata(s, par, pb, size) < 0)
91
        return AVERROR(ENOMEM);
92 93 94
    return 0;
}

95
static void rm_read_metadata(AVFormatContext *s, AVIOContext *pb, int wide)
96 97 98
{
    char buf[1024];
    int i;
99

100
    for (i=0; i<FF_ARRAY_ELEMS(ff_rm_metadata); i++) {
101
        int len = wide ? avio_rb16(pb) : avio_r8(pb);
102 103 104 105
        if (len > 0) {
            get_strl(pb, buf, sizeof(buf), len);
            av_dict_set(&s->metadata, ff_rm_metadata[i], buf, 0);
        }
106 107 108
    }
}

109 110 111
RMStream *ff_rm_alloc_rmstream (void)
{
    RMStream *rms = av_mallocz(sizeof(RMStream));
112 113
    if (!rms)
        return NULL;
114 115 116 117 118 119
    rms->curpic_num = -1;
    return rms;
}

void ff_rm_free_rmstream (RMStream *rms)
{
120
    av_packet_unref(&rms->pkt);
121 122
}

123
static int rm_read_audio_stream_info(AVFormatContext *s, AVIOContext *pb,
124
                                     AVStream *st, RMStream *ast, int read_all)
125
{
126
    char buf[256];
127
    uint32_t version;
128
    int ret;
129 130

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

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

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

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

301
        if (read_all) {
302 303 304
            avio_r8(pb);
            avio_r8(pb);
            avio_r8(pb);
305
            rm_read_metadata(s, pb, 0);
306 307
        }
    }
308
    return 0;
309 310
}

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

320
    if (codec_data_size > INT_MAX)
321
        return AVERROR_INVALIDDATA;
322 323
    if (codec_data_size == 0)
        return 0;
324

325
    avpriv_set_pts_info(st, 64, 1, 1000);
326
    codec_pos = avio_tell(pb);
327
    v = avio_rb32(pb);
328

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

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

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

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

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

415
    return 0;
416 417
}

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

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

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

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

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

    return 0;
}
475

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

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

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

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

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

555 556
    tag_size = avio_rb32(pb);
    avio_skip(pb, tag_size - 8);
557

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

            size = avio_rb32(pb);
613
            codec_pos = avio_tell(pb);
614 615 616 617

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

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

    if (!data_off)
645
        data_off = avio_tell(pb) - 18;
646 647
    if (indx_off && (pb->seekable & AVIO_SEEKABLE_NORMAL) &&
        !(s->flags & AVFMT_FLAG_IGNIDX) &&
648
        avio_seek(pb, indx_off, SEEK_SET) >= 0) {
649
        rm_read_index(s);
650
        avio_seek(pb, data_off + 18, SEEK_SET);
651 652
    }

Fabrice Bellard's avatar
Fabrice Bellard committed
653
    return 0;
654 655 656 657

fail:
    rm_read_close(s);
    return ret;
Fabrice Bellard's avatar
Fabrice Bellard committed
658 659
}

660
static int get_num(AVIOContext *pb, int *len)
661 662 663
{
    int n, n1;

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

676 677 678
/* multiple of 20 bytes for ra144 (ugly) */
#define RAW_PACKET_SIZE 1000

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

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

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

720
            if(state > (unsigned)0xFFFF || state <= 12)
Michael Niedermayer's avatar
Michael Niedermayer committed
721
                continue;
722
            len=state - 12;
Michael Niedermayer's avatar
Michael Niedermayer committed
723 724
            state= 0xFFFFFFFF;

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

Michael Niedermayer's avatar
Michael Niedermayer committed
745 746 747 748 749
        return len;
    }
    return -1;
}

750
static int rm_assemble_video_frame(AVFormatContext *s, AVIOContext *pb,
751
                                   RMDemuxContext *rm, RMStream *vst,
752 753
                                   AVPacket *pkt, int len, int *pseq,
                                   int64_t *timestamp)
754
{
755
    int hdr;
Andreas Cadhalpun's avatar
Andreas Cadhalpun committed
756
    int seq = 0, pic_num = 0, len2 = 0, pos = 0; //init to silence compiler warning
757
    int type;
758
    int ret;
759

760
    hdr = avio_r8(pb); len--;
761
    type = hdr >> 6;
762 763

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

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

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

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

    return 1;
}

856 857 858 859 860 861
static inline void
rm_ac3_swap_bytes (AVStream *st, AVPacket *pkt)
{
    uint8_t *ptr;
    int j;

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

871 872 873 874 875 876 877 878 879 880
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;
}

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

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

905
            if (flags & 2)
906
                y = ast->sub_packet_cnt = 0;
907
            if (!y)
908
                ast->audiotimestamp = timestamp;
909

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

924
            if (++(ast->sub_packet_cnt) < h)
925
                return -1;
926
            if (ast->deint_id == DEINT_ID_SIPR)
927
                ff_rm_reorder_sipr_data(ast->pkt.data, h, w);
928

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

    pkt->stream_index = st->index;

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

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

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

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

978
    if (ast->deint_id == DEINT_ID_VBRF ||
979
        ast->deint_id == DEINT_ID_VBRS) {
980
        ret = av_get_packet(pb, pkt, ast->sub_packet_lengths[ast->sub_packet_cnt - rm->audio_pkt_cnt]);
981 982 983
        if (ret < 0)
            return ret;
    } else {
984
        ret = av_new_packet(pkt, st->codecpar->block_align);
985 986
        if (ret < 0)
            return ret;
987 988 989
        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);
990 991
    }
    rm->audio_pkt_cnt--;
992 993
    if ((pkt->pts = ast->audiotimestamp) != AV_NOPTS_VALUE) {
        ast->audiotimestamp = AV_NOPTS_VALUE;
994
        pkt->flags = AV_PKT_FLAG_KEY;
995
    } else
996
        pkt->flags = 0;
997
    pkt->stream_index = st->index;
998 999

    return rm->audio_pkt_cnt;
1000 1001
}

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

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

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

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

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

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

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

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

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

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

1070
static int rm_probe(const AVProbeData *p)
Fabrice Bellard's avatar
Fabrice Bellard committed
1071 1072
{
    /* check file header */
1073 1074 1075 1076 1077
    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
1078 1079 1080 1081 1082
        return AVPROBE_SCORE_MAX;
    else
        return 0;
}

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

    pos = *ppos;
1091

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

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

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

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

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

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

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

1129 1130 1131 1132 1133 1134 1135 1136 1137 1138 1139 1140
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;
}


1141
AVInputFormat ff_rm_demuxer = {
1142
    .name           = "rm",
1143
    .long_name      = NULL_IF_CONFIG_SMALL("RealMedia"),
1144 1145 1146 1147 1148 1149
    .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,
1150
    .read_seek      = rm_read_seek,
Fabrice Bellard's avatar
Fabrice Bellard committed
1151
};
1152

1153
AVInputFormat ff_rdt_demuxer = {
1154 1155 1156 1157
    .name           = "rdt",
    .long_name      = NULL_IF_CONFIG_SMALL("RDT demuxer"),
    .priv_data_size = sizeof(RMDemuxContext),
    .read_close     = rm_read_close,
1158
    .flags          = AVFMT_NOFILE,
1159
};
1160

1161
static int ivr_probe(const AVProbeData *p)
1162 1163 1164 1165 1166 1167 1168 1169 1170 1171 1172
{
    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;
1173
    int i, j, n, count, nb_streams = 0, ret;
1174 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
    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);
1225 1226 1227
            for (j = 0; j < len; j++) {
                if (avio_feof(pb))
                    return AVERROR_INVALIDDATA;
1228
                av_log(s, AV_LOG_DEBUG, "%X", avio_r8(pb));
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
            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 {
1272 1273
                    if (avio_feof(pb))
                        return AVERROR_INVALIDDATA;
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
                    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);

1356
                if (size < 1 || size > INT_MAX/4) {
1357
                    av_log(s, AV_LOG_ERROR, "size %u is invalid\n", size);
1358 1359 1360
                    return AVERROR_INVALIDDATA;
                }

1361 1362 1363 1364 1365 1366 1367 1368 1369 1370 1371 1372 1373 1374 1375 1376 1377 1378 1379
                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 {
1380
                av_log(s, AV_LOG_ERROR, "Unsupported opcode=%d at %"PRIX64"\n", opcode, avio_tell(pb) - 1);
1381 1382 1383 1384 1385 1386 1387 1388 1389 1390 1391 1392 1393 1394 1395 1396 1397
                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,
1398
    .read_close     = rm_read_close,
1399 1400
    .extensions     = "ivr",
};