annotate sierravmd.c @ 2293:9aea08e128f9 libavformat

treat NONE as U8 to fix qtNONE/000_0032.MOV, this should not any have side effect since if bps is 16 in stsd, codec will be changed to s16be, just yell if this breaks any sample
author bcoudurier
date Mon, 30 Jul 2007 10:00:42 +0000
parents b21c2af60bc9
children 2e7affad5b28
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
rev   line source
338
6f50cb0ead51 initial commit for Sierra VMD file demuxer
melanson
parents:
diff changeset
1 /*
6f50cb0ead51 initial commit for Sierra VMD file demuxer
melanson
parents:
diff changeset
2 * Sierra VMD Format Demuxer
6f50cb0ead51 initial commit for Sierra VMD file demuxer
melanson
parents:
diff changeset
3 * Copyright (c) 2004 The ffmpeg Project
6f50cb0ead51 initial commit for Sierra VMD file demuxer
melanson
parents:
diff changeset
4 *
1358
0899bfe4105c Change license headers to say 'FFmpeg' instead of 'this program/this library'
diego
parents: 1169
diff changeset
5 * This file is part of FFmpeg.
0899bfe4105c Change license headers to say 'FFmpeg' instead of 'this program/this library'
diego
parents: 1169
diff changeset
6 *
0899bfe4105c Change license headers to say 'FFmpeg' instead of 'this program/this library'
diego
parents: 1169
diff changeset
7 * FFmpeg is free software; you can redistribute it and/or
338
6f50cb0ead51 initial commit for Sierra VMD file demuxer
melanson
parents:
diff changeset
8 * modify it under the terms of the GNU Lesser General Public
6f50cb0ead51 initial commit for Sierra VMD file demuxer
melanson
parents:
diff changeset
9 * License as published by the Free Software Foundation; either
1358
0899bfe4105c Change license headers to say 'FFmpeg' instead of 'this program/this library'
diego
parents: 1169
diff changeset
10 * version 2.1 of the License, or (at your option) any later version.
338
6f50cb0ead51 initial commit for Sierra VMD file demuxer
melanson
parents:
diff changeset
11 *
1358
0899bfe4105c Change license headers to say 'FFmpeg' instead of 'this program/this library'
diego
parents: 1169
diff changeset
12 * FFmpeg is distributed in the hope that it will be useful,
338
6f50cb0ead51 initial commit for Sierra VMD file demuxer
melanson
parents:
diff changeset
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
6f50cb0ead51 initial commit for Sierra VMD file demuxer
melanson
parents:
diff changeset
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
6f50cb0ead51 initial commit for Sierra VMD file demuxer
melanson
parents:
diff changeset
15 * Lesser General Public License for more details.
6f50cb0ead51 initial commit for Sierra VMD file demuxer
melanson
parents:
diff changeset
16 *
6f50cb0ead51 initial commit for Sierra VMD file demuxer
melanson
parents:
diff changeset
17 * You should have received a copy of the GNU Lesser General Public
1358
0899bfe4105c Change license headers to say 'FFmpeg' instead of 'this program/this library'
diego
parents: 1169
diff changeset
18 * License along with FFmpeg; if not, write to the Free Software
896
edbe5c3717f9 Update licensing information: The FSF changed postal address.
diego
parents: 887
diff changeset
19 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
338
6f50cb0ead51 initial commit for Sierra VMD file demuxer
melanson
parents:
diff changeset
20 */
6f50cb0ead51 initial commit for Sierra VMD file demuxer
melanson
parents:
diff changeset
21
6f50cb0ead51 initial commit for Sierra VMD file demuxer
melanson
parents:
diff changeset
22 /**
6f50cb0ead51 initial commit for Sierra VMD file demuxer
melanson
parents:
diff changeset
23 * @file sierravmd.c
6f50cb0ead51 initial commit for Sierra VMD file demuxer
melanson
parents:
diff changeset
24 * Sierra VMD file demuxer
6f50cb0ead51 initial commit for Sierra VMD file demuxer
melanson
parents:
diff changeset
25 * by Vladimir "VAG" Gneushev (vagsoft at mail.ru)
387
f2760852ed18 minor VMD system update; still not perfect, but should not crash either
melanson
parents: 338
diff changeset
26 * for more information on the Sierra VMD file format, visit:
f2760852ed18 minor VMD system update; still not perfect, but should not crash either
melanson
parents: 338
diff changeset
27 * http://www.pcisys.net/~melanson/codecs/
338
6f50cb0ead51 initial commit for Sierra VMD file demuxer
melanson
parents:
diff changeset
28 */
6f50cb0ead51 initial commit for Sierra VMD file demuxer
melanson
parents:
diff changeset
29
6f50cb0ead51 initial commit for Sierra VMD file demuxer
melanson
parents:
diff changeset
30 #include "avformat.h"
6f50cb0ead51 initial commit for Sierra VMD file demuxer
melanson
parents:
diff changeset
31
6f50cb0ead51 initial commit for Sierra VMD file demuxer
melanson
parents:
diff changeset
32 #define VMD_HEADER_SIZE 0x0330
6f50cb0ead51 initial commit for Sierra VMD file demuxer
melanson
parents:
diff changeset
33 #define BYTES_PER_FRAME_RECORD 16
6f50cb0ead51 initial commit for Sierra VMD file demuxer
melanson
parents:
diff changeset
34
6f50cb0ead51 initial commit for Sierra VMD file demuxer
melanson
parents:
diff changeset
35 typedef struct {
6f50cb0ead51 initial commit for Sierra VMD file demuxer
melanson
parents:
diff changeset
36 int stream_index;
6f50cb0ead51 initial commit for Sierra VMD file demuxer
melanson
parents:
diff changeset
37 offset_t frame_offset;
6f50cb0ead51 initial commit for Sierra VMD file demuxer
melanson
parents:
diff changeset
38 unsigned int frame_size;
6f50cb0ead51 initial commit for Sierra VMD file demuxer
melanson
parents:
diff changeset
39 int64_t pts;
6f50cb0ead51 initial commit for Sierra VMD file demuxer
melanson
parents:
diff changeset
40 int keyframe;
6f50cb0ead51 initial commit for Sierra VMD file demuxer
melanson
parents:
diff changeset
41 unsigned char frame_record[BYTES_PER_FRAME_RECORD];
6f50cb0ead51 initial commit for Sierra VMD file demuxer
melanson
parents:
diff changeset
42 } vmd_frame_t;
6f50cb0ead51 initial commit for Sierra VMD file demuxer
melanson
parents:
diff changeset
43
6f50cb0ead51 initial commit for Sierra VMD file demuxer
melanson
parents:
diff changeset
44 typedef struct VmdDemuxContext {
6f50cb0ead51 initial commit for Sierra VMD file demuxer
melanson
parents:
diff changeset
45 int video_stream_index;
6f50cb0ead51 initial commit for Sierra VMD file demuxer
melanson
parents:
diff changeset
46 int audio_stream_index;
6f50cb0ead51 initial commit for Sierra VMD file demuxer
melanson
parents:
diff changeset
47
6f50cb0ead51 initial commit for Sierra VMD file demuxer
melanson
parents:
diff changeset
48 unsigned int frame_count;
1004
409b399440a3 More correct demuxing and timestamp setting fot Sierra VMD
kostya
parents: 896
diff changeset
49 unsigned int frames_per_block;
338
6f50cb0ead51 initial commit for Sierra VMD file demuxer
melanson
parents:
diff changeset
50 vmd_frame_t *frame_table;
6f50cb0ead51 initial commit for Sierra VMD file demuxer
melanson
parents:
diff changeset
51 unsigned int current_frame;
6f50cb0ead51 initial commit for Sierra VMD file demuxer
melanson
parents:
diff changeset
52
387
f2760852ed18 minor VMD system update; still not perfect, but should not crash either
melanson
parents: 338
diff changeset
53 int sample_rate;
f2760852ed18 minor VMD system update; still not perfect, but should not crash either
melanson
parents: 338
diff changeset
54 int64_t audio_sample_counter;
1004
409b399440a3 More correct demuxing and timestamp setting fot Sierra VMD
kostya
parents: 896
diff changeset
55 int skiphdr;
387
f2760852ed18 minor VMD system update; still not perfect, but should not crash either
melanson
parents: 338
diff changeset
56
338
6f50cb0ead51 initial commit for Sierra VMD file demuxer
melanson
parents:
diff changeset
57 unsigned char vmd_header[VMD_HEADER_SIZE];
6f50cb0ead51 initial commit for Sierra VMD file demuxer
melanson
parents:
diff changeset
58 } VmdDemuxContext;
6f50cb0ead51 initial commit for Sierra VMD file demuxer
melanson
parents:
diff changeset
59
6f50cb0ead51 initial commit for Sierra VMD file demuxer
melanson
parents:
diff changeset
60 static int vmd_probe(AVProbeData *p)
6f50cb0ead51 initial commit for Sierra VMD file demuxer
melanson
parents:
diff changeset
61 {
6f50cb0ead51 initial commit for Sierra VMD file demuxer
melanson
parents:
diff changeset
62 /* check if the first 2 bytes of the file contain the appropriate size
6f50cb0ead51 initial commit for Sierra VMD file demuxer
melanson
parents:
diff changeset
63 * of a VMD header chunk */
1673
a782462e2497 rename BE/LE_8/16/32 to AV_RL/B_8/16/32
alex
parents: 1529
diff changeset
64 if (AV_RL16(&p->buf[0]) != VMD_HEADER_SIZE - 2)
338
6f50cb0ead51 initial commit for Sierra VMD file demuxer
melanson
parents:
diff changeset
65 return 0;
6f50cb0ead51 initial commit for Sierra VMD file demuxer
melanson
parents:
diff changeset
66
6f50cb0ead51 initial commit for Sierra VMD file demuxer
melanson
parents:
diff changeset
67 /* only return half certainty since this check is a bit sketchy */
6f50cb0ead51 initial commit for Sierra VMD file demuxer
melanson
parents:
diff changeset
68 return AVPROBE_SCORE_MAX / 2;
6f50cb0ead51 initial commit for Sierra VMD file demuxer
melanson
parents:
diff changeset
69 }
6f50cb0ead51 initial commit for Sierra VMD file demuxer
melanson
parents:
diff changeset
70
6f50cb0ead51 initial commit for Sierra VMD file demuxer
melanson
parents:
diff changeset
71 static int vmd_read_header(AVFormatContext *s,
6f50cb0ead51 initial commit for Sierra VMD file demuxer
melanson
parents:
diff changeset
72 AVFormatParameters *ap)
6f50cb0ead51 initial commit for Sierra VMD file demuxer
melanson
parents:
diff changeset
73 {
2006
2f0154760e5f Get rid of unnecessary pointer casts.
diego
parents: 2001
diff changeset
74 VmdDemuxContext *vmd = s->priv_data;
338
6f50cb0ead51 initial commit for Sierra VMD file demuxer
melanson
parents:
diff changeset
75 ByteIOContext *pb = &s->pb;
1492
deaec052eec4 Simplify VMD demuxer (but it still does not work right)
kostya
parents: 1441
diff changeset
76 AVStream *st, *vst;
338
6f50cb0ead51 initial commit for Sierra VMD file demuxer
melanson
parents:
diff changeset
77 unsigned int toc_offset;
6f50cb0ead51 initial commit for Sierra VMD file demuxer
melanson
parents:
diff changeset
78 unsigned char *raw_frame_table;
6f50cb0ead51 initial commit for Sierra VMD file demuxer
melanson
parents:
diff changeset
79 int raw_frame_table_size;
6f50cb0ead51 initial commit for Sierra VMD file demuxer
melanson
parents:
diff changeset
80 offset_t current_offset;
1004
409b399440a3 More correct demuxing and timestamp setting fot Sierra VMD
kostya
parents: 896
diff changeset
81 int i, j;
338
6f50cb0ead51 initial commit for Sierra VMD file demuxer
melanson
parents:
diff changeset
82 unsigned int total_frames;
1492
deaec052eec4 Simplify VMD demuxer (but it still does not work right)
kostya
parents: 1441
diff changeset
83 int64_t pts_inc = 1;
deaec052eec4 Simplify VMD demuxer (but it still does not work right)
kostya
parents: 1441
diff changeset
84 int64_t current_video_pts = 0, current_audio_pts = 0;
1004
409b399440a3 More correct demuxing and timestamp setting fot Sierra VMD
kostya
parents: 896
diff changeset
85 unsigned char chunk[BYTES_PER_FRAME_RECORD];
1492
deaec052eec4 Simplify VMD demuxer (but it still does not work right)
kostya
parents: 1441
diff changeset
86 int num, den;
1528
32d49970f01a Divide first audio buffer chunk into atomary bufffers.
kostya
parents: 1492
diff changeset
87 int sound_buffers;
338
6f50cb0ead51 initial commit for Sierra VMD file demuxer
melanson
parents:
diff changeset
88
6f50cb0ead51 initial commit for Sierra VMD file demuxer
melanson
parents:
diff changeset
89 /* fetch the main header, including the 2 header length bytes */
6f50cb0ead51 initial commit for Sierra VMD file demuxer
melanson
parents:
diff changeset
90 url_fseek(pb, 0, SEEK_SET);
6f50cb0ead51 initial commit for Sierra VMD file demuxer
melanson
parents:
diff changeset
91 if (get_buffer(pb, vmd->vmd_header, VMD_HEADER_SIZE) != VMD_HEADER_SIZE)
2274
b21c2af60bc9 Replace all occurrences of AVERROR_IO with AVERROR(EIO).
takis
parents: 2273
diff changeset
92 return AVERROR(EIO);
338
6f50cb0ead51 initial commit for Sierra VMD file demuxer
melanson
parents:
diff changeset
93
6f50cb0ead51 initial commit for Sierra VMD file demuxer
melanson
parents:
diff changeset
94 /* start up the decoders */
1492
deaec052eec4 Simplify VMD demuxer (but it still does not work right)
kostya
parents: 1441
diff changeset
95 vst = av_new_stream(s, 0);
deaec052eec4 Simplify VMD demuxer (but it still does not work right)
kostya
parents: 1441
diff changeset
96 if (!vst)
2273
7eb456c4ed8a Replace all occurrences of AVERROR_NOMEM with AVERROR(ENOMEM).
takis
parents: 2006
diff changeset
97 return AVERROR(ENOMEM);
1492
deaec052eec4 Simplify VMD demuxer (but it still does not work right)
kostya
parents: 1441
diff changeset
98 av_set_pts_info(vst, 33, 1, 10);
deaec052eec4 Simplify VMD demuxer (but it still does not work right)
kostya
parents: 1441
diff changeset
99 vmd->video_stream_index = vst->index;
deaec052eec4 Simplify VMD demuxer (but it still does not work right)
kostya
parents: 1441
diff changeset
100 vst->codec->codec_type = CODEC_TYPE_VIDEO;
deaec052eec4 Simplify VMD demuxer (but it still does not work right)
kostya
parents: 1441
diff changeset
101 vst->codec->codec_id = CODEC_ID_VMDVIDEO;
deaec052eec4 Simplify VMD demuxer (but it still does not work right)
kostya
parents: 1441
diff changeset
102 vst->codec->codec_tag = 0; /* no fourcc */
1673
a782462e2497 rename BE/LE_8/16/32 to AV_RL/B_8/16/32
alex
parents: 1529
diff changeset
103 vst->codec->width = AV_RL16(&vmd->vmd_header[12]);
a782462e2497 rename BE/LE_8/16/32 to AV_RL/B_8/16/32
alex
parents: 1529
diff changeset
104 vst->codec->height = AV_RL16(&vmd->vmd_header[14]);
1492
deaec052eec4 Simplify VMD demuxer (but it still does not work right)
kostya
parents: 1441
diff changeset
105 vst->codec->extradata_size = VMD_HEADER_SIZE;
deaec052eec4 Simplify VMD demuxer (but it still does not work right)
kostya
parents: 1441
diff changeset
106 vst->codec->extradata = av_mallocz(VMD_HEADER_SIZE + FF_INPUT_BUFFER_PADDING_SIZE);
deaec052eec4 Simplify VMD demuxer (but it still does not work right)
kostya
parents: 1441
diff changeset
107 memcpy(vst->codec->extradata, vmd->vmd_header, VMD_HEADER_SIZE);
338
6f50cb0ead51 initial commit for Sierra VMD file demuxer
melanson
parents:
diff changeset
108
6f50cb0ead51 initial commit for Sierra VMD file demuxer
melanson
parents:
diff changeset
109 /* if sample rate is 0, assume no audio */
1673
a782462e2497 rename BE/LE_8/16/32 to AV_RL/B_8/16/32
alex
parents: 1529
diff changeset
110 vmd->sample_rate = AV_RL16(&vmd->vmd_header[804]);
387
f2760852ed18 minor VMD system update; still not perfect, but should not crash either
melanson
parents: 338
diff changeset
111 if (vmd->sample_rate) {
338
6f50cb0ead51 initial commit for Sierra VMD file demuxer
melanson
parents:
diff changeset
112 st = av_new_stream(s, 0);
6f50cb0ead51 initial commit for Sierra VMD file demuxer
melanson
parents:
diff changeset
113 if (!st)
2273
7eb456c4ed8a Replace all occurrences of AVERROR_NOMEM with AVERROR(ENOMEM).
takis
parents: 2006
diff changeset
114 return AVERROR(ENOMEM);
338
6f50cb0ead51 initial commit for Sierra VMD file demuxer
melanson
parents:
diff changeset
115 vmd->audio_stream_index = st->index;
820
feca73904e67 changing AVCodecContext codec -> *codec in AVStream so additions to AVCodecContext dont randomize AVStream and break binary compatibility
michael
parents: 815
diff changeset
116 st->codec->codec_type = CODEC_TYPE_AUDIO;
feca73904e67 changing AVCodecContext codec -> *codec in AVStream so additions to AVCodecContext dont randomize AVStream and break binary compatibility
michael
parents: 815
diff changeset
117 st->codec->codec_id = CODEC_ID_VMDAUDIO;
1004
409b399440a3 More correct demuxing and timestamp setting fot Sierra VMD
kostya
parents: 896
diff changeset
118 st->codec->codec_tag = 0; /* no fourcc */
1492
deaec052eec4 Simplify VMD demuxer (but it still does not work right)
kostya
parents: 1441
diff changeset
119 st->codec->channels = (vmd->vmd_header[811] & 0x80) ? 2 : 1;
820
feca73904e67 changing AVCodecContext codec -> *codec in AVStream so additions to AVCodecContext dont randomize AVStream and break binary compatibility
michael
parents: 815
diff changeset
120 st->codec->sample_rate = vmd->sample_rate;
1673
a782462e2497 rename BE/LE_8/16/32 to AV_RL/B_8/16/32
alex
parents: 1529
diff changeset
121 st->codec->block_align = AV_RL16(&vmd->vmd_header[806]);
820
feca73904e67 changing AVCodecContext codec -> *codec in AVStream so additions to AVCodecContext dont randomize AVStream and break binary compatibility
michael
parents: 815
diff changeset
122 if (st->codec->block_align & 0x8000) {
feca73904e67 changing AVCodecContext codec -> *codec in AVStream so additions to AVCodecContext dont randomize AVStream and break binary compatibility
michael
parents: 815
diff changeset
123 st->codec->bits_per_sample = 16;
feca73904e67 changing AVCodecContext codec -> *codec in AVStream so additions to AVCodecContext dont randomize AVStream and break binary compatibility
michael
parents: 815
diff changeset
124 st->codec->block_align = -(st->codec->block_align - 0x10000);
1004
409b399440a3 More correct demuxing and timestamp setting fot Sierra VMD
kostya
parents: 896
diff changeset
125 } else {
409b399440a3 More correct demuxing and timestamp setting fot Sierra VMD
kostya
parents: 896
diff changeset
126 st->codec->bits_per_sample = 8;
409b399440a3 More correct demuxing and timestamp setting fot Sierra VMD
kostya
parents: 896
diff changeset
127 }
885
da1d5db0ce5c COSMETICS: Remove all trailing whitespace.
diego
parents: 884
diff changeset
128 st->codec->bit_rate = st->codec->sample_rate *
820
feca73904e67 changing AVCodecContext codec -> *codec in AVStream so additions to AVCodecContext dont randomize AVStream and break binary compatibility
michael
parents: 815
diff changeset
129 st->codec->bits_per_sample * st->codec->channels;
387
f2760852ed18 minor VMD system update; still not perfect, but should not crash either
melanson
parents: 338
diff changeset
130
1492
deaec052eec4 Simplify VMD demuxer (but it still does not work right)
kostya
parents: 1441
diff changeset
131 /* calculate pts */
deaec052eec4 Simplify VMD demuxer (but it still does not work right)
kostya
parents: 1441
diff changeset
132 num = st->codec->block_align;
deaec052eec4 Simplify VMD demuxer (but it still does not work right)
kostya
parents: 1441
diff changeset
133 den = st->codec->sample_rate * st->codec->channels;
deaec052eec4 Simplify VMD demuxer (but it still does not work right)
kostya
parents: 1441
diff changeset
134 av_reduce(&den, &num, den, num, (1UL<<31)-1);
deaec052eec4 Simplify VMD demuxer (but it still does not work right)
kostya
parents: 1441
diff changeset
135 av_set_pts_info(vst, 33, num, den);
deaec052eec4 Simplify VMD demuxer (but it still does not work right)
kostya
parents: 1441
diff changeset
136 av_set_pts_info(st, 33, num, den);
deaec052eec4 Simplify VMD demuxer (but it still does not work right)
kostya
parents: 1441
diff changeset
137 pts_inc = num;
338
6f50cb0ead51 initial commit for Sierra VMD file demuxer
melanson
parents:
diff changeset
138 }
6f50cb0ead51 initial commit for Sierra VMD file demuxer
melanson
parents:
diff changeset
139
1673
a782462e2497 rename BE/LE_8/16/32 to AV_RL/B_8/16/32
alex
parents: 1529
diff changeset
140 toc_offset = AV_RL32(&vmd->vmd_header[812]);
a782462e2497 rename BE/LE_8/16/32 to AV_RL/B_8/16/32
alex
parents: 1529
diff changeset
141 vmd->frame_count = AV_RL16(&vmd->vmd_header[6]);
a782462e2497 rename BE/LE_8/16/32 to AV_RL/B_8/16/32
alex
parents: 1529
diff changeset
142 vmd->frames_per_block = AV_RL16(&vmd->vmd_header[18]);
1004
409b399440a3 More correct demuxing and timestamp setting fot Sierra VMD
kostya
parents: 896
diff changeset
143 url_fseek(pb, toc_offset, SEEK_SET);
338
6f50cb0ead51 initial commit for Sierra VMD file demuxer
melanson
parents:
diff changeset
144
6f50cb0ead51 initial commit for Sierra VMD file demuxer
melanson
parents:
diff changeset
145 raw_frame_table = NULL;
6f50cb0ead51 initial commit for Sierra VMD file demuxer
melanson
parents:
diff changeset
146 vmd->frame_table = NULL;
1673
a782462e2497 rename BE/LE_8/16/32 to AV_RL/B_8/16/32
alex
parents: 1529
diff changeset
147 sound_buffers = AV_RL16(&vmd->vmd_header[808]);
1004
409b399440a3 More correct demuxing and timestamp setting fot Sierra VMD
kostya
parents: 896
diff changeset
148 raw_frame_table_size = vmd->frame_count * 6;
338
6f50cb0ead51 initial commit for Sierra VMD file demuxer
melanson
parents:
diff changeset
149 raw_frame_table = av_malloc(raw_frame_table_size);
1079
40e81416015d sanity checks some might have been exploitable
michael
parents: 1004
diff changeset
150 if(vmd->frame_count * vmd->frames_per_block >= UINT_MAX / sizeof(vmd_frame_t)){
40e81416015d sanity checks some might have been exploitable
michael
parents: 1004
diff changeset
151 av_log(s, AV_LOG_ERROR, "vmd->frame_count * vmd->frames_per_block too large\n");
40e81416015d sanity checks some might have been exploitable
michael
parents: 1004
diff changeset
152 return -1;
40e81416015d sanity checks some might have been exploitable
michael
parents: 1004
diff changeset
153 }
1528
32d49970f01a Divide first audio buffer chunk into atomary bufffers.
kostya
parents: 1492
diff changeset
154 vmd->frame_table = av_malloc((vmd->frame_count * vmd->frames_per_block + sound_buffers) * sizeof(vmd_frame_t));
338
6f50cb0ead51 initial commit for Sierra VMD file demuxer
melanson
parents:
diff changeset
155 if (!raw_frame_table || !vmd->frame_table) {
6f50cb0ead51 initial commit for Sierra VMD file demuxer
melanson
parents:
diff changeset
156 av_free(raw_frame_table);
6f50cb0ead51 initial commit for Sierra VMD file demuxer
melanson
parents:
diff changeset
157 av_free(vmd->frame_table);
2273
7eb456c4ed8a Replace all occurrences of AVERROR_NOMEM with AVERROR(ENOMEM).
takis
parents: 2006
diff changeset
158 return AVERROR(ENOMEM);
338
6f50cb0ead51 initial commit for Sierra VMD file demuxer
melanson
parents:
diff changeset
159 }
885
da1d5db0ce5c COSMETICS: Remove all trailing whitespace.
diego
parents: 884
diff changeset
160 if (get_buffer(pb, raw_frame_table, raw_frame_table_size) !=
338
6f50cb0ead51 initial commit for Sierra VMD file demuxer
melanson
parents:
diff changeset
161 raw_frame_table_size) {
6f50cb0ead51 initial commit for Sierra VMD file demuxer
melanson
parents:
diff changeset
162 av_free(raw_frame_table);
6f50cb0ead51 initial commit for Sierra VMD file demuxer
melanson
parents:
diff changeset
163 av_free(vmd->frame_table);
2274
b21c2af60bc9 Replace all occurrences of AVERROR_IO with AVERROR(EIO).
takis
parents: 2273
diff changeset
164 return AVERROR(EIO);
338
6f50cb0ead51 initial commit for Sierra VMD file demuxer
melanson
parents:
diff changeset
165 }
6f50cb0ead51 initial commit for Sierra VMD file demuxer
melanson
parents:
diff changeset
166
1004
409b399440a3 More correct demuxing and timestamp setting fot Sierra VMD
kostya
parents: 896
diff changeset
167 total_frames = 0;
409b399440a3 More correct demuxing and timestamp setting fot Sierra VMD
kostya
parents: 896
diff changeset
168 for (i = 0; i < vmd->frame_count; i++) {
409b399440a3 More correct demuxing and timestamp setting fot Sierra VMD
kostya
parents: 896
diff changeset
169
1673
a782462e2497 rename BE/LE_8/16/32 to AV_RL/B_8/16/32
alex
parents: 1529
diff changeset
170 current_offset = AV_RL32(&raw_frame_table[6 * i + 2]);
338
6f50cb0ead51 initial commit for Sierra VMD file demuxer
melanson
parents:
diff changeset
171
1004
409b399440a3 More correct demuxing and timestamp setting fot Sierra VMD
kostya
parents: 896
diff changeset
172 /* handle each entry in index block */
409b399440a3 More correct demuxing and timestamp setting fot Sierra VMD
kostya
parents: 896
diff changeset
173 for (j = 0; j < vmd->frames_per_block; j++) {
409b399440a3 More correct demuxing and timestamp setting fot Sierra VMD
kostya
parents: 896
diff changeset
174 int type;
409b399440a3 More correct demuxing and timestamp setting fot Sierra VMD
kostya
parents: 896
diff changeset
175 uint32_t size;
338
6f50cb0ead51 initial commit for Sierra VMD file demuxer
melanson
parents:
diff changeset
176
1004
409b399440a3 More correct demuxing and timestamp setting fot Sierra VMD
kostya
parents: 896
diff changeset
177 get_buffer(pb, chunk, BYTES_PER_FRAME_RECORD);
409b399440a3 More correct demuxing and timestamp setting fot Sierra VMD
kostya
parents: 896
diff changeset
178 type = chunk[0];
1673
a782462e2497 rename BE/LE_8/16/32 to AV_RL/B_8/16/32
alex
parents: 1529
diff changeset
179 size = AV_RL32(&chunk[2]);
1004
409b399440a3 More correct demuxing and timestamp setting fot Sierra VMD
kostya
parents: 896
diff changeset
180 if(!size)
409b399440a3 More correct demuxing and timestamp setting fot Sierra VMD
kostya
parents: 896
diff changeset
181 continue;
409b399440a3 More correct demuxing and timestamp setting fot Sierra VMD
kostya
parents: 896
diff changeset
182 switch(type) {
409b399440a3 More correct demuxing and timestamp setting fot Sierra VMD
kostya
parents: 896
diff changeset
183 case 1: /* Audio Chunk */
1528
32d49970f01a Divide first audio buffer chunk into atomary bufffers.
kostya
parents: 1492
diff changeset
184 /* first audio chunk contains several audio buffers */
32d49970f01a Divide first audio buffer chunk into atomary bufffers.
kostya
parents: 1492
diff changeset
185 if(current_audio_pts){
1529
07898e88c5b9 Identation
kostya
parents: 1528
diff changeset
186 vmd->frame_table[total_frames].frame_offset = current_offset;
07898e88c5b9 Identation
kostya
parents: 1528
diff changeset
187 vmd->frame_table[total_frames].stream_index = vmd->audio_stream_index;
07898e88c5b9 Identation
kostya
parents: 1528
diff changeset
188 vmd->frame_table[total_frames].frame_size = size;
07898e88c5b9 Identation
kostya
parents: 1528
diff changeset
189 memcpy(vmd->frame_table[total_frames].frame_record, chunk, BYTES_PER_FRAME_RECORD);
07898e88c5b9 Identation
kostya
parents: 1528
diff changeset
190 vmd->frame_table[total_frames].pts = current_audio_pts;
07898e88c5b9 Identation
kostya
parents: 1528
diff changeset
191 total_frames++;
07898e88c5b9 Identation
kostya
parents: 1528
diff changeset
192 current_audio_pts += pts_inc;
1528
32d49970f01a Divide first audio buffer chunk into atomary bufffers.
kostya
parents: 1492
diff changeset
193 }else{
32d49970f01a Divide first audio buffer chunk into atomary bufffers.
kostya
parents: 1492
diff changeset
194 uint32_t flags;
32d49970f01a Divide first audio buffer chunk into atomary bufffers.
kostya
parents: 1492
diff changeset
195 int k;
32d49970f01a Divide first audio buffer chunk into atomary bufffers.
kostya
parents: 1492
diff changeset
196 int noff;
32d49970f01a Divide first audio buffer chunk into atomary bufffers.
kostya
parents: 1492
diff changeset
197 int64_t pos;
32d49970f01a Divide first audio buffer chunk into atomary bufffers.
kostya
parents: 1492
diff changeset
198
32d49970f01a Divide first audio buffer chunk into atomary bufffers.
kostya
parents: 1492
diff changeset
199 pos = url_ftell(pb);
32d49970f01a Divide first audio buffer chunk into atomary bufffers.
kostya
parents: 1492
diff changeset
200 url_fseek(pb, current_offset, SEEK_SET);
32d49970f01a Divide first audio buffer chunk into atomary bufffers.
kostya
parents: 1492
diff changeset
201 flags = get_le32(pb);
32d49970f01a Divide first audio buffer chunk into atomary bufffers.
kostya
parents: 1492
diff changeset
202 noff = 4;
32d49970f01a Divide first audio buffer chunk into atomary bufffers.
kostya
parents: 1492
diff changeset
203 url_fseek(pb, pos, SEEK_SET);
32d49970f01a Divide first audio buffer chunk into atomary bufffers.
kostya
parents: 1492
diff changeset
204 av_log(s, AV_LOG_DEBUG, "Sound mapping = %08X (%i bufs)\n", flags, sound_buffers);
32d49970f01a Divide first audio buffer chunk into atomary bufffers.
kostya
parents: 1492
diff changeset
205 for(k = 0; k < sound_buffers - 1; k++){
32d49970f01a Divide first audio buffer chunk into atomary bufffers.
kostya
parents: 1492
diff changeset
206 if(flags & 1) { /* silent block */
32d49970f01a Divide first audio buffer chunk into atomary bufffers.
kostya
parents: 1492
diff changeset
207 vmd->frame_table[total_frames].frame_size = 0;
32d49970f01a Divide first audio buffer chunk into atomary bufffers.
kostya
parents: 1492
diff changeset
208 }else{
32d49970f01a Divide first audio buffer chunk into atomary bufffers.
kostya
parents: 1492
diff changeset
209 vmd->frame_table[total_frames].frame_size = st->codec->block_align + (st->codec->block_align & 1);
32d49970f01a Divide first audio buffer chunk into atomary bufffers.
kostya
parents: 1492
diff changeset
210 }
32d49970f01a Divide first audio buffer chunk into atomary bufffers.
kostya
parents: 1492
diff changeset
211 noff += vmd->frame_table[total_frames].frame_size;
32d49970f01a Divide first audio buffer chunk into atomary bufffers.
kostya
parents: 1492
diff changeset
212 vmd->frame_table[total_frames].frame_offset = current_offset + noff;
32d49970f01a Divide first audio buffer chunk into atomary bufffers.
kostya
parents: 1492
diff changeset
213 vmd->frame_table[total_frames].stream_index = vmd->audio_stream_index;
32d49970f01a Divide first audio buffer chunk into atomary bufffers.
kostya
parents: 1492
diff changeset
214 memcpy(vmd->frame_table[total_frames].frame_record, chunk, BYTES_PER_FRAME_RECORD);
32d49970f01a Divide first audio buffer chunk into atomary bufffers.
kostya
parents: 1492
diff changeset
215 vmd->frame_table[total_frames].pts = current_audio_pts;
32d49970f01a Divide first audio buffer chunk into atomary bufffers.
kostya
parents: 1492
diff changeset
216 total_frames++;
32d49970f01a Divide first audio buffer chunk into atomary bufffers.
kostya
parents: 1492
diff changeset
217 current_audio_pts += pts_inc;
32d49970f01a Divide first audio buffer chunk into atomary bufffers.
kostya
parents: 1492
diff changeset
218 flags >>= 1;
32d49970f01a Divide first audio buffer chunk into atomary bufffers.
kostya
parents: 1492
diff changeset
219 }
32d49970f01a Divide first audio buffer chunk into atomary bufffers.
kostya
parents: 1492
diff changeset
220 }
1004
409b399440a3 More correct demuxing and timestamp setting fot Sierra VMD
kostya
parents: 896
diff changeset
221 break;
409b399440a3 More correct demuxing and timestamp setting fot Sierra VMD
kostya
parents: 896
diff changeset
222 case 2: /* Video Chunk */
409b399440a3 More correct demuxing and timestamp setting fot Sierra VMD
kostya
parents: 896
diff changeset
223 vmd->frame_table[total_frames].frame_offset = current_offset;
1492
deaec052eec4 Simplify VMD demuxer (but it still does not work right)
kostya
parents: 1441
diff changeset
224 vmd->frame_table[total_frames].stream_index = vmd->video_stream_index;
1004
409b399440a3 More correct demuxing and timestamp setting fot Sierra VMD
kostya
parents: 896
diff changeset
225 vmd->frame_table[total_frames].frame_size = size;
409b399440a3 More correct demuxing and timestamp setting fot Sierra VMD
kostya
parents: 896
diff changeset
226 memcpy(vmd->frame_table[total_frames].frame_record, chunk, BYTES_PER_FRAME_RECORD);
409b399440a3 More correct demuxing and timestamp setting fot Sierra VMD
kostya
parents: 896
diff changeset
227 vmd->frame_table[total_frames].pts = current_video_pts;
409b399440a3 More correct demuxing and timestamp setting fot Sierra VMD
kostya
parents: 896
diff changeset
228 total_frames++;
409b399440a3 More correct demuxing and timestamp setting fot Sierra VMD
kostya
parents: 896
diff changeset
229 break;
409b399440a3 More correct demuxing and timestamp setting fot Sierra VMD
kostya
parents: 896
diff changeset
230 }
409b399440a3 More correct demuxing and timestamp setting fot Sierra VMD
kostya
parents: 896
diff changeset
231 current_offset += size;
387
f2760852ed18 minor VMD system update; still not perfect, but should not crash either
melanson
parents: 338
diff changeset
232 }
1492
deaec052eec4 Simplify VMD demuxer (but it still does not work right)
kostya
parents: 1441
diff changeset
233 current_video_pts += pts_inc;
338
6f50cb0ead51 initial commit for Sierra VMD file demuxer
melanson
parents:
diff changeset
234 }
6f50cb0ead51 initial commit for Sierra VMD file demuxer
melanson
parents:
diff changeset
235
6f50cb0ead51 initial commit for Sierra VMD file demuxer
melanson
parents:
diff changeset
236 av_free(raw_frame_table);
6f50cb0ead51 initial commit for Sierra VMD file demuxer
melanson
parents:
diff changeset
237
6f50cb0ead51 initial commit for Sierra VMD file demuxer
melanson
parents:
diff changeset
238 vmd->current_frame = 0;
1004
409b399440a3 More correct demuxing and timestamp setting fot Sierra VMD
kostya
parents: 896
diff changeset
239 vmd->frame_count = total_frames;
338
6f50cb0ead51 initial commit for Sierra VMD file demuxer
melanson
parents:
diff changeset
240
6f50cb0ead51 initial commit for Sierra VMD file demuxer
melanson
parents:
diff changeset
241 return 0;
6f50cb0ead51 initial commit for Sierra VMD file demuxer
melanson
parents:
diff changeset
242 }
6f50cb0ead51 initial commit for Sierra VMD file demuxer
melanson
parents:
diff changeset
243
6f50cb0ead51 initial commit for Sierra VMD file demuxer
melanson
parents:
diff changeset
244 static int vmd_read_packet(AVFormatContext *s,
6f50cb0ead51 initial commit for Sierra VMD file demuxer
melanson
parents:
diff changeset
245 AVPacket *pkt)
6f50cb0ead51 initial commit for Sierra VMD file demuxer
melanson
parents:
diff changeset
246 {
2006
2f0154760e5f Get rid of unnecessary pointer casts.
diego
parents: 2001
diff changeset
247 VmdDemuxContext *vmd = s->priv_data;
338
6f50cb0ead51 initial commit for Sierra VMD file demuxer
melanson
parents:
diff changeset
248 ByteIOContext *pb = &s->pb;
6f50cb0ead51 initial commit for Sierra VMD file demuxer
melanson
parents:
diff changeset
249 int ret = 0;
6f50cb0ead51 initial commit for Sierra VMD file demuxer
melanson
parents:
diff changeset
250 vmd_frame_t *frame;
6f50cb0ead51 initial commit for Sierra VMD file demuxer
melanson
parents:
diff changeset
251
6f50cb0ead51 initial commit for Sierra VMD file demuxer
melanson
parents:
diff changeset
252 if (vmd->current_frame >= vmd->frame_count)
2274
b21c2af60bc9 Replace all occurrences of AVERROR_IO with AVERROR(EIO).
takis
parents: 2273
diff changeset
253 return AVERROR(EIO);
338
6f50cb0ead51 initial commit for Sierra VMD file demuxer
melanson
parents:
diff changeset
254
6f50cb0ead51 initial commit for Sierra VMD file demuxer
melanson
parents:
diff changeset
255 frame = &vmd->frame_table[vmd->current_frame];
6f50cb0ead51 initial commit for Sierra VMD file demuxer
melanson
parents:
diff changeset
256 /* position the stream (will probably be there already) */
6f50cb0ead51 initial commit for Sierra VMD file demuxer
melanson
parents:
diff changeset
257 url_fseek(pb, frame->frame_offset, SEEK_SET);
6f50cb0ead51 initial commit for Sierra VMD file demuxer
melanson
parents:
diff changeset
258
6f50cb0ead51 initial commit for Sierra VMD file demuxer
melanson
parents:
diff changeset
259 if (av_new_packet(pkt, frame->frame_size + BYTES_PER_FRAME_RECORD))
2273
7eb456c4ed8a Replace all occurrences of AVERROR_NOMEM with AVERROR(ENOMEM).
takis
parents: 2006
diff changeset
260 return AVERROR(ENOMEM);
775
c5077fdab490 AVPacket.pos
michael
parents: 669
diff changeset
261 pkt->pos= url_ftell(pb);
338
6f50cb0ead51 initial commit for Sierra VMD file demuxer
melanson
parents:
diff changeset
262 memcpy(pkt->data, frame->frame_record, BYTES_PER_FRAME_RECORD);
885
da1d5db0ce5c COSMETICS: Remove all trailing whitespace.
diego
parents: 884
diff changeset
263 ret = get_buffer(pb, pkt->data + BYTES_PER_FRAME_RECORD,
338
6f50cb0ead51 initial commit for Sierra VMD file demuxer
melanson
parents:
diff changeset
264 frame->frame_size);
6f50cb0ead51 initial commit for Sierra VMD file demuxer
melanson
parents:
diff changeset
265
387
f2760852ed18 minor VMD system update; still not perfect, but should not crash either
melanson
parents: 338
diff changeset
266 if (ret != frame->frame_size) {
f2760852ed18 minor VMD system update; still not perfect, but should not crash either
melanson
parents: 338
diff changeset
267 av_free_packet(pkt);
2274
b21c2af60bc9 Replace all occurrences of AVERROR_IO with AVERROR(EIO).
takis
parents: 2273
diff changeset
268 ret = AVERROR(EIO);
387
f2760852ed18 minor VMD system update; still not perfect, but should not crash either
melanson
parents: 338
diff changeset
269 }
338
6f50cb0ead51 initial commit for Sierra VMD file demuxer
melanson
parents:
diff changeset
270 pkt->stream_index = frame->stream_index;
1492
deaec052eec4 Simplify VMD demuxer (but it still does not work right)
kostya
parents: 1441
diff changeset
271 pkt->pts = frame->pts;
deaec052eec4 Simplify VMD demuxer (but it still does not work right)
kostya
parents: 1441
diff changeset
272 av_log(NULL, AV_LOG_INFO, " dispatching %s frame with %d bytes and pts %"PRId64"\n",
1441
ad3b03b7b142 reindentation, patch by From: Steve Lhomme, slhomme divxcorp com
diego
parents: 1358
diff changeset
273 (frame->frame_record[0] == 0x02) ? "video" : "audio",
ad3b03b7b142 reindentation, patch by From: Steve Lhomme, slhomme divxcorp com
diego
parents: 1358
diff changeset
274 frame->frame_size + BYTES_PER_FRAME_RECORD,
1492
deaec052eec4 Simplify VMD demuxer (but it still does not work right)
kostya
parents: 1441
diff changeset
275 pkt->pts);
338
6f50cb0ead51 initial commit for Sierra VMD file demuxer
melanson
parents:
diff changeset
276
6f50cb0ead51 initial commit for Sierra VMD file demuxer
melanson
parents:
diff changeset
277 vmd->current_frame++;
6f50cb0ead51 initial commit for Sierra VMD file demuxer
melanson
parents:
diff changeset
278
6f50cb0ead51 initial commit for Sierra VMD file demuxer
melanson
parents:
diff changeset
279 return ret;
6f50cb0ead51 initial commit for Sierra VMD file demuxer
melanson
parents:
diff changeset
280 }
6f50cb0ead51 initial commit for Sierra VMD file demuxer
melanson
parents:
diff changeset
281
6f50cb0ead51 initial commit for Sierra VMD file demuxer
melanson
parents:
diff changeset
282 static int vmd_read_close(AVFormatContext *s)
6f50cb0ead51 initial commit for Sierra VMD file demuxer
melanson
parents:
diff changeset
283 {
2006
2f0154760e5f Get rid of unnecessary pointer casts.
diego
parents: 2001
diff changeset
284 VmdDemuxContext *vmd = s->priv_data;
338
6f50cb0ead51 initial commit for Sierra VMD file demuxer
melanson
parents:
diff changeset
285
6f50cb0ead51 initial commit for Sierra VMD file demuxer
melanson
parents:
diff changeset
286 av_free(vmd->frame_table);
6f50cb0ead51 initial commit for Sierra VMD file demuxer
melanson
parents:
diff changeset
287
6f50cb0ead51 initial commit for Sierra VMD file demuxer
melanson
parents:
diff changeset
288 return 0;
6f50cb0ead51 initial commit for Sierra VMD file demuxer
melanson
parents:
diff changeset
289 }
6f50cb0ead51 initial commit for Sierra VMD file demuxer
melanson
parents:
diff changeset
290
1169
d18cc9a1fd02 allow individual selection of muxers and demuxers
mru
parents: 1167
diff changeset
291 AVInputFormat vmd_demuxer = {
338
6f50cb0ead51 initial commit for Sierra VMD file demuxer
melanson
parents:
diff changeset
292 "vmd",
6f50cb0ead51 initial commit for Sierra VMD file demuxer
melanson
parents:
diff changeset
293 "Sierra VMD format",
6f50cb0ead51 initial commit for Sierra VMD file demuxer
melanson
parents:
diff changeset
294 sizeof(VmdDemuxContext),
6f50cb0ead51 initial commit for Sierra VMD file demuxer
melanson
parents:
diff changeset
295 vmd_probe,
6f50cb0ead51 initial commit for Sierra VMD file demuxer
melanson
parents:
diff changeset
296 vmd_read_header,
6f50cb0ead51 initial commit for Sierra VMD file demuxer
melanson
parents:
diff changeset
297 vmd_read_packet,
6f50cb0ead51 initial commit for Sierra VMD file demuxer
melanson
parents:
diff changeset
298 vmd_read_close,
6f50cb0ead51 initial commit for Sierra VMD file demuxer
melanson
parents:
diff changeset
299 };