rmdec.c 31.3 KB
Newer Older
Fabrice Bellard's avatar
Fabrice Bellard committed
1
/*
2
 * "Real" compatible demuxer.
3
 * Copyright (c) 2000, 2001 Fabrice Bellard
Fabrice Bellard's avatar
Fabrice Bellard committed
4
 *
5 6 7
 * This file is part of FFmpeg.
 *
 * FFmpeg is free software; you can redistribute it and/or
8 9
 * modify it under the terms of the GNU Lesser General Public
 * License as published by the Free Software Foundation; either
10
 * version 2.1 of the License, or (at your option) any later version.
Fabrice Bellard's avatar
Fabrice Bellard committed
11
 *
12
 * FFmpeg is distributed in the hope that it will be useful,
Fabrice Bellard's avatar
Fabrice Bellard committed
13
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 15
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 * Lesser General Public License for more details.
Fabrice Bellard's avatar
Fabrice Bellard committed
16
 *
17
 * You should have received a copy of the GNU Lesser General Public
18
 * License along with FFmpeg; if not, write to the Free Software
19
 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
Fabrice Bellard's avatar
Fabrice Bellard committed
20
 */
21 22

#include "libavutil/avstring.h"
23
#include "libavutil/intreadwrite.h"
Fabrice Bellard's avatar
Fabrice Bellard committed
24
#include "avformat.h"
25
#include "riff.h"
26
#include "rm.h"
27

28
struct RMStream {
29
    AVPacket pkt;      ///< place to store merged video frame / reordered audio data
30 31 32 33 34 35 36 37 38
    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
39 40 41 42 43 44 45 46 47
    int audio_framesize; /// Audio frame size from container
    int sub_packet_lengths[16]; /// Length of each subpacket
};

typedef struct {
    int nb_packets;
    int old_format;
    int current_stream;
    int remaining_len;
48 49 50
    int audio_stream_num; ///< Stream number for audio packets
    int audio_pkt_cnt; ///< Output packet counter
} RMDemuxContext;
Fabrice Bellard's avatar
Fabrice Bellard committed
51

52 53 54 55 56 57 58 59 60 61 62 63 64 65
static const AVCodecTag rm_codec_tags[] = {
    { CODEC_ID_RV10,   MKTAG('R','V','1','0') },
    { CODEC_ID_RV20,   MKTAG('R','V','2','0') },
    { CODEC_ID_RV20,   MKTAG('R','V','T','R') },
    { CODEC_ID_RV30,   MKTAG('R','V','3','0') },
    { CODEC_ID_RV40,   MKTAG('R','V','4','0') },
    { CODEC_ID_AC3,    MKTAG('d','n','e','t') },
    { CODEC_ID_RA_144, MKTAG('l','p','c','J') },
    { CODEC_ID_RA_288, MKTAG('2','8','_','8') },
    { CODEC_ID_COOK,   MKTAG('c','o','o','k') },
    { CODEC_ID_ATRAC3, MKTAG('a','t','r','c') },
    { CODEC_ID_SIPR,   MKTAG('s','i','p','r') },
    { CODEC_ID_AAC,    MKTAG('r','a','a','c') },
    { CODEC_ID_AAC,    MKTAG('r','a','c','p') },
66
    { CODEC_ID_NONE },
67 68
};

69 70 71 72 73 74 75 76 77 78 79 80 81 82 83
static const unsigned char sipr_swaps[38][2] = {
    {  0, 63 }, {  1, 22 }, {  2, 44 }, {  3, 90 },
    {  5, 81 }, {  7, 31 }, {  8, 86 }, {  9, 58 },
    { 10, 36 }, { 12, 68 }, { 13, 39 }, { 14, 73 },
    { 15, 53 }, { 16, 69 }, { 17, 57 }, { 19, 88 },
    { 20, 34 }, { 21, 71 }, { 24, 46 }, { 25, 94 },
    { 26, 54 }, { 28, 75 }, { 29, 50 }, { 32, 70 },
    { 33, 92 }, { 35, 74 }, { 38, 85 }, { 40, 56 },
    { 42, 87 }, { 43, 65 }, { 45, 59 }, { 48, 79 },
    { 49, 93 }, { 51, 89 }, { 55, 95 }, { 61, 76 },
    { 67, 83 }, { 77, 80 }
};

static const unsigned char sipr_subpk_size[4] = { 29, 19, 37, 20 };

84
static inline void get_strl(ByteIOContext *pb, char *buf, int buf_size, int len)
Fabrice Bellard's avatar
Fabrice Bellard committed
85
{
86
    int i;
87
    char *q, r;
Fabrice Bellard's avatar
Fabrice Bellard committed
88 89 90

    q = buf;
    for(i=0;i<len;i++) {
91
        r = get_byte(pb);
Fabrice Bellard's avatar
Fabrice Bellard committed
92
        if (i < buf_size - 1)
93
            *q++ = r;
Fabrice Bellard's avatar
Fabrice Bellard committed
94
    }
95
    if (buf_size > 0) *q = '\0';
Fabrice Bellard's avatar
Fabrice Bellard committed
96 97
}

98 99 100
static void get_str8(ByteIOContext *pb, char *buf, int buf_size)
{
    get_strl(pb, buf, buf_size, get_byte(pb));
Fabrice Bellard's avatar
Fabrice Bellard committed
101 102
}

