annotate 4xm.c @ 6119:16ca32d9c5f0 libavformat

Use a bitstream filter for converting the extradata syntax when generating an SDP. This allows to generate correct SDPs for H.264 video in "MP4 syntax".
author lucabe
date Fri, 11 Jun 2010 08:01:45 +0000
parents 178de7695c6c
children
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 /**
5969
178de7695c6c Remove explicit filename from Doxygen @file commands.
diego
parents: 5910
diff changeset
23 * @file
137
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
4201
7d2f3f1b68d8 Fix build: Add intreadwrite.h and bswap.h #includes where necessary.
diego
parents: 4199
diff changeset
30 #include "libavutil/intreadwrite.h"
137
857a026b7e93 first pass at an experimental 4xm demuxer
tmmm
parents:
diff changeset
31 #include "avformat.h"
857a026b7e93 first pass at an experimental 4xm demuxer
tmmm
parents:
diff changeset
32
4199
0702e0927a4f cosmetics: indentation
diego
parents: 4198
diff changeset
33 #define RIFF_TAG MKTAG('R', 'I', 'F', 'F')
4198
64ece9005d76 Fix illegal identifier starting with an underscore.
diego
parents: 3908
diff changeset
34 #define FOURXMV_TAG MKTAG('4', 'X', 'M', 'V')
4199
0702e0927a4f cosmetics: indentation
diego
parents: 4198
diff changeset
35 #define LIST_TAG MKTAG('L', 'I', 'S', 'T')
0702e0927a4f cosmetics: indentation
diego
parents: 4198
diff changeset
36 #define HEAD_TAG MKTAG('H', 'E', 'A', 'D')
0702e0927a4f cosmetics: indentation
diego
parents: 4198
diff changeset
37 #define TRK__TAG MKTAG('T', 'R', 'K', '_')
0702e0927a4f cosmetics: indentation
diego
parents: 4198
diff changeset
38 #define MOVI_TAG MKTAG('M', 'O', 'V', 'I')
0702e0927a4f cosmetics: indentation
diego
parents: 4198
diff changeset
39 #define VTRK_TAG MKTAG('V', 'T', 'R', 'K')
0702e0927a4f cosmetics: indentation
diego
parents: 4198
diff changeset
40 #define STRK_TAG MKTAG('S', 'T', 'R', 'K')
0702e0927a4f cosmetics: indentation
diego
parents: 4198
diff changeset
41 #define std__TAG MKTAG('s', 't', 'd', '_')
0702e0927a4f cosmetics: indentation
diego
parents: 4198
diff changeset
42 #define name_TAG MKTAG('n', 'a', 'm', 'e')
0702e0927a4f cosmetics: indentation
diego
parents: 4198
diff changeset
43 #define vtrk_TAG MKTAG('v', 't', 'r', 'k')
0702e0927a4f cosmetics: indentation
diego
parents: 4198
diff changeset
44 #define strk_TAG MKTAG('s', 't', 'r', 'k')
0702e0927a4f cosmetics: indentation
diego
parents: 4198
diff changeset
45 #define ifrm_TAG MKTAG('i', 'f', 'r', 'm')
0702e0927a4f cosmetics: indentation
diego
parents: 4198
diff changeset
46 #define pfrm_TAG MKTAG('p', 'f', 'r', 'm')
0702e0927a4f cosmetics: indentation
diego
parents: 4198
diff changeset
47 #define cfrm_TAG MKTAG('c', 'f', 'r', 'm')
0702e0927a4f cosmetics: indentation
diego
parents: 4198
diff changeset
48 #define ifr2_TAG MKTAG('i', 'f', 'r', '2')
0702e0927a4f cosmetics: indentation
diego
parents: 4198
diff changeset
49 #define pfr2_TAG MKTAG('p', 'f', 'r', '2')
0702e0927a4f cosmetics: indentation
diego
parents: 4198
diff changeset
50 #define cfr2_TAG MKTAG('c', 'f', 'r', '2')
0702e0927a4f cosmetics: indentation
diego
parents: 4198
diff changeset
51 #define snd__TAG MKTAG('s', 'n', 'd', '_')
137
857a026b7e93 first pass at an experimental 4xm demuxer
tmmm
parents:
diff changeset
52
857a026b7e93 first pass at an experimental 4xm demuxer
tmmm
parents:
diff changeset
53 #define vtrk_SIZE 0x44
857a026b7e93 first pass at an experimental 4xm demuxer
tmmm
parents:
diff changeset
54 #define strk_SIZE 0x28
857a026b7e93 first pass at an experimental 4xm demuxer
tmmm
parents:
diff changeset
55
857a026b7e93 first pass at an experimental 4xm demuxer
tmmm
parents:
diff changeset
56 #define GET_LIST_HEADER() \
143
76dd1e93b064 dispatch video as well as audio
tmmm
parents: 141
diff changeset
57 fourcc_tag = get_le32(pb); \
137
857a026b7e93 first pass at an experimental 4xm demuxer
tmmm
parents:
diff changeset
58 size = get_le32(pb); \
857a026b7e93 first pass at an experimental 4xm demuxer
tmmm
parents:
diff changeset
59 if (fourcc_tag != LIST_TAG) \
857a026b7e93 first pass at an experimental 4xm demuxer
tmmm
parents:
diff changeset
60 return AVERROR_INVALIDDATA; \
143
76dd1e93b064 dispatch video as well as audio
tmmm
parents: 141
diff changeset
61 fourcc_tag = get_le32(pb);
137
857a026b7e93 first pass at an experimental 4xm demuxer
tmmm
parents:
diff changeset
62
857a026b7e93 first pass at an experimental 4xm demuxer
tmmm
parents:
diff changeset
63 typedef struct AudioTrack {
857a026b7e93 first pass at an experimental 4xm demuxer
tmmm
parents:
diff changeset
64 int sample_rate;
857a026b7e93 first pass at an experimental 4xm demuxer
tmmm
parents:
diff changeset
65 int bits;
857a026b7e93 first pass at an experimental 4xm demuxer
tmmm
parents:
diff changeset
66 int channels;
143
76dd1e93b064 dispatch video as well as audio
tmmm
parents: 141
diff changeset
67 int stream_index;
145
4f3960430e54 4xm adpcm
michaelni
parents: 144
diff changeset
68 int adpcm;
4301
e7ef6404ec88 Export all tracks (each is a different language) instead of just one.
michael
parents: 4300
diff changeset
69 int64_t audio_pts;
137
857a026b7e93 first pass at an experimental 4xm demuxer
tmmm
parents:
diff changeset
70 } AudioTrack;
857a026b7e93 first pass at an experimental 4xm demuxer
tmmm
parents:
diff changeset
71
857a026b7e93 first pass at an experimental 4xm demuxer
tmmm
parents:
diff changeset
72 typedef struct FourxmDemuxContext {
857a026b7e93 first pass at an experimental 4xm demuxer
tmmm
parents:
diff changeset
73 int width;
857a026b7e93 first pass at an experimental 4xm demuxer
tmmm
parents:
diff changeset
74 int height;
143
76dd1e93b064 dispatch video as well as audio
tmmm
parents: 141
diff changeset
75 int video_stream_index;
137
857a026b7e93 first pass at an experimental 4xm demuxer
tmmm
parents:
diff changeset
76 int track_count;
857a026b7e93 first pass at an experimental 4xm demuxer
tmmm
parents:
diff changeset
77 AudioTrack *tracks;
143
76dd1e93b064 dispatch video as well as audio
tmmm
parents: 141
diff changeset
78
316
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) ||
4198
64ece9005d76 Fix illegal identifier starting with an underscore.
diego
parents: 3908
diff changeset
86 (AV_RL32(&p->buf[8]) != FOURXMV_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;
4298
dad1519b0829 Fix memleak of fourxm->tracks on error return.
michael
parents: 4297
diff changeset
101 int i, ret;
137
857a026b7e93 first pass at an experimental 4xm demuxer
tmmm
parents:
diff changeset
102 AVStream *st;
857a026b7e93 first pass at an experimental 4xm demuxer
tmmm
parents:
diff changeset
103
857a026b7e93 first pass at an experimental 4xm demuxer
tmmm
parents:
diff changeset
104 fourxm->track_count = 0;
857a026b7e93 first pass at an experimental 4xm demuxer
tmmm
parents:
diff changeset
105 fourxm->tracks = NULL;
317
5cd41ae1debf set frame rate information, for good measure
melanson
parents: 316
diff changeset
106 fourxm->fps = 1.0;
137
857a026b7e93 first pass at an experimental 4xm demuxer
tmmm
parents:
diff changeset
107
857a026b7e93 first pass at an experimental 4xm demuxer
tmmm
parents:
diff changeset
108 /* skip the first 3 32-bit numbers */
857a026b7e93 first pass at an experimental 4xm demuxer
tmmm
parents:
diff changeset
109 url_fseek(pb, 12, SEEK_CUR);
857a026b7e93 first pass at an experimental 4xm demuxer
tmmm
parents:
diff changeset
110
857a026b7e93 first pass at an experimental 4xm demuxer
tmmm
parents:
diff changeset
111 /* check for LIST-HEAD */
857a026b7e93 first pass at an experimental 4xm demuxer
tmmm
parents:
diff changeset
112 GET_LIST_HEADER();
857a026b7e93 first pass at an experimental 4xm demuxer
tmmm
parents:
diff changeset
113 header_size = size - 4;
4295
36a6d25e95ea better header_size check
michael
parents: 4294
diff changeset
114 if (fourcc_tag != HEAD_TAG || header_size < 0)
137
857a026b7e93 first pass at an experimental 4xm demuxer
tmmm
parents:
diff changeset
115 return AVERROR_INVALIDDATA;
857a026b7e93 first pass at an experimental 4xm demuxer
tmmm
parents:
diff changeset
116
857a026b7e93 first pass at an experimental 4xm demuxer
tmmm
parents:
diff changeset
117 /* allocate space for the header and load the whole thing */
857a026b7e93 first pass at an experimental 4xm demuxer
tmmm
parents:
diff changeset
118 header = av_malloc(header_size);
857a026b7e93 first pass at an experimental 4xm demuxer
tmmm
parents:
diff changeset
119 if (!header)
2273
7eb456c4ed8a Replace all occurrences of AVERROR_NOMEM with AVERROR(ENOMEM).
takis
parents: 2006
diff changeset
120 return AVERROR(ENOMEM);
4296
42a9dba93e69 Fix memleak of header in error returns.
michael
parents: 4295
diff changeset
121 if (get_buffer(pb, header, header_size) != header_size){
42a9dba93e69 Fix memleak of header in error returns.
michael
parents: 4295
diff changeset
122 av_free(header);
2274
b21c2af60bc9 Replace all occurrences of AVERROR_IO with AVERROR(EIO).
takis
parents: 2273
diff changeset
123 return AVERROR(EIO);
4296
42a9dba93e69 Fix memleak of header in error returns.
michael
parents: 4295
diff changeset
124 }
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) {
4298
dad1519b0829 Fix memleak of fourxm->tracks on error return.
michael
parents: 4297
diff changeset
136 ret= AVERROR_INVALIDDATA;
dad1519b0829 Fix memleak of fourxm->tracks on error return.
michael
parents: 4297
diff changeset
137 goto fail;
137
857a026b7e93 first pass at an experimental 4xm demuxer
tmmm
parents:
diff changeset
138 }
4297
85aa6639649a vertical align
michael
parents: 4296
diff changeset
139 fourxm->width = AV_RL32(&header[i + 36]);
1673
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);
4296
42a9dba93e69 Fix memleak of header in error returns.
michael
parents: 4295
diff changeset
144 if (!st){
4298
dad1519b0829 Fix memleak of fourxm->tracks on error return.
michael
parents: 4297
diff changeset
145 ret= AVERROR(ENOMEM);
dad1519b0829 Fix memleak of fourxm->tracks on error return.
michael
parents: 4297
diff changeset
146 goto fail;
4296
42a9dba93e69 Fix memleak of header in error returns.
michael
parents: 4295
diff changeset
147 }
740
58a2da07cb18 fix nonsens timestamp calculation
michael
parents: 643
diff changeset
148 av_set_pts_info(st, 60, 1, fourxm->fps);
143
76dd1e93b064 dispatch video as well as audio
tmmm
parents: 141
diff changeset
149
76dd1e93b064 dispatch video as well as audio
tmmm
parents: 141
diff changeset
150 fourxm->video_stream_index = st->index;
76dd1e93b064 dispatch video as well as audio
tmmm
parents: 141
diff changeset
151
5910
536e5527c1e0 Define AVMediaType enum, and use it instead of enum CodecType, which
stefano
parents: 4331
diff changeset
152 st->codec->codec_type = AVMEDIA_TYPE_VIDEO;
820
feca73904e67 changing AVCodecContext codec -> *codec in AVStream so additions to AVCodecContext dont randomize AVStream and break binary compatibility
michael
parents: 775
diff changeset
153 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
154 st->codec->extradata_size = 4;
9b58a031620e Change 4xm demuxer and video decoder to pass the video format version in
rtogni
parents: 2379
diff changeset
155 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
156 AV_WL32(st->codec->extradata, AV_RL32(&header[i + 16]));
4297
85aa6639649a vertical align
michael
parents: 4296
diff changeset
157 st->codec->width = fourxm->width;
820
feca73904e67 changing AVCodecContext codec -> *codec in AVStream so additions to AVCodecContext dont randomize AVStream and break binary compatibility
michael
parents: 775
diff changeset
158 st->codec->height = fourxm->height;
143
76dd1e93b064 dispatch video as well as audio
tmmm
parents: 141
diff changeset
159
2379
14b9277b6491 export 4xm video version
michael
parents: 2377
diff changeset
160 i += 8 + size;
137
857a026b7e93 first pass at an experimental 4xm demuxer
tmmm
parents:
diff changeset
161 } else if (fourcc_tag == strk_TAG) {
4299
59c385f94310 Move current_track variable closer to where it is used.
michael
parents: 4298
diff changeset
162 int current_track;
137
857a026b7e93 first pass at an experimental 4xm demuxer
tmmm
parents:
diff changeset
163 /* check that there is enough data */
857a026b7e93 first pass at an experimental 4xm demuxer
tmmm
parents:
diff changeset
164 if (size != strk_SIZE) {
4298
dad1519b0829 Fix memleak of fourxm->tracks on error return.
michael
parents: 4297
diff changeset
165 ret= AVERROR_INVALIDDATA;
dad1519b0829 Fix memleak of fourxm->tracks on error return.
michael
parents: 4297
diff changeset
166 goto fail;
137
857a026b7e93 first pass at an experimental 4xm demuxer
tmmm
parents:
diff changeset
167 }
1673
a782462e2497 rename BE/LE_8/16/32 to AV_RL/B_8/16/32
alex
parents: 1450
diff changeset
168 current_track = AV_RL32(&header[i + 8]);
4305
3e1bf36d7c73 Fix remotely exploitable arbitrary code execution vulnerability.
michael
parents: 4303
diff changeset
169 if((unsigned)current_track >= UINT_MAX / sizeof(AudioTrack) - 1){
3e1bf36d7c73 Fix remotely exploitable arbitrary code execution vulnerability.
michael
parents: 4303
diff changeset
170 av_log(s, AV_LOG_ERROR, "current_track too large\n");
3e1bf36d7c73 Fix remotely exploitable arbitrary code execution vulnerability.
michael
parents: 4303
diff changeset
171 ret= -1;
3e1bf36d7c73 Fix remotely exploitable arbitrary code execution vulnerability.
michael
parents: 4303
diff changeset
172 goto fail;
3e1bf36d7c73 Fix remotely exploitable arbitrary code execution vulnerability.
michael
parents: 4303
diff changeset
173 }
137
857a026b7e93 first pass at an experimental 4xm demuxer
tmmm
parents:
diff changeset
174 if (current_track + 1 > fourxm->track_count) {
141
d2d2ec541148 allocate enough bytes
tmmm
parents: 140
diff changeset
175 fourxm->track_count = current_track + 1;
885
da1d5db0ce5c COSMETICS: Remove all trailing whitespace.
diego
parents: 824
diff changeset
176 fourxm->tracks = av_realloc(fourxm->tracks,
141
d2d2ec541148 allocate enough bytes
tmmm
parents: 140
diff changeset
177 fourxm->track_count * sizeof(AudioTrack));
137
857a026b7e93 first pass at an experimental 4xm demuxer
tmmm
parents:
diff changeset
178 if (!fourxm->tracks) {
4298
dad1519b0829 Fix memleak of fourxm->tracks on error return.
michael
parents: 4297
diff changeset
179 ret= AVERROR(ENOMEM);
dad1519b0829 Fix memleak of fourxm->tracks on error return.
michael
parents: 4297
diff changeset
180 goto fail;
137
857a026b7e93 first pass at an experimental 4xm demuxer
tmmm
parents:
diff changeset
181 }
857a026b7e93 first pass at an experimental 4xm demuxer
tmmm
parents:
diff changeset
182 }
4297
85aa6639649a vertical align
michael
parents: 4296
diff changeset
183 fourxm->tracks[current_track].adpcm = AV_RL32(&header[i + 12]);
85aa6639649a vertical align
michael
parents: 4296
diff changeset
184 fourxm->tracks[current_track].channels = AV_RL32(&header[i + 36]);
1673
a782462e2497 rename BE/LE_8/16/32 to AV_RL/B_8/16/32
alex
parents: 1450
diff changeset
185 fourxm->tracks[current_track].sample_rate = AV_RL32(&header[i + 40]);
4297
85aa6639649a vertical align
michael
parents: 4296
diff changeset
186 fourxm->tracks[current_track].bits = AV_RL32(&header[i + 44]);
4301
e7ef6404ec88 Export all tracks (each is a different language) instead of just one.
michael
parents: 4300
diff changeset
187 fourxm->tracks[current_track].audio_pts = 0;
137
857a026b7e93 first pass at an experimental 4xm demuxer
tmmm
parents:
diff changeset
188 i += 8 + size;
143
76dd1e93b064 dispatch video as well as audio
tmmm
parents: 141
diff changeset
189
76dd1e93b064 dispatch video as well as audio
tmmm
parents: 141
diff changeset
190 /* allocate a new AVStream */
76dd1e93b064 dispatch video as well as audio
tmmm
parents: 141
diff changeset
191 st = av_new_stream(s, current_track);
4296
42a9dba93e69 Fix memleak of header in error returns.
michael
parents: 4295
diff changeset
192 if (!st){
4298
dad1519b0829 Fix memleak of fourxm->tracks on error return.
michael
parents: 4297
diff changeset
193 ret= AVERROR(ENOMEM);
dad1519b0829 Fix memleak of fourxm->tracks on error return.
michael
parents: 4297
diff changeset
194 goto fail;
4296
42a9dba93e69 Fix memleak of header in error returns.
michael
parents: 4295
diff changeset
195 }
143
76dd1e93b064 dispatch video as well as audio
tmmm
parents: 141
diff changeset
196
740
58a2da07cb18 fix nonsens timestamp calculation
michael
parents: 643
diff changeset
197 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
198
143
76dd1e93b064 dispatch video as well as audio
tmmm
parents: 141
diff changeset
199 fourxm->tracks[current_track].stream_index = st->index;
76dd1e93b064 dispatch video as well as audio
tmmm
parents: 141
diff changeset
200
5910
536e5527c1e0 Define AVMediaType enum, and use it instead of enum CodecType, which
stefano
parents: 4331
diff changeset
201 st->codec->codec_type = AVMEDIA_TYPE_AUDIO;
1450
1580c48ba4b9 Do not set audio codec_tag to 1, that would be PCM audio.
diego
parents: 1358
diff changeset
202 st->codec->codec_tag = 0;
4297
85aa6639649a vertical align
michael
parents: 4296
diff changeset
203 st->codec->channels = fourxm->tracks[current_track].channels;
85aa6639649a vertical align
michael
parents: 4296
diff changeset
204 st->codec->sample_rate = fourxm->tracks[current_track].sample_rate;
3908
1d3d17de20ba Bump Major version, this commit is almost just renaming bits_per_sample to
michael
parents: 3424
diff changeset
205 st->codec->bits_per_coded_sample = fourxm->tracks[current_track].bits;
4297
85aa6639649a vertical align
michael
parents: 4296
diff changeset
206 st->codec->bit_rate = st->codec->channels * st->codec->sample_rate *
3908
1d3d17de20ba Bump Major version, this commit is almost just renaming bits_per_sample to
michael
parents: 3424
diff changeset
207 st->codec->bits_per_coded_sample;
1d3d17de20ba Bump Major version, this commit is almost just renaming bits_per_sample to
michael
parents: 3424
diff changeset
208 st->codec->block_align = st->codec->channels * st->codec->bits_per_coded_sample;
4302
ef58b73b138c Add {} between if/else
michael
parents: 4301
diff changeset
209 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
210 st->codec->codec_id = CODEC_ID_ADPCM_4XM;
4302
ef58b73b138c Add {} between if/else
michael
parents: 4301
diff changeset
211 }else if (st->codec->bits_per_coded_sample == 8){
820
feca73904e67 changing AVCodecContext codec -> *codec in AVStream so additions to AVCodecContext dont randomize AVStream and break binary compatibility
michael
parents: 775
diff changeset
212 st->codec->codec_id = CODEC_ID_PCM_U8;
4302
ef58b73b138c Add {} between if/else
michael
parents: 4301
diff changeset
213 }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
214 st->codec->codec_id = CODEC_ID_PCM_S16LE;
137
857a026b7e93 first pass at an experimental 4xm demuxer
tmmm
parents:
diff changeset
215 }
857a026b7e93 first pass at an experimental 4xm demuxer
tmmm
parents:
diff changeset
216 }
857a026b7e93 first pass at an experimental 4xm demuxer
tmmm
parents:
diff changeset
217
857a026b7e93 first pass at an experimental 4xm demuxer
tmmm
parents:
diff changeset
218 /* 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
219 GET_LIST_HEADER();
4298
dad1519b0829 Fix memleak of fourxm->tracks on error return.
michael
parents: 4297
diff changeset
220 if (fourcc_tag != MOVI_TAG){
dad1519b0829 Fix memleak of fourxm->tracks on error return.
michael
parents: 4297
diff changeset
221 ret= AVERROR_INVALIDDATA;
dad1519b0829 Fix memleak of fourxm->tracks on error return.
michael
parents: 4297
diff changeset
222 goto fail;
dad1519b0829 Fix memleak of fourxm->tracks on error return.
michael
parents: 4297
diff changeset
223 }
137
857a026b7e93 first pass at an experimental 4xm demuxer
tmmm
parents:
diff changeset
224
4298
dad1519b0829 Fix memleak of fourxm->tracks on error return.
michael
parents: 4297
diff changeset
225 av_free(header);
143
76dd1e93b064 dispatch video as well as audio
tmmm
parents: 141
diff changeset
226 /* initialize context members */
740
58a2da07cb18 fix nonsens timestamp calculation
michael
parents: 643
diff changeset
227 fourxm->video_pts = -1; /* first frame will push to 0 */
137
857a026b7e93 first pass at an experimental 4xm demuxer
tmmm
parents:
diff changeset
228
857a026b7e93 first pass at an experimental 4xm demuxer
tmmm
parents:
diff changeset
229 return 0;
4298
dad1519b0829 Fix memleak of fourxm->tracks on error return.
michael
parents: 4297
diff changeset
230 fail:
dad1519b0829 Fix memleak of fourxm->tracks on error return.
michael
parents: 4297
diff changeset
231 av_freep(&fourxm->tracks);
dad1519b0829 Fix memleak of fourxm->tracks on error return.
michael
parents: 4297
diff changeset
232 av_free(header);
dad1519b0829 Fix memleak of fourxm->tracks on error return.
michael
parents: 4297
diff changeset
233 return ret;
137
857a026b7e93 first pass at an experimental 4xm demuxer
tmmm
parents:
diff changeset
234 }
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 static int fourxm_read_packet(AVFormatContext *s,
143
76dd1e93b064 dispatch video as well as audio
tmmm
parents: 141
diff changeset
237 AVPacket *pkt)
137
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 FourxmDemuxContext *fourxm = s->priv_data;
2771
d52c718e83f9 Use dynamically allocated ByteIOContext in AVFormatContext
andoma
parents: 2410
diff changeset
240 ByteIOContext *pb = s->pb;
137
857a026b7e93 first pass at an experimental 4xm demuxer
tmmm
parents:
diff changeset
241 unsigned int fourcc_tag;
145
4f3960430e54 4xm adpcm
michaelni
parents: 144
diff changeset
242 unsigned int size, out_size;
137
857a026b7e93 first pass at an experimental 4xm demuxer
tmmm
parents:
diff changeset
243 int ret = 0;
4301
e7ef6404ec88 Export all tracks (each is a different language) instead of just one.
michael
parents: 4300
diff changeset
244 unsigned int track_number;
137
857a026b7e93 first pass at an experimental 4xm demuxer
tmmm
parents:
diff changeset
245 int packet_read = 0;
143
76dd1e93b064 dispatch video as well as audio
tmmm
parents: 141
diff changeset
246 unsigned char header[8];
316
9aa23c6d396e use the proper file framerate (specified by a float); account the pts
melanson
parents: 254
diff changeset
247 int audio_frame_count;
137
857a026b7e93 first pass at an experimental 4xm demuxer
tmmm
parents:
diff changeset
248
857a026b7e93 first pass at an experimental 4xm demuxer
tmmm
parents:
diff changeset
249 while (!packet_read) {
857a026b7e93 first pass at an experimental 4xm demuxer
tmmm
parents:
diff changeset
250
2771
d52c718e83f9 Use dynamically allocated ByteIOContext in AVFormatContext
andoma
parents: 2410
diff changeset
251 if ((ret = get_buffer(s->pb, header, 8)) < 0)
143
76dd1e93b064 dispatch video as well as audio
tmmm
parents: 141
diff changeset
252 return ret;
1673
a782462e2497 rename BE/LE_8/16/32 to AV_RL/B_8/16/32
alex
parents: 1450
diff changeset
253 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
254 size = AV_RL32(&header[4]);
137
857a026b7e93 first pass at an experimental 4xm demuxer
tmmm
parents:
diff changeset
255 if (url_feof(pb))
2274
b21c2af60bc9 Replace all occurrences of AVERROR_IO with AVERROR(EIO).
takis
parents: 2273
diff changeset
256 return AVERROR(EIO);
137
857a026b7e93 first pass at an experimental 4xm demuxer
tmmm
parents:
diff changeset
257 switch (fourcc_tag) {
857a026b7e93 first pass at an experimental 4xm demuxer
tmmm
parents:
diff changeset
258
144
9e73bf732800 get the video dispatch straight
tmmm
parents: 143
diff changeset
259 case LIST_TAG:
316
9aa23c6d396e use the proper file framerate (specified by a float); account the pts
melanson
parents: 254
diff changeset
260 /* this is a good time to bump the video pts */
740
58a2da07cb18 fix nonsens timestamp calculation
michael
parents: 643
diff changeset
261 fourxm->video_pts ++;
316
9aa23c6d396e use the proper file framerate (specified by a float); account the pts
melanson
parents: 254
diff changeset
262
144
9e73bf732800 get the video dispatch straight
tmmm
parents: 143
diff changeset
263 /* skip the LIST-* tag and move on to the next fourcc */
9e73bf732800 get the video dispatch straight
tmmm
parents: 143
diff changeset
264 get_le32(pb);
9e73bf732800 get the video dispatch straight
tmmm
parents: 143
diff changeset
265 break;
9e73bf732800 get the video dispatch straight
tmmm
parents: 143
diff changeset
266
137
857a026b7e93 first pass at an experimental 4xm demuxer
tmmm
parents:
diff changeset
267 case ifrm_TAG:
857a026b7e93 first pass at an experimental 4xm demuxer
tmmm
parents:
diff changeset
268 case pfrm_TAG:
2377
2a44e9c75bf3 pass *fr2 chunks to decoder (Toy-Story2_better-image-quality.4xa contains them)
michael
parents: 2274
diff changeset
269 case cfrm_TAG:
2a44e9c75bf3 pass *fr2 chunks to decoder (Toy-Story2_better-image-quality.4xa contains them)
michael
parents: 2274
diff changeset
270 case ifr2_TAG:
2a44e9c75bf3 pass *fr2 chunks to decoder (Toy-Story2_better-image-quality.4xa contains them)
michael
parents: 2274
diff changeset
271 case pfr2_TAG:
2a44e9c75bf3 pass *fr2 chunks to decoder (Toy-Story2_better-image-quality.4xa contains them)
michael
parents: 2274
diff changeset
272 case cfr2_TAG:
143
76dd1e93b064 dispatch video as well as audio
tmmm
parents: 141
diff changeset
273 /* allocate 8 more bytes than 'size' to account for fourcc
76dd1e93b064 dispatch video as well as audio
tmmm
parents: 141
diff changeset
274 * and size */
643
253b5292946a various security fixes and precautionary checks
michael
parents: 639
diff changeset
275 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
276 return AVERROR(EIO);
143
76dd1e93b064 dispatch video as well as audio
tmmm
parents: 141
diff changeset
277 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
278 pkt->pts = fourxm->video_pts;
2771
d52c718e83f9 Use dynamically allocated ByteIOContext in AVFormatContext
andoma
parents: 2410
diff changeset
279 pkt->pos = url_ftell(s->pb);
143
76dd1e93b064 dispatch video as well as audio
tmmm
parents: 141
diff changeset
280 memcpy(pkt->data, header, 8);
2771
d52c718e83f9 Use dynamically allocated ByteIOContext in AVFormatContext
andoma
parents: 2410
diff changeset
281 ret = get_buffer(s->pb, &pkt->data[8], size);
143
76dd1e93b064 dispatch video as well as audio
tmmm
parents: 141
diff changeset
282
4302
ef58b73b138c Add {} between if/else
michael
parents: 4301
diff changeset
283 if (ret < 0){
143
76dd1e93b064 dispatch video as well as audio
tmmm
parents: 141
diff changeset
284 av_free_packet(pkt);
4302
ef58b73b138c Add {} between if/else
michael
parents: 4301
diff changeset
285 }else
143
76dd1e93b064 dispatch video as well as audio
tmmm
parents: 141
diff changeset
286 packet_read = 1;
139
d5ac5007713c c frame size debug stuff
michaelni
parents: 137
diff changeset
287 break;
143
76dd1e93b064 dispatch video as well as audio
tmmm
parents: 141
diff changeset
288
137
857a026b7e93 first pass at an experimental 4xm demuxer
tmmm
parents:
diff changeset
289 case snd__TAG:
857a026b7e93 first pass at an experimental 4xm demuxer
tmmm
parents:
diff changeset
290 track_number = get_le32(pb);
145
4f3960430e54 4xm adpcm
michaelni
parents: 144
diff changeset
291 out_size= get_le32(pb);
4f3960430e54 4xm adpcm
michaelni
parents: 144
diff changeset
292 size-=8;
4f3960430e54 4xm adpcm
michaelni
parents: 144
diff changeset
293
4301
e7ef6404ec88 Export all tracks (each is a different language) instead of just one.
michael
parents: 4300
diff changeset
294 if (track_number < fourxm->track_count) {
2771
d52c718e83f9 Use dynamically allocated ByteIOContext in AVFormatContext
andoma
parents: 2410
diff changeset
295 ret= av_get_packet(s->pb, pkt, size);
775
c5077fdab490 AVPacket.pos
michael
parents: 743
diff changeset
296 if(ret<0)
2274
b21c2af60bc9 Replace all occurrences of AVERROR_IO with AVERROR(EIO).
takis
parents: 2273
diff changeset
297 return AVERROR(EIO);
885
da1d5db0ce5c COSMETICS: Remove all trailing whitespace.
diego
parents: 824
diff changeset
298 pkt->stream_index =
4301
e7ef6404ec88 Export all tracks (each is a different language) instead of just one.
michael
parents: 4300
diff changeset
299 fourxm->tracks[track_number].stream_index;
e7ef6404ec88 Export all tracks (each is a different language) instead of just one.
michael
parents: 4300
diff changeset
300 pkt->pts = fourxm->tracks[track_number].audio_pts;
775
c5077fdab490 AVPacket.pos
michael
parents: 743
diff changeset
301 packet_read = 1;
143
76dd1e93b064 dispatch video as well as audio
tmmm
parents: 141
diff changeset
302
316
9aa23c6d396e use the proper file framerate (specified by a float); account the pts
melanson
parents: 254
diff changeset
303 /* pts accounting */
9aa23c6d396e use the proper file framerate (specified by a float); account the pts
melanson
parents: 254
diff changeset
304 audio_frame_count = size;
4301
e7ef6404ec88 Export all tracks (each is a different language) instead of just one.
michael
parents: 4300
diff changeset
305 if (fourxm->tracks[track_number].adpcm)
885
da1d5db0ce5c COSMETICS: Remove all trailing whitespace.
diego
parents: 824
diff changeset
306 audio_frame_count -=
4301
e7ef6404ec88 Export all tracks (each is a different language) instead of just one.
michael
parents: 4300
diff changeset
307 2 * (fourxm->tracks[track_number].channels);
316
9aa23c6d396e use the proper file framerate (specified by a float); account the pts
melanson
parents: 254
diff changeset
308 audio_frame_count /=
4301
e7ef6404ec88 Export all tracks (each is a different language) instead of just one.
michael
parents: 4300
diff changeset
309 fourxm->tracks[track_number].channels;
4302
ef58b73b138c Add {} between if/else
michael
parents: 4301
diff changeset
310 if (fourxm->tracks[track_number].adpcm){
316
9aa23c6d396e use the proper file framerate (specified by a float); account the pts
melanson
parents: 254
diff changeset
311 audio_frame_count *= 2;
4302
ef58b73b138c Add {} between if/else
michael
parents: 4301
diff changeset
312 }else
316
9aa23c6d396e use the proper file framerate (specified by a float); account the pts
melanson
parents: 254
diff changeset
313 audio_frame_count /=
4301
e7ef6404ec88 Export all tracks (each is a different language) instead of just one.
michael
parents: 4300
diff changeset
314 (fourxm->tracks[track_number].bits / 8);
e7ef6404ec88 Export all tracks (each is a different language) instead of just one.
michael
parents: 4300
diff changeset
315 fourxm->tracks[track_number].audio_pts += audio_frame_count;
143
76dd1e93b064 dispatch video as well as audio
tmmm
parents: 141
diff changeset
316
137
857a026b7e93 first pass at an experimental 4xm demuxer
tmmm
parents:
diff changeset
317 } else {
857a026b7e93 first pass at an experimental 4xm demuxer
tmmm
parents:
diff changeset
318 url_fseek(pb, size, SEEK_CUR);
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 break;
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 default:
857a026b7e93 first pass at an experimental 4xm demuxer
tmmm
parents:
diff changeset
323 url_fseek(pb, size, SEEK_CUR);
857a026b7e93 first pass at an experimental 4xm demuxer
tmmm
parents:
diff changeset
324 break;
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 }
857a026b7e93 first pass at an experimental 4xm demuxer
tmmm
parents:
diff changeset
327 return ret;
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
857a026b7e93 first pass at an experimental 4xm demuxer
tmmm
parents:
diff changeset
330 static int fourxm_read_close(AVFormatContext *s)
857a026b7e93 first pass at an experimental 4xm demuxer
tmmm
parents:
diff changeset
331 {
2006
2f0154760e5f Get rid of unnecessary pointer casts.
diego
parents: 2001
diff changeset
332 FourxmDemuxContext *fourxm = s->priv_data;
137
857a026b7e93 first pass at an experimental 4xm demuxer
tmmm
parents:
diff changeset
333
4303
a6789651f297 Prefer av_freep() over av_free() for variables in the context for safety.
michael
parents: 4302
diff changeset
334 av_freep(&fourxm->tracks);
137
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 return 0;
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
1169
d18cc9a1fd02 allow individual selection of muxers and demuxers
mru
parents: 1167
diff changeset
339 AVInputFormat fourxm_demuxer = {
137
857a026b7e93 first pass at an experimental 4xm demuxer
tmmm
parents:
diff changeset
340 "4xm",
3424
7a0230981402 Make long_names in lavf/lavdev optional depending on CONFIG_SMALL.
diego
parents: 2771
diff changeset
341 NULL_IF_CONFIG_SMALL("4X Technologies format"),
137
857a026b7e93 first pass at an experimental 4xm demuxer
tmmm
parents:
diff changeset
342 sizeof(FourxmDemuxContext),
857a026b7e93 first pass at an experimental 4xm demuxer
tmmm
parents:
diff changeset
343 fourxm_probe,
857a026b7e93 first pass at an experimental 4xm demuxer
tmmm
parents:
diff changeset
344 fourxm_read_header,
857a026b7e93 first pass at an experimental 4xm demuxer
tmmm
parents:
diff changeset
345 fourxm_read_packet,
857a026b7e93 first pass at an experimental 4xm demuxer
tmmm
parents:
diff changeset
346 fourxm_read_close,
857a026b7e93 first pass at an experimental 4xm demuxer
tmmm
parents:
diff changeset
347 };