Mercurial > mplayer.hg
annotate libmpdemux/demux_rtp_codec.cpp @ 24515:c5c0cb0e90d2
getch2: Fix incorrect test
Keycode length wasn't checked in one case because of missing
parentheses. This was accidentally broken in my previous commit to the
file. Most likely the error had no practical effect; the length checks
are unreliable in any case as they can be satisfied by unrelated
data corresponding to other keypresses.
author | uau |
---|---|
date | Sat, 15 Sep 2007 18:13:56 +0000 |
parents | d44e23b469a3 |
children | 4cd12675cfbb |
rev | line source |
---|---|
9250 | 1 ////////// Codec-specific routines used to interface between "MPlayer" |
16572
56a5f69e9b35
"LIVE.COM Streaming Media" is now called "LIVE555 Streaming Media".
rsf
parents:
11398
diff
changeset
|
2 ////////// and the "LIVE555 Streaming Media" libraries: |
9250 | 3 |
4 #include "demux_rtp_internal.h" | |
5 extern "C" { | |
21911
e86bb13ec44b
demux_rtp_codec.cpp:100: `INT_MAX' undeclared (first use this function)
diego
parents:
21871
diff
changeset
|
6 #include <limits.h> |
21983
a6b624360aef
better autodetection of framerate in case of h264; it works correctly with b-frames.
nicodvb
parents:
21911
diff
changeset
|
7 #include <math.h> |
9250 | 8 #include "stheader.h" |
22852 | 9 #include "base64.h" |
10 } | |
11 | |
12 #ifdef USE_LIBAVCODEC | |
13 AVCodecParserContext * h264parserctx; | |
14 #endif | |
15 | |
16 // Copied from vlc | |
17 static unsigned char* parseH264ConfigStr( char const* configStr, | |
18 unsigned int& configSize ) | |
19 { | |
20 | |
21 char *dup, *psz; | |
22 int i, i_records = 1; | |
23 | |
24 if( configSize ) | |
25 configSize = 0; | |
26 if( configStr == NULL || *configStr == '\0' ) | |
27 return NULL; | |
28 psz = dup = strdup( configStr ); | |
29 | |
30 /* Count the number of comma's */ | |
31 for( psz = dup; *psz != '\0'; ++psz ) | |
32 { | |
33 if( *psz == ',') | |
34 { | |
35 ++i_records; | |
36 *psz = '\0'; | |
37 } | |
38 } | |
39 | |
40 unsigned char *cfg = new unsigned char[5 * strlen(dup)]; | |
41 psz = dup; | |
42 for( i = 0; i < i_records; i++ ) | |
43 { | |
44 | |
45 cfg[configSize++] = 0x00; | |
46 cfg[configSize++] = 0x00; | |
47 cfg[configSize++] = 0x01; | |
48 configSize += av_base64_decode( (uint8_t*)&cfg[configSize], | |
49 psz, | |
50 5 * strlen(dup) - 3 ); | |
51 | |
52 psz += strlen(psz)+1; | |
53 } | |
54 if( dup ) free( dup ); | |
55 | |
56 return cfg; | |
9250 | 57 } |
58 | |
9565
e74916774667
Improved RTP packet buffering, by relying on the underlying OS's UDP
rsf
parents:
9370
diff
changeset
|
59 static void |
e74916774667
Improved RTP packet buffering, by relying on the underlying OS's UDP
rsf
parents:
9370
diff
changeset
|
60 needVideoFrameRate(demuxer_t* demuxer, MediaSubsession* subsession); // forward |
9250 | 61 static Boolean |
62 parseQTState_video(QuickTimeGenericRTPSource::QTState const& qtState, | |
63 unsigned& fourcc); // forward | |
64 static Boolean | |
65 parseQTState_audio(QuickTimeGenericRTPSource::QTState const& qtState, | |
66 unsigned& fourcc, unsigned& numChannels); // forward | |
67 | |
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
|
68 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
|
69 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
|
70 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
|
71 { |
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
|
72 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
|
73 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
|
74 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
|
75 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
|
76 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
|
77 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
|
78 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
|
79 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
|
80 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
|
81 } |
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
|
82 |
9250 | 83 void rtpCodecInitialize_video(demuxer_t* demuxer, |
84 MediaSubsession* subsession, | |
85 unsigned& flags) { | |
86 flags = 0; | |
87 // Create a dummy video stream header | |
88 // to make the main MPlayer code happy: | |
89 sh_video_t* sh_video = new_sh_video(demuxer,0); | |
90 BITMAPINFOHEADER* bih | |
91 = (BITMAPINFOHEADER*)calloc(1,sizeof(BITMAPINFOHEADER)); | |
92 bih->biSize = sizeof(BITMAPINFOHEADER); | |
93 sh_video->bih = bih; | |
94 demux_stream_t* d_video = demuxer->video; | |
95 d_video->sh = sh_video; sh_video->ds = d_video; | |
96 | |
97 // Map known video MIME types to the BITMAPINFOHEADER parameters | |
98 // that this program uses. (Note that not all types need all | |
99 // 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
|
100 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
|
101 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
|
102 } 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
|
103 strcmp(subsession->codecName(), "MP2T") == 0) { |
b0d0aa726417
Added support for the "L16" and "L8" (raw PCM audio) RTP payload formats.
rsf
parents:
9910
diff
changeset
|
104 flags |= RTPSTATE_IS_MPEG12_VIDEO|RTPSTATE_IS_MULTIPLEXED; |
9250 | 105 } else if (strcmp(subsession->codecName(), "H263") == 0 || |
22211 | 106 strcmp(subsession->codecName(), "H263-2000") == 0 || |
9250 | 107 strcmp(subsession->codecName(), "H263-1998") == 0) { |
108 bih->biCompression = sh_video->format | |
109 = mmioFOURCC('H','2','6','3'); | |
9565
e74916774667
Improved RTP packet buffering, by relying on the underlying OS's UDP
rsf
parents:
9370
diff
changeset
|
110 needVideoFrameRate(demuxer, subsession); |
19415 | 111 } else if (strcmp(subsession->codecName(), "H264") == 0) { |
112 bih->biCompression = sh_video->format | |
113 = mmioFOURCC('H','2','6','4'); | |
22852 | 114 unsigned int configLen = 0; |
115 unsigned char* configData | |
116 = parseH264ConfigStr(subsession->fmtp_spropparametersets(), configLen); | |
117 sh_video->bih = bih = insertVideoExtradata(bih, configData, configLen); | |
118 delete[] configData; | |
119 #ifdef USE_LIBAVCODEC | |
24103
d44e23b469a3
Fix compilation of live555 support after FFmpegs r10173.
cehoyos
parents:
22852
diff
changeset
|
120 avcodec_register_all(); |
22852 | 121 h264parserctx = av_parser_init(CODEC_ID_H264); |
122 #endif | |
19415 | 123 needVideoFrameRate(demuxer, subsession); |
9250 | 124 } else if (strcmp(subsession->codecName(), "H261") == 0) { |
125 bih->biCompression = sh_video->format | |
126 = mmioFOURCC('H','2','6','1'); | |
9565
e74916774667
Improved RTP packet buffering, by relying on the underlying OS's UDP
rsf
parents:
9370
diff
changeset
|
127 needVideoFrameRate(demuxer, subsession); |
9370
88bd19564b64
Motion-JPEG RTP streams can now be played. Some MPEG-4 ES video RTP
arpi
parents:
9250
diff
changeset
|
128 } 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
|
129 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
|
130 = mmioFOURCC('M','J','P','G'); |
9565
e74916774667
Improved RTP packet buffering, by relying on the underlying OS's UDP
rsf
parents:
9370
diff
changeset
|
131 needVideoFrameRate(demuxer, subsession); |
9370
88bd19564b64
Motion-JPEG RTP streams can now be played. Some MPEG-4 ES video RTP
arpi
parents:
9250
diff
changeset
|
132 } 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
|
133 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
|
134 = mmioFOURCC('m','p','4','v'); |
9565
e74916774667
Improved RTP packet buffering, by relying on the underlying OS's UDP
rsf
parents:
9370
diff
changeset
|
135 // 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
|
136 // 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
|
137 // "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
|
138 // session's SDP description: |
e74916774667
Improved RTP packet buffering, by relying on the underlying OS's UDP
rsf
parents:
9370
diff
changeset
|
139 unsigned configLen; |
e74916774667
Improved RTP packet buffering, by relying on the underlying OS's UDP
rsf
parents:
9370
diff
changeset
|
140 unsigned char* configData |
e74916774667
Improved RTP packet buffering, by relying on the underlying OS's UDP
rsf
parents:
9370
diff
changeset
|
141 = 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
|
142 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
|
143 needVideoFrameRate(demuxer, subsession); |
9250 | 144 } else if (strcmp(subsession->codecName(), "X-QT") == 0 || |
145 strcmp(subsession->codecName(), "X-QUICKTIME") == 0) { | |
146 // QuickTime generic RTP format, as described in | |
147 // http://developer.apple.com/quicktime/icefloe/dispatch026.html | |
148 | |
149 // We can't initialize this stream until we've received the first packet | |
150 // that has QuickTime "sdAtom" information in the header. So, keep | |
151 // 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
|
152 unsigned char* packetData; unsigned packetDataLen; float pts; |
9250 | 153 QuickTimeGenericRTPSource* qtRTPSource |
154 = (QuickTimeGenericRTPSource*)(subsession->rtpSource()); | |
155 unsigned fourcc; | |
156 do { | |
9565
e74916774667
Improved RTP packet buffering, by relying on the underlying OS's UDP
rsf
parents:
9370
diff
changeset
|
157 if (!awaitRTPPacket(demuxer, demuxer->video, |
e74916774667
Improved RTP packet buffering, by relying on the underlying OS's UDP
rsf
parents:
9370
diff
changeset
|
158 packetData, packetDataLen, pts)) { |
9250 | 159 return; |
160 } | |
161 } while (!parseQTState_video(qtRTPSource->qtState, fourcc)); | |
162 | |
163 bih->biCompression = sh_video->format = fourcc; | |
21871 | 164 bih->biWidth = qtRTPSource->qtState.width; |
165 bih->biHeight = qtRTPSource->qtState.height; | |
166 uint8_t *pos = (uint8_t*)qtRTPSource->qtState.sdAtom + 86; | |
167 uint8_t *endpos = (uint8_t*)qtRTPSource->qtState.sdAtom | |
168 + qtRTPSource->qtState.sdAtomSize; | |
169 while (pos+8 < endpos) { | |
170 unsigned atomLength = pos[0]<<24 | pos[1]<<16 | pos[2]<<8 | pos[3]; | |
171 if (atomLength == 0 || atomLength > endpos-pos) break; | |
22809
09f97d0161ba
Handle X-QT extradata in a slightly more correct way
cehoyos
parents:
22756
diff
changeset
|
172 if ((!memcmp(pos+4, "avcC", 4) && fourcc==mmioFOURCC('a','v','c','1') || |
22154
1dc228327c55
when the video codec is mpeg4video copy the content of the esds in extradata; patch by ceyes ag or at
nicodvb
parents:
22112
diff
changeset
|
173 !memcmp(pos+4, "esds", 4) || |
22809
09f97d0161ba
Handle X-QT extradata in a slightly more correct way
cehoyos
parents:
22756
diff
changeset
|
174 !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
|
175 atomLength > 8) { |
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
|
176 sh_video->bih = 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
|
177 insertVideoExtradata(bih, pos+8, atomLength-8); |
21871 | 178 break; |
179 } | |
180 pos += atomLength; | |
181 } | |
22756
3d6a64f3d28f
Every X-QT stream needs video frame rate (not just avc, mpeg4 and svq3)
cehoyos
parents:
22463
diff
changeset
|
182 needVideoFrameRate(demuxer, subsession); |
9250 | 183 } else { |
184 fprintf(stderr, | |
185 "Unknown MPlayer format code for MIME type \"video/%s\"\n", | |
186 subsession->codecName()); | |
187 } | |
188 } | |
189 | |
190 void rtpCodecInitialize_audio(demuxer_t* demuxer, | |
191 MediaSubsession* subsession, | |
192 unsigned& flags) { | |
193 flags = 0; | |
194 // Create a dummy audio stream header | |
195 // to make the main MPlayer code happy: | |
196 sh_audio_t* sh_audio = new_sh_audio(demuxer,0); | |
197 WAVEFORMATEX* wf = (WAVEFORMATEX*)calloc(1,sizeof(WAVEFORMATEX)); | |
198 sh_audio->wf = wf; | |
199 demux_stream_t* d_audio = demuxer->audio; | |
200 d_audio->sh = sh_audio; sh_audio->ds = d_audio; | |
201 | |
9565
e74916774667
Improved RTP packet buffering, by relying on the underlying OS's UDP
rsf
parents:
9370
diff
changeset
|
202 wf->nChannels = subsession->numChannels(); |
e74916774667
Improved RTP packet buffering, by relying on the underlying OS's UDP
rsf
parents:
9370
diff
changeset
|
203 |
9250 | 204 // Map known audio MIME types to the WAVEFORMATEX parameters |
205 // that this program uses. (Note that not all types need all | |
206 // of the parameters to be set.) | |
207 wf->nSamplesPerSec | |
208 = subsession->rtpSource()->timestampFrequency(); // by default | |
209 if (strcmp(subsession->codecName(), "MPA") == 0 || | |
210 strcmp(subsession->codecName(), "MPA-ROBUST") == 0 || | |
211 strcmp(subsession->codecName(), "X-MP3-DRAFT-00") == 0) { | |
212 wf->wFormatTag = sh_audio->format = 0x55; | |
213 // Note: 0x55 is for layer III, but should work for I,II also | |
214 wf->nSamplesPerSec = 0; // sample rate is deduced from the data | |
215 } else if (strcmp(subsession->codecName(), "AC3") == 0) { | |
216 wf->wFormatTag = sh_audio->format = 0x2000; | |
217 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
|
218 } 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
|
219 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
|
220 wf->nBlockAlign = 1; |
b0d0aa726417
Added support for the "L16" and "L8" (raw PCM audio) RTP payload formats.
rsf
parents:
9910
diff
changeset
|
221 wf->wBitsPerSample = 16; |
b0d0aa726417
Added support for the "L16" and "L8" (raw PCM audio) RTP payload formats.
rsf
parents:
9910
diff
changeset
|
222 wf->cbSize = 0; |
b0d0aa726417
Added support for the "L16" and "L8" (raw PCM audio) RTP payload formats.
rsf
parents:
9910
diff
changeset
|
223 } 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
|
224 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
|
225 wf->nBlockAlign = 1; |
b0d0aa726417
Added support for the "L16" and "L8" (raw PCM audio) RTP payload formats.
rsf
parents:
9910
diff
changeset
|
226 wf->wBitsPerSample = 8; |
b0d0aa726417
Added support for the "L16" and "L8" (raw PCM audio) RTP payload formats.
rsf
parents:
9910
diff
changeset
|
227 wf->cbSize = 0; |
9250 | 228 } else if (strcmp(subsession->codecName(), "PCMU") == 0) { |
229 wf->wFormatTag = sh_audio->format = 0x7; | |
230 wf->nAvgBytesPerSec = 8000; | |
231 wf->nBlockAlign = 1; | |
232 wf->wBitsPerSample = 8; | |
233 wf->cbSize = 0; | |
234 } else if (strcmp(subsession->codecName(), "PCMA") == 0) { | |
235 wf->wFormatTag = sh_audio->format = 0x6; | |
236 wf->nAvgBytesPerSec = 8000; | |
237 wf->nBlockAlign = 1; | |
238 wf->wBitsPerSample = 8; | |
239 wf->cbSize = 0; | |
22463
979b2aa16e80
support for AMR; it works inserting in the first byte of the demux_packet
nicodvb
parents:
22354
diff
changeset
|
240 } 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
|
241 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
|
242 } 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
|
243 wf->wFormatTag = sh_audio->format = mmioFOURCC('s','a','w','b'); |
9250 | 244 } else if (strcmp(subsession->codecName(), "GSM") == 0) { |
245 wf->wFormatTag = sh_audio->format = mmioFOURCC('a','g','s','m'); | |
246 wf->nAvgBytesPerSec = 1650; | |
247 wf->nBlockAlign = 33; | |
248 wf->wBitsPerSample = 16; | |
249 wf->cbSize = 0; | |
250 } else if (strcmp(subsession->codecName(), "QCELP") == 0) { | |
251 wf->wFormatTag = sh_audio->format = mmioFOURCC('Q','c','l','p'); | |
252 wf->nAvgBytesPerSec = 1750; | |
253 wf->nBlockAlign = 35; | |
254 wf->wBitsPerSample = 16; | |
255 wf->cbSize = 0; | |
256 } else if (strcmp(subsession->codecName(), "MP4A-LATM") == 0) { | |
257 wf->wFormatTag = sh_audio->format = mmioFOURCC('m','p','4','a'); | |
258 // For the codec to work correctly, it needs "AudioSpecificConfig" | |
259 // data, which is parsed from the "StreamMuxConfig" string that | |
260 // was present (hopefully) in the SDP description: | |
261 unsigned codecdata_len; | |
262 sh_audio->codecdata | |
263 = parseStreamMuxConfigStr(subsession->fmtp_config(), | |
264 codecdata_len); | |
265 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
|
266 //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
|
267 ((MPEG4LATMAudioRTPSource*)subsession->rtpSource())->omitLATMDataLengthField(); |
9565
e74916774667
Improved RTP packet buffering, by relying on the underlying OS's UDP
rsf
parents:
9370
diff
changeset
|
268 } 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
|
269 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
|
270 // 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
|
271 // 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
|
272 unsigned codecdata_len; |
e74916774667
Improved RTP packet buffering, by relying on the underlying OS's UDP
rsf
parents:
9370
diff
changeset
|
273 sh_audio->codecdata |
e74916774667
Improved RTP packet buffering, by relying on the underlying OS's UDP
rsf
parents:
9370
diff
changeset
|
274 = parseGeneralConfigStr(subsession->fmtp_config(), |
e74916774667
Improved RTP packet buffering, by relying on the underlying OS's UDP
rsf
parents:
9370
diff
changeset
|
275 codecdata_len); |
e74916774667
Improved RTP packet buffering, by relying on the underlying OS's UDP
rsf
parents:
9370
diff
changeset
|
276 sh_audio->codecdata_len = codecdata_len; |
9250 | 277 } else if (strcmp(subsession->codecName(), "X-QT") == 0 || |
278 strcmp(subsession->codecName(), "X-QUICKTIME") == 0) { | |
279 // QuickTime generic RTP format, as described in | |
280 // http://developer.apple.com/quicktime/icefloe/dispatch026.html | |
281 | |
282 // We can't initialize this stream until we've received the first packet | |
283 // that has QuickTime "sdAtom" information in the header. So, keep | |
284 // 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
|
285 unsigned char* packetData; unsigned packetDataLen; float pts; |
9250 | 286 QuickTimeGenericRTPSource* qtRTPSource |
287 = (QuickTimeGenericRTPSource*)(subsession->rtpSource()); | |
288 unsigned fourcc, numChannels; | |
289 do { | |
9565
e74916774667
Improved RTP packet buffering, by relying on the underlying OS's UDP
rsf
parents:
9370
diff
changeset
|
290 if (!awaitRTPPacket(demuxer, demuxer->audio, |
e74916774667
Improved RTP packet buffering, by relying on the underlying OS's UDP
rsf
parents:
9370
diff
changeset
|
291 packetData, packetDataLen, pts)) { |
9250 | 292 return; |
293 } | |
294 } while (!parseQTState_audio(qtRTPSource->qtState, fourcc, numChannels)); | |
295 | |
296 wf->wFormatTag = sh_audio->format = fourcc; | |
297 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
|
298 |
760c74c078ce
copy the content of QDM2 atom as extradata for ffqdm2 playback; patch by Carl Eugen Hoyos
nicodvb
parents:
22278
diff
changeset
|
299 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
|
300 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
|
301 + 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
|
302 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
|
303 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
|
304 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
|
305 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
|
306 atomLength > 8 && |
760c74c078ce
copy the content of QDM2 atom as extradata for ffqdm2 playback; patch by Carl Eugen Hoyos
nicodvb
parents:
22278
diff
changeset
|
307 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
|
308 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
|
309 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
|
310 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
|
311 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
|
312 } |
760c74c078ce
copy the content of QDM2 atom as extradata for ffqdm2 playback; patch by Carl Eugen Hoyos
nicodvb
parents:
22278
diff
changeset
|
313 break; |
760c74c078ce
copy the content of QDM2 atom as extradata for ffqdm2 playback; patch by Carl Eugen Hoyos
nicodvb
parents:
22278
diff
changeset
|
314 } |
760c74c078ce
copy the content of QDM2 atom as extradata for ffqdm2 playback; patch by Carl Eugen Hoyos
nicodvb
parents:
22278
diff
changeset
|
315 pos += atomLength; |
760c74c078ce
copy the content of QDM2 atom as extradata for ffqdm2 playback; patch by Carl Eugen Hoyos
nicodvb
parents:
22278
diff
changeset
|
316 } |
9250 | 317 } else { |
318 fprintf(stderr, | |
319 "Unknown MPlayer format code for MIME type \"audio/%s\"\n", | |
320 subsession->codecName()); | |
321 } | |
322 } | |
323 | |
9565
e74916774667
Improved RTP packet buffering, by relying on the underlying OS's UDP
rsf
parents:
9370
diff
changeset
|
324 static void needVideoFrameRate(demuxer_t* demuxer, |
e74916774667
Improved RTP packet buffering, by relying on the underlying OS's UDP
rsf
parents:
9370
diff
changeset
|
325 MediaSubsession* subsession) { |
e74916774667
Improved RTP packet buffering, by relying on the underlying OS's UDP
rsf
parents:
9370
diff
changeset
|
326 // 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
|
327 // 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
|
328 // 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
|
329 // presentation timestamps in successive packets, |
e74916774667
Improved RTP packet buffering, by relying on the underlying OS's UDP
rsf
parents:
9370
diff
changeset
|
330 extern float force_fps; if (force_fps != 0.0) return; // user used "-fps" |
e74916774667
Improved RTP packet buffering, by relying on the underlying OS's UDP
rsf
parents:
9370
diff
changeset
|
331 |
e74916774667
Improved RTP packet buffering, by relying on the underlying OS's UDP
rsf
parents:
9370
diff
changeset
|
332 demux_stream_t* d_video = demuxer->video; |
9910 | 333 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
|
334 |
e74916774667
Improved RTP packet buffering, by relying on the underlying OS's UDP
rsf
parents:
9370
diff
changeset
|
335 // 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
|
336 int fps = (int)(subsession->videoFPS()); |
e74916774667
Improved RTP packet buffering, by relying on the underlying OS's UDP
rsf
parents:
9370
diff
changeset
|
337 if (fps != 0) { |
e74916774667
Improved RTP packet buffering, by relying on the underlying OS's UDP
rsf
parents:
9370
diff
changeset
|
338 sh_video->fps = fps; |
22354
b465e5be1a53
assign missing frametime as 1.0/fps; patch by Carl Eigen Hoyos
nicodvb
parents:
22336
diff
changeset
|
339 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
|
340 return; |
e74916774667
Improved RTP packet buffering, by relying on the underlying OS's UDP
rsf
parents:
9370
diff
changeset
|
341 } |
e74916774667
Improved RTP packet buffering, by relying on the underlying OS's UDP
rsf
parents:
9370
diff
changeset
|
342 |
e74916774667
Improved RTP packet buffering, by relying on the underlying OS's UDP
rsf
parents:
9370
diff
changeset
|
343 // 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
|
344 // non-zero "pts" timestamps: |
e74916774667
Improved RTP packet buffering, by relying on the underlying OS's UDP
rsf
parents:
9370
diff
changeset
|
345 unsigned char* packetData; unsigned packetDataLen; |
e74916774667
Improved RTP packet buffering, by relying on the underlying OS's UDP
rsf
parents:
9370
diff
changeset
|
346 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
|
347 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
|
348 int lastfps = 0; |
9565
e74916774667
Improved RTP packet buffering, by relying on the underlying OS's UDP
rsf
parents:
9370
diff
changeset
|
349 for (unsigned i = 0; i < maxNumFramesToWaitFor; ++i) { |
9910 | 350 if (!awaitRTPPacket(demuxer, d_video, packetData, packetDataLen, curPTS)) { |
351 break; | |
352 } | |
9565
e74916774667
Improved RTP packet buffering, by relying on the underlying OS's UDP
rsf
parents:
9370
diff
changeset
|
353 |
21983
a6b624360aef
better autodetection of framerate in case of h264; it works correctly with b-frames.
nicodvb
parents:
21911
diff
changeset
|
354 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
|
355 // 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
|
356 // (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
|
357 // 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
|
358 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
|
359 if (fps == lastfps) { |
9565
e74916774667
Improved RTP packet buffering, by relying on the underlying OS's UDP
rsf
parents:
9370
diff
changeset
|
360 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
|
361 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
|
362 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
|
363 return; |
21983
a6b624360aef
better autodetection of framerate in case of h264; it works correctly with b-frames.
nicodvb
parents:
21911
diff
changeset
|
364 } |
a6b624360aef
better autodetection of framerate in case of h264; it works correctly with b-frames.
nicodvb
parents:
21911
diff
changeset
|
365 if (fps>lastfps) lastfps = 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 lastPTS = curPTS; |
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 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
|
370 } |
e74916774667
Improved RTP packet buffering, by relying on the underlying OS's UDP
rsf
parents:
9370
diff
changeset
|
371 |
9250 | 372 static Boolean |
373 parseQTState_video(QuickTimeGenericRTPSource::QTState const& qtState, | |
374 unsigned& fourcc) { | |
375 // qtState's "sdAtom" field is supposed to contain a QuickTime video | |
376 // 'sample description' atom. This atom's name is the 'fourcc' that we want: | |
377 char const* sdAtom = qtState.sdAtom; | |
378 if (sdAtom == NULL || qtState.sdAtomSize < 2*4) return False; | |
379 | |
380 fourcc = *(unsigned*)(&sdAtom[4]); // put in host order | |
381 return True; | |
382 } | |
383 | |
384 static Boolean | |
385 parseQTState_audio(QuickTimeGenericRTPSource::QTState const& qtState, | |
386 unsigned& fourcc, unsigned& numChannels) { | |
387 // qtState's "sdAtom" field is supposed to contain a QuickTime audio | |
388 // 'sample description' atom. This atom's name is the 'fourcc' that we want. | |
389 // Also, the top half of the 5th word following the atom name should | |
390 // contain the number of channels ("numChannels") that we want: | |
391 char const* sdAtom = qtState.sdAtom; | |
392 if (sdAtom == NULL || qtState.sdAtomSize < 7*4) return False; | |
393 | |
394 fourcc = *(unsigned*)(&sdAtom[4]); // put in host order | |
395 | |
396 char const* word7Ptr = &sdAtom[6*4]; | |
397 numChannels = (word7Ptr[0]<<8)|(word7Ptr[1]); | |
398 return True; | |
399 } |