103 104 105 106 107 108 109 110 111 112 113 114 115 116
static int rm_read_extradata(ByteIOContext *pb, AVCodecContext *avctx, unsigned size)
{
    if (size >= 1<<24)
        return -1;
    avctx->extradata = av_malloc(size + FF_INPUT_BUFFER_PADDING_SIZE);
    if (!avctx->extradata)
        return AVERROR_NOMEM;
    avctx->extradata_size = get_buffer(pb, avctx->extradata, size);
    memset(avctx->extradata + avctx->extradata_size, 0, FF_INPUT_BUFFER_PADDING_SIZE);
    if (avctx->extradata_size != size)
        return AVERROR(EIO);
    return 0;
}

117 118 119 120 121 122 123 124 125 126 127
static void rm_read_metadata(AVFormatContext *s, int wide)
{
    char buf[1024];
    int i;
    for (i=0; i<FF_ARRAY_ELEMS(ff_rm_metadata); i++) {
        int len = wide ? get_be16(s->pb) : get_byte(s->pb);
        get_strl(s->pb, buf, sizeof(buf), len);
        av_metadata_set(&s->metadata, ff_rm_metadata[i], buf);
    }
}

128 129 130 131 132 133 134 135 136
RMStream *ff_rm_alloc_rmstream (void)
{
    RMStream *rms = av_mallocz(sizeof(RMStream));
    rms->curpic_num = -1;
    return rms;
}

void ff_rm_free_rmstream (RMStream *rms)
{
137
    av_free_packet(&rms->pkt);
138 139
}

140
static int rm_read_audio_stream_info(AVFormatContext *s, ByteIOContext *pb,
141
                                     AVStream *st, RMStream *ast, int read_all)
142
{
143
    char buf[256];
144
    uint32_t version;
145
    int ret;
146 147

    /* ra type header */
148 149 150
    version = get_be16(pb); /* version */
    if (version == 3) {
        int header_size = get_be16(pb);
151
        int64_t startpos = url_ftell(pb);
152
        url_fskip(pb, 14);
153
        rm_read_metadata(s, 0);
154
        if ((startpos + header_size) >= url_ftell(pb) + 2) {
Ronald S. Bultje's avatar
Ronald S. Bultje committed
155 156 157
            // fourcc (should always be "lpcJ")
            get_byte(pb);
            get_str8(pb, buf, sizeof(buf));
158 159
        }
        // Skip extra header crap (this should never happen)
160 161
        if ((startpos + header_size) > url_ftell(pb))
            url_fskip(pb, header_size + startpos - url_ftell(pb));
162 163 164 165
        st->codec->sample_rate = 8000;
        st->codec->channels = 1;
        st->codec->codec_type = CODEC_TYPE_AUDIO;
        st->codec->codec_id = CODEC_ID_RA_144;
166
    } else {
167
        int flavor, sub_packet_h, coded_framesize, sub_packet_size;
168
        int codecdata_length;
169
        /* old version (4) */
170
        url_fskip(pb, 2); /* unused */
171
        get_be32(pb); /* .ra4 */
172 173
        get_be32(pb); /* data size */
        get_be16(pb); /* version2 */
174
        get_be32(pb); /* header size */
175
        flavor= get_be16(pb); /* add codec info / flavor */
176
        ast->coded_framesize = coded_framesize = get_be32(pb); /* coded frame size */
177 178 179
        get_be32(pb); /* ??? */
        get_be32(pb); /* ??? */
        get_be32(pb); /* ??? */
180
        ast->sub_packet_h = sub_packet_h = get_be16(pb); /* 1 */
181
        st->codec->block_align= get_be16(pb); /* frame size */
182
        ast->sub_packet_size = sub_packet_size = get_be16(pb); /* sub packet size */
183
        get_be16(pb); /* ??? */
184
        if (version == 5) {
185 186
            get_be16(pb); get_be16(pb); get_be16(pb);
        }
187
        st->codec->sample_rate = get_be16(pb);
188
        get_be32(pb);
189
        st->codec->channels = get_be16(pb);
190
        if (version == 5) {
191
            get_be32(pb);
192
            get_buffer(pb, buf, 4);
193 194
            buf[4] = 0;
        } else {
195 196
            get_str8(pb, buf, sizeof(buf)); /* desc */
            get_str8(pb, buf, sizeof(buf)); /* desc */
197
        }
198
        st->codec->codec_type = CODEC_TYPE_AUDIO;
199 200 201 202
        st->codec->codec_tag  = AV_RL32(buf);
        st->codec->codec_id   = ff_codec_get_id(rm_codec_tags, st->codec->codec_tag);
        switch (st->codec->codec_id) {
        case CODEC_ID_AC3:
203
            st->need_parsing = AVSTREAM_PARSE_FULL;
204 205
            break;
        case CODEC_ID_RA_288:
206
            st->codec->extradata_size= 0;
207
            ast->audio_framesize = st->codec->block_align;
208
            st->codec->block_align = coded_framesize;
209

210 211
            if(ast->audio_framesize >= UINT_MAX / sub_packet_h){
                av_log(s, AV_LOG_ERROR, "ast->audio_framesize * sub_packet_h too large\n");
212 213 214
                return -1;
            }

215
            av_new_packet(&ast->pkt, ast->audio_framesize * sub_packet_h);
216 217 218 219
            break;
        case CODEC_ID_COOK:
        case CODEC_ID_ATRAC3:
        case CODEC_ID_SIPR:
220
            get_be16(pb); get_byte(pb);
221
            if (version == 5)
222 223
                get_byte(pb);
            codecdata_length = get_be32(pb);
224 225 226 227 228
            if(codecdata_length + FF_INPUT_BUFFER_PADDING_SIZE <= (unsigned)codecdata_length){
                av_log(s, AV_LOG_ERROR, "codecdata_length too large\n");
                return -1;
            }

Benjamin Larsson's avatar
Benjamin Larsson committed
229
            if (!strcmp(buf, "cook")) st->codec->codec_id = CODEC_ID_COOK;
230
            else if (!strcmp(buf, "sipr")) st->codec->codec_id = CODEC_ID_SIPR;
Benjamin Larsson's avatar
Benjamin Larsson committed
231
            else st->codec->codec_id = CODEC_ID_ATRAC3;
232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247

            ast->audio_framesize = st->codec->block_align;
            if (st->codec->codec_id == CODEC_ID_SIPR) {
                if (flavor > 3) {
                    av_log(s, AV_LOG_ERROR, "bad SIPR file flavor %d\n",
                           flavor);
                    return -1;
                }
                st->codec->block_align = sipr_subpk_size[flavor];
            } else {
                if(sub_packet_size <= 0){
                    av_log(s, AV_LOG_ERROR, "sub_packet_size is invalid\n");
                    return -1;
                }
                st->codec->block_align = ast->sub_packet_size;
            }
248
            if ((ret = rm_read_extradata(pb, st->codec, codecdata_length)) < 0)
249
                return ret;
250

251
            if(ast->audio_framesize >= UINT_MAX / sub_packet_h){
252 253 254 255
                av_log(s, AV_LOG_ERROR, "rm->audio_framesize * sub_packet_h too large\n");
                return -1;
            }

256
            av_new_packet(&ast->pkt, ast->audio_framesize * sub_packet_h);
257 258
            break;
        case CODEC_ID_AAC:
259
            get_be16(pb); get_byte(pb);
260
            if (version == 5)
261 262 263
                get_byte(pb);
            st->codec->codec_id = CODEC_ID_AAC;
            codecdata_length = get_be32(pb);
264 265 266 267
            if(codecdata_length + FF_INPUT_BUFFER_PADDING_SIZE <= (unsigned)codecdata_length){
                av_log(s, AV_LOG_ERROR, "codecdata_length too large\n");
                return -1;
            }
268 269
            if (codecdata_length >= 1) {
                get_byte(pb);
270
                if ((ret = rm_read_extradata(pb, st->codec, codecdata_length - 1)) < 0)
271
                    return ret;
272
            }
273 274
            break;
        default:
275
            av_strlcpy(st->codec->codec_name, buf, sizeof(st->codec->codec_name));
276 277 278 279 280
        }
        if (read_all) {
            get_byte(pb);
            get_byte(pb);
            get_byte(pb);
281
            rm_read_metadata(s, 0);
282 283
        }
    }
284
    return 0;
285 286
}

