Mercurial > mplayer.hg
annotate libmpdemux/demux_rtp_codec.cpp @ 35418:cedb0ba2b5c6
Move the code to set guiInfo's Track, Chapter and Angle start values.
Set them before checking whether there is any media opened, because
with no media opened we clear the counters.
author | ib |
---|---|
date | Thu, 29 Nov 2012 14:11:03 +0000 |
parents | f3d53cd55376 |
children | 8517826b0dbd |
rev | line source |
---|---|
29238
d643e4643313
Add standard license header to all files in libmpdemux.
diego
parents:
27417
diff
changeset
|
1 /* |
d643e4643313
Add standard license header to all files in libmpdemux.
diego
parents:
27417
diff
changeset
|
2 * codec-specific routines used to interface between MPlayer |
d643e4643313
Add standard license header to all files in libmpdemux.
diego
parents:
27417
diff
changeset
|
3 * and the "LIVE555 Streaming Media" libraries |
d643e4643313
Add standard license header to all files in libmpdemux.
diego
parents:
27417
diff
changeset
|
4 * |
d643e4643313
Add standard license header to all files in libmpdemux.
diego
parents:
27417
diff
changeset
|
5 * This file is part of MPlayer. |
d643e4643313
Add standard license header to all files in libmpdemux.
diego
parents:
27417
diff
changeset
|
6 * |
d643e4643313
Add standard license header to all files in libmpdemux.
diego
parents:
27417
diff
changeset
|
7 * MPlayer is free software; you can redistribute it and/or modify |
d643e4643313
Add standard license header to all files in libmpdemux.
diego
parents:
27417
diff
changeset
|
8 * it under the terms of the GNU General Public License as published by |
d643e4643313
Add standard license header to all files in libmpdemux.
diego
parents:
27417
diff
changeset
|
9 * the Free Software Foundation; either version 2 of the License, or |
d643e4643313
Add standard license header to all files in libmpdemux.
diego
parents:
27417
diff
changeset
|
10 * (at your option) any later version. |
d643e4643313
Add standard license header to all files in libmpdemux.
diego
parents:
27417
diff
changeset
|
11 * |
d643e4643313
Add standard license header to all files in libmpdemux.
diego
parents:
27417
diff
changeset
|
12 * MPlayer is distributed in the hope that it will be useful, |
d643e4643313
Add standard license header to all files in libmpdemux.
diego
parents:
27417
diff
changeset
|
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of |
d643e4643313
Add standard license header to all files in libmpdemux.
diego
parents:
27417
diff
changeset
|
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
d643e4643313
Add standard license header to all files in libmpdemux.
diego
parents:
27417
diff
changeset
|
15 * GNU General Public License for more details. |
d643e4643313
Add standard license header to all files in libmpdemux.
diego
parents:
27417
diff
changeset
|
16 * |
d643e4643313
Add standard license header to all files in libmpdemux.
diego
parents:
27417
diff
changeset
|
17 * You should have received a copy of the GNU General Public License along |
d643e4643313
Add standard license header to all files in libmpdemux.
diego
parents:
27417
diff
changeset
|
18 * with MPlayer; if not, write to the Free Software Foundation, Inc., |
d643e4643313
Add standard license header to all files in libmpdemux.
diego
parents:
27417
diff
changeset
|
19 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. |
d643e4643313
Add standard license header to all files in libmpdemux.
diego
parents:
27417
diff
changeset
|
20 */ |
9250 | 21 |
22 #include "demux_rtp_internal.h" | |
23 extern "C" { | |
21911
e86bb13ec44b
demux_rtp_codec.cpp:100: `INT_MAX' undeclared (first use this function)
diego
parents:
21871
diff
changeset
|
24 #include <limits.h> |
21983
a6b624360aef
better autodetection of framerate in case of h264; it works correctly with b-frames.
nicodvb
parents:
21911
diff
changeset
|
25 #include <math.h> |
34173
a5d8b198c214
demux_rtp: Replace extern declarations by proper header #includes.
diego
parents:
32537
diff
changeset
|
26 |
a5d8b198c214
demux_rtp: Replace extern declarations by proper header #includes.
diego
parents:
32537
diff
changeset
|
27 #include "mpcommon.h" |
9250 | 28 #include "stheader.h" |
26486 | 29 #include "libavutil/base64.h" |
22852 | 30 } |
31 | |
32142
4614728cab25
build system: Merge all FFmpeg library checks into a single FFmpeg check.
diego
parents:
31627
diff
changeset
|
32 #ifdef CONFIG_FFMPEG |
22852 | 33 AVCodecParserContext * h264parserctx; |
29453 | 34 AVCodecContext *avcctx; |
22852 | 35 #endif |
36 | |
37 // Copied from vlc | |
38 static unsigned char* parseH264ConfigStr( char const* configStr, | |
39 unsigned int& configSize ) | |
40 { | |
41 | |
42 char *dup, *psz; | |
43 int i, i_records = 1; | |
44 | |
45 if( configSize ) | |
46 configSize = 0; | |
47 if( configStr == NULL || *configStr == '\0' ) | |
48 return NULL; | |
49 psz = dup = strdup( configStr ); | |
50 | |
51 /* Count the number of comma's */ | |
52 for( psz = dup; *psz != '\0'; ++psz ) | |
53 { | |
54 if( *psz == ',') | |
55 { | |
56 ++i_records; | |
57 *psz = '\0'; | |
58 } | |
59 } | |
60 | |
61 unsigned char *cfg = new unsigned char[5 * strlen(dup)]; | |
62 psz = dup; | |
63 for( i = 0; i < i_records; i++ ) | |
64 { | |
65 | |
66 cfg[configSize++] = 0x00; | |
67 cfg[configSize++] = 0x00; | |
68 cfg[configSize++] = 0x01; | |
69 configSize += av_base64_decode( (uint8_t*)&cfg[configSize], | |
70 psz, | |
71 5 * strlen(dup) - 3 ); | |
72 | |
73 psz += strlen(psz)+1; | |
74 } | |
32537
8fa2f43cb760
Remove most of the NULL pointer check before free all over the code
cboesch
parents:
32142
diff
changeset
|
75 free( dup ); |
22852 | 76 |
77 return cfg; | |
9250 | 78 } |
79 | |
9565
e74916774667
Improved RTP packet buffering, by relying on the underlying OS's UDP
rsf
parents:
9370
diff
changeset
|
80 static void |
e74916774667
Improved RTP packet buffering, by relying on the underlying OS's UDP
rsf
parents:
9370
diff
changeset
|
81 needVideoFrameRate(demuxer_t* demuxer, MediaSubsession* subsession); // forward |
9250 | 82 static Boolean |
83 parseQTState_video(QuickTimeGenericRTPSource::QTState const& qtState, | |
84 unsigned& fourcc); // forward | |
85 static Boolean | |
86 parseQTState_audio(QuickTimeGenericRTPSource::QTState const& qtState, | |
87 unsigned& fourcc, unsigned& numChannels); // forward | |
29263
0f1b5b68af32
whitespace cosmetics: Remove all trailing whitespace.
diego
parents:
29238
diff
changeset
|
88 |
22278
ac8ac9e3761d
insert extradata in sh_video->bih+1 instead of pushing it to demuxer->video as separate packet; patch by C.E.Hoyos
nicodvb
parents:
22235
diff
changeset
|
89 static BITMAPINFOHEADER * insertVideoExtradata(BITMAPINFOHEADER *bih, |
ac8ac9e3761d
insert extradata in sh_video->bih+1 instead of pushing it to demuxer->video as separate packet; patch by C.E.Hoyos
nicodvb
parents:
22235
diff
changeset
|
90 unsigned char * extraData, |
ac8ac9e3761d
insert extradata in sh_video->bih+1 instead of pushing it to demuxer->video as separate packet; patch by C.E.Hoyos
nicodvb
parents:
22235
diff
changeset
|
91 unsigned size) |
ac8ac9e3761d
insert extradata in sh_video->bih+1 instead of pushing it to demuxer->video as separate packet; patch by C.E.Hoyos
nicodvb
parents:
22235
diff
changeset
|
92 { |
ac8ac9e3761d
insert extradata in sh_video->bih+1 instead of pushing it to demuxer->video as separate packet; patch by C.E.Hoyos
nicodvb
parents:
22235
diff
changeset
|
93 BITMAPINFOHEADER * original = bih; |
ac8ac9e3761d
insert extradata in sh_video->bih+1 instead of pushing it to demuxer->video as separate packet; patch by C.E.Hoyos
nicodvb
parents:
22235
diff
changeset
|
94 if (!size || size > INT_MAX - sizeof(BITMAPINFOHEADER)) |
ac8ac9e3761d
insert extradata in sh_video->bih+1 instead of pushing it to demuxer->video as separate packet; patch by C.E.Hoyos
nicodvb
parents:
22235
diff
changeset
|
95 return bih; |
ac8ac9e3761d
insert extradata in sh_video->bih+1 instead of pushing it to demuxer->video as separate packet; patch by C.E.Hoyos
nicodvb
parents:
22235
diff
changeset
|
96 bih = (BITMAPINFOHEADER*)realloc(bih, sizeof(BITMAPINFOHEADER) + size); |
ac8ac9e3761d
insert extradata in sh_video->bih+1 instead of pushing it to demuxer->video as separate packet; patch by C.E.Hoyos
nicodvb
parents:
22235
diff
changeset
|
97 if (!bih) |
ac8ac9e3761d
insert extradata in sh_video->bih+1 instead of pushing it to demuxer->video as separate packet; patch by C.E.Hoyos
nicodvb
parents:
22235
diff
changeset
|
98 return original; |
ac8ac9e3761d
insert extradata in sh_video->bih+1 instead of pushing it to demuxer->video as separate packet; patch by C.E.Hoyos
nicodvb
parents:
22235
diff
changeset
|
99 bih->biSize = sizeof(BITMAPINFOHEADER) + size; |
ac8ac9e3761d
insert extradata in sh_video->bih+1 instead of pushing it to demuxer->video as separate packet; patch by C.E.Hoyos
nicodvb
parents:
22235
diff
changeset
|
100 memcpy(bih+1, extraData, size); |
ac8ac9e3761d
insert extradata in sh_video->bih+1 instead of pushing it to demuxer->video as separate packet; patch by C.E.Hoyos
nicodvb
parents:
22235
diff
changeset
|
101 return bih; |
ac8ac9e3761d
insert extradata in sh_video->bih+1 instead of pushing it to demuxer->video as separate packet; patch by C.E.Hoyos
nicodvb
parents:
22235
diff
changeset
|
102 } |
ac8ac9e3761d
insert extradata in sh_video->bih+1 instead of pushing it to demuxer->video as separate packet; patch by C.E.Hoyos
nicodvb
parents:
22235
diff
changeset
|
103 |
9250 | 104 void rtpCodecInitialize_video(demuxer_t* demuxer, |
105 MediaSubsession* subsession, | |
106 unsigned& flags) { | |
107 flags = 0; | |
108 // Create a dummy video stream header | |
109 // to make the main MPlayer code happy: | |
110 sh_video_t* sh_video = new_sh_video(demuxer,0); | |
111 BITMAPINFOHEADER* bih | |
112 = (BITMAPINFOHEADER*)calloc(1,sizeof(BITMAPINFOHEADER)); | |
113 bih->biSize = sizeof(BITMAPINFOHEADER); | |
114 sh_video->bih = bih; | |
115 demux_stream_t* d_video = demuxer->video; | |
116 d_video->sh = sh_video; sh_video->ds = d_video; | |
29263
0f1b5b68af32
whitespace cosmetics: Remove all trailing whitespace.
diego
parents:
29238
diff
changeset
|
117 |
9250 | 118 // Map known video MIME types to the BITMAPINFOHEADER parameters |
119 // that this program uses. (Note that not all types need all | |
120 // of the parameters to be set.) | |
10478
b0d0aa726417
Added support for the "L16" and "L8" (raw PCM audio) RTP payload formats.
rsf
parents:
9910
diff
changeset
|
121 if (strcmp(subsession->codecName(), "MPV") == 0) { |
9565
e74916774667
Improved RTP packet buffering, by relying on the underlying OS's UDP
rsf
parents:
9370
diff
changeset
|
122 flags |= RTPSTATE_IS_MPEG12_VIDEO; |
10478
b0d0aa726417
Added support for the "L16" and "L8" (raw PCM audio) RTP payload formats.
rsf
parents:
9910
diff
changeset
|
123 } else if (strcmp(subsession->codecName(), "MP1S") == 0 || |
b0d0aa726417
Added support for the "L16" and "L8" (raw PCM audio) RTP payload formats.
rsf
parents:
9910
diff
changeset
|
124 strcmp(subsession->codecName(), "MP2T") == 0) { |
b0d0aa726417
Added support for the "L16" and "L8" (raw PCM audio) RTP payload formats.
rsf
parents:
9910
diff
changeset
|
125 flags |= RTPSTATE_IS_MPEG12_VIDEO|RTPSTATE_IS_MULTIPLEXED; |
9250 | 126 } else if (strcmp(subsession->codecName(), "H263") == 0 || |
22211 | 127 strcmp(subsession->codecName(), "H263-2000") == 0 || |
9250 | 128 strcmp(subsession->codecName(), "H263-1998") == 0) { |
129 bih->biCompression = sh_video->format | |
130 = mmioFOURCC('H','2','6','3'); | |
9565
e74916774667
Improved RTP packet buffering, by relying on the underlying OS's UDP
rsf
parents:
9370
diff
changeset
|
131 needVideoFrameRate(demuxer, subsession); |
19415 | 132 } else if (strcmp(subsession->codecName(), "H264") == 0) { |
133 bih->biCompression = sh_video->format | |
134 = mmioFOURCC('H','2','6','4'); | |
22852 | 135 unsigned int configLen = 0; |
136 unsigned char* configData | |
137 = parseH264ConfigStr(subsession->fmtp_spropparametersets(), configLen); | |
138 sh_video->bih = bih = insertVideoExtradata(bih, configData, configLen); | |
32142
4614728cab25
build system: Merge all FFmpeg library checks into a single FFmpeg check.
diego
parents:
31627
diff
changeset
|
139 #ifdef CONFIG_FFMPEG |
31071
adf57737978c
Silence permanent warning messages when decoding H264 over rtsp with
cehoyos
parents:
29892
diff
changeset
|
140 int fooLen; |
adf57737978c
Silence permanent warning messages when decoding H264 over rtsp with
cehoyos
parents:
29892
diff
changeset
|
141 const uint8_t* fooData; |
24103
d44e23b469a3
Fix compilation of live555 support after FFmpegs r10173.
cehoyos
parents:
22852
diff
changeset
|
142 avcodec_register_all(); |
22852 | 143 h264parserctx = av_parser_init(CODEC_ID_H264); |
34566
f3d53cd55376
Update deprecated avcodec_alloc_context()/avcodec_open() API calls
siretart
parents:
34173
diff
changeset
|
144 avcctx = avcodec_alloc_context3(NULL); |
31071
adf57737978c
Silence permanent warning messages when decoding H264 over rtsp with
cehoyos
parents:
29892
diff
changeset
|
145 // Pass the config to the parser |
adf57737978c
Silence permanent warning messages when decoding H264 over rtsp with
cehoyos
parents:
29892
diff
changeset
|
146 h264parserctx->parser->parser_parse(h264parserctx, avcctx, |
adf57737978c
Silence permanent warning messages when decoding H264 over rtsp with
cehoyos
parents:
29892
diff
changeset
|
147 &fooData, &fooLen, configData, configLen); |
22852 | 148 #endif |
31071
adf57737978c
Silence permanent warning messages when decoding H264 over rtsp with
cehoyos
parents:
29892
diff
changeset
|
149 delete[] configData; |
19415 | 150 needVideoFrameRate(demuxer, subsession); |
9250 | 151 } else if (strcmp(subsession->codecName(), "H261") == 0) { |
152 bih->biCompression = sh_video->format | |
153 = mmioFOURCC('H','2','6','1'); | |
9565
e74916774667
Improved RTP packet buffering, by relying on the underlying OS's UDP
rsf
parents:
9370
diff
changeset
|
154 needVideoFrameRate(demuxer, subsession); |
9370
88bd19564b64
Motion-JPEG RTP streams can now be played. Some MPEG-4 ES video RTP
arpi
parents:
9250
diff
changeset
|
155 } else if (strcmp(subsession->codecName(), "JPEG") == 0) { |
88bd19564b64
Motion-JPEG RTP streams can now be played. Some MPEG-4 ES video RTP
arpi
parents:
9250
diff
changeset
|
156 bih->biCompression = sh_video->format |
88bd19564b64
Motion-JPEG RTP streams can now be played. Some MPEG-4 ES video RTP
arpi
parents:
9250
diff
changeset
|
157 = mmioFOURCC('M','J','P','G'); |
9565
e74916774667
Improved RTP packet buffering, by relying on the underlying OS's UDP
rsf
parents:
9370
diff
changeset
|
158 needVideoFrameRate(demuxer, subsession); |
9370
88bd19564b64
Motion-JPEG RTP streams can now be played. Some MPEG-4 ES video RTP
arpi
parents:
9250
diff
changeset
|
159 } else if (strcmp(subsession->codecName(), "MP4V-ES") == 0) { |
88bd19564b64
Motion-JPEG RTP streams can now be played. Some MPEG-4 ES video RTP
arpi
parents:
9250
diff
changeset
|
160 bih->biCompression = sh_video->format |
88bd19564b64
Motion-JPEG RTP streams can now be played. Some MPEG-4 ES video RTP
arpi
parents:
9250
diff
changeset
|
161 = mmioFOURCC('m','p','4','v'); |
9565
e74916774667
Improved RTP packet buffering, by relying on the underlying OS's UDP
rsf
parents:
9370
diff
changeset
|
162 // For the codec to work correctly, it may need a 'VOL Header' to be |
e74916774667
Improved RTP packet buffering, by relying on the underlying OS's UDP
rsf
parents:
9370
diff
changeset
|
163 // inserted at the front of the data stream. Construct this from the |
e74916774667
Improved RTP packet buffering, by relying on the underlying OS's UDP
rsf
parents:
9370
diff
changeset
|
164 // "config" MIME parameter, which was present (hopefully) in the |
e74916774667
Improved RTP packet buffering, by relying on the underlying OS's UDP
rsf
parents:
9370
diff
changeset
|
165 // session's SDP description: |
e74916774667
Improved RTP packet buffering, by relying on the underlying OS's UDP
rsf
parents:
9370
diff
changeset
|
166 unsigned configLen; |
e74916774667
Improved RTP packet buffering, by relying on the underlying OS's UDP
rsf
parents:
9370
diff
changeset
|
167 unsigned char* configData |
e74916774667
Improved RTP packet buffering, by relying on the underlying OS's UDP
rsf
parents:
9370
diff
changeset
|
168 = parseGeneralConfigStr(subsession->fmtp_config(), configLen); |
22278
ac8ac9e3761d
insert extradata in sh_video->bih+1 instead of pushing it to demuxer->video as separate packet; patch by C.E.Hoyos
nicodvb
parents:
22235
diff
changeset
|
169 sh_video->bih = bih = insertVideoExtradata(bih, configData, configLen); |
9565
e74916774667
Improved RTP packet buffering, by relying on the underlying OS's UDP
rsf
parents:
9370
diff
changeset
|
170 needVideoFrameRate(demuxer, subsession); |
9250 | 171 } else if (strcmp(subsession->codecName(), "X-QT") == 0 || |
172 strcmp(subsession->codecName(), "X-QUICKTIME") == 0) { | |
173 // QuickTime generic RTP format, as described in | |
174 // http://developer.apple.com/quicktime/icefloe/dispatch026.html | |
175 | |
176 // We can't initialize this stream until we've received the first packet | |
177 // that has QuickTime "sdAtom" information in the header. So, keep | |
178 // reading packets until we get one: | |
9565
e74916774667
Improved RTP packet buffering, by relying on the underlying OS's UDP
rsf
parents:
9370
diff
changeset
|
179 unsigned char* packetData; unsigned packetDataLen; float pts; |
9250 | 180 QuickTimeGenericRTPSource* qtRTPSource |
181 = (QuickTimeGenericRTPSource*)(subsession->rtpSource()); | |
182 unsigned fourcc; | |
183 do { | |
9565
e74916774667
Improved RTP packet buffering, by relying on the underlying OS's UDP
rsf
parents:
9370
diff
changeset
|
184 if (!awaitRTPPacket(demuxer, demuxer->video, |
e74916774667
Improved RTP packet buffering, by relying on the underlying OS's UDP
rsf
parents:
9370
diff
changeset
|
185 packetData, packetDataLen, pts)) { |
9250 | 186 return; |
187 } | |
188 } while (!parseQTState_video(qtRTPSource->qtState, fourcc)); | |
189 | |
190 bih->biCompression = sh_video->format = fourcc; | |
21871 | 191 bih->biWidth = qtRTPSource->qtState.width; |
192 bih->biHeight = qtRTPSource->qtState.height; | |
29435 | 193 if (qtRTPSource->qtState.sdAtomSize > 83) |
194 bih->biBitCount = qtRTPSource->qtState.sdAtom[83]; | |
21871 | 195 uint8_t *pos = (uint8_t*)qtRTPSource->qtState.sdAtom + 86; |
196 uint8_t *endpos = (uint8_t*)qtRTPSource->qtState.sdAtom | |
197 + qtRTPSource->qtState.sdAtomSize; | |
198 while (pos+8 < endpos) { | |
199 unsigned atomLength = pos[0]<<24 | pos[1]<<16 | pos[2]<<8 | pos[3]; | |
200 if (atomLength == 0 || atomLength > endpos-pos) break; | |
29892
ecf6cbab0b8d
Silence two gcc warnings: suggest parentheses around && within ||
cehoyos
parents:
29453
diff
changeset
|
201 if (((!memcmp(pos+4, "avcC", 4) && fourcc==mmioFOURCC('a','v','c','1')) || |
29263
0f1b5b68af32
whitespace cosmetics: Remove all trailing whitespace.
diego
parents:
29238
diff
changeset
|
202 !memcmp(pos+4, "esds", 4) || |
29892
ecf6cbab0b8d
Silence two gcc warnings: suggest parentheses around && within ||
cehoyos
parents:
29453
diff
changeset
|
203 (!memcmp(pos+4, "SMI ", 4) && fourcc==mmioFOURCC('S','V','Q','3'))) && |
22278
ac8ac9e3761d
insert extradata in sh_video->bih+1 instead of pushing it to demuxer->video as separate packet; patch by C.E.Hoyos
nicodvb
parents:
22235
diff
changeset
|
204 atomLength > 8) { |
29263
0f1b5b68af32
whitespace cosmetics: Remove all trailing whitespace.
diego
parents:
29238
diff
changeset
|
205 sh_video->bih = bih = |
22278
ac8ac9e3761d
insert extradata in sh_video->bih+1 instead of pushing it to demuxer->video as separate packet; patch by C.E.Hoyos
nicodvb
parents:
22235
diff
changeset
|
206 insertVideoExtradata(bih, pos+8, atomLength-8); |
21871 | 207 break; |
208 } | |
209 pos += atomLength; | |
210 } | |
22756
3d6a64f3d28f
Every X-QT stream needs video frame rate (not just avc, mpeg4 and svq3)
cehoyos
parents:
22463
diff
changeset
|
211 needVideoFrameRate(demuxer, subsession); |
9250 | 212 } else { |
213 fprintf(stderr, | |
214 "Unknown MPlayer format code for MIME type \"video/%s\"\n", | |
215 subsession->codecName()); | |
216 } | |
217 } | |
218 | |
219 void rtpCodecInitialize_audio(demuxer_t* demuxer, | |
220 MediaSubsession* subsession, | |
221 unsigned& flags) { | |
222 flags = 0; | |
223 // Create a dummy audio stream header | |
224 // to make the main MPlayer code happy: | |
31627 | 225 sh_audio_t* sh_audio = new_sh_audio(demuxer,0, NULL); |
9250 | 226 WAVEFORMATEX* wf = (WAVEFORMATEX*)calloc(1,sizeof(WAVEFORMATEX)); |
227 sh_audio->wf = wf; | |
228 demux_stream_t* d_audio = demuxer->audio; | |
229 d_audio->sh = sh_audio; sh_audio->ds = d_audio; | |
27417 | 230 d_audio->id = sh_audio->aid; |
29263
0f1b5b68af32
whitespace cosmetics: Remove all trailing whitespace.
diego
parents:
29238
diff
changeset
|
231 |
9565
e74916774667
Improved RTP packet buffering, by relying on the underlying OS's UDP
rsf
parents:
9370
diff
changeset
|
232 wf->nChannels = subsession->numChannels(); |
e74916774667
Improved RTP packet buffering, by relying on the underlying OS's UDP
rsf
parents:
9370
diff
changeset
|
233 |
9250 | 234 // Map known audio MIME types to the WAVEFORMATEX parameters |
235 // that this program uses. (Note that not all types need all | |
236 // of the parameters to be set.) | |
237 wf->nSamplesPerSec | |
238 = subsession->rtpSource()->timestampFrequency(); // by default | |
239 if (strcmp(subsession->codecName(), "MPA") == 0 || | |
240 strcmp(subsession->codecName(), "MPA-ROBUST") == 0 || | |
241 strcmp(subsession->codecName(), "X-MP3-DRAFT-00") == 0) { | |
242 wf->wFormatTag = sh_audio->format = 0x55; | |
243 // Note: 0x55 is for layer III, but should work for I,II also | |
244 wf->nSamplesPerSec = 0; // sample rate is deduced from the data | |
245 } else if (strcmp(subsession->codecName(), "AC3") == 0) { | |
246 wf->wFormatTag = sh_audio->format = 0x2000; | |
247 wf->nSamplesPerSec = 0; // sample rate is deduced from the data | |
10478
b0d0aa726417
Added support for the "L16" and "L8" (raw PCM audio) RTP payload formats.
rsf
parents:
9910
diff
changeset
|
248 } else if (strcmp(subsession->codecName(), "L16") == 0) { |
b0d0aa726417
Added support for the "L16" and "L8" (raw PCM audio) RTP payload formats.
rsf
parents:
9910
diff
changeset
|
249 wf->wFormatTag = sh_audio->format = 0x736f7774; // "twos" |
b0d0aa726417
Added support for the "L16" and "L8" (raw PCM audio) RTP payload formats.
rsf
parents:
9910
diff
changeset
|
250 wf->nBlockAlign = 1; |
b0d0aa726417
Added support for the "L16" and "L8" (raw PCM audio) RTP payload formats.
rsf
parents:
9910
diff
changeset
|
251 wf->wBitsPerSample = 16; |
b0d0aa726417
Added support for the "L16" and "L8" (raw PCM audio) RTP payload formats.
rsf
parents:
9910
diff
changeset
|
252 wf->cbSize = 0; |
b0d0aa726417
Added support for the "L16" and "L8" (raw PCM audio) RTP payload formats.
rsf
parents:
9910
diff
changeset
|
253 } else if (strcmp(subsession->codecName(), "L8") == 0) { |
b0d0aa726417
Added support for the "L16" and "L8" (raw PCM audio) RTP payload formats.
rsf
parents:
9910
diff
changeset
|
254 wf->wFormatTag = sh_audio->format = 0x20776172; // "raw " |
b0d0aa726417
Added support for the "L16" and "L8" (raw PCM audio) RTP payload formats.
rsf
parents:
9910
diff
changeset
|
255 wf->nBlockAlign = 1; |
b0d0aa726417
Added support for the "L16" and "L8" (raw PCM audio) RTP payload formats.
rsf
parents:
9910
diff
changeset
|
256 wf->wBitsPerSample = 8; |
b0d0aa726417
Added support for the "L16" and "L8" (raw PCM audio) RTP payload formats.
rsf
parents:
9910
diff
changeset
|
257 wf->cbSize = 0; |
9250 | 258 } else if (strcmp(subsession->codecName(), "PCMU") == 0) { |
259 wf->wFormatTag = sh_audio->format = 0x7; | |
260 wf->nAvgBytesPerSec = 8000; | |
261 wf->nBlockAlign = 1; | |
262 wf->wBitsPerSample = 8; | |
263 wf->cbSize = 0; | |
264 } else if (strcmp(subsession->codecName(), "PCMA") == 0) { | |
265 wf->wFormatTag = sh_audio->format = 0x6; | |
266 wf->nAvgBytesPerSec = 8000; | |
267 wf->nBlockAlign = 1; | |
268 wf->wBitsPerSample = 8; | |
269 wf->cbSize = 0; | |
22463
979b2aa16e80
support for AMR; it works inserting in the first byte of the demux_packet
nicodvb
parents:
22354
diff
changeset
|
270 } else if (strcmp(subsession->codecName(), "AMR") == 0) { |
979b2aa16e80
support for AMR; it works inserting in the first byte of the demux_packet
nicodvb
parents:
22354
diff
changeset
|
271 wf->wFormatTag = sh_audio->format = mmioFOURCC('s','a','m','r'); |
979b2aa16e80
support for AMR; it works inserting in the first byte of the demux_packet
nicodvb
parents:
22354
diff
changeset
|
272 } else if (strcmp(subsession->codecName(), "AMR-WB") == 0) { |
979b2aa16e80
support for AMR; it works inserting in the first byte of the demux_packet
nicodvb
parents:
22354
diff
changeset
|
273 wf->wFormatTag = sh_audio->format = mmioFOURCC('s','a','w','b'); |
9250 | 274 } else if (strcmp(subsession->codecName(), "GSM") == 0) { |
275 wf->wFormatTag = sh_audio->format = mmioFOURCC('a','g','s','m'); | |
276 wf->nAvgBytesPerSec = 1650; | |
277 wf->nBlockAlign = 33; | |
278 wf->wBitsPerSample = 16; | |
279 wf->cbSize = 0; | |
280 } else if (strcmp(subsession->codecName(), "QCELP") == 0) { | |
281 wf->wFormatTag = sh_audio->format = mmioFOURCC('Q','c','l','p'); | |
282 wf->nAvgBytesPerSec = 1750; | |
283 wf->nBlockAlign = 35; | |
284 wf->wBitsPerSample = 16; | |
285 wf->cbSize = 0; | |
286 } else if (strcmp(subsession->codecName(), "MP4A-LATM") == 0) { | |
287 wf->wFormatTag = sh_audio->format = mmioFOURCC('m','p','4','a'); | |
288 // For the codec to work correctly, it needs "AudioSpecificConfig" | |
289 // data, which is parsed from the "StreamMuxConfig" string that | |
290 // was present (hopefully) in the SDP description: | |
291 unsigned codecdata_len; | |
292 sh_audio->codecdata | |
293 = parseStreamMuxConfigStr(subsession->fmtp_config(), | |
294 codecdata_len); | |
295 sh_audio->codecdata_len = codecdata_len; | |
22235
583926af08ac
omit length field of AAC-LATM audio streams; fixes decoding by faad. Patch by Carl Eugen Hoyos (cehoyos ag or at)
nicodvb
parents:
22211
diff
changeset
|
296 //faad doesn't understand LATM's data length field, so omit it |
583926af08ac
omit length field of AAC-LATM audio streams; fixes decoding by faad. Patch by Carl Eugen Hoyos (cehoyos ag or at)
nicodvb
parents:
22211
diff
changeset
|
297 ((MPEG4LATMAudioRTPSource*)subsession->rtpSource())->omitLATMDataLengthField(); |
9565
e74916774667
Improved RTP packet buffering, by relying on the underlying OS's UDP
rsf
parents:
9370
diff
changeset
|
298 } else if (strcmp(subsession->codecName(), "MPEG4-GENERIC") == 0) { |
e74916774667
Improved RTP packet buffering, by relying on the underlying OS's UDP
rsf
parents:
9370
diff
changeset
|
299 wf->wFormatTag = sh_audio->format = mmioFOURCC('m','p','4','a'); |
e74916774667
Improved RTP packet buffering, by relying on the underlying OS's UDP
rsf
parents:
9370
diff
changeset
|
300 // For the codec to work correctly, it needs "AudioSpecificConfig" |
e74916774667
Improved RTP packet buffering, by relying on the underlying OS's UDP
rsf
parents:
9370
diff
changeset
|
301 // data, which was present (hopefully) in the SDP description: |
e74916774667
Improved RTP packet buffering, by relying on the underlying OS's UDP
rsf
parents:
9370
diff
changeset
|
302 unsigned codecdata_len; |
e74916774667
Improved RTP packet buffering, by relying on the underlying OS's UDP
rsf
parents:
9370
diff
changeset
|
303 sh_audio->codecdata |
e74916774667
Improved RTP packet buffering, by relying on the underlying OS's UDP
rsf
parents:
9370
diff
changeset
|
304 = parseGeneralConfigStr(subsession->fmtp_config(), |
e74916774667
Improved RTP packet buffering, by relying on the underlying OS's UDP
rsf
parents:
9370
diff
changeset
|
305 codecdata_len); |
e74916774667
Improved RTP packet buffering, by relying on the underlying OS's UDP
rsf
parents:
9370
diff
changeset
|
306 sh_audio->codecdata_len = codecdata_len; |
9250 | 307 } else if (strcmp(subsession->codecName(), "X-QT") == 0 || |
308 strcmp(subsession->codecName(), "X-QUICKTIME") == 0) { | |
309 // QuickTime generic RTP format, as described in | |
310 // http://developer.apple.com/quicktime/icefloe/dispatch026.html | |
311 | |
312 // We can't initialize this stream until we've received the first packet | |
313 // that has QuickTime "sdAtom" information in the header. So, keep | |
314 // reading packets until we get one: | |
9565
e74916774667
Improved RTP packet buffering, by relying on the underlying OS's UDP
rsf
parents:
9370
diff
changeset
|
315 unsigned char* packetData; unsigned packetDataLen; float pts; |
9250 | 316 QuickTimeGenericRTPSource* qtRTPSource |
317 = (QuickTimeGenericRTPSource*)(subsession->rtpSource()); | |
318 unsigned fourcc, numChannels; | |
319 do { | |
9565
e74916774667
Improved RTP packet buffering, by relying on the underlying OS's UDP
rsf
parents:
9370
diff
changeset
|
320 if (!awaitRTPPacket(demuxer, demuxer->audio, |
e74916774667
Improved RTP packet buffering, by relying on the underlying OS's UDP
rsf
parents:
9370
diff
changeset
|
321 packetData, packetDataLen, pts)) { |
9250 | 322 return; |
323 } | |
324 } while (!parseQTState_audio(qtRTPSource->qtState, fourcc, numChannels)); | |
325 | |
326 wf->wFormatTag = sh_audio->format = fourcc; | |
327 wf->nChannels = numChannels; | |
22336
760c74c078ce
copy the content of QDM2 atom as extradata for ffqdm2 playback; patch by Carl Eugen Hoyos
nicodvb
parents:
22278
diff
changeset
|
328 |
29448
80c6dd85f7f8
Parse BitsPerSample and SamplesPerSec when playing PCM in X-QT over
cehoyos
parents:
29435
diff
changeset
|
329 if (qtRTPSource->qtState.sdAtomSize > 33) { |
80c6dd85f7f8
Parse BitsPerSample and SamplesPerSec when playing PCM in X-QT over
cehoyos
parents:
29435
diff
changeset
|
330 wf->wBitsPerSample = qtRTPSource->qtState.sdAtom[27]; |
80c6dd85f7f8
Parse BitsPerSample and SamplesPerSec when playing PCM in X-QT over
cehoyos
parents:
29435
diff
changeset
|
331 wf->nSamplesPerSec = qtRTPSource->qtState.sdAtom[32]<<8|qtRTPSource->qtState.sdAtom[33]; |
80c6dd85f7f8
Parse BitsPerSample and SamplesPerSec when playing PCM in X-QT over
cehoyos
parents:
29435
diff
changeset
|
332 } |
22336
760c74c078ce
copy the content of QDM2 atom as extradata for ffqdm2 playback; patch by Carl Eugen Hoyos
nicodvb
parents:
22278
diff
changeset
|
333 uint8_t *pos = (uint8_t*)qtRTPSource->qtState.sdAtom + 52; |
760c74c078ce
copy the content of QDM2 atom as extradata for ffqdm2 playback; patch by Carl Eugen Hoyos
nicodvb
parents:
22278
diff
changeset
|
334 uint8_t *endpos = (uint8_t*)qtRTPSource->qtState.sdAtom |
760c74c078ce
copy the content of QDM2 atom as extradata for ffqdm2 playback; patch by Carl Eugen Hoyos
nicodvb
parents:
22278
diff
changeset
|
335 + qtRTPSource->qtState.sdAtomSize; |
760c74c078ce
copy the content of QDM2 atom as extradata for ffqdm2 playback; patch by Carl Eugen Hoyos
nicodvb
parents:
22278
diff
changeset
|
336 while (pos+8 < endpos) { |
760c74c078ce
copy the content of QDM2 atom as extradata for ffqdm2 playback; patch by Carl Eugen Hoyos
nicodvb
parents:
22278
diff
changeset
|
337 unsigned atomLength = pos[0]<<24 | pos[1]<<16 | pos[2]<<8 | pos[3]; |
760c74c078ce
copy the content of QDM2 atom as extradata for ffqdm2 playback; patch by Carl Eugen Hoyos
nicodvb
parents:
22278
diff
changeset
|
338 if (atomLength == 0 || atomLength > endpos-pos) break; |
760c74c078ce
copy the content of QDM2 atom as extradata for ffqdm2 playback; patch by Carl Eugen Hoyos
nicodvb
parents:
22278
diff
changeset
|
339 if (!memcmp(pos+4, "wave", 4) && fourcc==mmioFOURCC('Q','D','M','2') && |
760c74c078ce
copy the content of QDM2 atom as extradata for ffqdm2 playback; patch by Carl Eugen Hoyos
nicodvb
parents:
22278
diff
changeset
|
340 atomLength > 8 && |
760c74c078ce
copy the content of QDM2 atom as extradata for ffqdm2 playback; patch by Carl Eugen Hoyos
nicodvb
parents:
22278
diff
changeset
|
341 atomLength <= INT_MAX) { |
760c74c078ce
copy the content of QDM2 atom as extradata for ffqdm2 playback; patch by Carl Eugen Hoyos
nicodvb
parents:
22278
diff
changeset
|
342 sh_audio->codecdata = (unsigned char*) malloc(atomLength-8); |
760c74c078ce
copy the content of QDM2 atom as extradata for ffqdm2 playback; patch by Carl Eugen Hoyos
nicodvb
parents:
22278
diff
changeset
|
343 if (sh_audio->codecdata) { |
760c74c078ce
copy the content of QDM2 atom as extradata for ffqdm2 playback; patch by Carl Eugen Hoyos
nicodvb
parents:
22278
diff
changeset
|
344 memcpy(sh_audio->codecdata, pos+8, atomLength-8); |
760c74c078ce
copy the content of QDM2 atom as extradata for ffqdm2 playback; patch by Carl Eugen Hoyos
nicodvb
parents:
22278
diff
changeset
|
345 sh_audio->codecdata_len = atomLength-8; |
760c74c078ce
copy the content of QDM2 atom as extradata for ffqdm2 playback; patch by Carl Eugen Hoyos
nicodvb
parents:
22278
diff
changeset
|
346 } |
760c74c078ce
copy the content of QDM2 atom as extradata for ffqdm2 playback; patch by Carl Eugen Hoyos
nicodvb
parents:
22278
diff
changeset
|
347 break; |
760c74c078ce
copy the content of QDM2 atom as extradata for ffqdm2 playback; patch by Carl Eugen Hoyos
nicodvb
parents:
22278
diff
changeset
|
348 } |
760c74c078ce
copy the content of QDM2 atom as extradata for ffqdm2 playback; patch by Carl Eugen Hoyos
nicodvb
parents:
22278
diff
changeset
|
349 pos += atomLength; |
760c74c078ce
copy the content of QDM2 atom as extradata for ffqdm2 playback; patch by Carl Eugen Hoyos
nicodvb
parents:
22278
diff
changeset
|
350 } |
9250 | 351 } else { |
352 fprintf(stderr, | |
353 "Unknown MPlayer format code for MIME type \"audio/%s\"\n", | |
354 subsession->codecName()); | |
355 } | |
356 } | |
357 | |
9565
e74916774667
Improved RTP packet buffering, by relying on the underlying OS's UDP
rsf
parents:
9370
diff
changeset
|
358 static void needVideoFrameRate(demuxer_t* demuxer, |
e74916774667
Improved RTP packet buffering, by relying on the underlying OS's UDP
rsf
parents:
9370
diff
changeset
|
359 MediaSubsession* subsession) { |
e74916774667
Improved RTP packet buffering, by relying on the underlying OS's UDP
rsf
parents:
9370
diff
changeset
|
360 // For some codecs, MPlayer's decoding software can't (or refuses to :-) |
e74916774667
Improved RTP packet buffering, by relying on the underlying OS's UDP
rsf
parents:
9370
diff
changeset
|
361 // figure out the frame rate by itself, so (unless the user specifies |
e74916774667
Improved RTP packet buffering, by relying on the underlying OS's UDP
rsf
parents:
9370
diff
changeset
|
362 // it manually, using "-fps") we figure it out ourselves here, using the |
e74916774667
Improved RTP packet buffering, by relying on the underlying OS's UDP
rsf
parents:
9370
diff
changeset
|
363 // presentation timestamps in successive packets, |
34173
a5d8b198c214
demux_rtp: Replace extern declarations by proper header #includes.
diego
parents:
32537
diff
changeset
|
364 if (force_fps != 0.0) return; // user used "-fps" |
9565
e74916774667
Improved RTP packet buffering, by relying on the underlying OS's UDP
rsf
parents:
9370
diff
changeset
|
365 |
e74916774667
Improved RTP packet buffering, by relying on the underlying OS's UDP
rsf
parents:
9370
diff
changeset
|
366 demux_stream_t* d_video = demuxer->video; |
9910 | 367 sh_video_t* sh_video = (sh_video_t*)(d_video->sh); |
9565
e74916774667
Improved RTP packet buffering, by relying on the underlying OS's UDP
rsf
parents:
9370
diff
changeset
|
368 |
e74916774667
Improved RTP packet buffering, by relying on the underlying OS's UDP
rsf
parents:
9370
diff
changeset
|
369 // If we already know the subsession's video frame rate, use it: |
e74916774667
Improved RTP packet buffering, by relying on the underlying OS's UDP
rsf
parents:
9370
diff
changeset
|
370 int fps = (int)(subsession->videoFPS()); |
e74916774667
Improved RTP packet buffering, by relying on the underlying OS's UDP
rsf
parents:
9370
diff
changeset
|
371 if (fps != 0) { |
e74916774667
Improved RTP packet buffering, by relying on the underlying OS's UDP
rsf
parents:
9370
diff
changeset
|
372 sh_video->fps = fps; |
22354
b465e5be1a53
assign missing frametime as 1.0/fps; patch by Carl Eigen Hoyos
nicodvb
parents:
22336
diff
changeset
|
373 sh_video->frametime = 1.0f/fps; |
9565
e74916774667
Improved RTP packet buffering, by relying on the underlying OS's UDP
rsf
parents:
9370
diff
changeset
|
374 return; |
e74916774667
Improved RTP packet buffering, by relying on the underlying OS's UDP
rsf
parents:
9370
diff
changeset
|
375 } |
29263
0f1b5b68af32
whitespace cosmetics: Remove all trailing whitespace.
diego
parents:
29238
diff
changeset
|
376 |
9565
e74916774667
Improved RTP packet buffering, by relying on the underlying OS's UDP
rsf
parents:
9370
diff
changeset
|
377 // Keep looking at incoming frames until we see two with different, |
e74916774667
Improved RTP packet buffering, by relying on the underlying OS's UDP
rsf
parents:
9370
diff
changeset
|
378 // non-zero "pts" timestamps: |
e74916774667
Improved RTP packet buffering, by relying on the underlying OS's UDP
rsf
parents:
9370
diff
changeset
|
379 unsigned char* packetData; unsigned packetDataLen; |
e74916774667
Improved RTP packet buffering, by relying on the underlying OS's UDP
rsf
parents:
9370
diff
changeset
|
380 float lastPTS = 0.0, curPTS; |
11397
d0db11b74e82
Increased the threshold for how many incoming frames to look at while guessing
rsf
parents:
10478
diff
changeset
|
381 unsigned const maxNumFramesToWaitFor = 300; |
21983
a6b624360aef
better autodetection of framerate in case of h264; it works correctly with b-frames.
nicodvb
parents:
21911
diff
changeset
|
382 int lastfps = 0; |
9565
e74916774667
Improved RTP packet buffering, by relying on the underlying OS's UDP
rsf
parents:
9370
diff
changeset
|
383 for (unsigned i = 0; i < maxNumFramesToWaitFor; ++i) { |
9910 | 384 if (!awaitRTPPacket(demuxer, d_video, packetData, packetDataLen, curPTS)) { |
385 break; | |
386 } | |
9565
e74916774667
Improved RTP packet buffering, by relying on the underlying OS's UDP
rsf
parents:
9370
diff
changeset
|
387 |
21983
a6b624360aef
better autodetection of framerate in case of h264; it works correctly with b-frames.
nicodvb
parents:
21911
diff
changeset
|
388 if (curPTS != lastPTS && lastPTS != 0.0) { |
9565
e74916774667
Improved RTP packet buffering, by relying on the underlying OS's UDP
rsf
parents:
9370
diff
changeset
|
389 // Use the difference between these two "pts"s to guess the frame rate. |
e74916774667
Improved RTP packet buffering, by relying on the underlying OS's UDP
rsf
parents:
9370
diff
changeset
|
390 // (should really check that there were no missing frames inbetween)##### |
e74916774667
Improved RTP packet buffering, by relying on the underlying OS's UDP
rsf
parents:
9370
diff
changeset
|
391 // Guess the frame rate as an integer. If it's not, use "-fps" instead. |
21983
a6b624360aef
better autodetection of framerate in case of h264; it works correctly with b-frames.
nicodvb
parents:
21911
diff
changeset
|
392 fps = (int)(1/fabs(curPTS-lastPTS) + 0.5); // rounding |
a6b624360aef
better autodetection of framerate in case of h264; it works correctly with b-frames.
nicodvb
parents:
21911
diff
changeset
|
393 if (fps == lastfps) { |
9565
e74916774667
Improved RTP packet buffering, by relying on the underlying OS's UDP
rsf
parents:
9370
diff
changeset
|
394 fprintf(stderr, "demux_rtp: Guessed the video frame rate as %d frames-per-second.\n\t(If this is wrong, use the \"-fps <frame-rate>\" option instead.)\n", fps); |
e74916774667
Improved RTP packet buffering, by relying on the underlying OS's UDP
rsf
parents:
9370
diff
changeset
|
395 sh_video->fps = fps; |
21983
a6b624360aef
better autodetection of framerate in case of h264; it works correctly with b-frames.
nicodvb
parents:
21911
diff
changeset
|
396 sh_video->frametime=1.0f/fps; |
9565
e74916774667
Improved RTP packet buffering, by relying on the underlying OS's UDP
rsf
parents:
9370
diff
changeset
|
397 return; |
21983
a6b624360aef
better autodetection of framerate in case of h264; it works correctly with b-frames.
nicodvb
parents:
21911
diff
changeset
|
398 } |
a6b624360aef
better autodetection of framerate in case of h264; it works correctly with b-frames.
nicodvb
parents:
21911
diff
changeset
|
399 if (fps>lastfps) lastfps = fps; |
9565
e74916774667
Improved RTP packet buffering, by relying on the underlying OS's UDP
rsf
parents:
9370
diff
changeset
|
400 } |
e74916774667
Improved RTP packet buffering, by relying on the underlying OS's UDP
rsf
parents:
9370
diff
changeset
|
401 lastPTS = curPTS; |
e74916774667
Improved RTP packet buffering, by relying on the underlying OS's UDP
rsf
parents:
9370
diff
changeset
|
402 } |
e74916774667
Improved RTP packet buffering, by relying on the underlying OS's UDP
rsf
parents:
9370
diff
changeset
|
403 fprintf(stderr, "demux_rtp: Failed to guess the video frame rate\n"); |
e74916774667
Improved RTP packet buffering, by relying on the underlying OS's UDP
rsf
parents:
9370
diff
changeset
|
404 } |
e74916774667
Improved RTP packet buffering, by relying on the underlying OS's UDP
rsf
parents:
9370
diff
changeset
|
405 |
9250 | 406 static Boolean |
407 parseQTState_video(QuickTimeGenericRTPSource::QTState const& qtState, | |
408 unsigned& fourcc) { | |
409 // qtState's "sdAtom" field is supposed to contain a QuickTime video | |
410 // 'sample description' atom. This atom's name is the 'fourcc' that we want: | |
411 char const* sdAtom = qtState.sdAtom; | |
412 if (sdAtom == NULL || qtState.sdAtomSize < 2*4) return False; | |
413 | |
414 fourcc = *(unsigned*)(&sdAtom[4]); // put in host order | |
415 return True; | |
416 } | |
417 | |
418 static Boolean | |
419 parseQTState_audio(QuickTimeGenericRTPSource::QTState const& qtState, | |
420 unsigned& fourcc, unsigned& numChannels) { | |
421 // qtState's "sdAtom" field is supposed to contain a QuickTime audio | |
422 // 'sample description' atom. This atom's name is the 'fourcc' that we want. | |
423 // Also, the top half of the 5th word following the atom name should | |
424 // contain the number of channels ("numChannels") that we want: | |
425 char const* sdAtom = qtState.sdAtom; | |
426 if (sdAtom == NULL || qtState.sdAtomSize < 7*4) return False; | |
427 | |
428 fourcc = *(unsigned*)(&sdAtom[4]); // put in host order | |
429 | |
430 char const* word7Ptr = &sdAtom[6*4]; | |
431 numChannels = (word7Ptr[0]<<8)|(word7Ptr[1]); | |
432 return True; | |
433 } |