Mercurial > mplayer.hg
annotate libmpdemux/demux_rtp_codec.cpp @ 37003:2d8157b3b386
Fix the index passed to PutImage() for item type itVPotmeter.
Unlike the position for drawing the button (from bottom to top), the
index for the phase image has to be in the usual range, i.e. 0 for 0%
and numphases - 1 for 100%, so that the phase image can be designed
straightforwardly.
Fix the parameter although PutImage() currently doesn't work for item
type itVPotmeter at all.
author | ib |
---|---|
date | Fri, 28 Mar 2014 12:21:07 +0000 |
parents | 92dd1764392a |
children |
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; | |
36811 | 116 d_video->sh = sh_video; |
36800
f3c835ddce85
demuxers: ensure that stream ids are correctly initialized.
reimar
parents:
35715
diff
changeset
|
117 d_video->id = 0; |
29263
0f1b5b68af32
whitespace cosmetics: Remove all trailing whitespace.
diego
parents:
29238
diff
changeset
|
118 |
9250 | 119 // Map known video MIME types to the BITMAPINFOHEADER parameters |
120 // that this program uses. (Note that not all types need all | |
121 // 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
|
122 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
|
123 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
|
124 } 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
|
125 strcmp(subsession->codecName(), "MP2T") == 0) { |
b0d0aa726417
Added support for the "L16" and "L8" (raw PCM audio) RTP payload formats.
rsf
parents:
9910
diff
changeset
|
126 flags |= RTPSTATE_IS_MPEG12_VIDEO|RTPSTATE_IS_MULTIPLEXED; |
9250 | 127 } else if (strcmp(subsession->codecName(), "H263") == 0 || |
22211 | 128 strcmp(subsession->codecName(), "H263-2000") == 0 || |
9250 | 129 strcmp(subsession->codecName(), "H263-1998") == 0) { |
130 bih->biCompression = sh_video->format | |
131 = mmioFOURCC('H','2','6','3'); | |
9565
e74916774667
Improved RTP packet buffering, by relying on the underlying OS's UDP
rsf
parents:
9370
diff
changeset
|
132 needVideoFrameRate(demuxer, subsession); |
19415 | 133 } else if (strcmp(subsession->codecName(), "H264") == 0) { |
134 bih->biCompression = sh_video->format | |
135 = mmioFOURCC('H','2','6','4'); | |
22852 | 136 unsigned int configLen = 0; |
137 unsigned char* configData | |
138 = parseH264ConfigStr(subsession->fmtp_spropparametersets(), configLen); | |
139 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
|
140 #ifdef CONFIG_FFMPEG |
31071
adf57737978c
Silence permanent warning messages when decoding H264 over rtsp with
cehoyos
parents:
29892
diff
changeset
|
141 int fooLen; |
adf57737978c
Silence permanent warning messages when decoding H264 over rtsp with
cehoyos
parents:
29892
diff
changeset
|
142 const uint8_t* fooData; |
24103
d44e23b469a3
Fix compilation of live555 support after FFmpegs r10173.
cehoyos
parents:
22852
diff
changeset
|
143 avcodec_register_all(); |
35715
8517826b0dbd
Replace CODEC_IDs their modern AV_-prefixed counterparts.
diego
parents:
34566
diff
changeset
|
144 h264parserctx = av_parser_init(AV_CODEC_ID_H264); |
34566
f3d53cd55376
Update deprecated avcodec_alloc_context()/avcodec_open() API calls
siretart
parents:
34173
diff
changeset
|
145 avcctx = avcodec_alloc_context3(NULL); |
31071
adf57737978c
Silence permanent warning messages when decoding H264 over rtsp with
cehoyos
parents:
29892
diff
changeset
|
146 // Pass the config to the parser |
adf57737978c
Silence permanent warning messages when decoding H264 over rtsp with
cehoyos
parents:
29892
diff
changeset
|
147 h264parserctx->parser->parser_parse(h264parserctx, avcctx, |
adf57737978c
Silence permanent warning messages when decoding H264 over rtsp with
cehoyos
parents:
29892
diff
changeset
|
148 &fooData, &fooLen, configData, configLen); |
22852 | 149 #endif |
31071
adf57737978c
Silence permanent warning messages when decoding H264 over rtsp with
cehoyos
parents:
29892
diff
changeset
|
150 delete[] configData; |
19415 | 151 needVideoFrameRate(demuxer, subsession); |
9250 | 152 } else if (strcmp(subsession->codecName(), "H261") == 0) { |
153 bih->biCompression = sh_video->format | |
154 = mmioFOURCC('H','2','6','1'); | |
9565
e74916774667
Improved RTP packet buffering, by relying on the underlying OS's UDP
rsf
parents:
9370
diff
changeset
|
155 needVideoFrameRate(demuxer, subsession); |
9370
88bd19564b64
Motion-JPEG RTP streams can now be played. Some MPEG-4 ES video RTP
arpi
parents:
9250
diff
changeset
|
156 } 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
|
157 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
|
158 = mmioFOURCC('M','J','P','G'); |
9565
e74916774667
Improved RTP packet buffering, by relying on the underlying OS's UDP
rsf
parents:
9370
diff
changeset
|
159 needVideoFrameRate(demuxer, subsession); |
9370
88bd19564b64
Motion-JPEG RTP streams can now be played. Some MPEG-4 ES video RTP
arpi
parents:
9250
diff
changeset
|
160 } 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
|
161 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
|
162 = mmioFOURCC('m','p','4','v'); |
9565
e74916774667
Improved RTP packet buffering, by relying on the underlying OS's UDP
rsf
parents:
9370
diff
changeset
|
163 // 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
|
164 // 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
|
165 // "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
|
166 // session's SDP description: |
e74916774667
Improved RTP packet buffering, by relying on the underlying OS's UDP
rsf
parents:
9370
diff
changeset
|
167 unsigned configLen; |
e74916774667
Improved RTP packet buffering, by relying on the underlying OS's UDP
rsf
parents:
9370
diff
changeset
|
168 unsigned char* configData |
e74916774667
Improved RTP packet buffering, by relying on the underlying OS's UDP
rsf
parents:
9370
diff
changeset
|
169 = 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
|
170 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
|
171 needVideoFrameRate(demuxer, subsession); |
9250 | 172 } else if (strcmp(subsession->codecName(), "X-QT") == 0 || |
173 strcmp(subsession->codecName(), "X-QUICKTIME") == 0) { | |
174 // QuickTime generic RTP format, as described in | |
175 // http://developer.apple.com/quicktime/icefloe/dispatch026.html | |
176 | |
177 // We can't initialize this stream until we've received the first packet | |
178 // that has QuickTime "sdAtom" information in the header. So, keep | |
179 // 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
|
180 unsigned char* packetData; unsigned packetDataLen; float pts; |
9250 | 181 QuickTimeGenericRTPSource* qtRTPSource |
182 = (QuickTimeGenericRTPSource*)(subsession->rtpSource()); | |
183 unsigned fourcc; | |
184 do { | |
9565
e74916774667
Improved RTP packet buffering, by relying on the underlying OS's UDP
rsf
parents:
9370
diff
changeset
|
185 if (!awaitRTPPacket(demuxer, demuxer->video, |
e74916774667
Improved RTP packet buffering, by relying on the underlying OS's UDP
rsf
parents:
9370
diff
changeset
|
186 packetData, packetDataLen, pts)) { |
9250 | 187 return; |
188 } | |
189 } while (!parseQTState_video(qtRTPSource->qtState, fourcc)); | |
190 | |
191 bih->biCompression = sh_video->format = fourcc; | |
21871 | 192 bih->biWidth = qtRTPSource->qtState.width; |
193 bih->biHeight = qtRTPSource->qtState.height; | |
29435 | 194 if (qtRTPSource->qtState.sdAtomSize > 83) |
195 bih->biBitCount = qtRTPSource->qtState.sdAtom[83]; | |
21871 | 196 uint8_t *pos = (uint8_t*)qtRTPSource->qtState.sdAtom + 86; |
197 uint8_t *endpos = (uint8_t*)qtRTPSource->qtState.sdAtom | |
198 + qtRTPSource->qtState.sdAtomSize; | |
199 while (pos+8 < endpos) { | |
200 unsigned atomLength = pos[0]<<24 | pos[1]<<16 | pos[2]<<8 | pos[3]; | |
201 if (atomLength == 0 || atomLength > endpos-pos) break; | |
29892
ecf6cbab0b8d
Silence two gcc warnings: suggest parentheses around && within ||
cehoyos
parents:
29453
diff
changeset
|
202 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
|
203 !memcmp(pos+4, "esds", 4) || |
29892
ecf6cbab0b8d
Silence two gcc warnings: suggest parentheses around && within ||
cehoyos
parents:
29453
diff
changeset
|
204 (!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
|
205 atomLength > 8) { |
29263
0f1b5b68af32
whitespace cosmetics: Remove all trailing whitespace.
diego
parents:
29238
diff
changeset
|
206 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
|
207 insertVideoExtradata(bih, pos+8, atomLength-8); |
21871 | 208 break; |
209 } | |
210 pos += atomLength; | |
211 } | |
22756
3d6a64f3d28f
Every X-QT stream needs video frame rate (not just avc, mpeg4 and svq3)
cehoyos
parents:
22463
diff
changeset
|
212 needVideoFrameRate(demuxer, subsession); |
9250 | 213 } else { |
214 fprintf(stderr, | |
215 "Unknown MPlayer format code for MIME type \"video/%s\"\n", | |
216 subsession->codecName()); | |
217 } | |
218 } | |
219 | |
220 void rtpCodecInitialize_audio(demuxer_t* demuxer, | |
221 MediaSubsession* subsession, | |
222 unsigned& flags) { | |
223 flags = 0; | |
224 // Create a dummy audio stream header | |
225 // to make the main MPlayer code happy: | |
31627 | 226 sh_audio_t* sh_audio = new_sh_audio(demuxer,0, NULL); |
9250 | 227 WAVEFORMATEX* wf = (WAVEFORMATEX*)calloc(1,sizeof(WAVEFORMATEX)); |
228 sh_audio->wf = wf; | |
229 demux_stream_t* d_audio = demuxer->audio; | |
36811 | 230 d_audio->sh = sh_audio; |
27417 | 231 d_audio->id = sh_audio->aid; |
29263
0f1b5b68af32
whitespace cosmetics: Remove all trailing whitespace.
diego
parents:
29238
diff
changeset
|
232 |
9565
e74916774667
Improved RTP packet buffering, by relying on the underlying OS's UDP
rsf
parents:
9370
diff
changeset
|
233 wf->nChannels = subsession->numChannels(); |
e74916774667
Improved RTP packet buffering, by relying on the underlying OS's UDP
rsf
parents:
9370
diff
changeset
|
234 |
9250 | 235 // Map known audio MIME types to the WAVEFORMATEX parameters |
236 // that this program uses. (Note that not all types need all | |
237 // of the parameters to be set.) | |
238 wf->nSamplesPerSec | |
239 = subsession->rtpSource()->timestampFrequency(); // by default | |
240 if (strcmp(subsession->codecName(), "MPA") == 0 || | |
241 strcmp(subsession->codecName(), "MPA-ROBUST") == 0 || | |
242 strcmp(subsession->codecName(), "X-MP3-DRAFT-00") == 0) { | |
243 wf->wFormatTag = sh_audio->format = 0x55; | |
244 // Note: 0x55 is for layer III, but should work for I,II also | |
245 wf->nSamplesPerSec = 0; // sample rate is deduced from the data | |
246 } else if (strcmp(subsession->codecName(), "AC3") == 0) { | |
247 wf->wFormatTag = sh_audio->format = 0x2000; | |
248 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
|
249 } 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
|
250 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
|
251 wf->nBlockAlign = 1; |
b0d0aa726417
Added support for the "L16" and "L8" (raw PCM audio) RTP payload formats.
rsf
parents:
9910
diff
changeset
|
252 wf->wBitsPerSample = 16; |
b0d0aa726417
Added support for the "L16" and "L8" (raw PCM audio) RTP payload formats.
rsf
parents:
9910
diff
changeset
|
253 wf->cbSize = 0; |
b0d0aa726417
Added support for the "L16" and "L8" (raw PCM audio) RTP payload formats.
rsf
parents:
9910
diff
changeset
|
254 } 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
|
255 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
|
256 wf->nBlockAlign = 1; |
b0d0aa726417
Added support for the "L16" and "L8" (raw PCM audio) RTP payload formats.
rsf
parents:
9910
diff
changeset
|
257 wf->wBitsPerSample = 8; |
b0d0aa726417
Added support for the "L16" and "L8" (raw PCM audio) RTP payload formats.
rsf
parents:
9910
diff
changeset
|
258 wf->cbSize = 0; |
9250 | 259 } else if (strcmp(subsession->codecName(), "PCMU") == 0) { |
260 wf->wFormatTag = sh_audio->format = 0x7; | |
261 wf->nAvgBytesPerSec = 8000; | |
262 wf->nBlockAlign = 1; | |
263 wf->wBitsPerSample = 8; | |
264 wf->cbSize = 0; | |
265 } else if (strcmp(subsession->codecName(), "PCMA") == 0) { | |
266 wf->wFormatTag = sh_audio->format = 0x6; | |
267 wf->nAvgBytesPerSec = 8000; | |
268 wf->nBlockAlign = 1; | |
269 wf->wBitsPerSample = 8; | |
270 wf->cbSize = 0; | |
22463
979b2aa16e80
support for AMR; it works inserting in the first byte of the demux_packet
nicodvb
parents:
22354
diff
changeset
|
271 } 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
|
272 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
|
273 } 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
|
274 wf->wFormatTag = sh_audio->format = mmioFOURCC('s','a','w','b'); |
9250 | 275 } else if (strcmp(subsession->codecName(), "GSM") == 0) { |
276 wf->wFormatTag = sh_audio->format = mmioFOURCC('a','g','s','m'); | |
277 wf->nAvgBytesPerSec = 1650; | |
278 wf->nBlockAlign = 33; | |
279 wf->wBitsPerSample = 16; | |
280 wf->cbSize = 0; | |
281 } else if (strcmp(subsession->codecName(), "QCELP") == 0) { | |
282 wf->wFormatTag = sh_audio->format = mmioFOURCC('Q','c','l','p'); | |
283 wf->nAvgBytesPerSec = 1750; | |
284 wf->nBlockAlign = 35; | |
285 wf->wBitsPerSample = 16; | |
286 wf->cbSize = 0; | |
287 } else if (strcmp(subsession->codecName(), "MP4A-LATM") == 0) { | |
288 wf->wFormatTag = sh_audio->format = mmioFOURCC('m','p','4','a'); | |
289 // For the codec to work correctly, it needs "AudioSpecificConfig" | |
290 // data, which is parsed from the "StreamMuxConfig" string that | |
291 // was present (hopefully) in the SDP description: | |
292 unsigned codecdata_len; | |
293 sh_audio->codecdata | |
294 = parseStreamMuxConfigStr(subsession->fmtp_config(), | |
295 codecdata_len); | |
296 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
|
297 //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
|
298 ((MPEG4LATMAudioRTPSource*)subsession->rtpSource())->omitLATMDataLengthField(); |
9565
e74916774667
Improved RTP packet buffering, by relying on the underlying OS's UDP
rsf
parents:
9370
diff
changeset
|
299 } 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
|
300 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
|
301 // 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
|
302 // 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
|
303 unsigned codecdata_len; |
e74916774667
Improved RTP packet buffering, by relying on the underlying OS's UDP
rsf
parents:
9370
diff
changeset
|
304 sh_audio->codecdata |
e74916774667
Improved RTP packet buffering, by relying on the underlying OS's UDP
rsf
parents:
9370
diff
changeset
|
305 = parseGeneralConfigStr(subsession->fmtp_config(), |
e74916774667
Improved RTP packet buffering, by relying on the underlying OS's UDP
rsf
parents:
9370
diff
changeset
|
306 codecdata_len); |
e74916774667
Improved RTP packet buffering, by relying on the underlying OS's UDP
rsf
parents:
9370
diff
changeset
|
307 sh_audio->codecdata_len = codecdata_len; |
9250 | 308 } else if (strcmp(subsession->codecName(), "X-QT") == 0 || |
309 strcmp(subsession->codecName(), "X-QUICKTIME") == 0) { | |
310 // QuickTime generic RTP format, as described in | |
311 // http://developer.apple.com/quicktime/icefloe/dispatch026.html | |
312 | |
313 // We can't initialize this stream until we've received the first packet | |
314 // that has QuickTime "sdAtom" information in the header. So, keep | |
315 // 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
|
316 unsigned char* packetData; unsigned packetDataLen; float pts; |
9250 | 317 QuickTimeGenericRTPSource* qtRTPSource |
318 = (QuickTimeGenericRTPSource*)(subsession->rtpSource()); | |
319 unsigned fourcc, numChannels; | |
320 do { | |
9565
e74916774667
Improved RTP packet buffering, by relying on the underlying OS's UDP
rsf
parents:
9370
diff
changeset
|
321 if (!awaitRTPPacket(demuxer, demuxer->audio, |
e74916774667
Improved RTP packet buffering, by relying on the underlying OS's UDP
rsf
parents:
9370
diff
changeset
|
322 packetData, packetDataLen, pts)) { |
9250 | 323 return; |
324 } | |
325 } while (!parseQTState_audio(qtRTPSource->qtState, fourcc, numChannels)); | |
326 | |
327 wf->wFormatTag = sh_audio->format = fourcc; | |
328 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
|
329 |
29448
80c6dd85f7f8
Parse BitsPerSample and SamplesPerSec when playing PCM in X-QT over
cehoyos
parents:
29435
diff
changeset
|
330 if (qtRTPSource->qtState.sdAtomSize > 33) { |
80c6dd85f7f8
Parse BitsPerSample and SamplesPerSec when playing PCM in X-QT over
cehoyos
parents:
29435
diff
changeset
|
331 wf->wBitsPerSample = qtRTPSource->qtState.sdAtom[27]; |
80c6dd85f7f8
Parse BitsPerSample and SamplesPerSec when playing PCM in X-QT over
cehoyos
parents:
29435
diff
changeset
|
332 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
|
333 } |
22336
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 *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
|
335 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
|
336 + 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
|
337 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
|
338 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
|
339 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
|
340 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
|
341 atomLength > 8 && |
760c74c078ce
copy the content of QDM2 atom as extradata for ffqdm2 playback; patch by Carl Eugen Hoyos
nicodvb
parents:
22278
diff
changeset
|
342 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
|
343 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
|
344 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
|
345 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
|
346 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
|
347 } |
760c74c078ce
copy the content of QDM2 atom as extradata for ffqdm2 playback; patch by Carl Eugen Hoyos
nicodvb
parents:
22278
diff
changeset
|
348 break; |
760c74c078ce
copy the content of QDM2 atom as extradata for ffqdm2 playback; patch by Carl Eugen Hoyos
nicodvb
parents:
22278
diff
changeset
|
349 } |
760c74c078ce
copy the content of QDM2 atom as extradata for ffqdm2 playback; patch by Carl Eugen Hoyos
nicodvb
parents:
22278
diff
changeset
|
350 pos += atomLength; |
760c74c078ce
copy the content of QDM2 atom as extradata for ffqdm2 playback; patch by Carl Eugen Hoyos
nicodvb
parents:
22278
diff
changeset
|
351 } |
9250 | 352 } else { |
353 fprintf(stderr, | |
354 "Unknown MPlayer format code for MIME type \"audio/%s\"\n", | |
355 subsession->codecName()); | |
356 } | |
357 } | |
358 | |
9565
e74916774667
Improved RTP packet buffering, by relying on the underlying OS's UDP
rsf
parents:
9370
diff
changeset
|
359 static void needVideoFrameRate(demuxer_t* demuxer, |
e74916774667
Improved RTP packet buffering, by relying on the underlying OS's UDP
rsf
parents:
9370
diff
changeset
|
360 MediaSubsession* subsession) { |
e74916774667
Improved RTP packet buffering, by relying on the underlying OS's UDP
rsf
parents:
9370
diff
changeset
|
361 // 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
|
362 // 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
|
363 // 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
|
364 // presentation timestamps in successive packets, |
34173
a5d8b198c214
demux_rtp: Replace extern declarations by proper header #includes.
diego
parents:
32537
diff
changeset
|
365 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
|
366 |
e74916774667
Improved RTP packet buffering, by relying on the underlying OS's UDP
rsf
parents:
9370
diff
changeset
|
367 demux_stream_t* d_video = demuxer->video; |
9910 | 368 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
|
369 |
e74916774667
Improved RTP packet buffering, by relying on the underlying OS's UDP
rsf
parents:
9370
diff
changeset
|
370 // 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
|
371 int fps = (int)(subsession->videoFPS()); |
e74916774667
Improved RTP packet buffering, by relying on the underlying OS's UDP
rsf
parents:
9370
diff
changeset
|
372 if (fps != 0) { |
e74916774667
Improved RTP packet buffering, by relying on the underlying OS's UDP
rsf
parents:
9370
diff
changeset
|
373 sh_video->fps = fps; |
22354
b465e5be1a53
assign missing frametime as 1.0/fps; patch by Carl Eigen Hoyos
nicodvb
parents:
22336
diff
changeset
|
374 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
|
375 return; |
e74916774667
Improved RTP packet buffering, by relying on the underlying OS's UDP
rsf
parents:
9370
diff
changeset
|
376 } |
29263
0f1b5b68af32
whitespace cosmetics: Remove all trailing whitespace.
diego
parents:
29238
diff
changeset
|
377 |
9565
e74916774667
Improved RTP packet buffering, by relying on the underlying OS's UDP
rsf
parents:
9370
diff
changeset
|
378 // 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
|
379 // non-zero "pts" timestamps: |
e74916774667
Improved RTP packet buffering, by relying on the underlying OS's UDP
rsf
parents:
9370
diff
changeset
|
380 unsigned char* packetData; unsigned packetDataLen; |
e74916774667
Improved RTP packet buffering, by relying on the underlying OS's UDP
rsf
parents:
9370
diff
changeset
|
381 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
|
382 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
|
383 int lastfps = 0; |
9565
e74916774667
Improved RTP packet buffering, by relying on the underlying OS's UDP
rsf
parents:
9370
diff
changeset
|
384 for (unsigned i = 0; i < maxNumFramesToWaitFor; ++i) { |
9910 | 385 if (!awaitRTPPacket(demuxer, d_video, packetData, packetDataLen, curPTS)) { |
386 break; | |
387 } | |
9565
e74916774667
Improved RTP packet buffering, by relying on the underlying OS's UDP
rsf
parents:
9370
diff
changeset
|
388 |
21983
a6b624360aef
better autodetection of framerate in case of h264; it works correctly with b-frames.
nicodvb
parents:
21911
diff
changeset
|
389 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
|
390 // 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
|
391 // (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
|
392 // 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
|
393 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
|
394 if (fps == lastfps) { |
9565
e74916774667
Improved RTP packet buffering, by relying on the underlying OS's UDP
rsf
parents:
9370
diff
changeset
|
395 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
|
396 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
|
397 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
|
398 return; |
21983
a6b624360aef
better autodetection of framerate in case of h264; it works correctly with b-frames.
nicodvb
parents:
21911
diff
changeset
|
399 } |
a6b624360aef
better autodetection of framerate in case of h264; it works correctly with b-frames.
nicodvb
parents:
21911
diff
changeset
|
400 if (fps>lastfps) lastfps = fps; |
9565
e74916774667
Improved RTP packet buffering, by relying on the underlying OS's UDP
rsf
parents:
9370
diff
changeset
|
401 } |
e74916774667
Improved RTP packet buffering, by relying on the underlying OS's UDP
rsf
parents:
9370
diff
changeset
|
402 lastPTS = curPTS; |
e74916774667
Improved RTP packet buffering, by relying on the underlying OS's UDP
rsf
parents:
9370
diff
changeset
|
403 } |
e74916774667
Improved RTP packet buffering, by relying on the underlying OS's UDP
rsf
parents:
9370
diff
changeset
|
404 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
|
405 } |
e74916774667
Improved RTP packet buffering, by relying on the underlying OS's UDP
rsf
parents:
9370
diff
changeset
|
406 |
9250 | 407 static Boolean |
408 parseQTState_video(QuickTimeGenericRTPSource::QTState const& qtState, | |
409 unsigned& fourcc) { | |
410 // qtState's "sdAtom" field is supposed to contain a QuickTime video | |
411 // 'sample description' atom. This atom's name is the 'fourcc' that we want: | |
412 char const* sdAtom = qtState.sdAtom; | |
413 if (sdAtom == NULL || qtState.sdAtomSize < 2*4) return False; | |
414 | |
415 fourcc = *(unsigned*)(&sdAtom[4]); // put in host order | |
416 return True; | |
417 } | |
418 | |
419 static Boolean | |
420 parseQTState_audio(QuickTimeGenericRTPSource::QTState const& qtState, | |
421 unsigned& fourcc, unsigned& numChannels) { | |
422 // qtState's "sdAtom" field is supposed to contain a QuickTime audio | |
423 // 'sample description' atom. This atom's name is the 'fourcc' that we want. | |
424 // Also, the top half of the 5th word following the atom name should | |
425 // contain the number of channels ("numChannels") that we want: | |
426 char const* sdAtom = qtState.sdAtom; | |
427 if (sdAtom == NULL || qtState.sdAtomSize < 7*4) return False; | |
428 | |
429 fourcc = *(unsigned*)(&sdAtom[4]); // put in host order | |
430 | |
431 char const* word7Ptr = &sdAtom[6*4]; | |
432 numChannels = (word7Ptr[0]<<8)|(word7Ptr[1]); | |
433 return True; | |
434 } |