Mercurial > mplayer.hg
annotate libmpdemux/demux_rtp_codec.cpp @ 15205:19243f85e164
nico partially fixed the bug i reported; here's the rest of the fix.
basically demux_audio was mixing data in its header buffer in a bogus
manner, whereby it could sometimes "make up" valid mpeg headers where
no such header actually occurred in the file. it should be correct now.
btw these changes also fix the bug where mplayer reports huge initial
cpu usage for sound when playing mp3 files.
author | rfelker |
---|---|
date | Sun, 17 Apr 2005 17:17:52 +0000 |
parents | fca816d2f4a6 |
children | 56a5f69e9b35 |
rev | line source |
---|---|
9250 | 1 ////////// Codec-specific routines used to interface between "MPlayer" |
2 ////////// and the "LIVE.COM Streaming Media" libraries: | |
3 | |
4 #include "demux_rtp_internal.h" | |
5 extern "C" { | |
6 #include "stheader.h" | |
7 } | |
8 | |
9565
e74916774667
Improved RTP packet buffering, by relying on the underlying OS's UDP
rsf
parents:
9370
diff
changeset
|
9 static void |
e74916774667
Improved RTP packet buffering, by relying on the underlying OS's UDP
rsf
parents:
9370
diff
changeset
|
10 needVideoFrameRate(demuxer_t* demuxer, MediaSubsession* subsession); // forward |
9250 | 11 static Boolean |
12 parseQTState_video(QuickTimeGenericRTPSource::QTState const& qtState, | |
13 unsigned& fourcc); // forward | |
14 static Boolean | |
15 parseQTState_audio(QuickTimeGenericRTPSource::QTState const& qtState, | |
16 unsigned& fourcc, unsigned& numChannels); // forward | |
17 | |
18 void rtpCodecInitialize_video(demuxer_t* demuxer, | |
19 MediaSubsession* subsession, | |
20 unsigned& flags) { | |
21 flags = 0; | |
22 // Create a dummy video stream header | |
23 // to make the main MPlayer code happy: | |
24 sh_video_t* sh_video = new_sh_video(demuxer,0); | |
25 BITMAPINFOHEADER* bih | |
26 = (BITMAPINFOHEADER*)calloc(1,sizeof(BITMAPINFOHEADER)); | |
27 bih->biSize = sizeof(BITMAPINFOHEADER); | |
28 sh_video->bih = bih; | |
29 demux_stream_t* d_video = demuxer->video; | |
30 d_video->sh = sh_video; sh_video->ds = d_video; | |
31 | |
32 // Map known video MIME types to the BITMAPINFOHEADER parameters | |
33 // that this program uses. (Note that not all types need all | |
34 // 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
|
35 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
|
36 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
|
37 } 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
|
38 strcmp(subsession->codecName(), "MP2T") == 0) { |
b0d0aa726417
Added support for the "L16" and "L8" (raw PCM audio) RTP payload formats.
rsf
parents:
9910
diff
changeset
|
39 flags |= RTPSTATE_IS_MPEG12_VIDEO|RTPSTATE_IS_MULTIPLEXED; |
9250 | 40 } else if (strcmp(subsession->codecName(), "H263") == 0 || |
41 strcmp(subsession->codecName(), "H263-1998") == 0) { | |
42 bih->biCompression = sh_video->format | |
43 = mmioFOURCC('H','2','6','3'); | |
9565
e74916774667
Improved RTP packet buffering, by relying on the underlying OS's UDP
rsf
parents:
9370
diff
changeset
|
44 needVideoFrameRate(demuxer, subsession); |
9250 | 45 } else if (strcmp(subsession->codecName(), "H261") == 0) { |
46 bih->biCompression = sh_video->format | |
47 = mmioFOURCC('H','2','6','1'); | |
9565
e74916774667
Improved RTP packet buffering, by relying on the underlying OS's UDP
rsf
parents:
9370
diff
changeset
|
48 needVideoFrameRate(demuxer, subsession); |
9370
88bd19564b64
Motion-JPEG RTP streams can now be played. Some MPEG-4 ES video RTP
arpi
parents:
9250
diff
changeset
|
49 } 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
|
50 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
|
51 = mmioFOURCC('M','J','P','G'); |
9565
e74916774667
Improved RTP packet buffering, by relying on the underlying OS's UDP
rsf
parents:
9370
diff
changeset
|
52 needVideoFrameRate(demuxer, subsession); |
9370
88bd19564b64
Motion-JPEG RTP streams can now be played. Some MPEG-4 ES video RTP
arpi
parents:
9250
diff
changeset
|
53 } 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
|
54 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
|
55 = mmioFOURCC('m','p','4','v'); |
9565
e74916774667
Improved RTP packet buffering, by relying on the underlying OS's UDP
rsf
parents:
9370
diff
changeset
|
56 // 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
|
57 // 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
|
58 // "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
|
59 // session's SDP description: |
e74916774667
Improved RTP packet buffering, by relying on the underlying OS's UDP
rsf
parents:
9370
diff
changeset
|
60 unsigned configLen; |
e74916774667
Improved RTP packet buffering, by relying on the underlying OS's UDP
rsf
parents:
9370
diff
changeset
|
61 unsigned char* configData |
e74916774667
Improved RTP packet buffering, by relying on the underlying OS's UDP
rsf
parents:
9370
diff
changeset
|
62 = parseGeneralConfigStr(subsession->fmtp_config(), configLen); |
e74916774667
Improved RTP packet buffering, by relying on the underlying OS's UDP
rsf
parents:
9370
diff
changeset
|
63 insertRTPData(demuxer, demuxer->video, configData, configLen); |
e74916774667
Improved RTP packet buffering, by relying on the underlying OS's UDP
rsf
parents:
9370
diff
changeset
|
64 needVideoFrameRate(demuxer, subsession); |
9250 | 65 } else if (strcmp(subsession->codecName(), "X-QT") == 0 || |
66 strcmp(subsession->codecName(), "X-QUICKTIME") == 0) { | |
67 // QuickTime generic RTP format, as described in | |
68 // http://developer.apple.com/quicktime/icefloe/dispatch026.html | |
69 | |
70 // We can't initialize this stream until we've received the first packet | |
71 // that has QuickTime "sdAtom" information in the header. So, keep | |
72 // 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
|
73 unsigned char* packetData; unsigned packetDataLen; float pts; |
9250 | 74 QuickTimeGenericRTPSource* qtRTPSource |
75 = (QuickTimeGenericRTPSource*)(subsession->rtpSource()); | |
76 unsigned fourcc; | |
77 do { | |
9565
e74916774667
Improved RTP packet buffering, by relying on the underlying OS's UDP
rsf
parents:
9370
diff
changeset
|
78 if (!awaitRTPPacket(demuxer, demuxer->video, |
e74916774667
Improved RTP packet buffering, by relying on the underlying OS's UDP
rsf
parents:
9370
diff
changeset
|
79 packetData, packetDataLen, pts)) { |
9250 | 80 return; |
81 } | |
82 } while (!parseQTState_video(qtRTPSource->qtState, fourcc)); | |
83 | |
84 bih->biCompression = sh_video->format = fourcc; | |
85 } else { | |
86 fprintf(stderr, | |
87 "Unknown MPlayer format code for MIME type \"video/%s\"\n", | |
88 subsession->codecName()); | |
89 } | |
90 } | |
91 | |
92 void rtpCodecInitialize_audio(demuxer_t* demuxer, | |
93 MediaSubsession* subsession, | |
94 unsigned& flags) { | |
95 flags = 0; | |
96 // Create a dummy audio stream header | |
97 // to make the main MPlayer code happy: | |
98 sh_audio_t* sh_audio = new_sh_audio(demuxer,0); | |
99 WAVEFORMATEX* wf = (WAVEFORMATEX*)calloc(1,sizeof(WAVEFORMATEX)); | |
100 sh_audio->wf = wf; | |
101 demux_stream_t* d_audio = demuxer->audio; | |
102 d_audio->sh = sh_audio; sh_audio->ds = d_audio; | |
103 | |
9565
e74916774667
Improved RTP packet buffering, by relying on the underlying OS's UDP
rsf
parents:
9370
diff
changeset
|
104 wf->nChannels = subsession->numChannels(); |
e74916774667
Improved RTP packet buffering, by relying on the underlying OS's UDP
rsf
parents:
9370
diff
changeset
|
105 |
9250 | 106 // Map known audio MIME types to the WAVEFORMATEX parameters |
107 // that this program uses. (Note that not all types need all | |
108 // of the parameters to be set.) | |
109 wf->nSamplesPerSec | |
110 = subsession->rtpSource()->timestampFrequency(); // by default | |
111 if (strcmp(subsession->codecName(), "MPA") == 0 || | |
112 strcmp(subsession->codecName(), "MPA-ROBUST") == 0 || | |
113 strcmp(subsession->codecName(), "X-MP3-DRAFT-00") == 0) { | |
114 wf->wFormatTag = sh_audio->format = 0x55; | |
115 // Note: 0x55 is for layer III, but should work for I,II also | |
116 wf->nSamplesPerSec = 0; // sample rate is deduced from the data | |
117 } else if (strcmp(subsession->codecName(), "AC3") == 0) { | |
118 wf->wFormatTag = sh_audio->format = 0x2000; | |
119 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
|
120 } 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
|
121 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
|
122 wf->nBlockAlign = 1; |
b0d0aa726417
Added support for the "L16" and "L8" (raw PCM audio) RTP payload formats.
rsf
parents:
9910
diff
changeset
|
123 wf->wBitsPerSample = 16; |
b0d0aa726417
Added support for the "L16" and "L8" (raw PCM audio) RTP payload formats.
rsf
parents:
9910
diff
changeset
|
124 wf->cbSize = 0; |
b0d0aa726417
Added support for the "L16" and "L8" (raw PCM audio) RTP payload formats.
rsf
parents:
9910
diff
changeset
|
125 } 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
|
126 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
|
127 wf->nBlockAlign = 1; |
b0d0aa726417
Added support for the "L16" and "L8" (raw PCM audio) RTP payload formats.
rsf
parents:
9910
diff
changeset
|
128 wf->wBitsPerSample = 8; |
b0d0aa726417
Added support for the "L16" and "L8" (raw PCM audio) RTP payload formats.
rsf
parents:
9910
diff
changeset
|
129 wf->cbSize = 0; |
9250 | 130 } else if (strcmp(subsession->codecName(), "PCMU") == 0) { |
131 wf->wFormatTag = sh_audio->format = 0x7; | |
132 wf->nAvgBytesPerSec = 8000; | |
133 wf->nBlockAlign = 1; | |
134 wf->wBitsPerSample = 8; | |
135 wf->cbSize = 0; | |
136 } else if (strcmp(subsession->codecName(), "PCMA") == 0) { | |
137 wf->wFormatTag = sh_audio->format = 0x6; | |
138 wf->nAvgBytesPerSec = 8000; | |
139 wf->nBlockAlign = 1; | |
140 wf->wBitsPerSample = 8; | |
141 wf->cbSize = 0; | |
142 } else if (strcmp(subsession->codecName(), "GSM") == 0) { | |
143 wf->wFormatTag = sh_audio->format = mmioFOURCC('a','g','s','m'); | |
144 wf->nAvgBytesPerSec = 1650; | |
145 wf->nBlockAlign = 33; | |
146 wf->wBitsPerSample = 16; | |
147 wf->cbSize = 0; | |
148 } else if (strcmp(subsession->codecName(), "QCELP") == 0) { | |
149 wf->wFormatTag = sh_audio->format = mmioFOURCC('Q','c','l','p'); | |
150 wf->nAvgBytesPerSec = 1750; | |
151 wf->nBlockAlign = 35; | |
152 wf->wBitsPerSample = 16; | |
153 wf->cbSize = 0; | |
154 } else if (strcmp(subsession->codecName(), "MP4A-LATM") == 0) { | |
155 wf->wFormatTag = sh_audio->format = mmioFOURCC('m','p','4','a'); | |
156 // For the codec to work correctly, it needs "AudioSpecificConfig" | |
157 // data, which is parsed from the "StreamMuxConfig" string that | |
158 // was present (hopefully) in the SDP description: | |
159 unsigned codecdata_len; | |
160 sh_audio->codecdata | |
161 = parseStreamMuxConfigStr(subsession->fmtp_config(), | |
162 codecdata_len); | |
163 sh_audio->codecdata_len = codecdata_len; | |
9565
e74916774667
Improved RTP packet buffering, by relying on the underlying OS's UDP
rsf
parents:
9370
diff
changeset
|
164 } 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
|
165 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
|
166 // 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
|
167 // 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
|
168 unsigned codecdata_len; |
e74916774667
Improved RTP packet buffering, by relying on the underlying OS's UDP
rsf
parents:
9370
diff
changeset
|
169 sh_audio->codecdata |
e74916774667
Improved RTP packet buffering, by relying on the underlying OS's UDP
rsf
parents:
9370
diff
changeset
|
170 = parseGeneralConfigStr(subsession->fmtp_config(), |
e74916774667
Improved RTP packet buffering, by relying on the underlying OS's UDP
rsf
parents:
9370
diff
changeset
|
171 codecdata_len); |
e74916774667
Improved RTP packet buffering, by relying on the underlying OS's UDP
rsf
parents:
9370
diff
changeset
|
172 sh_audio->codecdata_len = codecdata_len; |
9250 | 173 } else if (strcmp(subsession->codecName(), "X-QT") == 0 || |
174 strcmp(subsession->codecName(), "X-QUICKTIME") == 0) { | |
175 // QuickTime generic RTP format, as described in | |
176 // http://developer.apple.com/quicktime/icefloe/dispatch026.html | |
177 | |
178 // We can't initialize this stream until we've received the first packet | |
179 // that has QuickTime "sdAtom" information in the header. So, keep | |
180 // 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
|
181 unsigned char* packetData; unsigned packetDataLen; float pts; |
9250 | 182 QuickTimeGenericRTPSource* qtRTPSource |
183 = (QuickTimeGenericRTPSource*)(subsession->rtpSource()); | |
184 unsigned fourcc, numChannels; | |
185 do { | |
9565
e74916774667
Improved RTP packet buffering, by relying on the underlying OS's UDP
rsf
parents:
9370
diff
changeset
|
186 if (!awaitRTPPacket(demuxer, demuxer->audio, |
e74916774667
Improved RTP packet buffering, by relying on the underlying OS's UDP
rsf
parents:
9370
diff
changeset
|
187 packetData, packetDataLen, pts)) { |
9250 | 188 return; |
189 } | |
190 } while (!parseQTState_audio(qtRTPSource->qtState, fourcc, numChannels)); | |
191 | |
192 wf->wFormatTag = sh_audio->format = fourcc; | |
193 wf->nChannels = numChannels; | |
194 } else { | |
195 fprintf(stderr, | |
196 "Unknown MPlayer format code for MIME type \"audio/%s\"\n", | |
197 subsession->codecName()); | |
198 } | |
199 } | |
200 | |
9565
e74916774667
Improved RTP packet buffering, by relying on the underlying OS's UDP
rsf
parents:
9370
diff
changeset
|
201 static void needVideoFrameRate(demuxer_t* demuxer, |
e74916774667
Improved RTP packet buffering, by relying on the underlying OS's UDP
rsf
parents:
9370
diff
changeset
|
202 MediaSubsession* subsession) { |
e74916774667
Improved RTP packet buffering, by relying on the underlying OS's UDP
rsf
parents:
9370
diff
changeset
|
203 // 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
|
204 // 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
|
205 // 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
|
206 // presentation timestamps in successive packets, |
e74916774667
Improved RTP packet buffering, by relying on the underlying OS's UDP
rsf
parents:
9370
diff
changeset
|
207 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
|
208 |
e74916774667
Improved RTP packet buffering, by relying on the underlying OS's UDP
rsf
parents:
9370
diff
changeset
|
209 demux_stream_t* d_video = demuxer->video; |
9910 | 210 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
|
211 |
e74916774667
Improved RTP packet buffering, by relying on the underlying OS's UDP
rsf
parents:
9370
diff
changeset
|
212 // 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
|
213 int fps = (int)(subsession->videoFPS()); |
e74916774667
Improved RTP packet buffering, by relying on the underlying OS's UDP
rsf
parents:
9370
diff
changeset
|
214 if (fps != 0) { |
e74916774667
Improved RTP packet buffering, by relying on the underlying OS's UDP
rsf
parents:
9370
diff
changeset
|
215 sh_video->fps = fps; |
e74916774667
Improved RTP packet buffering, by relying on the underlying OS's UDP
rsf
parents:
9370
diff
changeset
|
216 return; |
e74916774667
Improved RTP packet buffering, by relying on the underlying OS's UDP
rsf
parents:
9370
diff
changeset
|
217 } |
e74916774667
Improved RTP packet buffering, by relying on the underlying OS's UDP
rsf
parents:
9370
diff
changeset
|
218 |
e74916774667
Improved RTP packet buffering, by relying on the underlying OS's UDP
rsf
parents:
9370
diff
changeset
|
219 // 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
|
220 // non-zero "pts" timestamps: |
e74916774667
Improved RTP packet buffering, by relying on the underlying OS's UDP
rsf
parents:
9370
diff
changeset
|
221 unsigned char* packetData; unsigned packetDataLen; |
e74916774667
Improved RTP packet buffering, by relying on the underlying OS's UDP
rsf
parents:
9370
diff
changeset
|
222 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
|
223 unsigned const maxNumFramesToWaitFor = 300; |
9565
e74916774667
Improved RTP packet buffering, by relying on the underlying OS's UDP
rsf
parents:
9370
diff
changeset
|
224 for (unsigned i = 0; i < maxNumFramesToWaitFor; ++i) { |
9910 | 225 if (!awaitRTPPacket(demuxer, d_video, packetData, packetDataLen, curPTS)) { |
226 break; | |
227 } | |
9565
e74916774667
Improved RTP packet buffering, by relying on the underlying OS's UDP
rsf
parents:
9370
diff
changeset
|
228 |
e74916774667
Improved RTP packet buffering, by relying on the underlying OS's UDP
rsf
parents:
9370
diff
changeset
|
229 if (curPTS > lastPTS && lastPTS != 0.0) { |
e74916774667
Improved RTP packet buffering, by relying on the underlying OS's UDP
rsf
parents:
9370
diff
changeset
|
230 // 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
|
231 // (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
|
232 // Guess the frame rate as an integer. If it's not, use "-fps" instead. |
e74916774667
Improved RTP packet buffering, by relying on the underlying OS's UDP
rsf
parents:
9370
diff
changeset
|
233 fps = (int)(1/(curPTS-lastPTS) + 0.5); // rounding |
e74916774667
Improved RTP packet buffering, by relying on the underlying OS's UDP
rsf
parents:
9370
diff
changeset
|
234 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
|
235 sh_video->fps = fps; |
e74916774667
Improved RTP packet buffering, by relying on the underlying OS's UDP
rsf
parents:
9370
diff
changeset
|
236 return; |
e74916774667
Improved RTP packet buffering, by relying on the underlying OS's UDP
rsf
parents:
9370
diff
changeset
|
237 } |
e74916774667
Improved RTP packet buffering, by relying on the underlying OS's UDP
rsf
parents:
9370
diff
changeset
|
238 lastPTS = curPTS; |
e74916774667
Improved RTP packet buffering, by relying on the underlying OS's UDP
rsf
parents:
9370
diff
changeset
|
239 } |
e74916774667
Improved RTP packet buffering, by relying on the underlying OS's UDP
rsf
parents:
9370
diff
changeset
|
240 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
|
241 } |
e74916774667
Improved RTP packet buffering, by relying on the underlying OS's UDP
rsf
parents:
9370
diff
changeset
|
242 |
9250 | 243 static Boolean |
244 parseQTState_video(QuickTimeGenericRTPSource::QTState const& qtState, | |
245 unsigned& fourcc) { | |
246 // qtState's "sdAtom" field is supposed to contain a QuickTime video | |
247 // 'sample description' atom. This atom's name is the 'fourcc' that we want: | |
248 char const* sdAtom = qtState.sdAtom; | |
249 if (sdAtom == NULL || qtState.sdAtomSize < 2*4) return False; | |
250 | |
251 fourcc = *(unsigned*)(&sdAtom[4]); // put in host order | |
252 return True; | |
253 } | |
254 | |
255 static Boolean | |
256 parseQTState_audio(QuickTimeGenericRTPSource::QTState const& qtState, | |
257 unsigned& fourcc, unsigned& numChannels) { | |
258 // qtState's "sdAtom" field is supposed to contain a QuickTime audio | |
259 // 'sample description' atom. This atom's name is the 'fourcc' that we want. | |
260 // Also, the top half of the 5th word following the atom name should | |
261 // contain the number of channels ("numChannels") that we want: | |
262 char const* sdAtom = qtState.sdAtom; | |
263 if (sdAtom == NULL || qtState.sdAtomSize < 7*4) return False; | |
264 | |
265 fourcc = *(unsigned*)(&sdAtom[4]); // put in host order | |
266 | |
267 char const* word7Ptr = &sdAtom[6*4]; | |
268 numChannels = (word7Ptr[0]<<8)|(word7Ptr[1]); | |
269 return True; | |
270 } |