~ubuntu-branches/ubuntu/quantal/mplayer2/quantal-proposed

« back to all changes in this revision

Viewing changes to ffmpeg-mt/libavformat/ipmovie.c

  • Committer: Bazaar Package Importer
  • Author(s): Reinhard Tartler
  • Date: 2011-04-21 09:21:39 UTC
  • mfrom: (1.1.1 upstream)
  • Revision ID: james.westby@ubuntu.com-20110421092139-7a21foqroxvir3wr
Tags: 2.0-54-gd33877a-1
* New upstream version
* Bug fix: "internal MP3 decoder miscompiles with gcc 4.6", thanks to
  Norbert Preining (Closes: #623279). Fixed by no longer using internal
  mp3lib copy.
* drop build host specific optimizations

Show diffs side-by-side

added added

removed removed

Lines of Context:
2
2
 * Interplay MVE File Demuxer
3
3
 * Copyright (c) 2003 The ffmpeg Project
4
4
 *
5
 
 * This file is part of FFmpeg.
 
5
 * This file is part of Libav.
6
6
 *
7
 
 * FFmpeg is free software; you can redistribute it and/or
 
7
 * Libav is free software; you can redistribute it and/or
8
8
 * modify it under the terms of the GNU Lesser General Public
9
9
 * License as published by the Free Software Foundation; either
10
10
 * version 2.1 of the License, or (at your option) any later version.
11
11
 *
12
 
 * FFmpeg is distributed in the hope that it will be useful,
 
12
 * Libav is distributed in the hope that it will be useful,
13
13
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14
14
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
15
15
 * Lesser General Public License for more details.
16
16
 *
17
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
 
18
 * License along with Libav; if not, write to the Free Software
19
19
 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
20
20
 */
21
21
 
120
120
 
121
121
} IPMVEContext;
122
122
 
123
 
