Revision 2aa751d2

View differences:

MAINTAINERS
274 274
  gxf.c                                 Reimar Doeffinger
275 275
  gxfenc.c                              Baptiste Coudurier
276 276
  idcin.c                               Mike Melanson
277
  idroq.c                               Mike Melanson
277
  idroqdec.c                            Mike Melanson
278 278
  iff.c                                 Jaikrishnan Menon
279 279
  ipmovie.c                             Mike Melanson
280 280
  img2.c                                Michael Niedermayer
libavformat/Makefile
209 209
OBJS-$(CONFIG_RL2_DEMUXER)               += rl2.o
210 210
OBJS-$(CONFIG_RM_DEMUXER)                += rmdec.o rm.o
211 211
OBJS-$(CONFIG_RM_MUXER)                  += rmenc.o rm.o
212
OBJS-$(CONFIG_ROQ_DEMUXER)               += idroq.o
212
OBJS-$(CONFIG_ROQ_DEMUXER)               += idroqdec.o
213 213
OBJS-$(CONFIG_ROQ_MUXER)                 += idroqenc.o
214 214
OBJS-$(CONFIG_RSO_DEMUXER)               += rsodec.o rso.o raw.o
215 215
OBJS-$(CONFIG_RSO_MUXER)                 += rsoenc.o rso.o
libavformat/idroq.c
1
/*
2
 * id RoQ (.roq) File Demuxer
3
 * Copyright (c) 2003 The ffmpeg Project
4
 *
5
 * This file is part of FFmpeg.
6
 *
7
 * FFmpeg is free software; you can redistribute it and/or
8
 * modify it under the terms of the GNU Lesser General Public
9
 * License as published by the Free Software Foundation; either
10
 * version 2.1 of the License, or (at your option) any later version.
11
 *
12
 * FFmpeg is distributed in the hope that it will be useful,
13
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
15
 * Lesser General Public License for more details.
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
20
 */
21

  
22
/**
23
 * @file
24
 * id RoQ format file demuxer
25
 * by Mike Melanson (melanson@pcisys.net)
26
 * for more information on the .roq file format, visit:
27
 *   http://www.csse.monash.edu.au/~timf/
28
 */
29

  
30
#include "libavutil/intreadwrite.h"
31
#include "avformat.h"
32

  
33
#define RoQ_MAGIC_NUMBER 0x1084
34
#define RoQ_CHUNK_PREAMBLE_SIZE 8
35
#define RoQ_AUDIO_SAMPLE_RATE 22050
36
#define RoQ_CHUNKS_TO_SCAN 30
37

  
38
#define RoQ_INFO           0x1001
39
#define RoQ_QUAD_CODEBOOK  0x1002
40
#define RoQ_QUAD_VQ        0x1011
41
#define RoQ_SOUND_MONO     0x1020
42
#define RoQ_SOUND_STEREO   0x1021
43

  
44
typedef struct RoqDemuxContext {
45

  
46
    int width;
47
    int height;
48
    int audio_channels;
49

  
50
    int video_stream_index;
51
    int audio_stream_index;
52

  
53
    int64_t video_pts;
54
    unsigned int audio_frame_count;
55

  
56
} RoqDemuxContext;
57

  
58
static int roq_probe(AVProbeData *p)
59
{
60
    if ((AV_RL16(&p->buf[0]) != RoQ_MAGIC_NUMBER) ||
61
        (AV_RL32(&p->buf[2]) != 0xFFFFFFFF))
62
        return 0;
63

  
64
    return AVPROBE_SCORE_MAX;
65
}
66

  
67
static int roq_read_header(AVFormatContext *s,
68
                           AVFormatParameters *ap)