287
int
288
ff_rm_read_mdpr_codecdata (AVFormatContext *s, ByteIOContext *pb,
289
                           AVStream *st, RMStream *rst, int codec_data_size)
290 291
{
    unsigned int v;
292
    int size;
293
    int64_t codec_pos;
294
    int ret;
295

296
    av_set_pts_info(st, 64, 1, 1000);
297 298 299 300
    codec_pos = url_ftell(pb);
    v = get_be32(pb);
    if (v == MKTAG(0xfd, 'a', 'r', '.')) {
        /* ra type header */
301
        if (rm_read_audio_stream_info(s, pb, st, rst, 0))
302 303 304 305 306 307 308 309 310
            return -1;
    } else {
        int fps, fps2;
        if (get_le32(pb) != MKTAG('V', 'I', 'D', 'O')) {
        fail1:
            av_log(st->codec, AV_LOG_ERROR, "Unsupported video codec\n");
            goto skip;
        }
        st->codec->codec_tag = get_le32(pb);
311
        st->codec->codec_id  = ff_codec_get_id(rm_codec_tags, st->codec->codec_tag);
312
//        av_log(s, AV_LOG_DEBUG, "%X %X\n", st->codec->codec_tag, MKTAG('R', 'V', '2', '0'));
313
        if (st->codec->codec_id == CODEC_ID_NONE)
314 315 316 317 318 319 320 321 322 323
            goto fail1;
        st->codec->width = get_be16(pb);
        st->codec->height = get_be16(pb);
        st->codec->time_base.num= 1;
        fps= get_be16(pb);
        st->codec->codec_type = CODEC_TYPE_VIDEO;
        get_be32(pb);
        fps2= get_be16(pb);
        get_be16(pb);

324
        if ((ret = rm_read_extradata(pb, st->codec, codec_data_size - (url_ftell(pb) - codec_pos))) < 0)
325
            return ret;
326

327
//        av_log(s, AV_LOG_DEBUG, "fps= %d fps2= %d\n", fps, fps2);
328
        st->codec->time_base.den = fps * st->codec->time_base.num;
329
        //XXX: do we really need that?
330
        switch(st->codec->extradata[4]>>4){
331 332 333 334
        case 1: st->codec->codec_id = CODEC_ID_RV10; break;
        case 2: st->codec->codec_id = CODEC_ID_RV20; break;
        case 3: st->codec->codec_id = CODEC_ID_RV30; break;
        case 4: st->codec->codec_id = CODEC_ID_RV40; break;
335
        default:
336
            av_log(st->codec, AV_LOG_ERROR, "extra:%02X %02X %02X %02X %02X\n", st->codec->extradata[0], st->codec->extradata[1], st->codec->extradata[2], st->codec->extradata[3], st->codec->extradata[4]);
337
            goto fail1;
338 339 340 341 342 343 344 345
        }
    }

skip:
    /* skip codec info */
    size = url_ftell(pb) - codec_pos;
    url_fskip(pb, codec_data_size - size);

346
    return 0;
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 372 373 374 375 376 377 378 379 380 381 382 383 384 385 386 387 388 389 390 391
/** 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)
{
    ByteIOContext *pb = s->pb;
    unsigned int size, n_pkts, str_id, next_off, n, pos, pts;
    AVStream *st;

    do {
        if (get_le32(pb) != MKTAG('I','N','D','X'))
            return -1;
        size     = get_be32(pb);
        if (size < 20)
            return -1;
        url_fskip(pb, 2);
        n_pkts   = get_be32(pb);
        str_id   = get_be16(pb);
        next_off = get_be32(pb);
        for (n = 0; n < s->nb_streams; n++)
            if (s->streams[n]->id == str_id) {
                st = s->streams[n];
                break;
            }
        if (n == s->nb_streams)
            goto skip;

        for (n = 0; n < n_pkts; n++) {
            url_fskip(pb, 2);
            pts = get_be32(pb);
            pos = get_be32(pb);
            url_fskip(pb, 4); /* packet no. */

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

skip:
        if (next_off && url_ftell(pb) != next_off &&
            url_fseek(pb, next_off, SEEK_SET) < 0)
            return -1;
    } while (next_off);

    return 0;
}
392

