annotate 4xm.c @ 791:f961db8ea65d libavformat

This trivial patch adds "avc1" as fourcc for h264 in mp4, which makes it a little bit more standard, although it still seems to lack some metadata. Anyway, recent mplayer plays these streams without problems. It also has two globally scoped global structs changed to "static". patch by (Erik Slagter <erik slagter name)
author michael
date Sun, 19 Jun 2005 23:45:54 +0000
parents c5077fdab490
children feca73904e67
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 *
857a026b7e93 first pass at an experimental 4xm demuxer
tmmm
parents:
diff changeset
5 * This library is free software; you can redistribute it and/or
857a026b7e93 first pass at an experimental 4xm demuxer
tmmm
parents:
diff changeset
6 * modify it under the terms of the GNU Lesser General Public
857a026b7e93 first pass at an experimental 4xm demuxer
tmmm
parents:
diff changeset
7 * License as published by the Free Software Foundation; either
857a026b7e93 first pass at an experimental 4xm demuxer
tmmm
parents:
diff changeset
8 * version 2 of the License, or (at your option) any later version.
857a026b7e93 first pass at an experimental 4xm demuxer
tmmm
parents:
diff changeset
9 *
857a026b7e93 first pass at an experimental 4xm demuxer
tmmm
parents:
diff changeset
10 * This library is distributed in the hope that it will be useful,
857a026b7e93 first pass at an experimental 4xm demuxer
tmmm
parents:
diff changeset
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
857a026b7e93 first pass at an experimental 4xm demuxer
tmmm
parents:
diff changeset
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
857a026b7e93 first pass at an experimental 4xm demuxer
tmmm
parents:
diff changeset
13 * Lesser General Public License for more details.
857a026b7e93 first pass at an experimental 4xm demuxer
tmmm
parents:
diff changeset
14 *
857a026b7e93 first pass at an experimental 4xm demuxer
tmmm
parents:
diff changeset
15 * You should have received a copy of the GNU Lesser General Public
857a026b7e93 first pass at an experimental 4xm demuxer
tmmm
parents:
diff changeset
16 * License along with this library; if not, write to the Free Software
857a026b7e93 first pass at an experimental 4xm demuxer
tmmm
parents:
diff changeset
17 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
857a026b7e93 first pass at an experimental 4xm demuxer
tmmm
parents:
diff changeset
18 */
857a026b7e93 first pass at an experimental 4xm demuxer
tmmm
parents:
diff changeset
19
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 * @file 4xm.c
857a026b7e93 first pass at an experimental 4xm demuxer
tmmm
parents:
diff changeset
22 * 4X Technologies file demuxer
857a026b7e93 first pass at an experimental 4xm demuxer
tmmm
parents:
diff changeset
23 * by Mike Melanson (melanson@pcisys.net)
857a026b7e93 first pass at an experimental 4xm demuxer
tmmm
parents:
diff changeset
24 * for more information on the .4xm file format, visit:
857a026b7e93 first pass at an experimental 4xm demuxer
tmmm
parents:
diff changeset
25 * http://www.pcisys.net/~melanson/codecs/
857a026b7e93 first pass at an experimental 4xm demuxer
tmmm
parents:
diff changeset
26 */
857a026b7e93 first pass at an experimental 4xm demuxer
tmmm
parents:
diff changeset
27
857a026b7e93 first pass at an experimental 4xm demuxer
tmmm
parents:
diff changeset
28 #include "avformat.h"
857a026b7e93 first pass at an experimental 4xm demuxer
tmmm
parents:
diff changeset
29
386
c152849ee643 remove numerous definitions of BE_*/LE_* macros; convert FOURCC_TAG ->
melanson
parents: 317
diff changeset
30 #define RIFF_TAG MKTAG('R', 'I', 'F', 'F')
c152849ee643 remove numerous definitions of BE_*/LE_* macros; convert FOURCC_TAG ->
melanson
parents: 317
diff changeset
31 #define _4XMV_TAG MKTAG('4', 'X', 'M', 'V')
c152849ee643 remove numerous definitions of BE_*/LE_* macros; convert FOURCC_TAG ->
melanson
parents: 317
diff changeset
32 #define LIST_TAG MKTAG('L', 'I', 'S', 'T')
c152849ee643 remove numerous definitions of BE_*/LE_* macros; convert FOURCC_TAG ->
melanson
parents: 317
diff changeset
33 #define HEAD_TAG MKTAG('H', 'E', 'A', 'D')
c152849ee643 remove numerous definitions of BE_*/LE_* macros; convert FOURCC_TAG ->
melanson
parents: 317
diff changeset
34 #define TRK__TAG MKTAG('T', 'R', 'K', '_')
c152849ee643 remove numerous definitions of BE_*/LE_* macros; convert FOURCC_TAG ->
melanson
parents: 317
diff changeset
35 #define MOVI_TAG MKTAG('M', 'O', 'V', 'I')
c152849ee643 remove numerous definitions of BE_*/LE_* macros; convert FOURCC_TAG ->
melanson
parents: 317
diff changeset
36 #define VTRK_TAG MKTAG('V', 'T', 'R', 'K')
c152849ee643 remove numerous definitions of BE_*/LE_* macros; convert FOURCC_TAG ->
melanson
parents: 317
diff changeset
37 #define STRK_TAG MKTAG('S', 'T', 'R', 'K')
c152849ee643 remove numerous definitions of BE_*/LE_* macros; convert FOURCC_TAG ->
melanson
parents: 317
diff changeset
38 #define std__TAG MKTAG('s', 't', 'd', '_')
c152849ee643 remove numerous definitions of BE_*/LE_* macros; convert FOURCC_TAG ->
melanson
parents: 317
diff changeset
39 #define name_TAG MKTAG('n', 'a', 'm', 'e')
c152849ee643 remove numerous definitions of BE_*/LE_* macros; convert FOURCC_TAG ->
melanson
parents: 317
diff changeset
40 #define vtrk_TAG MKTAG('v', 't', 'r', 'k')
c152849ee643 remove numerous definitions of BE_*/LE_* macros; convert FOURCC_TAG ->
melanson
parents: 317
diff changeset
41 #define strk_TAG MKTAG('s', 't', 'r', 'k')
c152849ee643 remove numerous definitions of BE_*/LE_* macros; convert FOURCC_TAG ->
melanson
parents: 317
diff changeset
42 #define ifrm_TAG MKTAG('i', 'f', 'r', 'm')
c152849ee643 remove numerous definitions of BE_*/LE_* macros; convert FOURCC_TAG ->
melanson
parents: 317
diff changeset
43 #define pfrm_TAG MKTAG('p', 'f', 'r', 'm')
c152849ee643 remove numerous definitions of BE_*/LE_* macros; convert FOURCC_TAG ->
melanson
parents: 317
diff changeset
44 #define cfrm_TAG MKTAG('c', 'f', 'r', 'm')
c152849ee643 remove numerous definitions of BE_*/LE_* macros; convert FOURCC_TAG ->
melanson
parents: 317
diff changeset
45 #define snd__TAG MKTAG('s', 'n', 'd', '_')
137
857a026b7e93 first pass at an experimental 4xm demuxer
tmmm
parents:
diff changeset
46
857a026b7e93 first pass at an experimental 4xm demuxer
tmmm
parents:
diff changeset
47 #define vtrk_SIZE 0x44
857a026b7e93 first pass at an experimental 4xm demuxer
tmmm
parents:
diff changeset
48 #define strk_SIZE 0x28
857a026b7e93 first pass at an experimental 4xm demuxer
tmmm
parents:
diff changeset
49
857a026b7e93 first pass at an experimental 4xm demuxer
tmmm
parents:
diff changeset
50 #define GET_LIST_HEADER() \
143
76dd1e93b064 dispatch video as well as audio
tmmm
parents: 141
diff changeset
51 fourcc_tag = get_le32(pb); \
137
857a026b7e93 first pass at an experimental 4xm demuxer
tmmm
parents:
diff changeset
52 size = get_le32(pb); \
857a026b7e93 first pass at an experimental 4xm demuxer
tmmm
parents:
diff changeset
53 if (fourcc_tag != LIST_TAG) \
857a026b7e93 first pass at an experimental 4xm demuxer
tmmm
parents:
diff changeset
54 return AVERROR_INVALIDDATA; \
143
76dd1e93b064 dispatch video as well as audio
tmmm
parents: 141
diff changeset
55 fourcc_tag = get_le32(pb);
137
857a026b7e93 first pass at an experimental 4xm demuxer
tmmm
parents:
diff changeset
56
857a026b7e93 first pass at an experimental 4xm demuxer
tmmm
parents:
diff changeset
57 typedef struct AudioTrack {
857a026b7e93 first pass at an experimental 4xm demuxer
tmmm
parents:
diff changeset
58 int sample_rate;
857a026b7e93 first pass at an experimental 4xm demuxer
tmmm
parents:
diff changeset
59 int bits;
857a026b7e93 first pass at an experimental 4xm demuxer
tmmm
parents:
diff changeset
60 int channels;
143
76dd1e93b064 dispatch video as well as audio
tmmm
parents: 141
diff changeset
61 int stream_index;
145
4f3960430e54 4xm adpcm
michaelni
parents: 144
diff changeset
62 int adpcm;
137
857a026b7e93 first pass at an experimental 4xm demuxer
tmmm
parents:
diff changeset
63 } AudioTrack;
857a026b7e93 first pass at an experimental 4xm demuxer
tmmm
parents:
diff changeset
64
857a026b7e93 first pass at an experimental 4xm demuxer
tmmm
parents:
diff changeset
65 typedef struct FourxmDemuxContext {
857a026b7e93 first pass at an experimental 4xm demuxer
tmmm
parents:
diff changeset
66 int width;
857a026b7e93 first pass at an experimental 4xm demuxer
tmmm
parents:
diff changeset
67 int height;
143
76dd1e93b064 dispatch video as well as audio
tmmm
parents: 141
diff changeset
68 int video_stream_index;
137
857a026b7e93 first pass at an experimental 4xm demuxer
tmmm
parents:
diff changeset
69 int track_count;
857a026b7e93 first pass at an experimental 4xm demuxer
tmmm
parents:
diff changeset
70 AudioTrack *tracks;
857a026b7e93 first pass at an experimental 4xm demuxer
tmmm
parents:
diff changeset
71 int selected_track;
143
76dd1e93b064 dispatch video as well as audio
tmmm
parents: 141
diff changeset
72
316
9aa23c6d396e use the proper file framerate (specified by a float); account the pts
melanson
parents: 254
diff changeset
73 int64_t audio_pts;
9aa23c6d396e use the proper file framerate (specified by a float); account the pts
melanson
parents: 254
diff changeset
74 int64_t video_pts;
317
5cd41ae1debf set frame rate information, for good measure
melanson
parents: 316
diff changeset
75 float fps;
137
857a026b7e93 first pass at an experimental 4xm demuxer
tmmm
parents:
diff changeset
76 } FourxmDemuxContext;
857a026b7e93 first pass at an experimental 4xm demuxer
tmmm
parents:
diff changeset
77
316
9aa23c6d396e use the proper file framerate (specified by a float); account the pts
melanson
parents: 254
diff changeset
78 static float get_le_float(unsigned char *buffer)
9aa23c6d396e use the proper file framerate (specified by a float); account the pts
melanson
parents: 254
diff changeset
79 {
9aa23c6d396e use the proper file framerate (specified by a float); account the pts
melanson
parents: 254
diff changeset
80 float f;
9aa23c6d396e use the proper file framerate (specified by a float); account the pts
melanson
parents: 254
diff changeset
81 unsigned char *float_buffer = (unsigned char *)&f;
9aa23c6d396e use the proper file framerate (specified by a float); account the pts
melanson
parents: 254
diff changeset
82
9aa23c6d396e use the proper file framerate (specified by a float); account the pts
melanson
parents: 254
diff changeset
83 #ifdef WORDS_BIGENDIAN
9aa23c6d396e use the proper file framerate (specified by a float); account the pts
melanson
parents: 254
diff changeset
84 float_buffer[0] = buffer[3];
9aa23c6d396e use the proper file framerate (specified by a float); account the pts
melanson
parents: 254
diff changeset
85 float_buffer[1] = buffer[2];
9aa23c6d396e use the proper file framerate (specified by a float); account the pts
melanson
parents: 254
diff changeset
86 float_buffer[2] = buffer[1];
9aa23c6d396e use the proper file framerate (specified by a float); account the pts
melanson
parents: 254
diff changeset
87 float_buffer[3] = buffer[0];
9aa23c6d396e use the proper file framerate (specified by a float); account the pts
melanson
parents: 254
diff changeset
88 #else
9aa23c6d396e use the proper file framerate (specified by a float); account the pts
melanson
parents: 254
diff changeset
89 float_buffer[0] = buffer[0];
9aa23c6d396e use the proper file framerate (specified by a float); account the pts
melanson
parents: 254
diff changeset
90 float_buffer[1] = buffer[1];
9aa23c6d396e use the proper file framerate (specified by a float); account the pts
melanson
parents: 254
diff changeset
91 float_buffer[2] = buffer[2];
9aa23c6d396e use the proper file framerate (specified by a float); account the pts
melanson
parents: 254
diff changeset
92 float_buffer[3] = buffer[3];
9aa23c6d396e use the proper file framerate (specified by a float); account the pts
melanson
parents: 254
diff changeset
93 #endif
9aa23c6d396e use the proper file framerate (specified by a float); account the pts
melanson
parents: 254
diff changeset
94
9aa23c6d396e use the proper file framerate (specified by a float); account the pts
melanson
parents: 254
diff changeset
95 return f;
9aa23c6d396e use the proper file framerate (specified by a float); account the pts
melanson
parents: 254
diff changeset
96 }
9aa23c6d396e use the proper file framerate (specified by a float); account the pts
melanson
parents: 254
diff changeset
97
137
857a026b7e93 first pass at an experimental 4xm demuxer
tmmm
parents:
diff changeset
98 static int fourxm_probe(AVProbeData *p)
857a026b7e93 first pass at an experimental 4xm demuxer
tmmm
parents:
diff changeset
99 {
254
bca5abd97e43 clean up 4xm demuxer; make valgrind just a little happier
tmmm
parents: 145
diff changeset
100 if (p->buf_size < 12)
bca5abd97e43 clean up 4xm demuxer; make valgrind just a little happier
tmmm
parents: 145
diff changeset
101 return 0;
bca5abd97e43 clean up 4xm demuxer; make valgrind just a little happier
tmmm
parents: 145
diff changeset
102
143
76dd1e93b064 dispatch video as well as audio
tmmm
parents: 141
diff changeset
103 if ((LE_32(&p->buf[0]) != RIFF_TAG) ||
76dd1e93b064 dispatch video as well as audio
tmmm
parents: 141
diff changeset
104 (LE_32(&p->buf[8]) != _4XMV_TAG))
137
857a026b7e93 first pass at an experimental 4xm demuxer
tmmm
parents:
diff changeset
105 return 0;
857a026b7e93 first pass at an experimental 4xm demuxer
tmmm
parents:
diff changeset
106
857a026b7e93 first pass at an experimental 4xm demuxer
tmmm
parents:
diff changeset
107 return AVPROBE_SCORE_MAX;
857a026b7e93 first pass at an experimental 4xm demuxer
tmmm
parents:
diff changeset
108 }
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 static int fourxm_read_header(AVFormatContext *s,
143
76dd1e93b064 dispatch video as well as audio
tmmm
parents: 141
diff changeset
111 AVFormatParameters *ap)
137
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 ByteIOContext *pb = &s->pb;
857a026b7e93 first pass at an experimental 4xm demuxer
tmmm
parents:
diff changeset
114 unsigned int fourcc_tag;
857a026b7e93 first pass at an experimental 4xm demuxer
tmmm
parents:
diff changeset
115 unsigned int size;
857a026b7e93 first pass at an experimental 4xm demuxer
tmmm
parents:
diff changeset
116 int header_size;
857a026b7e93 first pass at an experimental 4xm demuxer
tmmm
parents:
diff changeset
117 FourxmDemuxContext *fourxm = (FourxmDemuxContext *)s->priv_data;
857a026b7e93 first pass at an experimental 4xm demuxer
tmmm
parents:
diff changeset
118 unsigned char *header;
857a026b7e93 first pass at an experimental 4xm demuxer
tmmm
parents:
diff changeset
119 int i;
857a026b7e93 first pass at an experimental 4xm demuxer
tmmm
parents:
diff changeset
120 int current_track = -1;
857a026b7e93 first pass at an experimental 4xm demuxer
tmmm
parents:
diff changeset
121 AVStream *st;
857a026b7e93 first pass at an experimental 4xm demuxer
tmmm
parents:
diff changeset
122
857a026b7e93 first pass at an experimental 4xm demuxer
tmmm
parents:
diff changeset
123 fourxm->track_count = 0;
857a026b7e93 first pass at an experimental 4xm demuxer
tmmm
parents:
diff changeset
124 fourxm->tracks = NULL;
857a026b7e93 first pass at an experimental 4xm demuxer
tmmm
parents:
diff changeset
125 fourxm->selected_track = 0;
317
5cd41ae1debf set frame rate information, for good measure
melanson
parents: 316
diff changeset
126 fourxm->fps = 1.0;
137
857a026b7e93 first pass at an experimental 4xm demuxer
tmmm
parents:
diff changeset
127
857a026b7e93 first pass at an experimental 4xm demuxer
tmmm
parents:
diff changeset
128 /* skip the first 3 32-bit numbers */
857a026b7e93 first pass at an experimental 4xm demuxer
tmmm
parents:
diff changeset
129 url_fseek(pb, 12, SEEK_CUR);
857a026b7e93 first pass at an experimental 4xm demuxer
tmmm
parents:
diff changeset
130
857a026b7e93 first pass at an experimental 4xm demuxer
tmmm
parents:
diff changeset
131 /* check for LIST-HEAD */
857a026b7e93 first pass at an experimental 4xm demuxer
tmmm
parents:
diff changeset
132 GET_LIST_HEADER();
857a026b7e93 first pass at an experimental 4xm demuxer
tmmm
parents:
diff changeset
133 header_size = size - 4;
857a026b7e93 first pass at an experimental 4xm demuxer
tmmm
parents:
diff changeset
134 if (fourcc_tag != HEAD_TAG)
857a026b7e93 first pass at an experimental 4xm demuxer
tmmm
parents:
diff changeset
135 return AVERROR_INVALIDDATA;
857a026b7e93 first pass at an experimental 4xm demuxer
tmmm
parents:
diff changeset
136
857a026b7e93 first pass at an experimental 4xm demuxer
tmmm
parents:
diff changeset
137 /* allocate space for the header and load the whole thing */
857a026b7e93 first pass at an experimental 4xm demuxer
tmmm
parents:
diff changeset
138 header = av_malloc(header_size);
857a026b7e93 first pass at an experimental 4xm demuxer
tmmm
parents:
diff changeset
139 if (!header)
857a026b7e93 first pass at an experimental 4xm demuxer
tmmm
parents:
diff changeset
140 return AVERROR_NOMEM;
857a026b7e93 first pass at an experimental 4xm demuxer
tmmm
parents:
diff changeset
141 if (get_buffer(pb, header, header_size) != header_size)
857a026b7e93 first pass at an experimental 4xm demuxer
tmmm
parents:
diff changeset
142 return AVERROR_IO;
857a026b7e93 first pass at an experimental 4xm demuxer
tmmm
parents:
diff changeset
143
857a026b7e93 first pass at an experimental 4xm demuxer
tmmm
parents:
diff changeset
144 /* 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
145 for (i = 0; i < header_size - 8; i++) {
143
76dd1e93b064 dispatch video as well as audio
tmmm
parents: 141
diff changeset
146 fourcc_tag = LE_32(&header[i]);
137
857a026b7e93 first pass at an experimental 4xm demuxer
tmmm
parents:
diff changeset
147 size = LE_32(&header[i + 4]);
857a026b7e93 first pass at an experimental 4xm demuxer
tmmm
parents:
diff changeset
148
316
9aa23c6d396e use the proper file framerate (specified by a float); account the pts
melanson
parents: 254
diff changeset
149 if (fourcc_tag == std__TAG) {
317
5cd41ae1debf set frame rate information, for good measure
melanson
parents: 316
diff changeset
150 fourxm->fps = get_le_float(&header[i + 12]);
316
9aa23c6d396e use the proper file framerate (specified by a float); account the pts
melanson
parents: 254
diff changeset
151 } else if (fourcc_tag == vtrk_TAG) {
137
857a026b7e93 first pass at an experimental 4xm demuxer
tmmm
parents:
diff changeset
152 /* check that there is enough data */
857a026b7e93 first pass at an experimental 4xm demuxer
tmmm
parents:
diff changeset
153 if (size != vtrk_SIZE) {
857a026b7e93 first pass at an experimental 4xm demuxer
tmmm
parents:
diff changeset
154 av_free(header);
857a026b7e93 first pass at an experimental 4xm demuxer
tmmm
parents:
diff changeset
155 return AVERROR_INVALIDDATA;
857a026b7e93 first pass at an experimental 4xm demuxer
tmmm
parents:
diff changeset
156 }
857a026b7e93 first pass at an experimental 4xm demuxer
tmmm
parents:
diff changeset
157 fourxm->width = LE_32(&header[i + 36]);
857a026b7e93 first pass at an experimental 4xm demuxer
tmmm
parents:
diff changeset
158 fourxm->height = LE_32(&header[i + 40]);
857a026b7e93 first pass at an experimental 4xm demuxer
tmmm
parents:
diff changeset
159 i += 8 + size;
143
76dd1e93b064 dispatch video as well as audio
tmmm
parents: 141
diff changeset
160
76dd1e93b064 dispatch video as well as audio
tmmm
parents: 141
diff changeset
161 /* allocate a new AVStream */
76dd1e93b064 dispatch video as well as audio
tmmm
parents: 141
diff changeset
162 st = av_new_stream(s, 0);
76dd1e93b064 dispatch video as well as audio
tmmm
parents: 141
diff changeset
163 if (!st)
76dd1e93b064 dispatch video as well as audio
tmmm
parents: 141
diff changeset
164 return AVERROR_NOMEM;
740
58a2da07cb18 fix nonsens timestamp calculation
michael
parents: 643
diff changeset
165 av_set_pts_info(st, 60, 1, fourxm->fps);
143
76dd1e93b064 dispatch video as well as audio
tmmm
parents: 141
diff changeset
166
76dd1e93b064 dispatch video as well as audio
tmmm
parents: 141
diff changeset
167 fourxm->video_stream_index = st->index;
76dd1e93b064 dispatch video as well as audio
tmmm
parents: 141
diff changeset
168
76dd1e93b064 dispatch video as well as audio
tmmm
parents: 141
diff changeset
169 st->codec.codec_type = CODEC_TYPE_VIDEO;
76dd1e93b064 dispatch video as well as audio
tmmm
parents: 141
diff changeset
170 st->codec.codec_id = CODEC_ID_4XM;
76dd1e93b064 dispatch video as well as audio
tmmm
parents: 141
diff changeset
171 st->codec.codec_tag = 0; /* no fourcc */
76dd1e93b064 dispatch video as well as audio
tmmm
parents: 141
diff changeset
172 st->codec.width = fourxm->width;
76dd1e93b064 dispatch video as well as audio
tmmm
parents: 141
diff changeset
173 st->codec.height = fourxm->height;
76dd1e93b064 dispatch video as well as audio
tmmm
parents: 141
diff changeset
174
137
857a026b7e93 first pass at an experimental 4xm demuxer
tmmm
parents:
diff changeset
175 } else if (fourcc_tag == strk_TAG) {
857a026b7e93 first pass at an experimental 4xm demuxer
tmmm
parents:
diff changeset
176 /* check that there is enough data */
857a026b7e93 first pass at an experimental 4xm demuxer
tmmm
parents:
diff changeset
177 if (size != strk_SIZE) {
857a026b7e93 first pass at an experimental 4xm demuxer
tmmm
parents:
diff changeset
178 av_free(header);
857a026b7e93 first pass at an experimental 4xm demuxer
tmmm
parents:
diff changeset
179 return AVERROR_INVALIDDATA;
857a026b7e93 first pass at an experimental 4xm demuxer
tmmm
parents:
diff changeset
180 }
857a026b7e93 first pass at an experimental 4xm demuxer
tmmm
parents:
diff changeset
181 current_track = LE_32(&header[i + 8]);
857a026b7e93 first pass at an experimental 4xm demuxer
tmmm
parents:
diff changeset
182 if (current_track + 1 > fourxm->track_count) {
141
d2d2ec541148 allocate enough bytes
tmmm
parents: 140
diff changeset
183 fourxm->track_count = current_track + 1;
639
0b52743104ac integer overflows, heap corruption
michael
parents: 482
diff changeset
184 if((unsigned)fourxm->track_count >= UINT_MAX / sizeof(AudioTrack))
0b52743104ac integer overflows, heap corruption
michael
parents: 482
diff changeset
185 return -1;
141
d2d2ec541148 allocate enough bytes
tmmm
parents: 140
diff changeset
186 fourxm->tracks = av_realloc(fourxm->tracks,
d2d2ec541148 allocate enough bytes
tmmm
parents: 140
diff changeset
187 fourxm->track_count * sizeof(AudioTrack));
137
857a026b7e93 first pass at an experimental 4xm demuxer
tmmm
parents:
diff changeset
188 if (!fourxm->tracks) {
857a026b7e93 first pass at an experimental 4xm demuxer
tmmm
parents:
diff changeset
189 av_free(header);
857a026b7e93 first pass at an experimental 4xm demuxer
tmmm
parents:
diff changeset
190 return AVERROR_NOMEM;
857a026b7e93 first pass at an experimental 4xm demuxer
tmmm
parents:
diff changeset
191 }
857a026b7e93 first pass at an experimental 4xm demuxer
tmmm
parents:
diff changeset
192 }
145
4f3960430e54 4xm adpcm
michaelni
parents: 144
diff changeset
193 fourxm->tracks[current_track].adpcm = LE_32(&header[i + 12]);
137
857a026b7e93 first pass at an experimental 4xm demuxer
tmmm
parents:
diff changeset
194 fourxm->tracks[current_track].channels = LE_32(&header[i + 36]);
857a026b7e93 first pass at an experimental 4xm demuxer
tmmm
parents:
diff changeset
195 fourxm->tracks[current_track].sample_rate = LE_32(&header[i + 40]);
857a026b7e93 first pass at an experimental 4xm demuxer
tmmm
parents:
diff changeset
196 fourxm->tracks[current_track].bits = LE_32(&header[i + 44]);
857a026b7e93 first pass at an experimental 4xm demuxer
tmmm
parents:
diff changeset
197 i += 8 + size;
143
76dd1e93b064 dispatch video as well as audio
tmmm
parents: 141
diff changeset
198
76dd1e93b064 dispatch video as well as audio
tmmm
parents: 141
diff changeset
199 /* allocate a new AVStream */
76dd1e93b064 dispatch video as well as audio
tmmm
parents: 141
diff changeset
200 st = av_new_stream(s, current_track);
76dd1e93b064 dispatch video as well as audio
tmmm
parents: 141
diff changeset
201 if (!st)
76dd1e93b064 dispatch video as well as audio
tmmm
parents: 141
diff changeset
202 return AVERROR_NOMEM;
76dd1e93b064 dispatch video as well as audio
tmmm
parents: 141
diff changeset
203
740
58a2da07cb18 fix nonsens timestamp calculation
michael
parents: 643
diff changeset
204 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
205
143
76dd1e93b064 dispatch video as well as audio
tmmm
parents: 141
diff changeset
206 fourxm->tracks[current_track].stream_index = st->index;
76dd1e93b064 dispatch video as well as audio
tmmm
parents: 141
diff changeset
207
76dd1e93b064 dispatch video as well as audio
tmmm
parents: 141
diff changeset
208 st->codec.codec_type = CODEC_TYPE_AUDIO;
76dd1e93b064 dispatch video as well as audio
tmmm
parents: 141
diff changeset
209 st->codec.codec_tag = 1;
76dd1e93b064 dispatch video as well as audio
tmmm
parents: 141
diff changeset
210 st->codec.channels = fourxm->tracks[current_track].channels;
76dd1e93b064 dispatch video as well as audio
tmmm
parents: 141
diff changeset
211 st->codec.sample_rate = fourxm->tracks[current_track].sample_rate;
76dd1e93b064 dispatch video as well as audio
tmmm
parents: 141
diff changeset
212 st->codec.bits_per_sample = fourxm->tracks[current_track].bits;
76dd1e93b064 dispatch video as well as audio
tmmm
parents: 141
diff changeset
213 st->codec.bit_rate = st->codec.channels * st->codec.sample_rate *
76dd1e93b064 dispatch video as well as audio
tmmm
parents: 141
diff changeset
214 st->codec.bits_per_sample;
76dd1e93b064 dispatch video as well as audio
tmmm
parents: 141
diff changeset
215 st->codec.block_align = st->codec.channels * st->codec.bits_per_sample;
145
4f3960430e54 4xm adpcm
michaelni
parents: 144
diff changeset
216 if (fourxm->tracks[current_track].adpcm)
4f3960430e54 4xm adpcm
michaelni
parents: 144
diff changeset
217 st->codec.codec_id = CODEC_ID_ADPCM_4XM;
4f3960430e54 4xm adpcm
michaelni
parents: 144
diff changeset
218 else if (st->codec.bits_per_sample == 8)
143
76dd1e93b064 dispatch video as well as audio
tmmm
parents: 141
diff changeset
219 st->codec.codec_id = CODEC_ID_PCM_U8;
76dd1e93b064 dispatch video as well as audio
tmmm
parents: 141
diff changeset
220 else
76dd1e93b064 dispatch video as well as audio
tmmm
parents: 141
diff changeset
221 st->codec.codec_id = CODEC_ID_PCM_S16LE;
137
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 }
857a026b7e93 first pass at an experimental 4xm demuxer
tmmm
parents:
diff changeset
224
857a026b7e93 first pass at an experimental 4xm demuxer
tmmm
parents:
diff changeset
225 av_free(header);
857a026b7e93 first pass at an experimental 4xm demuxer
tmmm
parents:
diff changeset
226
857a026b7e93 first pass at an experimental 4xm demuxer
tmmm
parents:
diff changeset
227 /* 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
228 GET_LIST_HEADER();
857a026b7e93 first pass at an experimental 4xm demuxer
tmmm
parents:
diff changeset
229 if (fourcc_tag != MOVI_TAG)
857a026b7e93 first pass at an experimental 4xm demuxer
tmmm
parents:
diff changeset
230 return AVERROR_INVALIDDATA;
857a026b7e93 first pass at an experimental 4xm demuxer
tmmm
parents:
diff changeset
231
143
76dd1e93b064 dispatch video as well as audio
tmmm
parents: 141
diff changeset
232 /* initialize context members */
740
58a2da07cb18 fix nonsens timestamp calculation
michael
parents: 643
diff changeset
233 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
234 fourxm->audio_pts = 0;
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 return 0;
857a026b7e93 first pass at an experimental 4xm demuxer
tmmm
parents:
diff changeset
237 }
857a026b7e93 first pass at an experimental 4xm demuxer
tmmm
parents:
diff changeset
238
857a026b7e93 first pass at an experimental 4xm demuxer
tmmm
parents:
diff changeset
239 static int fourxm_read_packet(AVFormatContext *s,
143
76dd1e93b064 dispatch video as well as audio
tmmm
parents: 141
diff changeset
240 AVPacket *pkt)
137
857a026b7e93 first pass at an experimental 4xm demuxer
tmmm
parents:
diff changeset
241 {
857a026b7e93 first pass at an experimental 4xm demuxer
tmmm
parents:
diff changeset
242 FourxmDemuxContext *fourxm = s->priv_data;
857a026b7e93 first pass at an experimental 4xm demuxer
tmmm
parents:
diff changeset
243 ByteIOContext *pb = &s->pb;
857a026b7e93 first pass at an experimental 4xm demuxer
tmmm
parents:
diff changeset
244 unsigned int fourcc_tag;
145
4f3960430e54 4xm adpcm
michaelni
parents: 144
diff changeset
245 unsigned int size, out_size;
137
857a026b7e93 first pass at an experimental 4xm demuxer
tmmm
parents:
diff changeset
246 int ret = 0;
857a026b7e93 first pass at an experimental 4xm demuxer
tmmm
parents:
diff changeset
247 int track_number;
857a026b7e93 first pass at an experimental 4xm demuxer
tmmm
parents:
diff changeset
248 int packet_read = 0;
143
76dd1e93b064 dispatch video as well as audio
tmmm
parents: 141
diff changeset
249 unsigned char header[8];
316
9aa23c6d396e use the proper file framerate (specified by a float); account the pts
melanson
parents: 254
diff changeset
250 int audio_frame_count;
137
857a026b7e93 first pass at an experimental 4xm demuxer
tmmm
parents:
diff changeset
251
857a026b7e93 first pass at an experimental 4xm demuxer
tmmm
parents:
diff changeset
252 while (!packet_read) {
857a026b7e93 first pass at an experimental 4xm demuxer
tmmm
parents:
diff changeset
253
143
76dd1e93b064 dispatch video as well as audio
tmmm
parents: 141
diff changeset
254 if ((ret = get_buffer(&s->pb, header, 8)) < 0)
76dd1e93b064 dispatch video as well as audio
tmmm
parents: 141
diff changeset
255 return ret;
76dd1e93b064 dispatch video as well as audio
tmmm
parents: 141
diff changeset
256 fourcc_tag = LE_32(&header[0]);
76dd1e93b064 dispatch video as well as audio
tmmm
parents: 141
diff changeset
257 size = LE_32(&header[4]);
137
857a026b7e93 first pass at an experimental 4xm demuxer
tmmm
parents:
diff changeset
258 if (url_feof(pb))
482
0fdc96c2f2fe sweeping change from -EIO -> AVERROR_IO
melanson
parents: 462
diff changeset
259 return AVERROR_IO;
137
857a026b7e93 first pass at an experimental 4xm demuxer
tmmm
parents:
diff changeset
260 switch (fourcc_tag) {
857a026b7e93 first pass at an experimental 4xm demuxer
tmmm
parents:
diff changeset
261
144
9e73bf732800 get the video dispatch straight
tmmm
parents: 143
diff changeset
262 case LIST_TAG:
316
9aa23c6d396e use the proper file framerate (specified by a float); account the pts
melanson
parents: 254
diff changeset
263 /* this is a good time to bump the video pts */
740
58a2da07cb18 fix nonsens timestamp calculation
michael
parents: 643
diff changeset
264 fourxm->video_pts ++;
316
9aa23c6d396e use the proper file framerate (specified by a float); account the pts
melanson
parents: 254
diff changeset
265
144
9e73bf732800 get the video dispatch straight
tmmm
parents: 143
diff changeset
266 /* skip the LIST-* tag and move on to the next fourcc */
9e73bf732800 get the video dispatch straight
tmmm
parents: 143
diff changeset
267 get_le32(pb);
9e73bf732800 get the video dispatch straight
tmmm
parents: 143
diff changeset
268 break;
9e73bf732800 get the video dispatch straight
tmmm
parents: 143
diff changeset
269
137
857a026b7e93 first pass at an experimental 4xm demuxer
tmmm
parents:
diff changeset
270 case ifrm_TAG:
857a026b7e93 first pass at an experimental 4xm demuxer
tmmm
parents:
diff changeset
271 case pfrm_TAG:
139
d5ac5007713c c frame size debug stuff
michaelni
parents: 137
diff changeset
272 case cfrm_TAG:{
143
76dd1e93b064 dispatch video as well as audio
tmmm
parents: 141
diff changeset
273
76dd1e93b064 dispatch video as well as audio
tmmm
parents: 141
diff changeset
274 /* allocate 8 more bytes than 'size' to account for fourcc
76dd1e93b064 dispatch video as well as audio
tmmm
parents: 141
diff changeset
275 * and size */
643
253b5292946a various security fixes and precautionary checks
michael
parents: 639
diff changeset
276 if (size + 8 < size || av_new_packet(pkt, size + 8))
482
0fdc96c2f2fe sweeping change from -EIO -> AVERROR_IO
melanson
parents: 462
diff changeset
277 return AVERROR_IO;
143
76dd1e93b064 dispatch video as well as audio
tmmm
parents: 141
diff changeset
278 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
279 pkt->pts = fourxm->video_pts;
775
c5077fdab490 AVPacket.pos
michael
parents: 743
diff changeset
280 pkt->pos = url_ftell(&s->pb);
143
76dd1e93b064 dispatch video as well as audio
tmmm
parents: 141
diff changeset
281 memcpy(pkt->data, header, 8);
76dd1e93b064 dispatch video as well as audio
tmmm
parents: 141
diff changeset
282 ret = get_buffer(&s->pb, &pkt->data[8], size);
76dd1e93b064 dispatch video as well as audio
tmmm
parents: 141
diff changeset
283
76dd1e93b064 dispatch video as well as audio
tmmm
parents: 141
diff changeset
284 if (ret < 0)
76dd1e93b064 dispatch video as well as audio
tmmm
parents: 141
diff changeset
285 av_free_packet(pkt);
76dd1e93b064 dispatch video as well as audio
tmmm
parents: 141
diff changeset
286 else
76dd1e93b064 dispatch video as well as audio
tmmm
parents: 141
diff changeset
287 packet_read = 1;
139
d5ac5007713c c frame size debug stuff
michaelni
parents: 137
diff changeset
288 break;
d5ac5007713c c frame size debug stuff
michaelni
parents: 137
diff changeset
289 }
143
76dd1e93b064 dispatch video as well as audio
tmmm
parents: 141
diff changeset
290
137
857a026b7e93 first pass at an experimental 4xm demuxer
tmmm
parents:
diff changeset
291 case snd__TAG:
857a026b7e93 first pass at an experimental 4xm demuxer
tmmm
parents:
diff changeset
292 track_number = get_le32(pb);
145
4f3960430e54 4xm adpcm
michaelni
parents: 144
diff changeset
293 out_size= get_le32(pb);
4f3960430e54 4xm adpcm
michaelni
parents: 144
diff changeset
294 size-=8;
4f3960430e54 4xm adpcm
michaelni
parents: 144
diff changeset
295
137
857a026b7e93 first pass at an experimental 4xm demuxer
tmmm
parents:
diff changeset
296 if (track_number == fourxm->selected_track) {
775
c5077fdab490 AVPacket.pos
michael
parents: 743
diff changeset
297 ret= av_get_packet(&s->pb, pkt, size);
c5077fdab490 AVPacket.pos
michael
parents: 743
diff changeset
298 if(ret<0)
482
0fdc96c2f2fe sweeping change from -EIO -> AVERROR_IO
melanson
parents: 462
diff changeset
299 return AVERROR_IO;
143
76dd1e93b064 dispatch video as well as audio
tmmm
parents: 141
diff changeset
300 pkt->stream_index =
76dd1e93b064 dispatch video as well as audio
tmmm
parents: 141
diff changeset
301 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
302 pkt->pts = fourxm->audio_pts;
775
c5077fdab490 AVPacket.pos
michael
parents: 743
diff changeset
303 packet_read = 1;
143
76dd1e93b064 dispatch video as well as audio
tmmm
parents: 141
diff changeset
304
316
9aa23c6d396e use the proper file framerate (specified by a float); account the pts
melanson
parents: 254
diff changeset
305 /* pts accounting */
9aa23c6d396e use the proper file framerate (specified by a float); account the pts
melanson
parents: 254
diff changeset
306 audio_frame_count = size;
9aa23c6d396e use the proper file framerate (specified by a float); account the pts
melanson
parents: 254
diff changeset
307 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
308 audio_frame_count -=
9aa23c6d396e use the proper file framerate (specified by a float); account the pts
melanson
parents: 254
diff changeset
309 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
310 audio_frame_count /=
9aa23c6d396e use the proper file framerate (specified by a float); account the pts
melanson
parents: 254
diff changeset
311 fourxm->tracks[fourxm->selected_track].channels;
9aa23c6d396e use the proper file framerate (specified by a float); account the pts
melanson
parents: 254
diff changeset
312 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
313 audio_frame_count *= 2;
9aa23c6d396e use the proper file framerate (specified by a float); account the pts
melanson
parents: 254
diff changeset
314 else
9aa23c6d396e use the proper file framerate (specified by a float); account the pts
melanson
parents: 254
diff changeset
315 audio_frame_count /=
9aa23c6d396e use the proper file framerate (specified by a float); account the pts
melanson
parents: 254
diff changeset
316 (fourxm->tracks[fourxm->selected_track].bits / 8);
740
58a2da07cb18 fix nonsens timestamp calculation
michael
parents: 643
diff changeset
317 fourxm->audio_pts += audio_frame_count;
143
76dd1e93b064 dispatch video as well as audio
tmmm
parents: 141
diff changeset
318
137
857a026b7e93 first pass at an experimental 4xm demuxer
tmmm
parents:
diff changeset
319 } else {
857a026b7e93 first pass at an experimental 4xm demuxer
tmmm
parents:
diff changeset
320 url_fseek(pb, size, SEEK_CUR);
857a026b7e93 first pass at an experimental 4xm demuxer
tmmm
parents:
diff changeset
321 }
857a026b7e93 first pass at an experimental 4xm demuxer
tmmm
parents:
diff changeset
322 break;
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 default:
857a026b7e93 first pass at an experimental 4xm demuxer
tmmm
parents:
diff changeset
325 url_fseek(pb, size, SEEK_CUR);
857a026b7e93 first pass at an experimental 4xm demuxer
tmmm
parents:
diff changeset
326 break;
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 }
857a026b7e93 first pass at an experimental 4xm demuxer
tmmm
parents:
diff changeset
329 return ret;
857a026b7e93 first pass at an experimental 4xm demuxer
tmmm
parents:
diff changeset
330 }
857a026b7e93 first pass at an experimental 4xm demuxer
tmmm
parents:
diff changeset
331
857a026b7e93 first pass at an experimental 4xm demuxer
tmmm
parents:
diff changeset
332 static int fourxm_read_close(AVFormatContext *s)
857a026b7e93 first pass at an experimental 4xm demuxer
tmmm
parents:
diff changeset
333 {
857a026b7e93 first pass at an experimental 4xm demuxer
tmmm
parents:
diff changeset
334 FourxmDemuxContext *fourxm = (FourxmDemuxContext *)s->priv_data;
857a026b7e93 first pass at an experimental 4xm demuxer
tmmm
parents:
diff changeset
335
857a026b7e93 first pass at an experimental 4xm demuxer
tmmm
parents:
diff changeset
336 av_free(fourxm->tracks);
857a026b7e93 first pass at an experimental 4xm demuxer
tmmm
parents:
diff changeset
337
857a026b7e93 first pass at an experimental 4xm demuxer
tmmm
parents:
diff changeset
338 return 0;
857a026b7e93 first pass at an experimental 4xm demuxer
tmmm
parents:
diff changeset
339 }
857a026b7e93 first pass at an experimental 4xm demuxer
tmmm
parents:
diff changeset
340
857a026b7e93 first pass at an experimental 4xm demuxer
tmmm
parents:
diff changeset
341 static AVInputFormat fourxm_iformat = {
857a026b7e93 first pass at an experimental 4xm demuxer
tmmm
parents:
diff changeset
342 "4xm",
857a026b7e93 first pass at an experimental 4xm demuxer
tmmm
parents:
diff changeset
343 "4X Technologies format",
857a026b7e93 first pass at an experimental 4xm demuxer
tmmm
parents:
diff changeset
344 sizeof(FourxmDemuxContext),
857a026b7e93 first pass at an experimental 4xm demuxer
tmmm
parents:
diff changeset
345 fourxm_probe,
857a026b7e93 first pass at an experimental 4xm demuxer
tmmm
parents:
diff changeset
346 fourxm_read_header,
857a026b7e93 first pass at an experimental 4xm demuxer
tmmm
parents:
diff changeset
347 fourxm_read_packet,
857a026b7e93 first pass at an experimental 4xm demuxer
tmmm
parents:
diff changeset
348 fourxm_read_close,
857a026b7e93 first pass at an experimental 4xm demuxer
tmmm
parents:
diff changeset
349 };
857a026b7e93 first pass at an experimental 4xm demuxer
tmmm
parents:
diff changeset
350
857a026b7e93 first pass at an experimental 4xm demuxer
tmmm
parents:
diff changeset
351 int fourxm_init(void)
857a026b7e93 first pass at an experimental 4xm demuxer
tmmm
parents:
diff changeset
352 {
857a026b7e93 first pass at an experimental 4xm demuxer
tmmm
parents:
diff changeset
353 av_register_input_format(&fourxm_iformat);
857a026b7e93 first pass at an experimental 4xm demuxer
tmmm
parents:
diff changeset
354 return 0;
857a026b7e93 first pass at an experimental 4xm demuxer
tmmm
parents:
diff changeset
355 }