69
{
70
    RoqDemuxContext *roq = s->priv_data;
71
    ByteIOContext *pb = s->pb;
72
    int framerate;
73
    AVStream *st;
74
    unsigned char preamble[RoQ_CHUNK_PREAMBLE_SIZE];
75

  
76
    /* get the main header */
77
    if (get_buffer(pb, preamble, RoQ_CHUNK_PREAMBLE_SIZE) !=
78
        RoQ_CHUNK_PREAMBLE_SIZE)
79
        return AVERROR(EIO);
80
    framerate = AV_RL16(&preamble[6]);
81

  
82
    /* init private context parameters */
83
    roq->width = roq->height = roq->audio_channels = roq->video_pts =
84
    roq->audio_frame_count = 0;
85
    roq->audio_stream_index = -1;
86

  
87
    st = av_new_stream(s, 0);
88
    if (!st)
89
        return AVERROR(ENOMEM);
90
    av_set_pts_info(st, 63, 1, framerate);
91
    roq->video_stream_index = st->index;
92
    st->codec->codec_type = AVMEDIA_TYPE_VIDEO;
93
    st->codec->codec_id = CODEC_ID_ROQ;
94
    st->codec->codec_tag = 0;  /* no fourcc */
95

  
96
    return 0;
97
}
98

  
99
static int roq_read_packet(AVFormatContext *s,
100
                           AVPacket *pkt)