static int load_ipmovie_packet(IPMVEContext *s, ByteIOContext *pb,
 
123
static int load_ipmovie_packet(IPMVEContext *s, AVIOContext *pb,
124
124
    AVPacket *pkt) {
125
125
 
126
126
    int chunk_type;
133
133
            s->audio_chunk_size -= 6;
134
134
        }
135
135
 
136
 
        url_fseek(pb, s->audio_chunk_offset, SEEK_SET);
 
136
        avio_seek(pb, s->audio_chunk_offset, SEEK_SET);
137
137
        s->audio_chunk_offset = 0;
138
138
 
139
139
        if (s->audio_chunk_size != av_get_packet(pb, pkt, s->audio_chunk_size))
163
163
            return CHUNK_NOMEM;
164
164
 
165
165
        pkt->pos= s->decode_map_chunk_offset;
166
 
        url_fseek(pb, s->decode_map_chunk_offset, SEEK_SET);
 
166
        avio_seek(pb, s->decode_map_chunk_offset, SEEK_SET);
167
167
        s->decode_map_chunk_offset = 0;
168
168
 
169
 
        if (get_buffer(pb, pkt->data, s->decode_map_chunk_size) !=
 
169
        if (avio_read(pb, pkt->data, s->decode_map_chunk_size) !=
170
170
            s->decode_map_chunk_size) {
171
171
            av_free_packet(pkt);
172
172
            return CHUNK_EOF;
173
173
        }
174
174
 
175
 
        url_fseek(pb, s->video_chunk_offset, SEEK_SET);
 
175
        avio_seek(pb, s->video_chunk_offset, SEEK_SET);
176
176
        s->video_chunk_offset = 0;
177
177
 
178
 
        if (get_buffer(pb, pkt->data + s->decode_map_chunk_size,
 
178
        if (avio_read(pb, pkt->data + s->decode_map_chunk_size,
179
179
            s->video_chunk_size) != s->video_chunk_size) {
180
180
            av_free_packet(pkt);
181
181
            return CHUNK_EOF;
193
193
 
194
194
    } else {
195
195
 
196
 
        url_fseek(pb, s->next_chunk_offset, SEEK_SET);
 
196
        avio_seek(pb, s->next_chunk_offset, SEEK_SET);
197
197
        chunk_type = CHUNK_DONE;
198
198
 
199
199
    }
203
203
 
204
204
/* This function loads and processes a single chunk in an IP movie file.
205
205
 * It returns the type of chunk that was processed. */
206
 
static int process_ipmovie_chunk(IPMVEContext *s, ByteIOContext *pb,
 
206
static int process_ipmovie_chunk(IPMVEContext *s, AVIOContext *pb,
207
207
    AVPacket *pkt)
208
208
{
209
209
    unsigned char chunk_preamble[CHUNK_PREAMBLE_SIZE];
225
225
        return chunk_type;
226
226
 
227
227
    /* read the next chunk, wherever the file happens to be pointing */
228
 
    if (url_feof(pb))
 
228
    if (pb->eof_reached)
229
229
        return CHUNK_EOF;
230
 
    if (get_buffer(pb, chunk_preamble, CHUNK_PREAMBLE_SIZE) !=
 
230
    if (avio_read(pb, chunk_preamble, CHUNK_PREAMBLE_SIZE) !=
231
231
        CHUNK_PREAMBLE_SIZE)
232
232
        return CHUNK_BAD;
233
233
    chunk_size = AV_RL16(&chunk_preamble[0]);
271
271
    while ((chunk_size > 0) && (chunk_type != CHUNK_BAD)) {
272
272
 
273
273
        /* read the next chunk, wherever the file happens to be pointing */
274
 
        if (url_feof(pb)) {
 
274
        if (pb->eof_reached) {
275
275
            chunk_type = CHUNK_EOF;
276
276
            break;
277
277
        }
278
 
        if (get_buffer(pb, opcode_preamble, CHUNK_PREAMBLE_SIZE) !=
 
278
        if (avio_read(pb, opcode_preamble, CHUNK_PREAMBLE_SIZE) !=
279
279
            CHUNK_PREAMBLE_SIZE) {
280
280
            chunk_type = CHUNK_BAD;
281
281
            break;
299
299
 
300
300
        case OPCODE_END_OF_STREAM:
301
301
            debug_ipmovie("end of stream\n");
302
 
            url_fseek(pb, opcode_size, SEEK_CUR);
 
302
            avio_skip(pb, opcode_size);
303
303
            break;
304
304
 
305
305
        case OPCODE_END_OF_CHUNK:
306
306
            debug_ipmovie("end of chunk\n");
307
 
            url_fseek(pb, opcode_size, SEEK_CUR);
 
307
            avio_skip(pb, opcode_size);
308
308
            break;
309
309
 
310
310
        case OPCODE_CREATE_TIMER:
314
314
                chunk_type = CHUNK_BAD;
315
315
                break;
316
316
            }
317
 
            if (get_buffer(pb, scratch, opcode_size) !=
 
317
            if (avio_read(pb, scratch, opcode_size) !=
318
318
                opcode_size) {
319
319
                chunk_type = CHUNK_BAD;
320
320
                break;
331
331
                chunk_type = CHUNK_BAD;
332
332
                break;
333
333
            }
334
 
            if (get_buffer(pb, scratch, opcode_size) !=
 
334
            if (avio_read(pb, scratch, opcode_size) !=
335
335
                opcode_size) {
336
336
                chunk_type = CHUNK_BAD;
337
337
                break;
359
359
 
360
360
        case OPCODE_START_STOP_AUDIO:
361
361
            debug_ipmovie("start/stop audio\n");
362
 
            url_fseek(pb, opcode_size, SEEK_CUR);
 
362
            avio_skip(pb, opcode_size);
363
363
            break;
364
364
 
365
365
        case OPCODE_INIT_VIDEO_BUFFERS:
369
369
                chunk_type = CHUNK_BAD;
370
370
                break;
371
371
            }
372
 
            if (get_buffer(pb, scratch, opcode_size) !=
 
372
            if (avio_read(pb, scratch, opcode_size) !=
373
373
                opcode_size) {
374
374
                chunk_type = CHUNK_BAD;
375
375
                break;
393
393
        case OPCODE_UNKNOWN_14:
394
394
        case OPCODE_UNKNOWN_15:
395
395
            debug_ipmovie("unknown (but documented) opcode %02X\n", opcode_type);
396
 
            url_fseek(pb, opcode_size, SEEK_CUR);
 
396
            avio_skip(pb, opcode_size);
397
397
            break;
398
398
 
399
399
        case OPCODE_SEND_BUFFER:
400
400
            debug_ipmovie("send buffer\n");
401
 
            url_fseek(pb, opcode_size, SEEK_CUR);
 
401
            avio_skip(pb, opcode_size);
402
402
            break;
403
403
 
404
404
        case OPCODE_AUDIO_FRAME:
405
405
            debug_ipmovie("audio frame\n");
406
406
 
407
407
            /* log position and move on for now */
408
 
            s->audio_chunk_offset = url_ftell(pb);
 
408
            s->audio_chunk_offset = avio_tell(pb);
409
409
            s->audio_chunk_size = opcode_size;
410
 
            url_fseek(pb, opcode_size, SEEK_CUR);
 
410
            avio_skip(pb, opcode_size);
411
411
            break;
412
412
 
413
413
        case OPCODE_SILENCE_FRAME:
414
414
            debug_ipmovie("silence frame\n");
415
 
            url_fseek(pb, opcode_size, SEEK_CUR);
 
415
            avio_skip(pb, opcode_size);
416
416
            break;
417
417
 
418
418
        case OPCODE_INIT_VIDEO_MODE:
419
419
            debug_ipmovie("initialize video mode\n");
420
 
            url_fseek(pb, opcode_size, SEEK_CUR);
 
420
            avio_skip(pb, opcode_size);
421
421
            break;
422
422
 
423
423
        case OPCODE_CREATE_GRADIENT:
424
424
            debug_ipmovie("create gradient\n");
425
 
            url_fseek(pb, opcode_size, SEEK_CUR);
 
425
            avio_skip(pb, opcode_size);
426
426
            break;
427
427
 
428
428
        case OPCODE_SET_PALETTE:
434
434
                chunk_type = CHUNK_BAD;
435
435
                break;
436
436
            }
437
 
            if (get_buffer(pb, scratch, opcode_size) != opcode_size) {
 
437
            if (avio_read(pb, scratch, opcode_size) != opcode_size) {
438
438
                chunk_type = CHUNK_BAD;
439
439
                break;
440
440
            }
464
464
 
465
465
        case OPCODE_SET_PALETTE_COMPRESSED:
466
466
            debug_ipmovie("set palette compressed\n");
467
 
            url_fseek(pb, opcode_size, SEEK_CUR);
 
467
            avio_skip(pb, opcode_size);
468
468
            break;
469
469
 
470
470
        case OPCODE_SET_DECODING_MAP:
471
471
            debug_ipmovie("set decoding map\n");
472
472
 
473
473
            /* log position and move on for now */
474
 
            s->decode_map_chunk_offset = url_ftell(pb);
 
474
            s->decode_map_chunk_offset = avio_tell(pb);
475
475
            s->decode_map_chunk_size = opcode_size;
476
 
            url_fseek(pb, opcode_size, SEEK_CUR);
 
476
            avio_skip(pb, opcode_size);
477
477
            break;
478
478
 
479
479
        case OPCODE_VIDEO_DATA:
480
480
            debug_ipmovie("set video data\n");
481
481
 
482
482
            /* log position and move on for now */
483
 
            s->video_chunk_offset = url_ftell(pb);
 
483
            s->video_chunk_offset = avio_tell(pb);
484
484
            s->video_chunk_size = opcode_size;
485
 
            url_fseek(pb, opcode_size, SEEK_CUR);
 
485
            avio_skip(pb, opcode_size);
486
486
            break;
487
487
 
488
488
        default:
494
494
    }
495
495
 
496
496
    /* make a note of where the stream is sitting */
497
 
    s->next_chunk_offset = url_ftell(pb);
 
497
    s->next_chunk_offset = avio_tell(pb);
498
498
 
499
499
    /* dispatch the first of any pending packets */
500
500
    if ((chunk_type == CHUNK_VIDEO) || (chunk_type == CHUNK_AUDIO_ONLY))
521
521
                               AVFormatParameters *ap)
522
522
{
523
523
    IPMVEContext *ipmovie = s->priv_data;
524
 
    ByteIOContext *pb = s->pb;
 
524
    AVIOContext *pb = s->pb;
525
525
    AVPacket pkt;
526
526
    AVStream *st;
527
527
    unsigned char chunk_preamble[CHUNK_PREAMBLE_SIZE];
528
528
    int chunk_type;
529
529
    uint8_t signature_buffer[sizeof(signature)];
530
530
 
531
 
    get_buffer(pb, signature_buffer, sizeof(signature_buffer));
 
531
    avio_read(pb, signature_buffer, sizeof(signature_buffer));
532
532
    while (memcmp(signature_buffer, signature, sizeof(signature))) {
533
533
        memmove(signature_buffer, signature_buffer + 1, sizeof(signature_buffer) - 1);
534
 
        signature_buffer[sizeof(signature_buffer) - 1] = get_byte(pb);
535
 
        if (url_feof(pb))
 
534
        signature_buffer[sizeof(signature_buffer) - 1] = avio_r8(pb);
 
535
        if (pb->eof_reached)
536
536
            return AVERROR_EOF;
537
537
    }
538
538
    /* initialize private context members */
541
541
    ipmovie->decode_map_chunk_offset = 0;
542
542
 
543
543
    /* on the first read, this will position the stream at the first chunk */
544
 
    ipmovie->next_chunk_offset = url_ftell(pb) + 4;
 
544
    ipmovie->next_chunk_offset = avio_tell(pb) + 4;
545
545
 
546
546
    /* process the first chunk which should be CHUNK_INIT_VIDEO */
547
547
    if (process_ipmovie_chunk(ipmovie, pb, &pkt) != CHUNK_INIT_VIDEO)
549
549
 
550
550
    /* peek ahead to the next chunk-- if it is an init audio chunk, process
551
551
     * it; if it is the first video chunk, this is a silent file */
552
 
    if (get_buffer(pb, chunk_preamble, CHUNK_PREAMBLE_SIZE) !=
 
552
    if (avio_read(pb, chunk_preamble, CHUNK_PREAMBLE_SIZE) !=
553
553
        CHUNK_PREAMBLE_SIZE)
554
554
        return AVERROR(EIO);
555
555
    chunk_type = AV_RL16(&chunk_preamble[2]);
556
 
    url_fseek(pb, -CHUNK_PREAMBLE_SIZE, SEEK_CUR);
 
556
    avio_seek(pb, -CHUNK_PREAMBLE_SIZE, SEEK_CUR);
557
557
 
558
558
    if (chunk_type == CHUNK_VIDEO)
559
559
        ipmovie->audio_type = CODEC_ID_NONE;  /* no audio */
602
602
                               AVPacket *pkt)
603
603
{
604
604
    IPMVEContext *ipmovie = s->priv_data;
605
 
    ByteIOContext *pb = s->pb;
 
605
    AVIOContext *pb = s->pb;
606
606
    int ret;
607
607
 
608
608
    ret = process_ipmovie_chunk(ipmovie, pb, pkt);
620
620
    return ret;
621
621
}
622
622
 
623
 
AVInputFormat ipmovie_demuxer = {
 
623
AVInputFormat ff_ipmovie_demuxer = {
624
624
    "ipmovie",
625
625
    NULL_IF_CONFIG_SMALL("Interplay MVE format"),
626
626
    sizeof(IPMVEContext),