393 394
static int rm_read_header_old(AVFormatContext *s, AVFormatParameters *ap)
{
395
    RMDemuxContext *rm = s->priv_data;
396 397 398 399 400
    AVStream *st;

    rm->old_format = 1;
    st = av_new_stream(s, 0);
    if (!st)
401
        return -1;
402 403
    st->priv_data = ff_rm_alloc_rmstream();
    return rm_read_audio_stream_info(s, s->pb, st, st->priv_data, 1);
404 405
}

Fabrice Bellard's avatar
Fabrice Bellard committed
406 407
static int rm_read_header(AVFormatContext *s, AVFormatParameters *ap)
{
408
    RMDemuxContext *rm = s->priv_data;
Fabrice Bellard's avatar
Fabrice Bellard committed
409
    AVStream *st;
410
    ByteIOContext *pb = s->pb;
411
    unsigned int tag;
412
    int tag_size;
413
    unsigned int start_time, duration;
414
    unsigned int data_off = 0, indx_off = 0;
Fabrice Bellard's avatar
Fabrice Bellard committed
415
    char buf[128];
416
    int flags = 0;
Fabrice Bellard's avatar
Fabrice Bellard committed
417

418 419 420 421 422
    tag = get_le32(pb);
    if (tag == MKTAG('.', 'r', 'a', 0xfd)) {
        /* very old .ra format */
        return rm_read_header_old(s, ap);
    } else if (tag != MKTAG('.', 'R', 'M', 'F')) {
423
        return AVERROR(EIO);
424
    }
Fabrice Bellard's avatar
Fabrice Bellard committed
425 426 427 428 429

    get_be32(pb); /* header size */
    get_be16(pb);
    get_be32(pb);
    get_be32(pb); /* number of headers */
430

Fabrice Bellard's avatar
Fabrice Bellard committed
431 432
    for(;;) {
        if (url_feof(pb))
433
            return -1;
Fabrice Bellard's avatar
Fabrice Bellard committed
434 435 436 437
        tag = get_le32(pb);
        tag_size = get_be32(pb);
        get_be16(pb);
#if 0
438
        printf("tag=%c%c%c%c (%08x) size=%d\n",
Fabrice Bellard's avatar
Fabrice Bellard committed
439 440 441 442 443 444 445
               (tag) & 0xff,
               (tag >> 8) & 0xff,
               (tag >> 16) & 0xff,
               (tag >> 24) & 0xff,
               tag,
               tag_size);
#endif
446
        if (tag_size < 10 && tag != MKTAG('D', 'A', 'T', 'A'))
447
            return -1;
Fabrice Bellard's avatar
Fabrice Bellard committed
448 449 450 451 452 453 454 455 456 457
        switch(tag) {
        case MKTAG('P', 'R', 'O', 'P'):
            /* file header */
            get_be32(pb); /* max bit rate */
            get_be32(pb); /* avg bit rate */
            get_be32(pb); /* max packet size */
            get_be32(pb); /* avg packet size */
            get_be32(pb); /* nb packets */
            get_be32(pb); /* duration */
            get_be32(pb); /* preroll */
458 459
            indx_off = get_be32(pb); /* index offset */
            data_off = get_be32(pb); /* data offset */
Fabrice Bellard's avatar
Fabrice Bellard committed
460
            get_be16(pb); /* nb streams */
461
            flags = get_be16(pb); /* flags */
Fabrice Bellard's avatar
Fabrice Bellard committed
462 463
            break;
        case MKTAG('C', 'O', 'N', 'T'):
464
            rm_read_metadata(s, 1);
Fabrice Bellard's avatar
Fabrice Bellard committed
465 466
            break;
        case MKTAG('M', 'D', 'P', 'R'):
467
            st = av_new_stream(s, 0);
Fabrice Bellard's avatar
Fabrice Bellard committed
468
            if (!st)
469
                return AVERROR(ENOMEM);
Fabrice Bellard's avatar
Fabrice Bellard committed
470 471
            st->id = get_be16(pb);
            get_be32(pb); /* max bit rate */
472
            st->codec->bit_rate = get_be32(pb); /* bit rate */
Fabrice Bellard's avatar
Fabrice Bellard committed
473 474
            get_be32(pb); /* max packet size */
            get_be32(pb); /* avg packet size */
475
            start_time = get_be32(pb); /* start time */
Fabrice Bellard's avatar
Fabrice Bellard committed
476
            get_be32(pb); /* preroll */
477
            duration = get_be32(pb); /* duration */
478 479
            st->start_time = start_time;
            st->duration = duration;
Fabrice Bellard's avatar
Fabrice Bellard committed
480 481
            get_str8(pb, buf, sizeof(buf)); /* desc */
            get_str8(pb, buf, sizeof(buf)); /* mimetype */
482
            st->codec->codec_type = CODEC_TYPE_DATA;
483 484 485
            st->priv_data = ff_rm_alloc_rmstream();
            if (ff_rm_read_mdpr_codecdata(s, s->pb, st, st->priv_data,
                                          get_be32(pb)) < 0)
486
                return -1;
Fabrice Bellard's avatar
Fabrice Bellard committed
487 488 489 490 491 492 493 494 495 496 497
            break;
        case MKTAG('D', 'A', 'T', 'A'):
            goto header_end;
        default:
            /* unknown tag: skip it */
            url_fskip(pb, tag_size - 10);
            break;
        }
    }
 header_end:
    rm->nb_packets = get_be32(pb); /* number of packets */
498 499
    if (!rm->nb_packets && (flags & 4))
        rm->nb_packets = 3600 * 25;
Fabrice Bellard's avatar
Fabrice Bellard committed
500
    get_be32(pb); /* next data header */
501 502 503 504 505 506 507 508

    if (!data_off)
        data_off = url_ftell(pb) - 18;
    if (indx_off && url_fseek(pb, indx_off, SEEK_SET) >= 0) {
        rm_read_index(s);
        url_fseek(pb, data_off + 18, SEEK_SET);
    }

Fabrice Bellard's avatar
Fabrice Bellard committed
509 510 511
    return 0;
}

