91
89
return AVPROBE_SCORE_MAX;
94
static int fourxm_read_header(AVFormatContext *s,
95
AVFormatParameters *ap)
92
static int parse_vtrk(AVFormatContext *s,
93
FourxmDemuxContext *fourxm, uint8_t *buf, int size,
97
/* check that there is enough data */
98
if (size != vtrk_SIZE || left < size + 8) {
99
return AVERROR_INVALIDDATA;
102
/* allocate a new AVStream */
103
st = avformat_new_stream(s, NULL);
105
return AVERROR(ENOMEM);
107
avpriv_set_pts_info(st, 60, 1, fourxm->fps);
109
fourxm->video_stream_index = st->index;
111
st->codec->codec_type = AVMEDIA_TYPE_VIDEO;
112
st->codec->codec_id = AV_CODEC_ID_4XM;
113
st->codec->extradata_size = 4;
114
st->codec->extradata = av_malloc(4);
115
AV_WL32(st->codec->extradata, AV_RL32(buf + 16));
116
st->codec->width = AV_RL32(buf + 36);
117
st->codec->height = AV_RL32(buf + 40);
123
static int parse_strk(AVFormatContext *s,
124
FourxmDemuxContext *fourxm, uint8_t *buf, int size,
129
/* check that there is enough data */
130
if (size != strk_SIZE || left < size + 8)
131
return AVERROR_INVALIDDATA;
133
track = AV_RL32(buf + 8);
135
if ((unsigned)track >= UINT_MAX / sizeof(AudioTrack) - 1) {
136
av_log(s, AV_LOG_ERROR, "current_track too large\n");
137
return AVERROR_INVALIDDATA;
140
return AVERROR_INVALIDDATA;
141
if (track + 1 > fourxm->track_count) {
142
AudioTrack *tmp = av_realloc(fourxm->tracks,
143
(track + 1) * sizeof(AudioTrack));
145
return AVERROR(ENOMEM);
146
fourxm->tracks = tmp;
147
memset(&fourxm->tracks[fourxm->track_count], 0,
148
sizeof(AudioTrack) * (track + 1 - fourxm->track_count));
149
fourxm->track_count = track + 1;
151
fourxm->tracks[track].adpcm = AV_RL32(buf + 12);
152
fourxm->tracks[track].channels = AV_RL32(buf + 36);
153
fourxm->tracks[track].sample_rate = AV_RL32(buf + 40);
154
fourxm->tracks[track].bits = AV_RL32(buf + 44);
155
fourxm->tracks[track].audio_pts = 0;
157
if (fourxm->tracks[track].channels <= 0 ||
158
fourxm->tracks[track].sample_rate <= 0 ||
159
fourxm->tracks[track].bits <= 0) {
160
av_log(s, AV_LOG_ERROR, "audio header invalid\n");
161
return AVERROR_INVALIDDATA;
163
/* allocate a new AVStream */
164
st = avformat_new_stream(s, NULL);
166
return AVERROR(ENOMEM);
169
avpriv_set_pts_info(st, 60, 1, fourxm->tracks[track].sample_rate);
171
fourxm->tracks[track].stream_index = st->index;
173
st->codec->codec_type = AVMEDIA_TYPE_AUDIO;
174
st->codec->codec_tag = 0;
175
st->codec->channels = fourxm->tracks[track].channels;
176
st->codec->sample_rate = fourxm->tracks[track].sample_rate;
177
st->codec->bits_per_coded_sample = fourxm->tracks[track].bits;
178
st->codec->bit_rate = st->codec->channels *
179
st->codec->sample_rate *
180
st->codec->bits_per_coded_sample;
181
st->codec->block_align = st->codec->channels *
182
st->codec->bits_per_coded_sample;
184
if (fourxm->tracks[track].adpcm){
185
st->codec->codec_id = AV_CODEC_ID_ADPCM_4XM;
186
} else if (st->codec->bits_per_coded_sample == 8) {
187
st->codec->codec_id = AV_CODEC_ID_PCM_U8;
189
st->codec->codec_id = AV_CODEC_ID_PCM_S16LE;
194
static int fourxm_read_header(AVFormatContext *s)
97
196
AVIOContext *pb = s->pb;
98
197
unsigned int fourcc_tag;
128
226
/* take the lazy approach and search for any and all vtrk and strk chunks */
129
227
for (i = 0; i < header_size - 8; i++) {
130
228
fourcc_tag = AV_RL32(&header[i]);
131
size = AV_RL32(&header[i + 4]);
229
size = AV_RL32(&header[i + 4]);
133
231
if (fourcc_tag == std__TAG) {
232
if (header_size - i < 16) {
233
ret = AVERROR_INVALIDDATA;
134
236
fourxm->fps = av_int2float(AV_RL32(&header[i + 12]));
135
237
} else if (fourcc_tag == vtrk_TAG) {
136
/* check that there is enough data */
137
if (size != vtrk_SIZE) {
138
ret= AVERROR_INVALIDDATA;
141
fourxm->width = AV_RL32(&header[i + 36]);
142
fourxm->height = AV_RL32(&header[i + 40]);
144
/* allocate a new AVStream */
145
st = avformat_new_stream(s, NULL);
147
ret= AVERROR(ENOMEM);
150
avpriv_set_pts_info(st, 60, 1, fourxm->fps);
152
fourxm->video_stream_index = st->index;
154
st->codec->codec_type = AVMEDIA_TYPE_VIDEO;
155
st->codec->codec_id = CODEC_ID_4XM;
156
st->codec->extradata_size = 4;
157
st->codec->extradata = av_malloc(4);
158
AV_WL32(st->codec->extradata, AV_RL32(&header[i + 16]));
159
st->codec->width = fourxm->width;
160
st->codec->height = fourxm->height;
238
if ((ret = parse_vtrk(s, fourxm, header + i, size,
239
header_size - i)) < 0)
163
243
} else if (fourcc_tag == strk_TAG) {
165
/* check that there is enough data */
166
if (size != strk_SIZE) {
167
ret= AVERROR_INVALIDDATA;
170
current_track = AV_RL32(&header[i + 8]);
171
if((unsigned)current_track >= UINT_MAX / sizeof(AudioTrack) - 1){
172
av_log(s, AV_LOG_ERROR, "current_track too large\n");
176
if (current_track + 1 > fourxm->track_count) {
177
fourxm->tracks = av_realloc(fourxm->tracks,
178
(current_track + 1) * sizeof(AudioTrack));
179
if (!fourxm->tracks) {
180
ret = AVERROR(ENOMEM);
183
memset(&fourxm->tracks[fourxm->track_count], 0,
184
sizeof(AudioTrack) * (current_track + 1 - fourxm->track_count));
185
fourxm->track_count = current_track + 1;
187
fourxm->tracks[current_track].adpcm = AV_RL32(&header[i + 12]);
188
fourxm->tracks[current_track].channels = AV_RL32(&header[i + 36]);
189
fourxm->tracks[current_track].sample_rate = AV_RL32(&header[i + 40]);
190
fourxm->tracks[current_track].bits = AV_RL32(&header[i + 44]);
191
fourxm->tracks[current_track].audio_pts = 0;
192
if( fourxm->tracks[current_track].channels <= 0
193
|| fourxm->tracks[current_track].sample_rate <= 0
194
|| fourxm->tracks[current_track].bits < 0){
195
av_log(s, AV_LOG_ERROR, "audio header invalid\n");
244
if ((ret = parse_strk(s, fourxm, header + i, size,
245
header_size - i)) < 0)
201
/* allocate a new AVStream */
202
st = avformat_new_stream(s, NULL);
204
ret= AVERROR(ENOMEM);
208
st->id = current_track;
209
avpriv_set_pts_info(st, 60, 1, fourxm->tracks[current_track].sample_rate);
211
fourxm->tracks[current_track].stream_index = st->index;
213
st->codec->codec_type = AVMEDIA_TYPE_AUDIO;
214
st->codec->codec_tag = 0;
215
st->codec->channels = fourxm->tracks[current_track].channels;
216
st->codec->sample_rate = fourxm->tracks[current_track].sample_rate;
217
st->codec->bits_per_coded_sample = fourxm->tracks[current_track].bits;
218
st->codec->bit_rate = st->codec->channels * st->codec->sample_rate *
219
st->codec->bits_per_coded_sample;
220
st->codec->block_align = st->codec->channels * st->codec->bits_per_coded_sample;
221
if (fourxm->tracks[current_track].adpcm){
222
st->codec->codec_id = CODEC_ID_ADPCM_4XM;
223
}else if (st->codec->bits_per_coded_sample == 8){
224
st->codec->codec_id = CODEC_ID_PCM_U8;
226
st->codec->codec_id = CODEC_ID_PCM_S16LE;
230
252
/* skip over the LIST-MOVI chunk (which is where the stream should be */
231
253
GET_LIST_HEADER();
232
if (fourcc_tag != MOVI_TAG){
233
ret= AVERROR_INVALIDDATA;
254
if (fourcc_tag != MOVI_TAG) {
255
ret = AVERROR_INVALIDDATA;
287
307
if (size + 8 < size || av_new_packet(pkt, size + 8))
288
308
return AVERROR(EIO);
289
309
pkt->stream_index = fourxm->video_stream_index;
290
pkt->pts = fourxm->video_pts;
291
pkt->pos = avio_tell(s->pb);
310
pkt->pts = fourxm->video_pts;
311
pkt->pos = avio_tell(s->pb);
292
312
memcpy(pkt->data, header, 8);
293
313
ret = avio_read(s->pb, &pkt->data[8], size);
296
316
av_free_packet(pkt);
302
322
track_number = avio_rl32(pb);
303
323
avio_skip(pb, 4);
306
if (track_number < fourxm->track_count && fourxm->tracks[track_number].channels>0) {
307
ret= av_get_packet(s->pb, pkt, size);
326
if (track_number < fourxm->track_count &&
327
fourxm->tracks[track_number].channels > 0) {
328
ret = av_get_packet(s->pb, pkt, size);
309
330
return AVERROR(EIO);
310
331
pkt->stream_index =
311
332
fourxm->tracks[track_number].stream_index;
312
pkt->pts = fourxm->tracks[track_number].audio_pts;
333
pkt->pts = fourxm->tracks[track_number].audio_pts;
315
336
/* pts accounting */
316
337
audio_frame_count = size;
317
338
if (fourxm->tracks[track_number].adpcm)
319
2 * (fourxm->tracks[track_number].channels);
321
fourxm->tracks[track_number].channels;
322
if (fourxm->tracks[track_number].adpcm){
339
audio_frame_count -= 2 * (fourxm->tracks[track_number].channels);
340
audio_frame_count /= fourxm->tracks[track_number].channels;
341
if (fourxm->tracks[track_number].adpcm) {
323
342
audio_frame_count *= 2;
325
344
audio_frame_count /=
326
(fourxm->tracks[track_number].bits / 8);
345
(fourxm->tracks[track_number].bits / 8);
327
346
fourxm->tracks[track_number].audio_pts += audio_frame_count;
330
348
avio_skip(pb, size);