Mercurial > libavformat.hg
annotate sierravmd.c @ 3240:78153a85dccc libavformat
Ensure that the timestamp reading code used for seeking chooses a position
which is a multiple of the packet size from the last packet start instead
of the file start. This fixes some seek issues with randomly cut ts files
and the mysterious "4 byte PCR somehing MTS something bug".
author | michael |
---|---|
date | Wed, 23 Apr 2008 21:16:25 +0000 |
parents | a086b58a3336 |
children | f95ddc69c48d |
rev | line source |
---|---|
338 | 1 /* |
2 * Sierra VMD Format Demuxer | |
3 * Copyright (c) 2004 The ffmpeg Project | |
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 | 8 * modify it under the terms of the GNU Lesser General Public |
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 | 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 | 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 | |
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 | 20 */ |
21 | |
22 /** | |
23 * @file sierravmd.c | |
24 * Sierra VMD file demuxer | |
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 | 28 */ |
29 | |
30 #include "avformat.h" | |
31 | |
32 #define VMD_HEADER_SIZE 0x0330 | |
33 #define BYTES_PER_FRAME_RECORD 16 | |
34 | |
35 typedef struct { | |
36 int stream_index; | |
37 offset_t frame_offset; | |
38 unsigned int frame_size; | |
39 int64_t pts; | |
40 int keyframe; | |
41 unsigned char frame_record[BYTES_PER_FRAME_RECORD]; | |
42 } vmd_frame_t; | |
43 | |
44 typedef struct VmdDemuxContext { | |
45 int video_stream_index; | |
46 int audio_stream_index; | |
47 | |
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 | 50 vmd_frame_t *frame_table; |
51 unsigned int current_frame; | |
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 | 57 unsigned char vmd_header[VMD_HEADER_SIZE]; |
58 } VmdDemuxContext; | |
59 | |
60 static int vmd_probe(AVProbeData *p) | |
61 { | |
62 /* check if the first 2 bytes of the file contain the appropriate size | |
63 * of a VMD header chunk */ | |
1673 | 64 if (AV_RL16(&p->buf[0]) != VMD_HEADER_SIZE - 2) |
338 | 65 return 0; |
66 | |
67 /* only return half certainty since this check is a bit sketchy */ | |
68 return AVPROBE_SCORE_MAX / 2; | |
69 } | |
70 | |
71 static int vmd_read_header(AVFormatContext *s, | |
72 AVFormatParameters *ap) | |
73 { | |
2006 | 74 VmdDemuxContext *vmd = s->priv_data; |
2771
d52c718e83f9
Use dynamically allocated ByteIOContext in AVFormatContext
andoma
parents:
2369
diff
changeset
|
75 ByteIOContext *pb = s->pb; |
3017 | 76 AVStream *st = NULL, *vst; |
338 | 77 unsigned int toc_offset; |
78 unsigned char *raw_frame_table; | |
79 int raw_frame_table_size; | |
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 | 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 | 88 |
89 /* fetch the main header, including the 2 header length bytes */ | |
90 url_fseek(pb, 0, SEEK_SET); | |
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 | 93 |
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 | 103 vst->codec->width = AV_RL16(&vmd->vmd_header[12]); |
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 | 108 |
109 /* if sample rate is 0, assume no audio */ | |
1673 | 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 | 112 st = av_new_stream(s, 0); |
113 if (!st) | |
2273
7eb456c4ed8a
Replace all occurrences of AVERROR_NOMEM with AVERROR(ENOMEM).
takis
parents:
2006
diff
changeset
|
114 return AVERROR(ENOMEM); |
338 | 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 | 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 | 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 | 138 } |
139 | |
1673 | 140 toc_offset = AV_RL32(&vmd->vmd_header[812]); |
141 vmd->frame_count = AV_RL16(&vmd->vmd_header[6]); | |
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 | 144 |
145 raw_frame_table = NULL; | |
146 vmd->frame_table = NULL; | |
1673 | 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 | 149 raw_frame_table = av_malloc(raw_frame_table_size); |
1079 | 150 if(vmd->frame_count * vmd->frames_per_block >= UINT_MAX / sizeof(vmd_frame_t)){ |
151 av_log(s, AV_LOG_ERROR, "vmd->frame_count * vmd->frames_per_block too large\n"); | |
152 return -1; | |
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 | 155 if (!raw_frame_table || !vmd->frame_table) { |
156 av_free(raw_frame_table); | |
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 | 159 } |
885 | 160 if (get_buffer(pb, raw_frame_table, raw_frame_table_size) != |
338 | 161 raw_frame_table_size) { |
162 av_free(raw_frame_table); | |
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 | 165 } |
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 | 170 current_offset = AV_RL32(&raw_frame_table[6 * i + 2]); |
338 | 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 | 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 | 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 */ |
3017 | 184 if (!st) break; |
1528
32d49970f01a
Divide first audio buffer chunk into atomary bufffers.
kostya
parents:
1492
diff
changeset
|
185 /* first audio chunk contains several audio buffers */ |
32d49970f01a
Divide first audio buffer chunk into atomary bufffers.
kostya
parents:
1492
diff
changeset
|
186 if(current_audio_pts){ |
1529 | 187 vmd->frame_table[total_frames].frame_offset = current_offset; |
188 vmd->frame_table[total_frames].stream_index = vmd->audio_stream_index; | |
189 vmd->frame_table[total_frames].frame_size = size; | |
190 memcpy(vmd->frame_table[total_frames].frame_record, chunk, BYTES_PER_FRAME_RECORD); | |
191 vmd->frame_table[total_frames].pts = current_audio_pts; | |
192 total_frames++; | |
193 current_audio_pts += pts_inc; | |
1528
32d49970f01a
Divide first audio buffer chunk into atomary bufffers.
kostya
parents:
1492
diff
changeset
|
194 }else{ |
32d49970f01a
Divide first audio buffer chunk into atomary bufffers.
kostya
parents:
1492
diff
changeset
|
195 uint32_t flags; |
32d49970f01a
Divide first audio buffer chunk into atomary bufffers.
kostya
parents:
1492
diff
changeset
|
196 int k; |
32d49970f01a
Divide first audio buffer chunk into atomary bufffers.
kostya
parents:
1492
diff
changeset
|
197 int noff; |
32d49970f01a
Divide first audio buffer chunk into atomary bufffers.
kostya
parents:
1492
diff
changeset
|
198 int64_t pos; |
32d49970f01a
Divide first audio buffer chunk into atomary bufffers.
kostya
parents:
1492
diff
changeset
|
199 |
32d49970f01a
Divide first audio buffer chunk into atomary bufffers.
kostya
parents:
1492
diff
changeset
|
200 pos = url_ftell(pb); |
32d49970f01a
Divide first audio buffer chunk into atomary bufffers.
kostya
parents:
1492
diff
changeset
|
201 url_fseek(pb, current_offset, SEEK_SET); |
32d49970f01a
Divide first audio buffer chunk into atomary bufffers.
kostya
parents:
1492
diff
changeset
|
202 flags = get_le32(pb); |
32d49970f01a
Divide first audio buffer chunk into atomary bufffers.
kostya
parents:
1492
diff
changeset
|
203 noff = 4; |
32d49970f01a
Divide first audio buffer chunk into atomary bufffers.
kostya
parents:
1492
diff
changeset
|
204 url_fseek(pb, pos, SEEK_SET); |
32d49970f01a
Divide first audio buffer chunk into atomary bufffers.
kostya
parents:
1492
diff
changeset
|
205 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
|
206 for(k = 0; k < sound_buffers - 1; k++){ |
32d49970f01a
Divide first audio buffer chunk into atomary bufffers.
kostya
parents:
1492
diff
changeset
|
207 if(flags & 1) { /* silent block */ |
32d49970f01a
Divide first audio buffer chunk into atomary bufffers.
kostya
parents:
1492
diff
changeset
|
208 vmd->frame_table[total_frames].frame_size = 0; |
32d49970f01a
Divide first audio buffer chunk into atomary bufffers.
kostya
parents:
1492
diff
changeset
|
209 }else{ |
32d49970f01a
Divide first audio buffer chunk into atomary bufffers.
kostya
parents:
1492
diff
changeset
|
210 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
|
211 } |
32d49970f01a
Divide first audio buffer chunk into atomary bufffers.
kostya
parents:
1492
diff
changeset
|
212 noff += vmd->frame_table[total_frames].frame_size; |
32d49970f01a
Divide first audio buffer chunk into atomary bufffers.
kostya
parents:
1492
diff
changeset
|
213 vmd->frame_table[total_frames].frame_offset = current_offset + noff; |
32d49970f01a
Divide first audio buffer chunk into atomary bufffers.
kostya
parents:
1492
diff
changeset
|
214 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
|
215 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
|
216 vmd->frame_table[total_frames].pts = current_audio_pts; |
32d49970f01a
Divide first audio buffer chunk into atomary bufffers.
kostya
parents:
1492
diff
changeset
|
217 total_frames++; |
32d49970f01a
Divide first audio buffer chunk into atomary bufffers.
kostya
parents:
1492
diff
changeset
|
218 current_audio_pts += pts_inc; |
32d49970f01a
Divide first audio buffer chunk into atomary bufffers.
kostya
parents:
1492
diff
changeset
|
219 flags >>= 1; |
32d49970f01a
Divide first audio buffer chunk into atomary bufffers.
kostya
parents:
1492
diff
changeset
|
220 } |
32d49970f01a
Divide first audio buffer chunk into atomary bufffers.
kostya
parents:
1492
diff
changeset
|
221 } |
1004
409b399440a3
More correct demuxing and timestamp setting fot Sierra VMD
kostya
parents:
896
diff
changeset
|
222 break; |
409b399440a3
More correct demuxing and timestamp setting fot Sierra VMD
kostya
parents:
896
diff
changeset
|
223 case 2: /* Video Chunk */ |
409b399440a3
More correct demuxing and timestamp setting fot Sierra VMD
kostya
parents:
896
diff
changeset
|
224 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
|
225 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
|
226 vmd->frame_table[total_frames].frame_size = size; |
409b399440a3
More correct demuxing and timestamp setting fot Sierra VMD
kostya
parents:
896
diff
changeset
|
227 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
|
228 vmd->frame_table[total_frames].pts = current_video_pts; |
409b399440a3
More correct demuxing and timestamp setting fot Sierra VMD
kostya
parents:
896
diff
changeset
|
229 total_frames++; |
409b399440a3
More correct demuxing and timestamp setting fot Sierra VMD
kostya
parents:
896
diff
changeset
|
230 break; |
409b399440a3
More correct demuxing and timestamp setting fot Sierra VMD
kostya
parents:
896
diff
changeset
|
231 } |
409b399440a3
More correct demuxing and timestamp setting fot Sierra VMD
kostya
parents:
896
diff
changeset
|
232 current_offset += size; |
387
f2760852ed18
minor VMD system update; still not perfect, but should not crash either
melanson
parents:
338
diff
changeset
|
233 } |
1492
deaec052eec4
Simplify VMD demuxer (but it still does not work right)
kostya
parents:
1441
diff
changeset
|
234 current_video_pts += pts_inc; |
338 | 235 } |
236 | |
237 av_free(raw_frame_table); | |
238 | |
239 vmd->current_frame = 0; | |
1004
409b399440a3
More correct demuxing and timestamp setting fot Sierra VMD
kostya
parents:
896
diff
changeset
|
240 vmd->frame_count = total_frames; |
338 | 241 |
242 return 0; | |
243 } | |
244 | |
245 static int vmd_read_packet(AVFormatContext *s, | |
246 AVPacket *pkt) | |
247 { | |
2006 | 248 VmdDemuxContext *vmd = s->priv_data; |
2771
d52c718e83f9
Use dynamically allocated ByteIOContext in AVFormatContext
andoma
parents:
2369
diff
changeset
|
249 ByteIOContext *pb = s->pb; |
338 | 250 int ret = 0; |
251 vmd_frame_t *frame; | |
252 | |
253 if (vmd->current_frame >= vmd->frame_count) | |
2274
b21c2af60bc9
Replace all occurrences of AVERROR_IO with AVERROR(EIO).
takis
parents:
2273
diff
changeset
|
254 return AVERROR(EIO); |
338 | 255 |
256 frame = &vmd->frame_table[vmd->current_frame]; | |
257 /* position the stream (will probably be there already) */ | |
258 url_fseek(pb, frame->frame_offset, SEEK_SET); | |
259 | |
260 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
|
261 return AVERROR(ENOMEM); |
775 | 262 pkt->pos= url_ftell(pb); |
338 | 263 memcpy(pkt->data, frame->frame_record, BYTES_PER_FRAME_RECORD); |
885 | 264 ret = get_buffer(pb, pkt->data + BYTES_PER_FRAME_RECORD, |
338 | 265 frame->frame_size); |
266 | |
387
f2760852ed18
minor VMD system update; still not perfect, but should not crash either
melanson
parents:
338
diff
changeset
|
267 if (ret != frame->frame_size) { |
f2760852ed18
minor VMD system update; still not perfect, but should not crash either
melanson
parents:
338
diff
changeset
|
268 av_free_packet(pkt); |
2274
b21c2af60bc9
Replace all occurrences of AVERROR_IO with AVERROR(EIO).
takis
parents:
2273
diff
changeset
|
269 ret = AVERROR(EIO); |
387
f2760852ed18
minor VMD system update; still not perfect, but should not crash either
melanson
parents:
338
diff
changeset
|
270 } |
338 | 271 pkt->stream_index = frame->stream_index; |
1492
deaec052eec4
Simplify VMD demuxer (but it still does not work right)
kostya
parents:
1441
diff
changeset
|
272 pkt->pts = frame->pts; |
2369 | 273 av_log(NULL, AV_LOG_DEBUG, " 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
|
274 (frame->frame_record[0] == 0x02) ? "video" : "audio", |
ad3b03b7b142
reindentation, patch by From: Steve Lhomme, slhomme divxcorp com
diego
parents:
1358
diff
changeset
|
275 frame->frame_size + BYTES_PER_FRAME_RECORD, |
1492
deaec052eec4
Simplify VMD demuxer (but it still does not work right)
kostya
parents:
1441
diff
changeset
|
276 pkt->pts); |
338 | 277 |
278 vmd->current_frame++; | |
279 | |
280 return ret; | |
281 } | |
282 | |
283 static int vmd_read_close(AVFormatContext *s) | |
284 { | |
2006 | 285 VmdDemuxContext *vmd = s->priv_data; |
338 | 286 |
287 av_free(vmd->frame_table); | |
288 | |
289 return 0; | |
290 } | |
291 | |
1169 | 292 AVInputFormat vmd_demuxer = { |
338 | 293 "vmd", |
294 "Sierra VMD format", | |
295 sizeof(VmdDemuxContext), | |
296 vmd_probe, | |
297 vmd_read_header, | |
298 vmd_read_packet, | |
299 vmd_read_close, | |
300 }; |