512 513 514 515 516 517
static int get_num(ByteIOContext *pb, int *len)
{
    int n, n1;

    n = get_be16(pb);
    (*len)-=2;
518
    n &= 0x7FFF;
519 520 521 522 523 524 525 526 527
    if (n >= 0x4000) {
        return n - 0x4000;
    } else {
        n1 = get_be16(pb);
        (*len)-=2;
        return (n << 16) | n1;
    }
}

528 529 530
/* multiple of 20 bytes for ra144 (ugly) */
#define RAW_PACKET_SIZE 1000

531
static int sync(AVFormatContext *s, int64_t *timestamp, int *flags, int *stream_index, int64_t *pos){
532
    RMDemuxContext *rm = s->priv_data;
533
    ByteIOContext *pb = s->pb;
Michael Niedermayer's avatar
Michael Niedermayer committed
534
    AVStream *st;
Michael Niedermayer's avatar
Michael Niedermayer committed
535
    uint32_t state=0xFFFFFFFF;
Michael Niedermayer's avatar
Michael Niedermayer committed
536 537

    while(!url_feof(pb)){
538
        int len, num, res, i;
Michael Niedermayer's avatar
Michael Niedermayer committed
539
        *pos= url_ftell(pb) - 3;
Michael Niedermayer's avatar
Michael Niedermayer committed
540 541 542 543 544 545
        if(rm->remaining_len > 0){
            num= rm->current_stream;
            len= rm->remaining_len;
            *timestamp = AV_NOPTS_VALUE;
            *flags= 0;
        }else{
Michael Niedermayer's avatar
Michael Niedermayer committed
546
            state= (state<<8) + get_byte(pb);
547

Michael Niedermayer's avatar
Michael Niedermayer committed
548
            if(state == MKBETAG('I', 'N', 'D', 'X')){
549 550 551 552 553 554 555 556 557 558 559 560 561
                int n_pkts, expected_len;
                len = get_be32(pb);
                url_fskip(pb, 2);
                n_pkts = get_be32(pb);
                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
562 563 564
                if(len<0)
                    continue;
                goto skip;
565 566 567
            } 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
568
            }
569

570
            if(state > (unsigned)0xFFFF || state <= 12)
Michael Niedermayer's avatar
Michael Niedermayer committed
571
                continue;
572
            len=state - 12;
Michael Niedermayer's avatar
Michael Niedermayer committed
573 574
            state= 0xFFFFFFFF;

Michael Niedermayer's avatar
Michael Niedermayer committed
575 576 577 578 579 580 581 582 583 584 585
            num = get_be16(pb);
            *timestamp = get_be32(pb);
            res= get_byte(pb); /* reserved */
            *flags = get_byte(pb); /* flags */
        }
        for(i=0;i<s->nb_streams;i++) {
            st = s->streams[i];
            if (num == st->id)
                break;
        }
        if (i == s->nb_streams) {
Michael Niedermayer's avatar
Michael Niedermayer committed
586
skip:
Michael Niedermayer's avatar
Michael Niedermayer committed
587 588
            /* skip packet if unknown number */
            url_fskip(pb, len);
589
            rm->remaining_len = 0;
Michael Niedermayer's avatar
Michael Niedermayer committed
590 591 592
            continue;
        }
        *stream_index= i;
593

Michael Niedermayer's avatar
Michael Niedermayer committed
594 595 596 597 598
        return len;
    }
    return -1;
}