101
{
102
    RoqDemuxContext *roq = s->priv_data;
103
    ByteIOContext *pb = s->pb;
104
    int ret = 0;
105
    unsigned int chunk_size;
106
    unsigned int chunk_type;
107
    unsigned int codebook_size;
108
    unsigned char preamble[RoQ_CHUNK_PREAMBLE_SIZE];
109
    int packet_read = 0;
110
    int64_t codebook_offset;
111

  
112
    while (!packet_read) {
113

  
114
        if (url_feof(s->pb))
115
            return AVERROR(EIO);
116

  
117
        /* get the next chunk preamble */
118
        if ((ret = get_buffer(pb, preamble, RoQ_CHUNK_PREAMBLE_SIZE)) !=
119
            RoQ_CHUNK_PREAMBLE_SIZE)
120
            return AVERROR(EIO);
121

  
122
        chunk_type = AV_RL16(&preamble[0]);
123
        chunk_size = AV_RL32(&preamble[2]);
124
        if(chunk_size > INT_MAX)
125
            return AVERROR_INVALIDDATA;
126

  
127
        switch (chunk_type) {
128

  
129
        case RoQ_INFO:
130
            if (!roq->width || !roq->height) {
131
                AVStream *st = s->streams[roq->video_stream_index];
132
                if (get_buffer(pb, preamble, RoQ_CHUNK_PREAMBLE_SIZE) != RoQ_CHUNK_PREAMBLE_SIZE)
133
                    return AVERROR(EIO);
134
                st->codec->width  = roq->width  = AV_RL16(preamble);
135
                st->codec->height = roq->height = AV_RL16(preamble + 2);
136
                break;
137
            }
138
            /* don't care about this chunk anymore */
139
            url_fseek(pb, RoQ_CHUNK_PREAMBLE_SIZE, SEEK_CUR);
140
            break;
141

  
142
        case RoQ_QUAD_CODEBOOK:
143
            /* packet needs to contain both this codebook and next VQ chunk */
144
            codebook_offset = url_ftell(pb) - RoQ_CHUNK_PREAMBLE_SIZE;
145
            codebook_size = chunk_size;
146
            url_fseek(pb, codebook_size, SEEK_CUR);
147
            if (get_buffer(pb, preamble, RoQ_CHUNK_PREAMBLE_SIZE) !=
148
                RoQ_CHUNK_PREAMBLE_SIZE)
149
                return AVERROR(EIO);
150
            chunk_size = AV_RL32(&preamble[2]) + RoQ_CHUNK_PREAMBLE_SIZE * 2 +
151
                codebook_size;
152

  
153
            /* rewind */
154
            url_fseek(pb, codebook_offset, SEEK_SET);
155

  
156
            /* load up the packet */
157
            ret= av_get_packet(pb, pkt, chunk_size);
158
            if (ret != chunk_size)
159
                return AVERROR(EIO);
160
            pkt->stream_index = roq->video_stream_index;
161
            pkt->pts = roq->video_pts++;
162

  
163
            packet_read = 1;
164
            break;
165

  
166
        case RoQ_SOUND_MONO:
167
        case RoQ_SOUND_STEREO:
168
            if (roq->audio_stream_index == -1) {
169
                AVStream *st = av_new_stream(s, 1);
170
                if (!st)
171
                    return AVERROR(ENOMEM);
172
                av_set_pts_info(st, 32, 1, RoQ_AUDIO_SAMPLE_RATE);
173
                roq->audio_stream_index = st->index;
174
                st->codec->codec_type = AVMEDIA_TYPE_AUDIO;
175
                st->codec->codec_id = CODEC_ID_ROQ_DPCM;
176
                st->codec->codec_tag = 0;  /* no tag */
177
                st->codec->channels = roq->audio_channels = chunk_type == RoQ_SOUND_STEREO ? 2 : 1;
178
                st->codec->sample_rate = RoQ_AUDIO_SAMPLE_RATE;
179
                st->codec->bits_per_coded_sample = 16;
180
                st->codec->bit_rate = st->codec->channels * st->codec->sample_rate *
181
                    st->codec->bits_per_coded_sample;
182
                st->codec->block_align = st->codec->channels * st->codec->bits_per_coded_sample;
183
            }
184
        case RoQ_QUAD_VQ:
185
            /* load up the packet */
186
            if (av_new_packet(pkt, chunk_size + RoQ_CHUNK_PREAMBLE_SIZE))
187
                return AVERROR(EIO);
188
            /* copy over preamble */
189
            memcpy(pkt->data, preamble, RoQ_CHUNK_PREAMBLE_SIZE);
190

  
191
            if (chunk_type == RoQ_QUAD_VQ) {
192
                pkt->stream_index = roq->video_stream_index;
193
                pkt->pts = roq->video_pts++;
194
            } else {
195
                pkt->stream_index = roq->audio_stream_index;
196
                pkt->pts = roq->audio_frame_count;
197
                roq->audio_frame_count += (chunk_size / roq->audio_channels);
198
            }
199

  
200
            pkt->pos= url_ftell(pb);
201
            ret = get_buffer(pb, pkt->data + RoQ_CHUNK_PREAMBLE_SIZE,
202
                chunk_size);
203
            if (ret != chunk_size)
204
                ret = AVERROR(EIO);
205

  
206
            packet_read = 1;
207
            break;
208

  
209
        default:
210
            av_log(s, AV_LOG_ERROR, "  unknown RoQ chunk (%04X)\n", chunk_type);
211
            return AVERROR_INVALIDDATA;
212
            break;
213
        }
214
    }
215

  
216
    return ret;
217
}
218

  
219
AVInputFormat roq_demuxer = {
220
    "RoQ",
221
    NULL_IF_CONFIG_SMALL("id RoQ format"),
222
    sizeof(RoqDemuxContext),
223
    roq_probe,
224
    roq_read_header,
225
    roq_read_packet,
226
};
libavformat/idroqdec.c
1
/*
2
 * id RoQ (.roq) File Demuxer
3
 * Copyright (c) 2003 The ffmpeg Project
4
 *
5
 * This file is part of FFmpeg.
6
 *
7
 * FFmpeg is free software; you can redistribute it and/or
8
 * modify it under the terms of the GNU Lesser General Public
9
 * License as published by the Free Software Foundation; either
10
 * version 2.1 of the License, or (at your option) any later version.
11
 *
12
 * FFmpeg is distributed in the hope that it will be useful,
13
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
15
 * Lesser General Public License for more details.
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
20
 */
21

  
22
/**
23
 * @file
24
 * id RoQ format file demuxer
25
 * by Mike Melanson (melanson@pcisys.net)
26
 * for more information on the .roq file format, visit:
27
 *   http://www.csse.monash.edu.au/~timf/
28
 */
