annotate sierravmd.c @ 713:3c8a21cd6296 libavformat

28_fix_parameters_in_G726.patch by (Calcium | calcium nurs or jp)
author michael
date Wed, 23 Mar 2005 12:35:27 +0000
parents ed7ed3588399
children c5077fdab490
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 *
6f50cb0ead51 initial commit for Sierra VMD file demuxer
melanson
parents:
diff changeset
5 * This library is free software; you can redistribute it and/or
6f50cb0ead51 initial commit for Sierra VMD file demuxer
melanson
parents:
diff changeset
6 * modify it under the terms of the GNU Lesser General Public
6f50cb0ead51 initial commit for Sierra VMD file demuxer
melanson
parents:
diff changeset
7 * License as published by the Free Software Foundation; either
6f50cb0ead51 initial commit for Sierra VMD file demuxer
melanson
parents:
diff changeset
8 * version 2 of the License, or (at your option) any later version.
6f50cb0ead51 initial commit for Sierra VMD file demuxer
melanson
parents:
diff changeset
9 *
6f50cb0ead51 initial commit for Sierra VMD file demuxer
melanson
parents:
diff changeset
10 * This library is distributed in the hope that it will be useful,
6f50cb0ead51 initial commit for Sierra VMD file demuxer
melanson
parents:
diff changeset
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
6f50cb0ead51 initial commit for Sierra VMD file demuxer
melanson
parents:
diff changeset
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
6f50cb0ead51 initial commit for Sierra VMD file demuxer
melanson
parents:
diff changeset
13 * Lesser General Public License for more details.
6f50cb0ead51 initial commit for Sierra VMD file demuxer
melanson
parents:
diff changeset
14 *
6f50cb0ead51 initial commit for Sierra VMD file demuxer
melanson
parents:
diff changeset
15 * You should have received a copy of the GNU Lesser General Public
6f50cb0ead51 initial commit for Sierra VMD file demuxer
melanson
parents:
diff changeset
16 * License along with this library; if not, write to the Free Software
6f50cb0ead51 initial commit for Sierra VMD file demuxer
melanson
parents:
diff changeset
17 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
6f50cb0ead51 initial commit for Sierra VMD file demuxer
melanson
parents:
diff changeset
18 */
6f50cb0ead51 initial commit for Sierra VMD file demuxer
melanson
parents:
diff changeset
19
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 * @file sierravmd.c
6f50cb0ead51 initial commit for Sierra VMD file demuxer
melanson
parents:
diff changeset
22 * Sierra VMD file demuxer
6f50cb0ead51 initial commit for Sierra VMD file demuxer
melanson
parents:
diff changeset
23 * 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
24 * 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
25 * http://www.pcisys.net/~melanson/codecs/
338
6f50cb0ead51 initial commit for Sierra VMD file demuxer
melanson
parents:
diff changeset
26 */
6f50cb0ead51 initial commit for Sierra VMD file demuxer
melanson
parents:
diff changeset
27
6f50cb0ead51 initial commit for Sierra VMD file demuxer
melanson
parents:
diff changeset
28 #include "avformat.h"
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 #define VMD_HEADER_SIZE 0x0330
6f50cb0ead51 initial commit for Sierra VMD file demuxer
melanson
parents:
diff changeset
31 #define BYTES_PER_FRAME_RECORD 16
6f50cb0ead51 initial commit for Sierra VMD file demuxer
melanson
parents:
diff changeset
32
6f50cb0ead51 initial commit for Sierra VMD file demuxer
melanson
parents:
diff changeset
33 typedef struct {
6f50cb0ead51 initial commit for Sierra VMD file demuxer
melanson
parents:
diff changeset
34 int stream_index;
6f50cb0ead51 initial commit for Sierra VMD file demuxer
melanson
parents:
diff changeset
35 offset_t frame_offset;
6f50cb0ead51 initial commit for Sierra VMD file demuxer
melanson
parents:
diff changeset
36 unsigned int frame_size;
6f50cb0ead51 initial commit for Sierra VMD file demuxer
melanson
parents:
diff changeset
37 int64_t pts;
6f50cb0ead51 initial commit for Sierra VMD file demuxer
melanson
parents:
diff changeset
38 int keyframe;
6f50cb0ead51 initial commit for Sierra VMD file demuxer
melanson
parents:
diff changeset
39 unsigned char frame_record[BYTES_PER_FRAME_RECORD];
6f50cb0ead51 initial commit for Sierra VMD file demuxer
melanson
parents:
diff changeset
40 } vmd_frame_t;
6f50cb0ead51 initial commit for Sierra VMD file demuxer
melanson
parents:
diff changeset
41
6f50cb0ead51 initial commit for Sierra VMD file demuxer
melanson
parents:
diff changeset
42 typedef struct VmdDemuxContext {
6f50cb0ead51 initial commit for Sierra VMD file demuxer
melanson
parents:
diff changeset
43 int video_stream_index;
6f50cb0ead51 initial commit for Sierra VMD file demuxer
melanson
parents:
diff changeset
44 int audio_stream_index;
6f50cb0ead51 initial commit for Sierra VMD file demuxer
melanson
parents:
diff changeset
45
6f50cb0ead51 initial commit for Sierra VMD file demuxer
melanson
parents:
diff changeset
46 unsigned int audio_type;
6f50cb0ead51 initial commit for Sierra VMD file demuxer
melanson
parents:
diff changeset
47 unsigned int audio_samplerate;
6f50cb0ead51 initial commit for Sierra VMD file demuxer
melanson
parents:
diff changeset
48 unsigned int audio_bits;
6f50cb0ead51 initial commit for Sierra VMD file demuxer
melanson
parents:
diff changeset
49 unsigned int audio_channels;
6f50cb0ead51 initial commit for Sierra VMD file demuxer
melanson
parents:
diff changeset
50
6f50cb0ead51 initial commit for Sierra VMD file demuxer
melanson
parents:
diff changeset
51 unsigned int frame_count;
6f50cb0ead51 initial commit for Sierra VMD file demuxer
melanson
parents:
diff changeset
52 vmd_frame_t *frame_table;
6f50cb0ead51 initial commit for Sierra VMD file demuxer
melanson
parents:
diff changeset
53 unsigned int current_frame;
6f50cb0ead51 initial commit for Sierra VMD file demuxer
melanson
parents:
diff changeset
54
387
f2760852ed18 minor VMD system update; still not perfect, but should not crash either
melanson
parents: 338
diff changeset
55 int sample_rate;
f2760852ed18 minor VMD system update; still not perfect, but should not crash either
melanson
parents: 338
diff changeset
56 int64_t audio_sample_counter;
f2760852ed18 minor VMD system update; still not perfect, but should not crash either
melanson
parents: 338
diff changeset
57 int audio_frame_divisor;
f2760852ed18 minor VMD system update; still not perfect, but should not crash either
melanson
parents: 338
diff changeset
58 int audio_block_align;
f2760852ed18 minor VMD system update; still not perfect, but should not crash either
melanson
parents: 338
diff changeset
59
338
6f50cb0ead51 initial commit for Sierra VMD file demuxer
melanson
parents:
diff changeset
60 unsigned char vmd_header[VMD_HEADER_SIZE];
6f50cb0ead51 initial commit for Sierra VMD file demuxer
melanson
parents:
diff changeset
61 } VmdDemuxContext;
6f50cb0ead51 initial commit for Sierra VMD file demuxer
melanson
parents:
diff changeset
62
6f50cb0ead51 initial commit for Sierra VMD file demuxer
melanson
parents:
diff changeset
63 static int vmd_probe(AVProbeData *p)
6f50cb0ead51 initial commit for Sierra VMD file demuxer
melanson
parents:
diff changeset
64 {
6f50cb0ead51 initial commit for Sierra VMD file demuxer
melanson
parents:
diff changeset
65 if (p->buf_size < 2)
6f50cb0ead51 initial commit for Sierra VMD file demuxer
melanson
parents:
diff changeset
66 return 0;
6f50cb0ead51 initial commit for Sierra VMD file demuxer
melanson
parents:
diff changeset
67
6f50cb0ead51 initial commit for Sierra VMD file demuxer
melanson
parents:
diff changeset
68 /* 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
69 * of a VMD header chunk */
6f50cb0ead51 initial commit for Sierra VMD file demuxer
melanson
parents:
diff changeset
70 if (LE_16(&p->buf[0]) != VMD_HEADER_SIZE - 2)
6f50cb0ead51 initial commit for Sierra VMD file demuxer
melanson
parents:
diff changeset
71 return 0;
6f50cb0ead51 initial commit for Sierra VMD file demuxer
melanson
parents:
diff changeset
72
6f50cb0ead51 initial commit for Sierra VMD file demuxer
melanson
parents:
diff changeset
73 /* only return half certainty since this check is a bit sketchy */
6f50cb0ead51 initial commit for Sierra VMD file demuxer
melanson
parents:
diff changeset
74 return AVPROBE_SCORE_MAX / 2;
6f50cb0ead51 initial commit for Sierra VMD file demuxer
melanson
parents:
diff changeset
75 }
6f50cb0ead51 initial commit for Sierra VMD file demuxer
melanson
parents:
diff changeset
76
387
f2760852ed18 minor VMD system update; still not perfect, but should not crash either
melanson
parents: 338
diff changeset
77 /* This is a support function to determine the duration, in sample
f2760852ed18 minor VMD system update; still not perfect, but should not crash either
melanson
parents: 338
diff changeset
78 * frames, of a particular audio chunk, taking into account silent
f2760852ed18 minor VMD system update; still not perfect, but should not crash either
melanson
parents: 338
diff changeset
79 * encodings. */
f2760852ed18 minor VMD system update; still not perfect, but should not crash either
melanson
parents: 338
diff changeset
80 static int vmd_calculate_audio_duration(unsigned char *audio_chunk,
f2760852ed18 minor VMD system update; still not perfect, but should not crash either
melanson
parents: 338
diff changeset
81 int audio_chunk_size, int block_align)
f2760852ed18 minor VMD system update; still not perfect, but should not crash either
melanson
parents: 338
diff changeset
82 {
f2760852ed18 minor VMD system update; still not perfect, but should not crash either
melanson
parents: 338
diff changeset
83 unsigned char *p = audio_chunk + 16;
f2760852ed18 minor VMD system update; still not perfect, but should not crash either
melanson
parents: 338
diff changeset
84 unsigned char *p_end = audio_chunk + audio_chunk_size;
f2760852ed18 minor VMD system update; still not perfect, but should not crash either
melanson
parents: 338
diff changeset
85 int total_samples = 0;
f2760852ed18 minor VMD system update; still not perfect, but should not crash either
melanson
parents: 338
diff changeset
86 unsigned int sound_flags;
f2760852ed18 minor VMD system update; still not perfect, but should not crash either
melanson
parents: 338
diff changeset
87
f2760852ed18 minor VMD system update; still not perfect, but should not crash either
melanson
parents: 338
diff changeset
88 if (audio_chunk_size < 16)
f2760852ed18 minor VMD system update; still not perfect, but should not crash either
melanson
parents: 338
diff changeset
89 return 0;
f2760852ed18 minor VMD system update; still not perfect, but should not crash either
melanson
parents: 338
diff changeset
90
f2760852ed18 minor VMD system update; still not perfect, but should not crash either
melanson
parents: 338
diff changeset
91 sound_flags = LE_32(p);
f2760852ed18 minor VMD system update; still not perfect, but should not crash either
melanson
parents: 338
diff changeset
92 p += 4;
f2760852ed18 minor VMD system update; still not perfect, but should not crash either
melanson
parents: 338
diff changeset
93 while (p < p_end) {
f2760852ed18 minor VMD system update; still not perfect, but should not crash either
melanson
parents: 338
diff changeset
94 total_samples += block_align;
f2760852ed18 minor VMD system update; still not perfect, but should not crash either
melanson
parents: 338
diff changeset
95 if ((sound_flags & 0x01) == 0)
f2760852ed18 minor VMD system update; still not perfect, but should not crash either
melanson
parents: 338
diff changeset
96 p += block_align;
f2760852ed18 minor VMD system update; still not perfect, but should not crash either
melanson
parents: 338
diff changeset
97 sound_flags >>= 1;
f2760852ed18 minor VMD system update; still not perfect, but should not crash either
melanson
parents: 338
diff changeset
98 }
f2760852ed18 minor VMD system update; still not perfect, but should not crash either
melanson
parents: 338
diff changeset
99
f2760852ed18 minor VMD system update; still not perfect, but should not crash either
melanson
parents: 338
diff changeset
100 return total_samples;
f2760852ed18 minor VMD system update; still not perfect, but should not crash either
melanson
parents: 338
diff changeset
101 }
f2760852ed18 minor VMD system update; still not perfect, but should not crash either
melanson
parents: 338
diff changeset
102
338
6f50cb0ead51 initial commit for Sierra VMD file demuxer
melanson
parents:
diff changeset
103 static int vmd_read_header(AVFormatContext *s,
6f50cb0ead51 initial commit for Sierra VMD file demuxer
melanson
parents:
diff changeset
104 AVFormatParameters *ap)
6f50cb0ead51 initial commit for Sierra VMD file demuxer
melanson
parents:
diff changeset
105 {
6f50cb0ead51 initial commit for Sierra VMD file demuxer
melanson
parents:
diff changeset
106 VmdDemuxContext *vmd = (VmdDemuxContext *)s->priv_data;
6f50cb0ead51 initial commit for Sierra VMD file demuxer
melanson
parents:
diff changeset
107 ByteIOContext *pb = &s->pb;
6f50cb0ead51 initial commit for Sierra VMD file demuxer
melanson
parents:
diff changeset
108 AVStream *st;
6f50cb0ead51 initial commit for Sierra VMD file demuxer
melanson
parents:
diff changeset
109 unsigned int toc_offset;
6f50cb0ead51 initial commit for Sierra VMD file demuxer
melanson
parents:
diff changeset
110 unsigned char *raw_frame_table;
6f50cb0ead51 initial commit for Sierra VMD file demuxer
melanson
parents:
diff changeset
111 int raw_frame_table_size;
6f50cb0ead51 initial commit for Sierra VMD file demuxer
melanson
parents:
diff changeset
112 unsigned char *current_frame_record;
6f50cb0ead51 initial commit for Sierra VMD file demuxer
melanson
parents:
diff changeset
113 offset_t current_offset;
6f50cb0ead51 initial commit for Sierra VMD file demuxer
melanson
parents:
diff changeset
114 int i;
6f50cb0ead51 initial commit for Sierra VMD file demuxer
melanson
parents:
diff changeset
115 unsigned int total_frames;
387
f2760852ed18 minor VMD system update; still not perfect, but should not crash either
melanson
parents: 338
diff changeset
116 int64_t video_pts_inc;
f2760852ed18 minor VMD system update; still not perfect, but should not crash either
melanson
parents: 338
diff changeset
117 int64_t current_video_pts = 0;
338
6f50cb0ead51 initial commit for Sierra VMD file demuxer
melanson
parents:
diff changeset
118
6f50cb0ead51 initial commit for Sierra VMD file demuxer
melanson
parents:
diff changeset
119 /* fetch the main header, including the 2 header length bytes */
6f50cb0ead51 initial commit for Sierra VMD file demuxer
melanson
parents:
diff changeset
120 url_fseek(pb, 0, SEEK_SET);
6f50cb0ead51 initial commit for Sierra VMD file demuxer
melanson
parents:
diff changeset
121 if (get_buffer(pb, vmd->vmd_header, VMD_HEADER_SIZE) != VMD_HEADER_SIZE)
482
0fdc96c2f2fe sweeping change from -EIO -> AVERROR_IO
melanson
parents: 462
diff changeset
122 return AVERROR_IO;
338
6f50cb0ead51 initial commit for Sierra VMD file demuxer
melanson
parents:
diff changeset
123
387
f2760852ed18 minor VMD system update; still not perfect, but should not crash either
melanson
parents: 338
diff changeset
124 vmd->audio_sample_counter = 0;
f2760852ed18 minor VMD system update; still not perfect, but should not crash either
melanson
parents: 338
diff changeset
125 vmd->audio_frame_divisor = 1;
f2760852ed18 minor VMD system update; still not perfect, but should not crash either
melanson
parents: 338
diff changeset
126 vmd->audio_block_align = 1;
f2760852ed18 minor VMD system update; still not perfect, but should not crash either
melanson
parents: 338
diff changeset
127
338
6f50cb0ead51 initial commit for Sierra VMD file demuxer
melanson
parents:
diff changeset
128 /* start up the decoders */
6f50cb0ead51 initial commit for Sierra VMD file demuxer
melanson
parents:
diff changeset
129 st = av_new_stream(s, 0);
6f50cb0ead51 initial commit for Sierra VMD file demuxer
melanson
parents:
diff changeset
130 if (!st)
6f50cb0ead51 initial commit for Sierra VMD file demuxer
melanson
parents:
diff changeset
131 return AVERROR_NOMEM;
462
b69898ffc92a move time_base (pts_num/pts_den) from AVFormatContext -> AVStream
michael
parents: 387
diff changeset
132 av_set_pts_info(st, 33, 1, 90000);
338
6f50cb0ead51 initial commit for Sierra VMD file demuxer
melanson
parents:
diff changeset
133 vmd->video_stream_index = st->index;
6f50cb0ead51 initial commit for Sierra VMD file demuxer
melanson
parents:
diff changeset
134 st->codec.codec_type = CODEC_TYPE_VIDEO;
6f50cb0ead51 initial commit for Sierra VMD file demuxer
melanson
parents:
diff changeset
135 st->codec.codec_id = CODEC_ID_VMDVIDEO;
6f50cb0ead51 initial commit for Sierra VMD file demuxer
melanson
parents:
diff changeset
136 st->codec.codec_tag = 0; /* no fourcc */
6f50cb0ead51 initial commit for Sierra VMD file demuxer
melanson
parents:
diff changeset
137 st->codec.width = LE_16(&vmd->vmd_header[12]);
6f50cb0ead51 initial commit for Sierra VMD file demuxer
melanson
parents:
diff changeset
138 st->codec.height = LE_16(&vmd->vmd_header[14]);
6f50cb0ead51 initial commit for Sierra VMD file demuxer
melanson
parents:
diff changeset
139 st->codec.extradata_size = VMD_HEADER_SIZE;
6f50cb0ead51 initial commit for Sierra VMD file demuxer
melanson
parents:
diff changeset
140 st->codec.extradata = av_malloc(VMD_HEADER_SIZE);
6f50cb0ead51 initial commit for Sierra VMD file demuxer
melanson
parents:
diff changeset
141 memcpy(st->codec.extradata, vmd->vmd_header, VMD_HEADER_SIZE);
6f50cb0ead51 initial commit for Sierra VMD file demuxer
melanson
parents:
diff changeset
142
6f50cb0ead51 initial commit for Sierra VMD file demuxer
melanson
parents:
diff changeset
143 /* if sample rate is 0, assume no audio */
387
f2760852ed18 minor VMD system update; still not perfect, but should not crash either
melanson
parents: 338
diff changeset
144 vmd->sample_rate = LE_16(&vmd->vmd_header[804]);
f2760852ed18 minor VMD system update; still not perfect, but should not crash either
melanson
parents: 338
diff changeset
145 if (vmd->sample_rate) {
338
6f50cb0ead51 initial commit for Sierra VMD file demuxer
melanson
parents:
diff changeset
146 st = av_new_stream(s, 0);
6f50cb0ead51 initial commit for Sierra VMD file demuxer
melanson
parents:
diff changeset
147 if (!st)
6f50cb0ead51 initial commit for Sierra VMD file demuxer
melanson
parents:
diff changeset
148 return AVERROR_NOMEM;
462
b69898ffc92a move time_base (pts_num/pts_den) from AVFormatContext -> AVStream
michael
parents: 387
diff changeset
149 av_set_pts_info(st, 33, 1, 90000);
338
6f50cb0ead51 initial commit for Sierra VMD file demuxer
melanson
parents:
diff changeset
150 vmd->audio_stream_index = st->index;
6f50cb0ead51 initial commit for Sierra VMD file demuxer
melanson
parents:
diff changeset
151 st->codec.codec_type = CODEC_TYPE_AUDIO;
6f50cb0ead51 initial commit for Sierra VMD file demuxer
melanson
parents:
diff changeset
152 st->codec.codec_id = CODEC_ID_VMDAUDIO;
6f50cb0ead51 initial commit for Sierra VMD file demuxer
melanson
parents:
diff changeset
153 st->codec.codec_tag = 0; /* no codec tag */
6f50cb0ead51 initial commit for Sierra VMD file demuxer
melanson
parents:
diff changeset
154 st->codec.channels = (vmd->vmd_header[811] & 0x80) ? 2 : 1;
387
f2760852ed18 minor VMD system update; still not perfect, but should not crash either
melanson
parents: 338
diff changeset
155 st->codec.sample_rate = vmd->sample_rate;
f2760852ed18 minor VMD system update; still not perfect, but should not crash either
melanson
parents: 338
diff changeset
156 st->codec.block_align = vmd->audio_block_align =
f2760852ed18 minor VMD system update; still not perfect, but should not crash either
melanson
parents: 338
diff changeset
157 LE_16(&vmd->vmd_header[806]);
338
6f50cb0ead51 initial commit for Sierra VMD file demuxer
melanson
parents:
diff changeset
158 if (st->codec.block_align & 0x8000) {
6f50cb0ead51 initial commit for Sierra VMD file demuxer
melanson
parents:
diff changeset
159 st->codec.bits_per_sample = 16;
6f50cb0ead51 initial commit for Sierra VMD file demuxer
melanson
parents:
diff changeset
160 st->codec.block_align = -(st->codec.block_align - 0x10000);
6f50cb0ead51 initial commit for Sierra VMD file demuxer
melanson
parents:
diff changeset
161 } else
387
f2760852ed18 minor VMD system update; still not perfect, but should not crash either
melanson
parents: 338
diff changeset
162 st->codec.bits_per_sample = 16;
f2760852ed18 minor VMD system update; still not perfect, but should not crash either
melanson
parents: 338
diff changeset
163 // st->codec.bits_per_sample = 8;
f2760852ed18 minor VMD system update; still not perfect, but should not crash either
melanson
parents: 338
diff changeset
164 st->codec.bit_rate = st->codec.sample_rate *
f2760852ed18 minor VMD system update; still not perfect, but should not crash either
melanson
parents: 338
diff changeset
165 st->codec.bits_per_sample * st->codec.channels;
f2760852ed18 minor VMD system update; still not perfect, but should not crash either
melanson
parents: 338
diff changeset
166
f2760852ed18 minor VMD system update; still not perfect, but should not crash either
melanson
parents: 338
diff changeset
167 /* for calculating pts */
f2760852ed18 minor VMD system update; still not perfect, but should not crash either
melanson
parents: 338
diff changeset
168 vmd->audio_frame_divisor = st->codec.bits_per_sample / 8 /
f2760852ed18 minor VMD system update; still not perfect, but should not crash either
melanson
parents: 338
diff changeset
169 st->codec.channels;
f2760852ed18 minor VMD system update; still not perfect, but should not crash either
melanson
parents: 338
diff changeset
170
f2760852ed18 minor VMD system update; still not perfect, but should not crash either
melanson
parents: 338
diff changeset
171 video_pts_inc = 90000;
f2760852ed18 minor VMD system update; still not perfect, but should not crash either
melanson
parents: 338
diff changeset
172 video_pts_inc *= st->codec.block_align;
f2760852ed18 minor VMD system update; still not perfect, but should not crash either
melanson
parents: 338
diff changeset
173 video_pts_inc /= st->codec.sample_rate;
f2760852ed18 minor VMD system update; still not perfect, but should not crash either
melanson
parents: 338
diff changeset
174 } else {
f2760852ed18 minor VMD system update; still not perfect, but should not crash either
melanson
parents: 338
diff changeset
175 /* if no audio, assume 10 frames/second */
f2760852ed18 minor VMD system update; still not perfect, but should not crash either
melanson
parents: 338
diff changeset
176 video_pts_inc = 90000 / 10;
338
6f50cb0ead51 initial commit for Sierra VMD file demuxer
melanson
parents:
diff changeset
177 }
6f50cb0ead51 initial commit for Sierra VMD file demuxer
melanson
parents:
diff changeset
178
6f50cb0ead51 initial commit for Sierra VMD file demuxer
melanson
parents:
diff changeset
179 /* skip over the offset table and load the table of contents; don't
6f50cb0ead51 initial commit for Sierra VMD file demuxer
melanson
parents:
diff changeset
180 * care about the offset table since demuxer will calculate those
6f50cb0ead51 initial commit for Sierra VMD file demuxer
melanson
parents:
diff changeset
181 * independently */
6f50cb0ead51 initial commit for Sierra VMD file demuxer
melanson
parents:
diff changeset
182 toc_offset = LE_32(&vmd->vmd_header[812]);
6f50cb0ead51 initial commit for Sierra VMD file demuxer
melanson
parents:
diff changeset
183 vmd->frame_count = LE_16(&vmd->vmd_header[6]);
6f50cb0ead51 initial commit for Sierra VMD file demuxer
melanson
parents:
diff changeset
184 url_fseek(pb, toc_offset + vmd->frame_count * 6, SEEK_SET);
6f50cb0ead51 initial commit for Sierra VMD file demuxer
melanson
parents:
diff changeset
185
6f50cb0ead51 initial commit for Sierra VMD file demuxer
melanson
parents:
diff changeset
186 /* each on-disk VMD frame has an audio part and a video part; demuxer
6f50cb0ead51 initial commit for Sierra VMD file demuxer
melanson
parents:
diff changeset
187 * accounts them separately */
667
57e9d1bdcb09 VMD playing error patch by (Kostya (cannonball bw-team com>)
michael
parents: 482
diff changeset
188 if(vmd->sample_rate)
57e9d1bdcb09 VMD playing error patch by (Kostya (cannonball bw-team com>)
michael
parents: 482
diff changeset
189 vmd->frame_count *= 2;
338
6f50cb0ead51 initial commit for Sierra VMD file demuxer
melanson
parents:
diff changeset
190 raw_frame_table = NULL;
6f50cb0ead51 initial commit for Sierra VMD file demuxer
melanson
parents:
diff changeset
191 vmd->frame_table = NULL;
6f50cb0ead51 initial commit for Sierra VMD file demuxer
melanson
parents:
diff changeset
192 raw_frame_table_size = vmd->frame_count * BYTES_PER_FRAME_RECORD;
6f50cb0ead51 initial commit for Sierra VMD file demuxer
melanson
parents:
diff changeset
193 raw_frame_table = av_malloc(raw_frame_table_size);
6f50cb0ead51 initial commit for Sierra VMD file demuxer
melanson
parents:
diff changeset
194 vmd->frame_table = av_malloc(vmd->frame_count * sizeof(vmd_frame_t));
6f50cb0ead51 initial commit for Sierra VMD file demuxer
melanson
parents:
diff changeset
195 if (!raw_frame_table || !vmd->frame_table) {
6f50cb0ead51 initial commit for Sierra VMD file demuxer
melanson
parents:
diff changeset
196 av_free(raw_frame_table);
6f50cb0ead51 initial commit for Sierra VMD file demuxer
melanson
parents:
diff changeset
197 av_free(vmd->frame_table);
6f50cb0ead51 initial commit for Sierra VMD file demuxer
melanson
parents:
diff changeset
198 return AVERROR_NOMEM;
6f50cb0ead51 initial commit for Sierra VMD file demuxer
melanson
parents:
diff changeset
199 }
6f50cb0ead51 initial commit for Sierra VMD file demuxer
melanson
parents:
diff changeset
200 if (get_buffer(pb, raw_frame_table, raw_frame_table_size) !=
6f50cb0ead51 initial commit for Sierra VMD file demuxer
melanson
parents:
diff changeset
201 raw_frame_table_size) {
6f50cb0ead51 initial commit for Sierra VMD file demuxer
melanson
parents:
diff changeset
202 av_free(raw_frame_table);
6f50cb0ead51 initial commit for Sierra VMD file demuxer
melanson
parents:
diff changeset
203 av_free(vmd->frame_table);
482
0fdc96c2f2fe sweeping change from -EIO -> AVERROR_IO
melanson
parents: 462
diff changeset
204 return AVERROR_IO;
338
6f50cb0ead51 initial commit for Sierra VMD file demuxer
melanson
parents:
diff changeset
205 }
6f50cb0ead51 initial commit for Sierra VMD file demuxer
melanson
parents:
diff changeset
206
6f50cb0ead51 initial commit for Sierra VMD file demuxer
melanson
parents:
diff changeset
207 current_offset = LE_32(&vmd->vmd_header[20]);
6f50cb0ead51 initial commit for Sierra VMD file demuxer
melanson
parents:
diff changeset
208 current_frame_record = raw_frame_table;
6f50cb0ead51 initial commit for Sierra VMD file demuxer
melanson
parents:
diff changeset
209 total_frames = vmd->frame_count;
6f50cb0ead51 initial commit for Sierra VMD file demuxer
melanson
parents:
diff changeset
210 i = 0;
6f50cb0ead51 initial commit for Sierra VMD file demuxer
melanson
parents:
diff changeset
211 while (total_frames--) {
6f50cb0ead51 initial commit for Sierra VMD file demuxer
melanson
parents:
diff changeset
212
6f50cb0ead51 initial commit for Sierra VMD file demuxer
melanson
parents:
diff changeset
213 /* if the frame size is 0, do not count the frame and bring the
6f50cb0ead51 initial commit for Sierra VMD file demuxer
melanson
parents:
diff changeset
214 * total frame count down */
669
ed7ed3588399 fixing an integer overflow, which could lead to overwriting the end of a malloced buffer by 8 bytes
michael
parents: 667
diff changeset
215 // note, we limit the size to 1Gb to ensure that we dont end up overflowing the size integer used to allocate the memory
ed7ed3588399 fixing an integer overflow, which could lead to overwriting the end of a malloced buffer by 8 bytes
michael
parents: 667
diff changeset
216 vmd->frame_table[i].frame_size = LE_32(&current_frame_record[2]) & 0x3FFFFFFF;
338
6f50cb0ead51 initial commit for Sierra VMD file demuxer
melanson
parents:
diff changeset
217
6f50cb0ead51 initial commit for Sierra VMD file demuxer
melanson
parents:
diff changeset
218 /* this logic is present so that 0-length audio chunks are not
6f50cb0ead51 initial commit for Sierra VMD file demuxer
melanson
parents:
diff changeset
219 * accounted */
6f50cb0ead51 initial commit for Sierra VMD file demuxer
melanson
parents:
diff changeset
220 if (!vmd->frame_table[i].frame_size) {
6f50cb0ead51 initial commit for Sierra VMD file demuxer
melanson
parents:
diff changeset
221 vmd->frame_count--; /* one less frame to count */
6f50cb0ead51 initial commit for Sierra VMD file demuxer
melanson
parents:
diff changeset
222 current_frame_record += BYTES_PER_FRAME_RECORD;
6f50cb0ead51 initial commit for Sierra VMD file demuxer
melanson
parents:
diff changeset
223 continue;
6f50cb0ead51 initial commit for Sierra VMD file demuxer
melanson
parents:
diff changeset
224 }
6f50cb0ead51 initial commit for Sierra VMD file demuxer
melanson
parents:
diff changeset
225
6f50cb0ead51 initial commit for Sierra VMD file demuxer
melanson
parents:
diff changeset
226 if (current_frame_record[0] == 0x02)
6f50cb0ead51 initial commit for Sierra VMD file demuxer
melanson
parents:
diff changeset
227 vmd->frame_table[i].stream_index = vmd->video_stream_index;
6f50cb0ead51 initial commit for Sierra VMD file demuxer
melanson
parents:
diff changeset
228 else
6f50cb0ead51 initial commit for Sierra VMD file demuxer
melanson
parents:
diff changeset
229 vmd->frame_table[i].stream_index = vmd->audio_stream_index;
6f50cb0ead51 initial commit for Sierra VMD file demuxer
melanson
parents:
diff changeset
230 vmd->frame_table[i].frame_offset = current_offset;
6f50cb0ead51 initial commit for Sierra VMD file demuxer
melanson
parents:
diff changeset
231 current_offset += vmd->frame_table[i].frame_size;
6f50cb0ead51 initial commit for Sierra VMD file demuxer
melanson
parents:
diff changeset
232 memcpy(vmd->frame_table[i].frame_record, current_frame_record,
6f50cb0ead51 initial commit for Sierra VMD file demuxer
melanson
parents:
diff changeset
233 BYTES_PER_FRAME_RECORD);
6f50cb0ead51 initial commit for Sierra VMD file demuxer
melanson
parents:
diff changeset
234
387
f2760852ed18 minor VMD system update; still not perfect, but should not crash either
melanson
parents: 338
diff changeset
235 /* figure out the pts for this frame */
f2760852ed18 minor VMD system update; still not perfect, but should not crash either
melanson
parents: 338
diff changeset
236 if (current_frame_record[0] == 0x02) {
f2760852ed18 minor VMD system update; still not perfect, but should not crash either
melanson
parents: 338
diff changeset
237 vmd->frame_table[i].pts = current_video_pts;
f2760852ed18 minor VMD system update; still not perfect, but should not crash either
melanson
parents: 338
diff changeset
238 current_video_pts += video_pts_inc;
f2760852ed18 minor VMD system update; still not perfect, but should not crash either
melanson
parents: 338
diff changeset
239 } else if (current_frame_record[0] == 0x01) {
f2760852ed18 minor VMD system update; still not perfect, but should not crash either
melanson
parents: 338
diff changeset
240 /* figure out the pts during the dispatch phase */
f2760852ed18 minor VMD system update; still not perfect, but should not crash either
melanson
parents: 338
diff changeset
241 vmd->frame_table[i].pts = 0;
f2760852ed18 minor VMD system update; still not perfect, but should not crash either
melanson
parents: 338
diff changeset
242 }
338
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 current_frame_record += BYTES_PER_FRAME_RECORD;
6f50cb0ead51 initial commit for Sierra VMD file demuxer
melanson
parents:
diff changeset
245 i++;
6f50cb0ead51 initial commit for Sierra VMD file demuxer
melanson
parents:
diff changeset
246 }
6f50cb0ead51 initial commit for Sierra VMD file demuxer
melanson
parents:
diff changeset
247
6f50cb0ead51 initial commit for Sierra VMD file demuxer
melanson
parents:
diff changeset
248 av_free(raw_frame_table);
6f50cb0ead51 initial commit for Sierra VMD file demuxer
melanson
parents:
diff changeset
249
6f50cb0ead51 initial commit for Sierra VMD file demuxer
melanson
parents:
diff changeset
250 vmd->current_frame = 0;
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 return 0;
6f50cb0ead51 initial commit for Sierra VMD file demuxer
melanson
parents:
diff changeset
253 }
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 static int vmd_read_packet(AVFormatContext *s,
6f50cb0ead51 initial commit for Sierra VMD file demuxer
melanson
parents:
diff changeset
256 AVPacket *pkt)
6f50cb0ead51 initial commit for Sierra VMD file demuxer
melanson
parents:
diff changeset
257 {
6f50cb0ead51 initial commit for Sierra VMD file demuxer
melanson
parents:
diff changeset
258 VmdDemuxContext *vmd = (VmdDemuxContext *)s->priv_data;
6f50cb0ead51 initial commit for Sierra VMD file demuxer
melanson
parents:
diff changeset
259 ByteIOContext *pb = &s->pb;
6f50cb0ead51 initial commit for Sierra VMD file demuxer
melanson
parents:
diff changeset
260 int ret = 0;
6f50cb0ead51 initial commit for Sierra VMD file demuxer
melanson
parents:
diff changeset
261 vmd_frame_t *frame;
6f50cb0ead51 initial commit for Sierra VMD file demuxer
melanson
parents:
diff changeset
262
6f50cb0ead51 initial commit for Sierra VMD file demuxer
melanson
parents:
diff changeset
263 if (vmd->current_frame >= vmd->frame_count)
482
0fdc96c2f2fe sweeping change from -EIO -> AVERROR_IO
melanson
parents: 462
diff changeset
264 return AVERROR_IO;
338
6f50cb0ead51 initial commit for Sierra VMD file demuxer
melanson
parents:
diff changeset
265
6f50cb0ead51 initial commit for Sierra VMD file demuxer
melanson
parents:
diff changeset
266 frame = &vmd->frame_table[vmd->current_frame];
6f50cb0ead51 initial commit for Sierra VMD file demuxer
melanson
parents:
diff changeset
267 /* position the stream (will probably be there already) */
6f50cb0ead51 initial commit for Sierra VMD file demuxer
melanson
parents:
diff changeset
268 url_fseek(pb, frame->frame_offset, SEEK_SET);
6f50cb0ead51 initial commit for Sierra VMD file demuxer
melanson
parents:
diff changeset
269
6f50cb0ead51 initial commit for Sierra VMD file demuxer
melanson
parents:
diff changeset
270 if (av_new_packet(pkt, frame->frame_size + BYTES_PER_FRAME_RECORD))
6f50cb0ead51 initial commit for Sierra VMD file demuxer
melanson
parents:
diff changeset
271 return AVERROR_NOMEM;
6f50cb0ead51 initial commit for Sierra VMD file demuxer
melanson
parents:
diff changeset
272 memcpy(pkt->data, frame->frame_record, BYTES_PER_FRAME_RECORD);
6f50cb0ead51 initial commit for Sierra VMD file demuxer
melanson
parents:
diff changeset
273 ret = get_buffer(pb, pkt->data + BYTES_PER_FRAME_RECORD,
6f50cb0ead51 initial commit for Sierra VMD file demuxer
melanson
parents:
diff changeset
274 frame->frame_size);
6f50cb0ead51 initial commit for Sierra VMD file demuxer
melanson
parents:
diff changeset
275
387
f2760852ed18 minor VMD system update; still not perfect, but should not crash either
melanson
parents: 338
diff changeset
276 if (ret != frame->frame_size) {
f2760852ed18 minor VMD system update; still not perfect, but should not crash either
melanson
parents: 338
diff changeset
277 av_free_packet(pkt);
482
0fdc96c2f2fe sweeping change from -EIO -> AVERROR_IO
melanson
parents: 462
diff changeset
278 ret = AVERROR_IO;
387
f2760852ed18 minor VMD system update; still not perfect, but should not crash either
melanson
parents: 338
diff changeset
279 }
338
6f50cb0ead51 initial commit for Sierra VMD file demuxer
melanson
parents:
diff changeset
280 pkt->stream_index = frame->stream_index;
387
f2760852ed18 minor VMD system update; still not perfect, but should not crash either
melanson
parents: 338
diff changeset
281 if (frame->frame_record[0] == 0x02)
f2760852ed18 minor VMD system update; still not perfect, but should not crash either
melanson
parents: 338
diff changeset
282 pkt->pts = frame->pts;
f2760852ed18 minor VMD system update; still not perfect, but should not crash either
melanson
parents: 338
diff changeset
283 else {
f2760852ed18 minor VMD system update; still not perfect, but should not crash either
melanson
parents: 338
diff changeset
284 pkt->pts = vmd->audio_sample_counter;
f2760852ed18 minor VMD system update; still not perfect, but should not crash either
melanson
parents: 338
diff changeset
285 pkt->pts *= 90000;
f2760852ed18 minor VMD system update; still not perfect, but should not crash either
melanson
parents: 338
diff changeset
286 pkt->pts /= vmd->sample_rate;
f2760852ed18 minor VMD system update; still not perfect, but should not crash either
melanson
parents: 338
diff changeset
287 // pkt->pts /= vmd->audio_frame_divisor;
f2760852ed18 minor VMD system update; still not perfect, but should not crash either
melanson
parents: 338
diff changeset
288 vmd->audio_sample_counter += vmd_calculate_audio_duration(
f2760852ed18 minor VMD system update; still not perfect, but should not crash either
melanson
parents: 338
diff changeset
289 pkt->data, pkt->size, vmd->audio_block_align);
f2760852ed18 minor VMD system update; still not perfect, but should not crash either
melanson
parents: 338
diff changeset
290
f2760852ed18 minor VMD system update; still not perfect, but should not crash either
melanson
parents: 338
diff changeset
291 }
f2760852ed18 minor VMD system update; still not perfect, but should not crash either
melanson
parents: 338
diff changeset
292 printf (" dispatching %s frame with %d bytes and pts %lld (%0.1f sec)\n",
f2760852ed18 minor VMD system update; still not perfect, but should not crash either
melanson
parents: 338
diff changeset
293 (frame->frame_record[0] == 0x02) ? "video" : "audio",
f2760852ed18 minor VMD system update; still not perfect, but should not crash either
melanson
parents: 338
diff changeset
294 frame->frame_size + BYTES_PER_FRAME_RECORD,
f2760852ed18 minor VMD system update; still not perfect, but should not crash either
melanson
parents: 338
diff changeset
295 pkt->pts, (float)(pkt->pts / 90000.0));
338
6f50cb0ead51 initial commit for Sierra VMD file demuxer
melanson
parents:
diff changeset
296
6f50cb0ead51 initial commit for Sierra VMD file demuxer
melanson
parents:
diff changeset
297 vmd->current_frame++;
6f50cb0ead51 initial commit for Sierra VMD file demuxer
melanson
parents:
diff changeset
298
6f50cb0ead51 initial commit for Sierra VMD file demuxer
melanson
parents:
diff changeset
299 return ret;
6f50cb0ead51 initial commit for Sierra VMD file demuxer
melanson
parents:
diff changeset
300 }
6f50cb0ead51 initial commit for Sierra VMD file demuxer
melanson
parents:
diff changeset
301
6f50cb0ead51 initial commit for Sierra VMD file demuxer
melanson
parents:
diff changeset
302 static int vmd_read_close(AVFormatContext *s)
6f50cb0ead51 initial commit for Sierra VMD file demuxer
melanson
parents:
diff changeset
303 {
6f50cb0ead51 initial commit for Sierra VMD file demuxer
melanson
parents:
diff changeset
304 VmdDemuxContext *vmd = (VmdDemuxContext *)s->priv_data;
6f50cb0ead51 initial commit for Sierra VMD file demuxer
melanson
parents:
diff changeset
305
6f50cb0ead51 initial commit for Sierra VMD file demuxer
melanson
parents:
diff changeset
306 av_free(vmd->frame_table);
6f50cb0ead51 initial commit for Sierra VMD file demuxer
melanson
parents:
diff changeset
307
6f50cb0ead51 initial commit for Sierra VMD file demuxer
melanson
parents:
diff changeset
308 return 0;
6f50cb0ead51 initial commit for Sierra VMD file demuxer
melanson
parents:
diff changeset
309 }
6f50cb0ead51 initial commit for Sierra VMD file demuxer
melanson
parents:
diff changeset
310
6f50cb0ead51 initial commit for Sierra VMD file demuxer
melanson
parents:
diff changeset
311 static AVInputFormat vmd_iformat = {
6f50cb0ead51 initial commit for Sierra VMD file demuxer
melanson
parents:
diff changeset
312 "vmd",
6f50cb0ead51 initial commit for Sierra VMD file demuxer
melanson
parents:
diff changeset
313 "Sierra VMD format",
6f50cb0ead51 initial commit for Sierra VMD file demuxer
melanson
parents:
diff changeset
314 sizeof(VmdDemuxContext),
6f50cb0ead51 initial commit for Sierra VMD file demuxer
melanson
parents:
diff changeset
315 vmd_probe,
6f50cb0ead51 initial commit for Sierra VMD file demuxer
melanson
parents:
diff changeset
316 vmd_read_header,
6f50cb0ead51 initial commit for Sierra VMD file demuxer
melanson
parents:
diff changeset
317 vmd_read_packet,
6f50cb0ead51 initial commit for Sierra VMD file demuxer
melanson
parents:
diff changeset
318 vmd_read_close,
6f50cb0ead51 initial commit for Sierra VMD file demuxer
melanson
parents:
diff changeset
319 };
6f50cb0ead51 initial commit for Sierra VMD file demuxer
melanson
parents:
diff changeset
320
6f50cb0ead51 initial commit for Sierra VMD file demuxer
melanson
parents:
diff changeset
321 int vmd_init(void)
6f50cb0ead51 initial commit for Sierra VMD file demuxer
melanson
parents:
diff changeset
322 {
6f50cb0ead51 initial commit for Sierra VMD file demuxer
melanson
parents:
diff changeset
323 av_register_input_format(&vmd_iformat);
6f50cb0ead51 initial commit for Sierra VMD file demuxer
melanson
parents:
diff changeset
324 return 0;
6f50cb0ead51 initial commit for Sierra VMD file demuxer
melanson
parents:
diff changeset
325 }