599
static int rm_assemble_video_frame(AVFormatContext *s, ByteIOContext *pb,
600
                                   RMDemuxContext *rm, RMStream *vst,
601
                                   AVPacket *pkt, int len, int *pseq)
602 603 604 605 606 607
{
    int hdr, seq, pic_num, len2, pos;
    int type;

    hdr = get_byte(pb); len--;
    type = hdr >> 6;
608 609

    if(type != 3){  // not frame as a part of packet
610
        seq = get_byte(pb); len--;
611 612
    }
    if(type != 1){  // not whole frame
613
        len2 = get_num(pb, &len);
614
        pos  = get_num(pb, &len);
615
        pic_num = get_byte(pb); len--;
616 617 618 619 620 621 622 623
    }
    if(len<0)
        return -1;
    rm->remaining_len = len;
    if(type&1){     // frame, not slice
        if(type == 3)  // frame as a part of packet
            len= len2;
        if(rm->remaining_len < len)
624
            return -1;
625
        rm->remaining_len -= len;
626 627 628 629 630 631 632 633 634 635
        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);
        get_buffer(pb, pkt->data + 9, len);
        return 0;
    }
    //now we have to deal with single slice

636
    *pseq = seq;
637 638 639
    if((seq & 0x7F) == 1 || vst->curpic_num != pic_num){
        vst->slices = ((hdr & 0x3F) << 1) + 1;
        vst->videobufsize = len2 + 8*vst->slices + 1;
640 641
        av_free_packet(&vst->pkt); //FIXME this should be output.
        if(av_new_packet(&vst->pkt, vst->videobufsize) < 0)
642
            return AVERROR(ENOMEM);
643 644 645 646
        vst->videobufpos = 8*vst->slices + 1;
        vst->cur_slice = 0;
        vst->curpic_num = pic_num;
        vst->pktpos = url_ftell(pb);
647
    }
Roberto Togni's avatar
Roberto Togni committed
648
    if(type == 2)
649 650
        len = FFMIN(len, pos);

651
    if(++vst->cur_slice > vst->slices)
652
        return 1;
653 654
    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);
655
    if(vst->videobufpos + len > vst->videobufsize)
656
        return 1;
657
    if (get_buffer(pb, vst->pkt.data + vst->videobufpos, len) != len)
658
        return AVERROR(EIO);
659
    vst->videobufpos += len;
660 661
    rm->remaining_len-= len;

662
    if(type == 2 || (vst->videobufpos) == vst->videobufsize){
663 664
        vst->pkt.data[0] = vst->cur_slice-1;
        *pkt= vst->pkt;
665
        vst->pkt.data= NULL;
666 667
        vst->pkt.size= 0;
        if(vst->slices != vst->cur_slice) //FIXME find out how to set slices correct from the begin
668
            memmove(pkt->data + 1 + 8*vst->cur_slice, pkt->data + 1 + 8*vst->slices,
669
                vst->videobufpos - 1 - 8*vst->slices);
670
        pkt->size = vst->videobufpos + 8*(vst->cur_slice - vst->slices);
671 672
        pkt->pts = AV_NOPTS_VALUE;
        pkt->pos = vst->pktpos;
673
        vst->slices = 0;
674
        return 0;
675 676 677 678 679
    }

    return 1;
}

680 681 682 683 684 685 686 687 688 689 690 691 692 693 694
static inline void
rm_ac3_swap_bytes (AVStream *st, AVPacket *pkt)
{
    uint8_t *ptr;
    int j;

    if (st->codec->codec_id == CODEC_ID_AC3) {
        ptr = pkt->data;
        for (j=0;j<pkt->size;j+=2) {
            FFSWAP(int, ptr[0], ptr[1]);
            ptr += 2;
        }
    }
}

695 696 697 698
/**
 * Perform 4-bit block reordering for SIPR data.
 * @todo This can be optimized, e.g. use memcpy() if data blocks are aligned
 */
699 700 701 702 703 704 705 706 707 708 709 710 711 712 713 714 715 716 717 718 719 720 721 722
static void
rm_reorder_sipr_data (RMStream *ast)
{
    int n, bs = ast->sub_packet_h * ast->audio_framesize * 2 / 96; // nibbles per subpacket

    for (n = 0; n < 38; n++) {
        int j;
        int i = bs * sipr_swaps[n][0];
        int o = bs * sipr_swaps[n][1];
        uint8_t *buf = ast->pkt.data;

        /* swap 4bit-nibbles of block 'i' with 'o' */
        for (j = 0; j < bs; j++, i++, o++) {
            int x = (buf[i >> 1] >> (4 * (i & 1))) & 0xF,
                y = (buf[o >> 1] >> (4 * (o & 1))) & 0xF;

            buf[o >> 1] = (x << (4 * (o & 1))) |
                (buf[o >> 1] & (0xF << (4 * !(o & 1))));
            buf[i >> 1] = (y << (4 * (i & 1))) |
                (buf[i >> 1] & (0xF << (4 * !(i & 1))));
        }
    }
}

723
int
724
ff_rm_parse_packet (AVFormatContext *s, ByteIOContext *pb,
725
                    AVStream *st, RMStream *ast, int len, AVPacket *pkt,
726
                    int *seq, int flags, int64_t timestamp)
