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
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;
2771
d52c718e83f9 Use dynamically allocated ByteIOContext in AVFormatContext
andoma
parents: 2369
diff changeset
75 ByteIOContext *pb = s->pb;
3017
a086b58a3336 Fix a possible use of an uninitialized pointer.
reimar
parents: 2771
diff changeset
76 AVStream *st = NULL, *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 */
3017
a086b58a3336 Fix a possible use of an uninitialized pointer.
reimar
parents: 2771
diff changeset
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
07898e88c5b9 Identation
kostya
parents: 1528
diff changeset
187 vmd->frame_table[total_frames].frame_offset = current_offset;
07898e88c5b9 Identation
kostya
parents: 1528
diff changeset
188 vmd->frame_table[total_frames].stream_index = vmd->audio_stream_index;
07898e88c5b9 Identation
kostya
parents: 1528
diff changeset
189 vmd->frame_table[total_frames].frame_size = size;
07898e88c5b9 Identation
kostya
parents: 1528
diff changeset
190 memcpy(vmd->frame_table[total_frames].frame_record, chunk, BYTES_PER_FRAME_RECORD);
07898e88c5b9 Identation
kostya
parents: 1528
diff changeset
191 vmd->frame_table[total_frames].pts = current_audio_pts;
07898e88c5b9 Identation
kostya
parents: 1528
diff changeset
192 total_frames++;
07898e88c5b9 Identation
kostya
parents: 1528
diff changeset
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
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
6f50cb0ead51 initial commit for Sierra VMD file demuxer
melanson
parents:
diff changeset
237 av_free(raw_frame_table);
6f50cb0ead51 initial commit for Sierra VMD file demuxer
melanson
parents:
diff changeset
238
6f50cb0ead51 initial commit for Sierra VMD file demuxer
melanson
parents:
diff changeset
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
6f50cb0ead51 initial commit for Sierra VMD file demuxer
melanson
parents:
diff changeset
241
6f50cb0ead51 initial commit for Sierra VMD file demuxer
melanson
parents:
diff changeset
242 return 0;
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
6f50cb0ead51 initial commit for Sierra VMD file demuxer
melanson
parents:
diff changeset
245 static int vmd_read_packet(AVFormatContext *s,
6f50cb0ead51 initial commit for Sierra VMD file demuxer
melanson
parents:
diff changeset
246 AVPacket *pkt)
6f50cb0ead51 initial commit for Sierra VMD file demuxer
melanson
parents:
diff changeset
247 {
2006
2f0154760e5f Get rid of unnecessary pointer casts.
diego
parents: 2001
diff changeset
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
6f50cb0ead51 initial commit for Sierra VMD file demuxer
melanson
parents:
diff changeset
250 int ret = 0;
6f50cb0ead51 initial commit for Sierra VMD file demuxer
melanson
parents:
diff changeset
251 vmd_frame_t *frame;
6f50cb0ead51 initial commit for Sierra VMD file demuxer
melanson
parents:
diff changeset
252
6f50cb0ead51 initial commit for Sierra VMD file demuxer
melanson
parents:
diff changeset
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
6f50cb0ead51 initial commit for Sierra VMD file demuxer
melanson
parents:
diff changeset
255
6f50cb0ead51 initial commit for Sierra VMD file demuxer
melanson
parents:
diff changeset
256 frame = &vmd->frame_table[vmd->current_frame];
6f50cb0ead51 initial commit for Sierra VMD file demuxer
melanson
parents:
diff changeset
257 /* position the stream (will probably be there already) */
6f50cb0ead51 initial commit for Sierra VMD file demuxer
melanson
parents:
diff changeset
258 url_fseek(pb, frame->frame_offset, SEEK_SET);
6f50cb0ead51 initial commit for Sierra VMD file demuxer
melanson
parents:
diff changeset
259
6f50cb0ead51 initial commit for Sierra VMD file demuxer
melanson
parents:
diff changeset
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
c5077fdab490 AVPacket.pos
michael
parents: 669
diff changeset
262 pkt->pos= url_ftell(pb);
338
6f50cb0ead51 initial commit for Sierra VMD file demuxer
melanson
parents:
diff changeset
263 memcpy(pkt->data, frame->frame_record, BYTES_PER_FRAME_RECORD);
885
da1d5db0ce5c COSMETICS: Remove all trailing whitespace.
diego
parents: 884
diff changeset
264 ret = get_buffer(pb, pkt->data + BYTES_PER_FRAME_RECORD,
338
6f50cb0ead51 initial commit for Sierra VMD file demuxer
melanson
parents:
diff changeset
265 frame->frame_size);
6f50cb0ead51 initial commit for Sierra VMD file demuxer
melanson
parents:
diff changeset
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
6f50cb0ead51 initial commit for Sierra VMD file demuxer
melanson
parents:
diff changeset
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
2e7affad5b28 this is debug not info
michael
parents: 2274
diff changeset
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
6f50cb0ead51 initial commit for Sierra VMD file demuxer
melanson
parents:
diff changeset
277
6f50cb0ead51 initial commit for Sierra VMD file demuxer
melanson
parents:
diff changeset
278 vmd->current_frame++;
6f50cb0ead51 initial commit for Sierra VMD file demuxer
melanson
parents:
diff changeset
279
6f50cb0ead51 initial commit for Sierra VMD file demuxer
melanson
parents:
diff changeset
280 return ret;
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
6f50cb0ead51 initial commit for Sierra VMD file demuxer
melanson
parents:
diff changeset
283 static int vmd_read_close(AVFormatContext *s)
6f50cb0ead51 initial commit for Sierra VMD file demuxer
melanson
parents:
diff changeset
284 {
2006
2f0154760e5f Get rid of unnecessary pointer casts.
diego
parents: 2001
diff changeset
285 VmdDemuxContext *vmd = s->priv_data;
338
6f50cb0ead51 initial commit for Sierra VMD file demuxer
melanson
parents:
diff changeset
286
6f50cb0ead51 initial commit for Sierra VMD file demuxer
melanson
parents:
diff changeset
287 av_free(vmd->frame_table);
6f50cb0ead51 initial commit for Sierra VMD file demuxer
melanson
parents:
diff changeset
288
6f50cb0ead51 initial commit for Sierra VMD file demuxer
melanson
parents:
diff changeset
289 return 0;
6f50cb0ead51 initial commit for Sierra VMD file demuxer
melanson
parents:
diff changeset
290 }
6f50cb0ead51 initial commit for Sierra VMD file demuxer
melanson
parents:
diff changeset
291
1169
d18cc9a1fd02 allow individual selection of muxers and demuxers
mru
parents: 1167
diff changeset
292 AVInputFormat vmd_demuxer = {
338
6f50cb0ead51 initial commit for Sierra VMD file demuxer
melanson
parents:
diff changeset
293 "vmd",
6f50cb0ead51 initial commit for Sierra VMD file demuxer
melanson
parents:
diff changeset
294 "Sierra VMD format",
6f50cb0ead51 initial commit for Sierra VMD file demuxer
melanson
parents:
diff changeset
295 sizeof(VmdDemuxContext),
6f50cb0ead51 initial commit for Sierra VMD file demuxer
melanson
parents:
diff changeset
296 vmd_probe,
6f50cb0ead51 initial commit for Sierra VMD file demuxer
melanson
parents:
diff changeset
297 vmd_read_header,
6f50cb0ead51 initial commit for Sierra VMD file demuxer
melanson
parents:
diff changeset
298 vmd_read_packet,
6f50cb0ead51 initial commit for Sierra VMD file demuxer
melanson
parents:
diff changeset
299 vmd_read_close,
6f50cb0ead51 initial commit for Sierra VMD file demuxer
melanson
parents:
diff changeset
300 };