29

  
30
#include "libavutil/intreadwrite.h"
31
#include "avformat.h"
32

  
33
#define RoQ_MAGIC_NUMBER 0x1084
34
#define RoQ_CHUNK_PREAMBLE_SIZE 8
35
#define RoQ_AUDIO_SAMPLE_RATE 22050
36
#define RoQ_CHUNKS_TO_SCAN 30
37

  
38
#define RoQ_INFO           0x1001
39
#define RoQ_QUAD_CODEBOOK  0x1002
40
#define RoQ_QUAD_VQ        0x1011
41
#define RoQ_SOUND_MONO     0x1020
42
#define RoQ_SOUND_STEREO   0x1021
43

  
44
typedef struct RoqDemuxContext {
45

  
46
    int width;
47
    int height;
48
    int audio_channels;
49

  
50
    int video_stream_index;
51
    int audio_stream_index;
52

  
53
    int64_t video_pts;
54
    unsigned int audio_frame_count;
55

  
56
} RoqDemuxContext;
57

  
58
static int roq_probe(AVProbeData *p)
59
{
60
    if ((AV_RL16(&p->buf[0]) != RoQ_MAGIC_NUMBER) ||
61
        (AV_RL32(&p->buf[2]) != 0xFFFFFFFF))
62
        return 0;
63

  
64
    return AVPROBE_SCORE_MAX;
65
}
66

  
67
static int roq_read_header(AVFormatContext *s,
68
                           AVFormatParameters *ap)
69
{
70
    RoqDemuxContext *roq = s->priv_data;
71
    ByteIOContext *pb = s->pb;
72
    int framerate;
73
    AVStream *st;
74
    unsigned char preamble[RoQ_CHUNK_PREAMBLE_SIZE];
75

  
76
    /* get the main header */
77
    if (get_buffer(pb, preamble, RoQ_CHUNK_PREAMBLE_SIZE) !=
78
        RoQ_CHUNK_PREAMBLE_SIZE)
79
        return AVERROR(EIO);
80
    framerate = AV_RL16(&preamble[6]);
81

  
82
    /* init private context parameters */
83
    roq->width = roq->height = roq->audio_channels = roq->video_pts =
84
    roq->audio_frame_count = 0;
85
    roq->audio_stream_index = -1;
86

  
87
    st = av_new_stream(s, 0);
88
    if (!st)
89
        return AVERROR(ENOMEM);
90
    av_set_pts_info(st, 63, 1, framerate);
91
    roq->video_stream_index = st->index;
92
    st->codec->codec_type = AVMEDIA_TYPE_VIDEO;
93
    st->codec->codec_id = CODEC_ID_ROQ;
94
    st->codec->codec_tag = 0;  /* no fourcc */
95

  
96
    return 0;
97
}
98

  
99
static int roq_read_packet(AVFormatContext *s,
100
                           AVPacket *pkt)