727
{
728
    RMDemuxContext *rm = s->priv_data;
729 730 731

    if (st->codec->codec_type == CODEC_TYPE_VIDEO) {
        rm->current_stream= st->id;
732
        if(rm_assemble_video_frame(s, pb, rm, ast, pkt, len, seq))
733 734 735 736
            return -1; //got partial frame
    } else if (st->codec->codec_type == CODEC_TYPE_AUDIO) {
        if ((st->codec->codec_id == CODEC_ID_RA_288) ||
            (st->codec->codec_id == CODEC_ID_COOK) ||
737 738
            (st->codec->codec_id == CODEC_ID_ATRAC3) ||
            (st->codec->codec_id == CODEC_ID_SIPR)) {
739
            int x;
740 741 742 743 744
            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;
745

746
            if (flags & 2)
747
                y = ast->sub_packet_cnt = 0;
748
            if (!y)
749
                ast->audiotimestamp = timestamp;
750 751 752 753

            switch(st->codec->codec_id) {
                case CODEC_ID_RA_288:
                    for (x = 0; x < h/2; x++)
754
                        get_buffer(pb, ast->pkt.data+x*2*w+y*cfs, cfs);
755 756 757 758
                    break;
                case CODEC_ID_ATRAC3:
                case CODEC_ID_COOK:
                    for (x = 0; x < w/sps; x++)
759
                        get_buffer(pb, ast->pkt.data+sps*(h*x+((h+1)/2)*(y&1)+(y>>1)), sps);
760
                    break;
761 762 763
                case CODEC_ID_SIPR:
                    get_buffer(pb, ast->pkt.data + y * w, w);
                    break;
764 765
            }

766
            if (++(ast->sub_packet_cnt) < h)
767
                return -1;
768 769 770
            if (st->codec->codec_id == CODEC_ID_SIPR)
                rm_reorder_sipr_data(ast);

771 772 773
             ast->sub_packet_cnt = 0;
             rm->audio_stream_num = st->index;
             rm->audio_pkt_cnt = h * w / st->codec->block_align;
774 775 776
        } else if (st->codec->codec_id == CODEC_ID_AAC) {
            int x;
            rm->audio_stream_num = st->index;
777 778 779 780
            ast->sub_packet_cnt = (get_be16(pb) & 0xf0) >> 4;
            if (ast->sub_packet_cnt) {
                for (x = 0; x < ast->sub_packet_cnt; x++)
                    ast->sub_packet_lengths[x] = get_be16(pb);
781
                rm->audio_pkt_cnt = ast->sub_packet_cnt;
782
                ast->audiotimestamp = timestamp;
783 784
            } else
                return -1;
785
        } else {
786
            av_get_packet(pb, pkt, len);
787
            rm_ac3_swap_bytes(st, pkt);
788
        }
789 790 791 792 793 794 795 796 797
    } else
        av_get_packet(pb, pkt, len);

    pkt->stream_index = st->index;

#if 0
    if (st->codec->codec_type == CODEC_TYPE_VIDEO) {
        if(st->codec->codec_id == CODEC_ID_RV20){
            int seq= 128*(pkt->data[2]&0x7F) + (pkt->data[3]>>1);
798
            av_log(s, AV_LOG_DEBUG, "%d %"PRId64" %d\n", *timestamp, *timestamp*512LL/25, seq);
799

800 801 802
            seq |= (timestamp&~0x3FFF);
            if(seq - timestamp >  0x2000) seq -= 0x4000;
            if(seq - timestamp < -0x2000) seq += 0x4000;
803 804 805 806
        }
    }
#endif

807 808
    pkt->pts= timestamp;
    if (flags & 2)
809 810
        pkt->flags |= PKT_FLAG_KEY;

811
    return st->codec->codec_type == CODEC_TYPE_AUDIO ? rm->audio_pkt_cnt : 0;
812 813
}

814
int
815
ff_rm_retrieve_cache (AVFormatContext *s, ByteIOContext *pb,
816
                      AVStream *st, RMStream *ast, AVPacket *pkt)
817
{
818
    RMDemuxContext *rm = s->priv_data;
819 820 821 822

    assert (rm->audio_pkt_cnt > 0);

    if (st->codec->codec_id == CODEC_ID_AAC)
823
        av_get_packet(pb, pkt, ast->sub_packet_lengths[ast->sub_packet_cnt - rm->audio_pkt_cnt]);
824 825
    else {
        av_new_packet(pkt, st->codec->block_align);
826
        memcpy(pkt->data, ast->pkt.data + st->codec->block_align * //FIXME avoid this
827
               (ast->sub_packet_h * ast->audio_framesize / st->codec->block_align - rm->audio_pkt_cnt),
828 829 830
               st->codec->block_align);
    }
    rm->audio_pkt_cnt--;
831 832 833 834
    if ((pkt->pts = ast->audiotimestamp) != AV_NOPTS_VALUE) {
        ast->audiotimestamp = AV_NOPTS_VALUE;
        pkt->flags = PKT_FLAG_KEY;
    } else
835
        pkt->flags = 0;
836
    pkt->stream_index = st->index;
837 838

    return rm->audio_pkt_cnt;
839 840
}

