annotate 4xm.c @ 3754:8d267b43eaba libavformat

Move malloc() down until after all initializations, so that the resource is only allocated if initialization worked. This means that on failure, we don't have to deallocate it.
author rbultje
date Sat, 23 Aug 2008 18:46:30 +0000
parents 7a0230981402
children 1d3d17de20ba
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
rev   line source
137
857a026b7e93 first pass at an experimental 4xm demuxer
tmmm
parents:
diff changeset
1 /*
857a026b7e93 first pass at an experimental 4xm demuxer
tmmm
parents:
diff changeset
2 * 4X Technologies .4xm File Demuxer (no muxer)
857a026b7e93 first pass at an experimental 4xm demuxer
tmmm
parents:
diff changeset
3 * Copyright (c) 2003 The ffmpeg Project
857a026b7e93 first pass at an experimental 4xm demuxer
tmmm
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
137
857a026b7e93 first pass at an experimental 4xm demuxer
tmmm
parents:
diff changeset
8 * modify it under the terms of the GNU Lesser General Public
857a026b7e93 first pass at an experimental 4xm demuxer
tmmm
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.
137
857a026b7e93 first pass at an experimental 4xm demuxer
tmmm
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,
137
857a026b7e93 first pass at an experimental 4xm demuxer
tmmm
parents:
diff changeset
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
857a026b7e93 first pass at an experimental 4xm demuxer
tmmm
parents:
diff changeset
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
857a026b7e93 first pass at an experimental 4xm demuxer
tmmm
parents:
diff changeset
15 * Lesser General Public License for more details.
857a026b7e93 first pass at an experimental 4xm demuxer
tmmm
parents:
diff changeset
16 *
857a026b7e93 first pass at an experimental 4xm demuxer
tmmm
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: 885
diff changeset
19 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
137
857a026b7e93 first pass at an experimental 4xm demuxer
tmmm
parents:
diff changeset
20 */
857a026b7e93 first pass at an experimental 4xm demuxer
tmmm
parents:
diff changeset
21
857a026b7e93 first pass at an experimental 4xm demuxer
tmmm
parents:
diff changeset
22 /**
857a026b7e93 first pass at an experimental 4xm demuxer
tmmm
parents:
diff changeset
23 * @file 4xm.c
857a026b7e93 first pass at an experimental 4xm demuxer
tmmm
parents:
diff changeset
24 * 4X Technologies file demuxer
857a026b7e93 first pass at an experimental 4xm demuxer
tmmm
parents:
diff changeset
25 * by Mike Melanson (melanson@pcisys.net)
857a026b7e93 first pass at an experimental 4xm demuxer
tmmm
parents:
diff changeset
26 * for more information on the .4xm file format, visit:
857a026b7e93 first pass at an experimental 4xm demuxer
tmmm
parents:
diff changeset
27 * http://www.pcisys.net/~melanson/codecs/
857a026b7e93 first pass at an experimental 4xm demuxer
tmmm
parents:
diff changeset
28 */
857a026b7e93 first pass at an experimental 4xm demuxer
tmmm
parents:
diff changeset
29
857a026b7e93 first pass at an experimental 4xm demuxer
tmmm
parents:
diff changeset
30 #include "avformat.h"
857a026b7e93 first pass at an experimental 4xm demuxer
tmmm
parents:
diff changeset
31
386
c152849ee643 remove numerous definitions of BE_*/LE_* macros; convert FOURCC_TAG ->
melanson
parents: 317
diff changeset
32 #define RIFF_TAG MKTAG('R', 'I', 'F', 'F')
c152849ee643 remove numerous definitions of BE_*/LE_* macros; convert FOURCC_TAG ->
melanson
parents: 317
diff changeset
33 #define _4XMV_TAG MKTAG('4', 'X', 'M', 'V')
c152849ee643 remove numerous definitions of BE_*/LE_* macros; convert FOURCC_TAG ->
melanson
parents: 317
diff changeset
34 #define LIST_TAG MKTAG('L', 'I', 'S', 'T')
c152849ee643 remove numerous definitions of BE_*/LE_* macros; convert FOURCC_TAG ->
melanson
parents: 317
diff changeset
35 #define HEAD_TAG MKTAG('H', 'E', 'A', 'D')
c152849ee643 remove numerous definitions of BE_*/LE_* macros; convert FOURCC_TAG ->
melanson
parents: 317
diff changeset
36 #define TRK__TAG MKTAG('T', 'R', 'K', '_')
c152849ee643 remove numerous definitions of BE_*/LE_* macros; convert FOURCC_TAG ->
melanson
parents: 317
diff changeset
37 #define MOVI_TAG MKTAG('M', 'O', 'V', 'I')
c152849ee643 remove numerous definitions of BE_*/LE_* macros; convert FOURCC_TAG ->
melanson
parents: 317
diff changeset
38 #define VTRK_TAG MKTAG('V', 'T', 'R', 'K')
c152849ee643 remove numerous definitions of BE_*/LE_* macros; convert FOURCC_TAG ->
melanson
parents: 317
diff changeset
39 #define STRK_TAG MKTAG('S', 'T', 'R', 'K')
c152849ee643 remove numerous definitions of BE_*/LE_* macros; convert FOURCC_TAG ->
melanson
parents: 317
diff changeset
40 #define std__TAG MKTAG('s', 't', 'd', '_')
c152849ee643 remove numerous definitions of BE_*/LE_* macros; convert FOURCC_TAG ->
melanson
parents: 317
diff changeset
41 #define name_TAG MKTAG('n', 'a', 'm', 'e')
c152849ee643 remove numerous definitions of BE_*/LE_* macros; convert FOURCC_TAG ->
melanson
parents: 317
diff changeset
42 #define vtrk_TAG MKTAG('v', 't', 'r', 'k')
c152849ee643 remove numerous definitions of BE_*/LE_* macros; convert FOURCC_TAG ->
melanson
parents: 317
diff changeset
43 #define strk_TAG MKTAG('s', 't', 'r', 'k')
c152849ee643 remove numerous definitions of BE_*/LE_* macros; convert FOURCC_TAG ->
melanson
parents: 317
diff changeset
44 #define ifrm_TAG MKTAG('i', 'f', 'r', 'm')
c152849ee643 remove numerous definitions of BE_*/LE_* macros; convert FOURCC_TAG ->
melanson
parents: 317
diff changeset
45 #define pfrm_TAG MKTAG('p', 'f', 'r', 'm')
c152849ee643 remove numerous definitions of BE_*/LE_* macros; convert FOURCC_TAG ->
melanson
parents: 317
diff changeset
46 #define cfrm_TAG MKTAG('c', 'f', 'r', 'm')
2377
2a44e9c75bf3 pass *fr2 chunks to decoder (Toy-Story2_better-image-quality.4xa contains them)
michael
parents: 2274
diff changeset
47 #define ifr2_TAG MKTAG('i', 'f', 'r', '2')
2a44e9c75bf3 pass *fr2 chunks to decoder (Toy-Story2_better-image-quality.4xa contains them)
michael
parents: 2274
diff changeset
48 #define pfr2_TAG MKTAG('p', 'f', 'r', '2')
2a44e9c75bf3 pass *fr2 chunks to decoder (Toy-Story2_better-image-quality.4xa contains them)
michael
parents: 2274
diff changeset
49 #define cfr2_TAG MKTAG('c', 'f', 'r', '2')
386
c152849ee643 remove numerous definitions of BE_*/LE_* macros; convert FOURCC_TAG ->
melanson
parents: 317
diff changeset
50 #define snd__TAG MKTAG('s', 'n', 'd', '_')
137
857a026b7e93 first pass at an experimental 4xm demuxer
tmmm
parents:
diff changeset
51
857a026b7e93 first pass at an experimental 4xm demuxer
tmmm
parents:
diff changeset
52 #define vtrk_SIZE 0x44
857a026b7e93 first pass at an experimental 4xm demuxer
tmmm
parents:
diff changeset
53 #define strk_SIZE 0x28
857a026b7e93 first pass at an experimental 4xm demuxer
tmmm
parents:
diff changeset
54
857a026b7e93 first pass at an experimental 4xm demuxer
tmmm
parents:
diff changeset
55 #define GET_LIST_HEADER() \
143
76dd1e93b064 dispatch video as well as audio
tmmm
parents: 141
diff changeset
56 fourcc_tag = get_le32(pb); \
137
857a026b7e93 first pass at an experimental 4xm demuxer
tmmm
parents:
diff changeset
57 size = get_le32(pb); \
857a026b7e93 first pass at an experimental 4xm demuxer
tmmm
parents:
diff changeset
58 if (fourcc_tag != LIST_TAG) \
857a026b7e93 first pass at an experimental 4xm demuxer
tmmm
parents:
diff changeset
59 return AVERROR_INVALIDDATA; \
143
76dd1e93b064 dispatch video as well as audio
tmmm
parents: 141
diff changeset
60 fourcc_tag = get_le32(pb);
137
857a026b7e93 first pass at an experimental 4xm demuxer
tmmm
parents:
diff changeset
61
857a026b7e93 first pass at an experimental 4xm demuxer
tmmm
parents:
diff changeset
62 typedef struct AudioTrack {
857a026b7e93 first pass at an experimental 4xm demuxer
tmmm
parents:
diff changeset
63 int sample_rate;
857a026b7e93 first pass at an experimental 4xm demuxer
tmmm
parents:
diff changeset
64 int bits;
857a026b7e93 first pass at an experimental 4xm demuxer
tmmm
parents:
diff changeset
65 int channels;
143
76dd1e93b064 dispatch video as well as audio
tmmm
parents: 141
diff changeset
66 int stream_index;
145
4f3960430e54 4xm adpcm
michaelni
parents: 144
diff changeset
67 int adpcm;
137
857a026b7e93 first pass at an experimental 4xm demuxer
tmmm
parents:
diff changeset
68 } AudioTrack;
857a026b7e93 first pass at an experimental 4xm demuxer
tmmm
parents:
diff changeset
69
857a026b7e93 first pass at an experimental 4xm demuxer
tmmm
parents:
diff changeset
70 typedef struct FourxmDemuxContext {
857a026b7e93 first pass at an experimental 4xm demuxer
tmmm
parents:
diff changeset
71 int width;
857a026b7e93 first pass at an experimental 4xm demuxer
tmmm
parents:
diff changeset
72 int height;
143
76dd1e93b064 dispatch video as well as audio
tmmm
parents: 141
diff changeset
73 int video_stream_index;
137
857a026b7e93 first pass at an experimental 4xm demuxer
tmmm
parents:
diff changeset
74 int track_count;
857a026b7e93 first pass at an experimental 4xm demuxer
tmmm
parents:
diff changeset
75 AudioTrack *tracks;
857a026b7e93 first pass at an experimental 4xm demuxer
tmmm
parents:
diff changeset
76 int selected_track;
143
76dd1e93b064 dispatch video as well as audio
tmmm
parents: 141
diff changeset
77
316
9aa23c6d396e use the proper file framerate (specified by a float); account the pts
melanson
parents: 254
diff changeset
78 int64_t audio_pts;
9aa23c6d396e use the proper file framerate (specified by a float); account the pts
melanson
parents: 254
diff changeset
79 int64_t video_pts;
317
5cd41ae1debf set frame rate information, for good measure
melanson
parents: 316
diff changeset
80 float fps;
137
857a026b7e93 first pass at an experimental 4xm demuxer
tmmm
parents:
diff changeset
81 } FourxmDemuxContext;
857a026b7e93 first pass at an experimental 4xm demuxer
tmmm
parents:
diff changeset
82
857a026b7e93 first pass at an experimental 4xm demuxer
tmmm
parents:
diff changeset
83 static int fourxm_probe(AVProbeData *p)
857a026b7e93 first pass at an experimental 4xm demuxer
tmmm
parents:
diff changeset
84 {
1673
a782462e2497 rename BE/LE_8/16/32 to AV_RL/B_8/16/32
alex
parents: 1450
diff changeset
85 if ((AV_RL32(&p->buf[0]) != RIFF_TAG) ||
a782462e2497 rename BE/LE_8/16/32 to AV_RL/B_8/16/32
alex
parents: 1450
diff changeset
86 (AV_RL32(&p->buf[8]) != _4XMV_TAG))
137
857a026b7e93 first pass at an experimental 4xm demuxer
tmmm
parents:
diff changeset
87 return 0;
857a026b7e93 first pass at an experimental 4xm demuxer
tmmm
parents:
diff changeset
88
857a026b7e93 first pass at an experimental 4xm demuxer
tmmm
parents:
diff changeset
89 return AVPROBE_SCORE_MAX;
857a026b7e93 first pass at an experimental 4xm demuxer
tmmm
parents:
diff changeset
90 }
857a026b7e93 first pass at an experimental 4xm demuxer
tmmm
parents:
diff changeset
91
857a026b7e93 first pass at an experimental 4xm demuxer
tmmm
parents:
diff changeset
92 static int fourxm_read_header(AVFormatContext *s,
143
76dd1e93b064 dispatch video as well as audio
tmmm
parents: 141
diff changeset
93 AVFormatParameters *ap)
137
857a026b7e93 first pass at an experimental 4xm demuxer
tmmm
parents:
diff changeset
94 {
2771
d52c718e83f9 Use dynamically allocated ByteIOContext in AVFormatContext
andoma
parents: 2410
diff changeset
95 ByteIOContext *pb = s->pb;
137
857a026b7e93 first pass at an experimental 4xm demuxer
tmmm
parents:
diff changeset
96 unsigned int fourcc_tag;
857a026b7e93 first pass at an experimental 4xm demuxer
tmmm
parents:
diff changeset
97 unsigned int size;
857a026b7e93 first pass at an experimental 4xm demuxer
tmmm
parents:
diff changeset
98 int header_size;
2006
2f0154760e5f Get rid of unnecessary pointer casts.
diego
parents: 2001
diff changeset
99 FourxmDemuxContext *fourxm = s->priv_data;
137
857a026b7e93 first pass at an experimental 4xm demuxer
tmmm
parents:
diff changeset
100 unsigned char *header;
857a026b7e93 first pass at an experimental 4xm demuxer
tmmm
parents:
diff changeset
101 int i;
857a026b7e93 first pass at an experimental 4xm demuxer
tmmm
parents:
diff changeset
102 int current_track = -1;
857a026b7e93 first pass at an experimental 4xm demuxer
tmmm
parents:
diff changeset
103 AVStream *st;
857a026b7e93 first pass at an experimental 4xm demuxer
tmmm
parents:
diff changeset
104
857a026b7e93 first pass at an experimental 4xm demuxer
tmmm
parents:
diff changeset
105 fourxm->track_count = 0;
857a026b7e93 first pass at an experimental 4xm demuxer
tmmm
parents:
diff changeset
106 fourxm->tracks = NULL;
857a026b7e93 first pass at an experimental 4xm demuxer
tmmm
parents:
diff changeset
107 fourxm->selected_track = 0;
317
5cd41ae1debf set frame rate information, for good measure
melanson
parents: 316
diff changeset
108 fourxm->fps = 1.0;
137
857a026b7e93 first pass at an experimental 4xm demuxer
tmmm
parents:
diff changeset
109
857a026b7e93 first pass at an experimental 4xm demuxer
tmmm
parents:
diff changeset
110 /* skip the first 3 32-bit numbers */
857a026b7e93 first pass at an experimental 4xm demuxer
tmmm
parents:
diff changeset
111 url_fseek(pb, 12, SEEK_CUR);
857a026b7e93 first pass at an experimental 4xm demuxer
tmmm
parents:
diff changeset
112
857a026b7e93 first pass at an experimental 4xm demuxer
tmmm
parents:
diff changeset
113 /* check for LIST-HEAD */
857a026b7e93 first pass at an experimental 4xm demuxer
tmmm
parents:
diff changeset
114 GET_LIST_HEADER();
857a026b7e93 first pass at an experimental 4xm demuxer
tmmm
parents:
diff changeset
115 header_size = size - 4;
857a026b7e93 first pass at an experimental 4xm demuxer
tmmm
parents:
diff changeset
116 if (fourcc_tag != HEAD_TAG)
857a026b7e93 first pass at an experimental 4xm demuxer
tmmm
parents:
diff changeset
117 return AVERROR_INVALIDDATA;
857a026b7e93 first pass at an experimental 4xm demuxer
tmmm
parents:
diff changeset
118
857a026b7e93 first pass at an experimental 4xm demuxer
tmmm
parents:
diff changeset
119 /* allocate space for the header and load the whole thing */
857a026b7e93 first pass at an experimental 4xm demuxer
tmmm
parents:
diff changeset
120 header = av_malloc(header_size);
857a026b7e93 first pass at an experimental 4xm demuxer
tmmm
parents:
diff changeset
121 if (!header)
2273
7eb456c4ed8a Replace all occurrences of AVERROR_NOMEM with AVERROR(ENOMEM).
takis
parents: 2006
diff changeset
122 return AVERROR(ENOMEM);
137
857a026b7e93 first pass at an experimental 4xm demuxer
tmmm
parents:
diff changeset
123 if (get_buffer(pb, header, header_size) != header_size)
2274
b21c2af60bc9 Replace all occurrences of AVERROR_IO with AVERROR(EIO).
takis
parents: 2273
diff changeset
124 return AVERROR(EIO);
137
857a026b7e93 first pass at an experimental 4xm demuxer
tmmm
parents:
diff changeset
125
857a026b7e93 first pass at an experimental 4xm demuxer
tmmm
parents:
diff changeset
126 /* take the lazy approach and search for any and all vtrk and strk chunks */
857a026b7e93 first pass at an experimental 4xm demuxer
tmmm
parents:
diff changeset
127 for (i = 0; i < header_size - 8; i++) {
1673
a782462e2497 rename BE/LE_8/16/32 to AV_RL/B_8/16/32
alex
parents: 1450
diff changeset
128 fourcc_tag = AV_RL32(&header[i]);
a782462e2497 rename BE/LE_8/16/32 to AV_RL/B_8/16/32
alex
parents: 1450
diff changeset
129 size = AV_RL32(&header[i + 4]);
137
857a026b7e93 first pass at an experimental 4xm demuxer
tmmm
parents:
diff changeset
130
316
9aa23c6d396e use the proper file framerate (specified by a float); account the pts
melanson
parents: 254
diff changeset
131 if (fourcc_tag == std__TAG) {
1673
a782462e2497 rename BE/LE_8/16/32 to AV_RL/B_8/16/32
alex
parents: 1450
diff changeset
132 fourxm->fps = av_int2flt(AV_RL32(&header[i + 12]));
316
9aa23c6d396e use the proper file framerate (specified by a float); account the pts
melanson
parents: 254
diff changeset
133 } else if (fourcc_tag == vtrk_TAG) {
137
857a026b7e93 first pass at an experimental 4xm demuxer
tmmm
parents:
diff changeset
134 /* check that there is enough data */
857a026b7e93 first pass at an experimental 4xm demuxer
tmmm
parents:
diff changeset
135 if (size != vtrk_SIZE) {
857a026b7e93 first pass at an experimental 4xm demuxer
tmmm
parents:
diff changeset
136 av_free(header);
857a026b7e93 first pass at an experimental 4xm demuxer
tmmm
parents:
diff changeset
137 return AVERROR_INVALIDDATA;
857a026b7e93 first pass at an experimental 4xm demuxer
tmmm
parents:
diff changeset
138 }
1673
a782462e2497 rename BE/LE_8/16/32 to AV_RL/B_8/16/32
alex
parents: 1450
diff changeset
139 fourxm->width = AV_RL32(&header[i + 36]);
a782462e2497 rename BE/LE_8/16/32 to AV_RL/B_8/16/32
alex
parents: 1450
diff changeset
140 fourxm->height = AV_RL32(&header[i + 40]);
143
76dd1e93b064 dispatch video as well as audio
tmmm
parents: 141
diff changeset
141
76dd1e93b064 dispatch video as well as audio
tmmm
parents: 141
diff changeset
142 /* allocate a new AVStream */
76dd1e93b064 dispatch video as well as audio
tmmm
parents: 141
diff changeset
143 st = av_new_stream(s, 0);
76dd1e93b064 dispatch video as well as audio
tmmm
parents: 141
diff changeset
144 if (!st)
2273
7eb456c4ed8a Replace all occurrences of AVERROR_NOMEM with AVERROR(ENOMEM).
takis
parents: 2006
diff changeset
145 return AVERROR(ENOMEM);
740
58a2da07cb18 fix nonsens timestamp calculation
michael
parents: 643
diff changeset
146 av_set_pts_info(st, 60, 1, fourxm->fps);
143
76dd1e93b064 dispatch video as well as audio
tmmm
parents: 141
diff changeset
147
76dd1e93b064 dispatch video as well as audio
tmmm
parents: 141
diff changeset
148 fourxm->video_stream_index = st->index;
76dd1e93b064 dispatch video as well as audio
tmmm
parents: 141
diff changeset
149
820
feca73904e67 changing AVCodecContext codec -> *codec in AVStream so additions to AVCodecContext dont randomize AVStream and break binary compatibility
michael
parents: 775
diff changeset
150 st->codec->codec_type = CODEC_TYPE_VIDEO;
feca73904e67 changing AVCodecContext codec -> *codec in AVStream so additions to AVCodecContext dont randomize AVStream and break binary compatibility
michael
parents: 775
diff changeset
151 st->codec->codec_id = CODEC_ID_4XM;
2410
9b58a031620e Change 4xm demuxer and video decoder to pass the video format version in
rtogni
parents: 2379
diff changeset
152 st->codec->extradata_size = 4;
9b58a031620e Change 4xm demuxer and video decoder to pass the video format version in
rtogni
parents: 2379
diff changeset
153 st->codec->extradata = av_malloc(4);
9b58a031620e Change 4xm demuxer and video decoder to pass the video format version in
rtogni
parents: 2379
diff changeset
154 AV_WL32(st->codec->extradata, AV_RL32(&header[i + 16]));
820
feca73904e67 changing AVCodecContext codec -> *codec in AVStream so additions to AVCodecContext dont randomize AVStream and break binary compatibility
michael
parents: 775
diff changeset
155 st->codec->width = fourxm->width;
feca73904e67 changing AVCodecContext codec -> *codec in AVStream so additions to AVCodecContext dont randomize AVStream and break binary compatibility
michael
parents: 775
diff changeset
156 st->codec->height = fourxm->height;
143
76dd1e93b064 dispatch video as well as audio
tmmm
parents: 141
diff changeset
157
2379
14b9277b6491 export 4xm video version
michael
parents: 2377
diff changeset
158 i += 8 + size;
137
857a026b7e93 first pass at an experimental 4xm demuxer
tmmm
parents:
diff changeset
159 } else if (fourcc_tag == strk_TAG) {
857a026b7e93 first pass at an experimental 4xm demuxer
tmmm
parents:
diff changeset
160 /* check that there is enough data */
857a026b7e93 first pass at an experimental 4xm demuxer
tmmm
parents:
diff changeset
161 if (size != strk_SIZE) {
857a026b7e93 first pass at an experimental 4xm demuxer
tmmm
parents:
diff changeset
162 av_free(header);
857a026b7e93 first pass at an experimental 4xm demuxer
tmmm
parents:
diff changeset
163 return AVERROR_INVALIDDATA;
857a026b7e93 first pass at an experimental 4xm demuxer
tmmm
parents:
diff changeset
164 }
1673
a782462e2497 rename BE/LE_8/16/32 to AV_RL/B_8/16/32
alex
parents: 1450
diff changeset
165 current_track = AV_RL32(&header[i + 8]);
137
857a026b7e93 first pass at an experimental 4xm demuxer
tmmm
parents:
diff changeset
166 if (current_track + 1 > fourxm->track_count) {
141
d2d2ec541148 allocate enough bytes
tmmm
parents: 140
diff changeset
167 fourxm->track_count = current_track + 1;
639
0b52743104ac integer overflows, heap corruption
michael
parents: 482
diff changeset
168 if((unsigned)fourxm->track_count >= UINT_MAX / sizeof(AudioTrack))
0b52743104ac integer overflows, heap corruption
michael
parents: 482
diff changeset
169 return -1;
885
da1d5db0ce5c COSMETICS: Remove all trailing whitespace.
diego
parents: 824
diff changeset
170 fourxm->tracks = av_realloc(fourxm->tracks,
141
d2d2ec541148 allocate enough bytes
tmmm
parents: 140
diff changeset
171 fourxm->track_count * sizeof(AudioTrack));
137
857a026b7e93 first pass at an experimental 4xm demuxer
tmmm
parents:
diff changeset
172 if (!fourxm->tracks) {
857a026b7e93 first pass at an experimental 4xm demuxer
tmmm
parents:
diff changeset
173 av_free(header);
2273
7eb456c4ed8a Replace all occurrences of AVERROR_NOMEM with AVERROR(ENOMEM).
takis
parents: 2006
diff changeset
174 return AVERROR(ENOMEM);
137
857a026b7e93 first pass at an experimental 4xm demuxer
tmmm
parents:
diff changeset
175 }
857a026b7e93 first pass at an experimental 4xm demuxer
tmmm
parents:
diff changeset
176 }
1673
a782462e2497 rename BE/LE_8/16/32 to AV_RL/B_8/16/32
alex
parents: 1450
diff changeset
177 fourxm->tracks[current_track].adpcm = AV_RL32(&header[i + 12]);
a782462e2497 rename BE/LE_8/16/32 to AV_RL/B_8/16/32
alex
parents: 1450
diff changeset
178 fourxm->tracks[current_track].channels = AV_RL32(&header[i + 36]);
a782462e2497 rename BE/LE_8/16/32 to AV_RL/B_8/16/32
alex
parents: 1450
diff changeset
179 fourxm->tracks[current_track].sample_rate = AV_RL32(&header[i + 40]);
a782462e2497 rename BE/LE_8/16/32 to AV_RL/B_8/16/32
alex
parents: 1450
diff changeset
180 fourxm->tracks[current_track].bits = AV_RL32(&header[i + 44]);
137
857a026b7e93 first pass at an experimental 4xm demuxer
tmmm
parents:
diff changeset
181 i += 8 + size;
143
76dd1e93b064 dispatch video as well as audio
tmmm
parents: 141
diff changeset
182
76dd1e93b064 dispatch video as well as audio
tmmm
parents: 141
diff changeset
183 /* allocate a new AVStream */
76dd1e93b064 dispatch video as well as audio
tmmm
parents: 141
diff changeset
184 st = av_new_stream(s, current_track);
76dd1e93b064 dispatch video as well as audio
tmmm
parents: 141
diff changeset
185 if (!st)
2273
7eb456c4ed8a Replace all occurrences of AVERROR_NOMEM with AVERROR(ENOMEM).
takis
parents: 2006
diff changeset
186 return AVERROR(ENOMEM);
143
76dd1e93b064 dispatch video as well as audio
tmmm
parents: 141
diff changeset
187
740
58a2da07cb18 fix nonsens timestamp calculation
michael
parents: 643
diff changeset
188 av_set_pts_info(st, 60, 1, fourxm->tracks[current_track].sample_rate);
462
b69898ffc92a move time_base (pts_num/pts_den) from AVFormatContext -> AVStream
michael
parents: 386
diff changeset
189
143
76dd1e93b064 dispatch video as well as audio
tmmm
parents: 141
diff changeset
190 fourxm->tracks[current_track].stream_index = st->index;
76dd1e93b064 dispatch video as well as audio
tmmm
parents: 141
diff changeset
191
820
feca73904e67 changing AVCodecContext codec -> *codec in AVStream so additions to AVCodecContext dont randomize AVStream and break binary compatibility
michael
parents: 775
diff changeset
192 st->codec->codec_type = CODEC_TYPE_AUDIO;
1450
1580c48ba4b9 Do not set audio codec_tag to 1, that would be PCM audio.
diego
parents: 1358
diff changeset
193 st->codec->codec_tag = 0;
820
feca73904e67 changing AVCodecContext codec -> *codec in AVStream so additions to AVCodecContext dont randomize AVStream and break binary compatibility
michael
parents: 775
diff changeset
194 st->codec->channels = fourxm->tracks[current_track].channels;
feca73904e67 changing AVCodecContext codec -> *codec in AVStream so additions to AVCodecContext dont randomize AVStream and break binary compatibility
michael
parents: 775
diff changeset
195 st->codec->sample_rate = fourxm->tracks[current_track].sample_rate;
feca73904e67 changing AVCodecContext codec -> *codec in AVStream so additions to AVCodecContext dont randomize AVStream and break binary compatibility
michael
parents: 775
diff changeset
196 st->codec->bits_per_sample = fourxm->tracks[current_track].bits;
feca73904e67 changing AVCodecContext codec -> *codec in AVStream so additions to AVCodecContext dont randomize AVStream and break binary compatibility
michael
parents: 775
diff changeset
197 st->codec->bit_rate = st->codec->channels * st->codec->sample_rate *
feca73904e67 changing AVCodecContext codec -> *codec in AVStream so additions to AVCodecContext dont randomize AVStream and break binary compatibility
michael
parents: 775
diff changeset
198 st->codec->bits_per_sample;
feca73904e67 changing AVCodecContext codec -> *codec in AVStream so additions to AVCodecContext dont randomize AVStream and break binary compatibility
michael
parents: 775
diff changeset
199 st->codec->block_align = st->codec->channels * st->codec->bits_per_sample;
145
4f3960430e54 4xm adpcm
michaelni
parents: 144
diff changeset
200 if (fourxm->tracks[current_track].adpcm)
820
feca73904e67 changing AVCodecContext codec -> *codec in AVStream so additions to AVCodecContext dont randomize AVStream and break binary compatibility
michael
parents: 775
diff changeset
201 st->codec->codec_id = CODEC_ID_ADPCM_4XM;
feca73904e67 changing AVCodecContext codec -> *codec in AVStream so additions to AVCodecContext dont randomize AVStream and break binary compatibility
michael
parents: 775
diff changeset
202 else if (st->codec->bits_per_sample == 8)
feca73904e67 changing AVCodecContext codec -> *codec in AVStream so additions to AVCodecContext dont randomize AVStream and break binary compatibility
michael
parents: 775
diff changeset
203 st->codec->codec_id = CODEC_ID_PCM_U8;
143
76dd1e93b064 dispatch video as well as audio
tmmm
parents: 141
diff changeset
204 else
820
feca73904e67 changing AVCodecContext codec -> *codec in AVStream so additions to AVCodecContext dont randomize AVStream and break binary compatibility
michael
parents: 775
diff changeset
205 st->codec->codec_id = CODEC_ID_PCM_S16LE;
137
857a026b7e93 first pass at an experimental 4xm demuxer
tmmm
parents:
diff changeset
206 }
857a026b7e93 first pass at an experimental 4xm demuxer
tmmm
parents:
diff changeset
207 }
857a026b7e93 first pass at an experimental 4xm demuxer
tmmm
parents:
diff changeset
208
857a026b7e93 first pass at an experimental 4xm demuxer
tmmm
parents:
diff changeset
209 av_free(header);
857a026b7e93 first pass at an experimental 4xm demuxer
tmmm
parents:
diff changeset
210
857a026b7e93 first pass at an experimental 4xm demuxer
tmmm
parents:
diff changeset
211 /* skip over the LIST-MOVI chunk (which is where the stream should be */
857a026b7e93 first pass at an experimental 4xm demuxer
tmmm
parents:
diff changeset
212 GET_LIST_HEADER();
857a026b7e93 first pass at an experimental 4xm demuxer
tmmm
parents:
diff changeset
213 if (fourcc_tag != MOVI_TAG)
857a026b7e93 first pass at an experimental 4xm demuxer
tmmm
parents:
diff changeset
214 return AVERROR_INVALIDDATA;
857a026b7e93 first pass at an experimental 4xm demuxer
tmmm
parents:
diff changeset
215
143
76dd1e93b064 dispatch video as well as audio
tmmm
parents: 141
diff changeset
216 /* initialize context members */
740
58a2da07cb18 fix nonsens timestamp calculation
michael
parents: 643
diff changeset
217 fourxm->video_pts = -1; /* first frame will push to 0 */
316
9aa23c6d396e use the proper file framerate (specified by a float); account the pts
melanson
parents: 254
diff changeset
218 fourxm->audio_pts = 0;
137
857a026b7e93 first pass at an experimental 4xm demuxer
tmmm
parents:
diff changeset
219
857a026b7e93 first pass at an experimental 4xm demuxer
tmmm
parents:
diff changeset
220 return 0;
857a026b7e93 first pass at an experimental 4xm demuxer
tmmm
parents:
diff changeset
221 }
857a026b7e93 first pass at an experimental 4xm demuxer
tmmm
parents:
diff changeset
222
857a026b7e93 first pass at an experimental 4xm demuxer
tmmm
parents:
diff changeset
223 static int fourxm_read_packet(AVFormatContext *s,
143
76dd1e93b064 dispatch video as well as audio
tmmm
parents: 141
diff changeset
224 AVPacket *pkt)
137
857a026b7e93 first pass at an experimental 4xm demuxer
tmmm
parents:
diff changeset
225 {
857a026b7e93 first pass at an experimental 4xm demuxer
tmmm
parents:
diff changeset
226 FourxmDemuxContext *fourxm = s->priv_data;
2771
d52c718e83f9 Use dynamically allocated ByteIOContext in AVFormatContext
andoma
parents: 2410
diff changeset
227 ByteIOContext *pb = s->pb;
137
857a026b7e93 first pass at an experimental 4xm demuxer
tmmm
parents:
diff changeset
228 unsigned int fourcc_tag;
145
4f3960430e54 4xm adpcm
michaelni
parents: 144
diff changeset
229 unsigned int size, out_size;
137
857a026b7e93 first pass at an experimental 4xm demuxer
tmmm
parents:
diff changeset
230 int ret = 0;
857a026b7e93 first pass at an experimental 4xm demuxer
tmmm
parents:
diff changeset
231 int track_number;
857a026b7e93 first pass at an experimental 4xm demuxer
tmmm
parents:
diff changeset
232 int packet_read = 0;
143
76dd1e93b064 dispatch video as well as audio
tmmm
parents: 141
diff changeset
233 unsigned char header[8];
316
9aa23c6d396e use the proper file framerate (specified by a float); account the pts
melanson
parents: 254
diff changeset
234 int audio_frame_count;
137
857a026b7e93 first pass at an experimental 4xm demuxer
tmmm
parents:
diff changeset
235
857a026b7e93 first pass at an experimental 4xm demuxer
tmmm
parents:
diff changeset
236 while (!packet_read) {
857a026b7e93 first pass at an experimental 4xm demuxer
tmmm
parents:
diff changeset
237
2771
d52c718e83f9 Use dynamically allocated ByteIOContext in AVFormatContext
andoma
parents: 2410
diff changeset
238 if ((ret = get_buffer(s->pb, header, 8)) < 0)
143
76dd1e93b064 dispatch video as well as audio
tmmm
parents: 141
diff changeset
239 return ret;
1673
a782462e2497 rename BE/LE_8/16/32 to AV_RL/B_8/16/32
alex
parents: 1450
diff changeset
240 fourcc_tag = AV_RL32(&header[0]);
a782462e2497 rename BE/LE_8/16/32 to AV_RL/B_8/16/32
alex
parents: 1450
diff changeset
241 size = AV_RL32(&header[4]);
137
857a026b7e93 first pass at an experimental 4xm demuxer
tmmm
parents:
diff changeset
242 if (url_feof(pb))
2274
b21c2af60bc9 Replace all occurrences of AVERROR_IO with AVERROR(EIO).
takis
parents: 2273
diff changeset
243 return AVERROR(EIO);
137
857a026b7e93 first pass at an experimental 4xm demuxer
tmmm
parents:
diff changeset
244 switch (fourcc_tag) {
857a026b7e93 first pass at an experimental 4xm demuxer
tmmm
parents:
diff changeset
245
144
9e73bf732800 get the video dispatch straight
tmmm
parents: 143
diff changeset
246 case LIST_TAG:
316
9aa23c6d396e use the proper file framerate (specified by a float); account the pts
melanson
parents: 254
diff changeset
247 /* this is a good time to bump the video pts */
740
58a2da07cb18 fix nonsens timestamp calculation
michael
parents: 643
diff changeset
248 fourxm->video_pts ++;
316
9aa23c6d396e use the proper file framerate (specified by a float); account the pts
melanson
parents: 254
diff changeset
249
144
9e73bf732800 get the video dispatch straight
tmmm
parents: 143
diff changeset
250 /* skip the LIST-* tag and move on to the next fourcc */
9e73bf732800 get the video dispatch straight
tmmm
parents: 143
diff changeset
251 get_le32(pb);
9e73bf732800 get the video dispatch straight
tmmm
parents: 143
diff changeset
252 break;
9e73bf732800 get the video dispatch straight
tmmm
parents: 143
diff changeset
253
137
857a026b7e93 first pass at an experimental 4xm demuxer
tmmm
parents:
diff changeset
254 case ifrm_TAG:
857a026b7e93 first pass at an experimental 4xm demuxer
tmmm
parents:
diff changeset
255 case pfrm_TAG:
2377
2a44e9c75bf3 pass *fr2 chunks to decoder (Toy-Story2_better-image-quality.4xa contains them)
michael
parents: 2274
diff changeset
256 case cfrm_TAG:
2a44e9c75bf3 pass *fr2 chunks to decoder (Toy-Story2_better-image-quality.4xa contains them)
michael
parents: 2274
diff changeset
257 case ifr2_TAG:
2a44e9c75bf3 pass *fr2 chunks to decoder (Toy-Story2_better-image-quality.4xa contains them)
michael
parents: 2274
diff changeset
258 case pfr2_TAG:
2a44e9c75bf3 pass *fr2 chunks to decoder (Toy-Story2_better-image-quality.4xa contains them)
michael
parents: 2274
diff changeset
259 case cfr2_TAG:
2a44e9c75bf3 pass *fr2 chunks to decoder (Toy-Story2_better-image-quality.4xa contains them)
michael
parents: 2274
diff changeset
260 {
143
76dd1e93b064 dispatch video as well as audio
tmmm
parents: 141
diff changeset
261
76dd1e93b064 dispatch video as well as audio
tmmm
parents: 141
diff changeset
262 /* allocate 8 more bytes than 'size' to account for fourcc
76dd1e93b064 dispatch video as well as audio
tmmm
parents: 141
diff changeset
263 * and size */
643
253b5292946a various security fixes and precautionary checks
michael
parents: 639
diff changeset
264 if (size + 8 < size || av_new_packet(pkt, size + 8))
2274
b21c2af60bc9 Replace all occurrences of AVERROR_IO with AVERROR(EIO).
takis
parents: 2273
diff changeset
265 return AVERROR(EIO);
143
76dd1e93b064 dispatch video as well as audio
tmmm
parents: 141
diff changeset
266 pkt->stream_index = fourxm->video_stream_index;
316
9aa23c6d396e use the proper file framerate (specified by a float); account the pts
melanson
parents: 254
diff changeset
267 pkt->pts = fourxm->video_pts;
2771
d52c718e83f9 Use dynamically allocated ByteIOContext in AVFormatContext
andoma
parents: 2410
diff changeset
268 pkt->pos = url_ftell(s->pb);
143
76dd1e93b064 dispatch video as well as audio
tmmm
parents: 141
diff changeset
269 memcpy(pkt->data, header, 8);
2771
d52c718e83f9 Use dynamically allocated ByteIOContext in AVFormatContext
andoma
parents: 2410
diff changeset
270 ret = get_buffer(s->pb, &pkt->data[8], size);
143
76dd1e93b064 dispatch video as well as audio
tmmm
parents: 141
diff changeset
271
76dd1e93b064 dispatch video as well as audio
tmmm
parents: 141
diff changeset
272 if (ret < 0)
76dd1e93b064 dispatch video as well as audio
tmmm
parents: 141
diff changeset
273 av_free_packet(pkt);
76dd1e93b064 dispatch video as well as audio
tmmm
parents: 141
diff changeset
274 else
76dd1e93b064 dispatch video as well as audio
tmmm
parents: 141
diff changeset
275 packet_read = 1;
139
d5ac5007713c c frame size debug stuff
michaelni
parents: 137
diff changeset
276 break;
d5ac5007713c c frame size debug stuff
michaelni
parents: 137
diff changeset
277 }
143
76dd1e93b064 dispatch video as well as audio
tmmm
parents: 141
diff changeset
278
137
857a026b7e93 first pass at an experimental 4xm demuxer
tmmm
parents:
diff changeset
279 case snd__TAG:
857a026b7e93 first pass at an experimental 4xm demuxer
tmmm
parents:
diff changeset
280 track_number = get_le32(pb);
145
4f3960430e54 4xm adpcm
michaelni
parents: 144
diff changeset
281 out_size= get_le32(pb);
4f3960430e54 4xm adpcm
michaelni
parents: 144
diff changeset
282 size-=8;
4f3960430e54 4xm adpcm
michaelni
parents: 144
diff changeset
283
137
857a026b7e93 first pass at an experimental 4xm demuxer
tmmm
parents:
diff changeset
284 if (track_number == fourxm->selected_track) {
2771
d52c718e83f9 Use dynamically allocated ByteIOContext in AVFormatContext
andoma
parents: 2410
diff changeset
285 ret= av_get_packet(s->pb, pkt, size);
775
c5077fdab490 AVPacket.pos
michael
parents: 743
diff changeset
286 if(ret<0)
2274
b21c2af60bc9 Replace all occurrences of AVERROR_IO with AVERROR(EIO).
takis
parents: 2273
diff changeset
287 return AVERROR(EIO);
885
da1d5db0ce5c COSMETICS: Remove all trailing whitespace.
diego
parents: 824
diff changeset
288 pkt->stream_index =
143
76dd1e93b064 dispatch video as well as audio
tmmm
parents: 141
diff changeset
289 fourxm->tracks[fourxm->selected_track].stream_index;
316
9aa23c6d396e use the proper file framerate (specified by a float); account the pts
melanson
parents: 254
diff changeset
290 pkt->pts = fourxm->audio_pts;
775
c5077fdab490 AVPacket.pos
michael
parents: 743
diff changeset
291 packet_read = 1;
143
76dd1e93b064 dispatch video as well as audio
tmmm
parents: 141
diff changeset
292
316
9aa23c6d396e use the proper file framerate (specified by a float); account the pts
melanson
parents: 254
diff changeset
293 /* pts accounting */
9aa23c6d396e use the proper file framerate (specified by a float); account the pts
melanson
parents: 254
diff changeset
294 audio_frame_count = size;
9aa23c6d396e use the proper file framerate (specified by a float); account the pts
melanson
parents: 254
diff changeset
295 if (fourxm->tracks[fourxm->selected_track].adpcm)
885
da1d5db0ce5c COSMETICS: Remove all trailing whitespace.
diego
parents: 824
diff changeset
296 audio_frame_count -=
316
9aa23c6d396e use the proper file framerate (specified by a float); account the pts
melanson
parents: 254
diff changeset
297 2 * (fourxm->tracks[fourxm->selected_track].channels);
9aa23c6d396e use the proper file framerate (specified by a float); account the pts
melanson
parents: 254
diff changeset
298 audio_frame_count /=
9aa23c6d396e use the proper file framerate (specified by a float); account the pts
melanson
parents: 254
diff changeset
299 fourxm->tracks[fourxm->selected_track].channels;
9aa23c6d396e use the proper file framerate (specified by a float); account the pts
melanson
parents: 254
diff changeset
300 if (fourxm->tracks[fourxm->selected_track].adpcm)
9aa23c6d396e use the proper file framerate (specified by a float); account the pts
melanson
parents: 254
diff changeset
301 audio_frame_count *= 2;
885
da1d5db0ce5c COSMETICS: Remove all trailing whitespace.
diego
parents: 824
diff changeset
302 else
316
9aa23c6d396e use the proper file framerate (specified by a float); account the pts
melanson
parents: 254
diff changeset
303 audio_frame_count /=
9aa23c6d396e use the proper file framerate (specified by a float); account the pts
melanson
parents: 254
diff changeset
304 (fourxm->tracks[fourxm->selected_track].bits / 8);
740
58a2da07cb18 fix nonsens timestamp calculation
michael
parents: 643
diff changeset
305 fourxm->audio_pts += audio_frame_count;
143
76dd1e93b064 dispatch video as well as audio
tmmm
parents: 141
diff changeset
306
137
857a026b7e93 first pass at an experimental 4xm demuxer
tmmm
parents:
diff changeset
307 } else {
857a026b7e93 first pass at an experimental 4xm demuxer
tmmm
parents:
diff changeset
308 url_fseek(pb, size, SEEK_CUR);
857a026b7e93 first pass at an experimental 4xm demuxer
tmmm
parents:
diff changeset
309 }
857a026b7e93 first pass at an experimental 4xm demuxer
tmmm
parents:
diff changeset
310 break;
857a026b7e93 first pass at an experimental 4xm demuxer
tmmm
parents:
diff changeset
311
857a026b7e93 first pass at an experimental 4xm demuxer
tmmm
parents:
diff changeset
312 default:
857a026b7e93 first pass at an experimental 4xm demuxer
tmmm
parents:
diff changeset
313 url_fseek(pb, size, SEEK_CUR);
857a026b7e93 first pass at an experimental 4xm demuxer
tmmm
parents:
diff changeset
314 break;
857a026b7e93 first pass at an experimental 4xm demuxer
tmmm
parents:
diff changeset
315 }
857a026b7e93 first pass at an experimental 4xm demuxer
tmmm
parents:
diff changeset
316 }
857a026b7e93 first pass at an experimental 4xm demuxer
tmmm
parents:
diff changeset
317 return ret;
857a026b7e93 first pass at an experimental 4xm demuxer
tmmm
parents:
diff changeset
318 }
857a026b7e93 first pass at an experimental 4xm demuxer
tmmm
parents:
diff changeset
319
857a026b7e93 first pass at an experimental 4xm demuxer
tmmm
parents:
diff changeset
320 static int fourxm_read_close(AVFormatContext *s)
857a026b7e93 first pass at an experimental 4xm demuxer
tmmm
parents:
diff changeset
321 {
2006
2f0154760e5f Get rid of unnecessary pointer casts.
diego
parents: 2001
diff changeset
322 FourxmDemuxContext *fourxm = s->priv_data;
137
857a026b7e93 first pass at an experimental 4xm demuxer
tmmm
parents:
diff changeset
323
857a026b7e93 first pass at an experimental 4xm demuxer
tmmm
parents:
diff changeset
324 av_free(fourxm->tracks);
857a026b7e93 first pass at an experimental 4xm demuxer
tmmm
parents:
diff changeset
325
857a026b7e93 first pass at an experimental 4xm demuxer
tmmm
parents:
diff changeset
326 return 0;
857a026b7e93 first pass at an experimental 4xm demuxer
tmmm
parents:
diff changeset
327 }
857a026b7e93 first pass at an experimental 4xm demuxer
tmmm
parents:
diff changeset
328
1169
d18cc9a1fd02 allow individual selection of muxers and demuxers
mru
parents: 1167
diff changeset
329 AVInputFormat fourxm_demuxer = {
137
857a026b7e93 first pass at an experimental 4xm demuxer
tmmm
parents:
diff changeset
330 "4xm",
3424
7a0230981402 Make long_names in lavf/lavdev optional depending on CONFIG_SMALL.
diego
parents: 2771
diff changeset
331 NULL_IF_CONFIG_SMALL("4X Technologies format"),
137
857a026b7e93 first pass at an experimental 4xm demuxer
tmmm
parents:
diff changeset
332 sizeof(FourxmDemuxContext),
857a026b7e93 first pass at an experimental 4xm demuxer
tmmm
parents:
diff changeset
333 fourxm_probe,
857a026b7e93 first pass at an experimental 4xm demuxer
tmmm
parents:
diff changeset
334 fourxm_read_header,
857a026b7e93 first pass at an experimental 4xm demuxer
tmmm
parents:
diff changeset
335 fourxm_read_packet,
857a026b7e93 first pass at an experimental 4xm demuxer
tmmm
parents:
diff changeset
336 fourxm_read_close,
857a026b7e93 first pass at an experimental 4xm demuxer
tmmm
parents:
diff changeset
337 };