101
{
102
    RoqDemuxContext *roq = s->priv_data;
103
    ByteIOContext *pb = s->pb;
104
    int ret = 0;
105
    unsigned int chunk_size;
106
    unsigned int chunk_type;
107
    unsigned int codebook_size;
108
    unsigned char preamble[RoQ_CHUNK_PREAMBLE_SIZE];
109
    int packet_read = 0;
110
    int64_t codebook_offset;
111

  
112
    while (!packet_read) {
113

  
114
        if (url_feof(s->pb))
115
            return AVERROR(EIO);
116

  
117
        /* get the next chunk preamble */
118
        if ((ret = get_buffer(pb, preamble, RoQ_CHUNK_PREAMBLE_SIZE)) !=
119
            RoQ_CHUNK_PREAMBLE_SIZE)
120
            return AVERROR(EIO);
121

  
122
        chunk_type = AV_RL16(&preamble[0]);
123
        chunk_size = AV_RL32(&preamble[2]);
124
        if(chunk_size > INT_MAX)
125
            return AVERROR_INVALIDDATA;
126

  
127
        switch (chunk_type) {
128

  
129
        case RoQ_INFO:
130
            if (!roq->width || !roq->height) {
131
                AVStream *st = s->streams[roq->video_stream_index];
132
                if (get_buffer(pb, preamble, RoQ_CHUNK_PREAMBLE_SIZE) != RoQ_CHUNK_PREAMBLE_SIZE)
133
                    return AVERROR(EIO);
134
                st->codec->width  = roq->width  = AV_RL16(preamble);
135
                st->codec->height = roq->height = AV_RL16(preamble + 2);
136
                break;
137
            }
138
            /* don't care about this chunk anymore */
139
            url_fseek(pb, RoQ_CHUNK_PREAMBLE_SIZE, SEEK_CUR);
140
            break;
141

  
142
        case RoQ_QUAD_CODEBOOK:
143
            /* packet needs to contain both this codebook and next VQ chunk */
144
            codebook_offset = url_ftell(pb) - RoQ_CHUNK_PREAMBLE_SIZE;
145
            codebook_size = chunk_size;
146
            url_fseek(pb, codebook_size, SEEK_CUR);
147
            if (get_buffer(pb, preamble, RoQ_CHUNK_PREAMBLE_SIZE) !=
148
                RoQ_CHUNK_PREAMBLE_SIZE)
149
                return AVERROR(EIO);
150
            chunk_size = AV_RL32(&preamble[2]) + RoQ_CHUNK_PREAMBLE_SIZE * 2 +
151
                codebook_size;
152

  
153
            /* rewind */
154
            url_fseek(pb, codebook_offset, SEEK_SET);
155

  
156
            /* load up the packet */
157
            ret= av_get_packet(pb, pkt, chunk_size);
158
            if (ret != chunk_size)
159
                return AVERROR(EIO);
160
            pkt->stream_index = roq->video_stream_index;
161
            pkt->pts = roq->video_pts++;
162

  
163
            packet_read = 1;
164
            break;
165

  
166
        case RoQ_SOUND_MONO:
167
        case RoQ_SOUND_STEREO:
168
            if (roq->audio_stream_index == -1) {
169
                AVStream *st = av_new_stream(s, 1);
170
                if (!st)
171
                    return AVERROR(ENOMEM);
172
                av_set_pts_info(st, 32, 1, RoQ_AUDIO_SAMPLE_RATE);
173
                roq->audio_stream_index = st->index;
174
                st->codec->codec_type = AVMEDIA_TYPE_AUDIO;
175
                st->codec->codec_id = CODEC_ID_ROQ_DPCM;
176
                st->codec->codec_tag = 0;  /* no tag */
177
                st->codec->channels = roq->audio_channels = chunk_type == RoQ_SOUND_STEREO ? 2 : 1;
178
                st->codec->sample_rate = RoQ_AUDIO_SAMPLE_RATE;
179
                st->codec->bits_per_coded_sample = 16;
180
                st->codec->bit_rate = st->codec->channels * st->codec->sample_rate *
181
                    st->codec->bits_per_coded_sample;
182
                st->codec->block_align = st->codec->channels * st->codec->bits_per_coded_sample;
183
            }
184
        case RoQ_QUAD_VQ:
185
            /* load up the packet */
186
            if (av_new_packet(pkt, chunk_size + RoQ_CHUNK_PREAMBLE_SIZE))
187
                return AVERROR(EIO);
188
            /* copy over preamble */
189
            memcpy(pkt->data, preamble, RoQ_CHUNK_PREAMBLE_SIZE);
190

  
191
            if (chunk_type == RoQ_QUAD_VQ) {
192
                pkt->stream_index = roq->video_stream_index;
193
                pkt->pts = roq->video_pts++;
194
            } else {
195
                pkt->stream_index = roq->audio_stream_index;
196
                pkt->pts = roq->audio_frame_count;
197
                roq->audio_frame_count += (chunk_size / roq->audio_channels);
198
            }
199

  
200
            pkt->pos= url_ftell(pb);
201
            ret = get_buffer(pb, pkt->data + RoQ_CHUNK_PREAMBLE_SIZE,
202
                chunk_size);
203
            if (ret != chunk_size)
204
                ret = AVERROR(EIO);
205

  
206
            packet_read = 1;
207
            break;
208

  
209
        default:
210
            av_log(s, AV_LOG_ERROR, "  unknown RoQ chunk (%04X)\n", chunk_type);
211
            return AVERROR_INVALIDDATA;
212
            break;
213
        }
214
    }
215

  
216
    return ret;
217
}
218

  
219
AVInputFormat roq_demuxer = {
220
    "RoQ",
221
    NULL_IF_CONFIG_SMALL("id RoQ format"),
222
    sizeof(RoqDemuxContext),
223
    roq_probe,
224
    roq_read_header,
225
    roq_read_packet,
226
};

Also available in: Unified diff