Fabrice Bellard's avatar
Fabrice Bellard committed
841 842
static int rm_read_packet(AVFormatContext *s, AVPacket *pkt)
{
843
    RMDemuxContext *rm = s->priv_data;
Fabrice Bellard's avatar
Fabrice Bellard committed
844
    AVStream *st;
845
    int i, len, res, seq = 1;
846
    int64_t timestamp, pos;
847
    int flags;
Fabrice Bellard's avatar
Fabrice Bellard committed
848

849
    for (;;) {
850 851 852 853
        if (rm->audio_pkt_cnt) {
            // If there are queued audio packet return them first
            st = s->streams[rm->audio_stream_num];
            ff_rm_retrieve_cache(s, s->pb, st, st->priv_data, pkt);
854 855
        } else {
            if (rm->old_format) {
856
                RMStream *ast;
Ronald S. Bultje's avatar
Ronald S. Bultje committed
857

858 859
                st = s->streams[0];
                ast = st->priv_data;
860 861 862 863
                timestamp = AV_NOPTS_VALUE;
                len = !ast->audio_framesize ? RAW_PACKET_SIZE :
                    ast->coded_framesize * ast->sub_packet_h / 2;
                flags = (seq++ == 1) ? 2 : 0;
864 865
            } else {
                len=sync(s, &timestamp, &flags, &i, &pos);
866 867
                if (len > 0)
                    st = s->streams[i];
868 869 870 871
            }

            if(len<0 || url_feof(s->pb))
                return AVERROR(EIO);
Michael Niedermayer's avatar
Michael Niedermayer committed
872

873
            res = ff_rm_parse_packet (s, s->pb, st, st->priv_data, len, pkt,
874
                                      &seq, flags, timestamp);
875
            if((flags&2) && (seq&0x7F) == 1)
876
                av_add_index_entry(st, pos, timestamp, 0, 0, AVINDEX_KEYFRAME);
877 878 879
            if (res)
                continue;
        }
Michael Niedermayer's avatar
Michael Niedermayer committed
880

881 882 883
        if(  (st->discard >= AVDISCARD_NONKEY && !(flags&2))
           || st->discard >= AVDISCARD_ALL){
            av_free_packet(pkt);
884 885
        } else
            break;
886 887
    }

Fabrice Bellard's avatar
Fabrice Bellard committed
888 889 890 891 892
    return 0;
}

static int rm_read_close(AVFormatContext *s)
{
893 894 895 896
    int i;

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

Fabrice Bellard's avatar
Fabrice Bellard committed
898 899 900
    return 0;
}

Fabrice Bellard's avatar
Fabrice Bellard committed
901 902 903
static int rm_probe(AVProbeData *p)
{
    /* check file header */
904 905 906 907 908
    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
909 910 911 912 913
        return AVPROBE_SCORE_MAX;
    else
        return 0;
}

914
static int64_t rm_read_dts(AVFormatContext *s, int stream_index,
Michael Niedermayer's avatar
Michael Niedermayer committed
915 916
                               int64_t *ppos, int64_t pos_limit)
{
917
    RMDemuxContext *rm = s->priv_data;
Michael Niedermayer's avatar
Michael Niedermayer committed
918
    int64_t pos, dts;
919
    int stream_index2, flags, len, h;
Michael Niedermayer's avatar
Michael Niedermayer committed
920 921

    pos = *ppos;
922

Michael Niedermayer's avatar
Michael Niedermayer committed
923 924 925
    if(rm->old_format)
        return AV_NOPTS_VALUE;

926
    url_fseek(s->pb, pos, SEEK_SET);
Michael Niedermayer's avatar
Michael Niedermayer committed
927 928
    rm->remaining_len=0;
    for(;;){
929 930 931 932
        int seq=1;
        AVStream *st;

        len=sync(s, &dts, &flags, &stream_index2, &pos);
Michael Niedermayer's avatar
Michael Niedermayer committed
933 934
        if(len<0)
            return AV_NOPTS_VALUE;
935 936

        st = s->streams[stream_index2];
937
        if (st->codec->codec_type == CODEC_TYPE_VIDEO) {
938
            h= get_byte(s->pb); len--;
939
            if(!(h & 0x40)){
940
                seq = get_byte(s->pb); len--;
Michael Niedermayer's avatar
Michael Niedermayer committed
941 942
            }
        }
943

944
        if((flags&2) && (seq&0x7F) == 1){
945
//            av_log(s, AV_LOG_DEBUG, "%d %d-%d %"PRId64" %d\n", flags, stream_index2, stream_index, dts, seq);
946
            av_add_index_entry(st, pos, dts, 0, 0, AVINDEX_KEYFRAME);
947 948 949 950
            if(stream_index2 == stream_index)
                break;
        }

951
        url_fskip(s->pb, len);
Michael Niedermayer's avatar
Michael Niedermayer committed
952 953 954 955 956
    }
    *ppos = pos;
    return dts;
}

957
AVInputFormat rm_demuxer = {
Fabrice Bellard's avatar
Fabrice Bellard committed
958
    "rm",
959
    NULL_IF_CONFIG_SMALL("RealMedia format"),
960
    sizeof(RMDemuxContext),
Fabrice Bellard's avatar
Fabrice Bellard committed
961 962 963 964
    rm_probe,
    rm_read_header,
    rm_read_packet,
    rm_read_close,
Michael Niedermayer's avatar
Michael Niedermayer committed
965 966
    NULL,
    rm_read_dts,
Fabrice Bellard's avatar
Fabrice Bellard committed
967
};
968 969 970 971

AVInputFormat rdt_demuxer = {
    "rdt",
    NULL_IF_CONFIG_SMALL("RDT demuxer"),
972
    sizeof(RMDemuxContext),
973 974 975 976
    NULL,
    NULL,
    NULL,
    rm_read_close,
977
};