MCPcopy Create free account
hub / github.com/FlaxEngine/FlaxEngine / ReadStream

Function ReadStream

Source/Engine/Video/MF/VideoBackendMF.cpp:195–386  ·  view source on GitHub ↗

Source from the content-addressed store, hash-verified

193 }
194
195 bool ReadStream(VideoBackendPlayer& player, VideoPlayerMF& playerMF, DWORD streamIndex, TimeSpan dt)
196 {
197 PROFILE_CPU_NAMED("ReadStream");
198 ZoneText(player.DebugUrl, player.DebugUrlLen);
199 const bool isVideo = streamIndex == MF_SOURCE_READER_FIRST_VIDEO_STREAM;
200 const bool isAudio = streamIndex == MF_SOURCE_READER_FIRST_AUDIO_STREAM;
201 int32 goodSamples = 1;
202 TimeSpan validTimeRangeStart(0), validTimeRangeEnd(0);
203 if (isAudio)
204 {
205 constexpr int32 AudioFramesQueue = 10; // How many frames to read into the audio buffers queue in advance (to improve audio playback smoothness)
206 if (player.AudioBufferDuration.Ticks == 0)
207 {
208 // Read more samples for audio to enqueue multiple audio buffers for smoother playback
209 goodSamples = AudioFramesQueue;
210 }
211 else
212 {
213 // Skip reading if the last sample was already over this range (we've got enough in a queue)
214 validTimeRangeStart = player.AudioBufferTime - player.AudioBufferDuration * AudioFramesQueue;
215 validTimeRangeEnd = validTimeRangeStart + player.AudioBufferDuration;
216 if (Math::IsInRange(playerMF.Time, validTimeRangeStart, validTimeRangeEnd))
217 {
218 return false;
219 }
220
221 // Allow to read future samples within queue range
222 validTimeRangeStart = player.AudioBufferTime - player.AudioBufferDuration;
223 validTimeRangeEnd = player.AudioBufferTime + player.AudioBufferDuration * AudioFramesQueue;
224
225 // Read more samples to keep queue at capacity
226 TimeSpan targetQueueEnd = playerMF.Time + player.AudioBufferDuration * AudioFramesQueue;
227 TimeSpan activeBufferEnd = player.AudioBufferTime + player.AudioBufferDuration;
228 TimeSpan missingQueueDuration = targetQueueEnd - activeBufferEnd;
229 goodSamples = (int32)Math::DivideAndRoundUp(missingQueueDuration.Ticks, player.AudioBufferDuration.Ticks);
230 if (goodSamples < 1)
231 goodSamples = 1;
232 }
233 }
234 else if (isVideo)
235 {
236 // Check if the current frame is valid (eg. when playing 24fps video at 60fps)
237 if (player.VideoFrameDuration.Ticks > 0 &&
238 Math::IsInRange(playerMF.Time, player.VideoFrameTime, player.VideoFrameTime + player.VideoFrameDuration))
239 {
240 return false;
241 }
242 }
243
244 // Read samples until frame is matching the current time
245 int32 samplesLeft = 500;
246 int32 goodSamplesLeft = goodSamples;
247 HRESULT hr;
248 for (; samplesLeft > 0 && goodSamplesLeft > 0; samplesLeft--)
249 {
250 // Read sample
251 DWORD flags = 0;
252 LONGLONG samplePos = 0, sampleDuration = 0;

Callers 1

UpdatePlayerFunction · 0.70

Calls 9

IsInRangeFunction · 0.85
DivideAndRoundUpFunction · 0.85
ConfigureFunction · 0.85
LockMethod · 0.80
UpdateVideoFrameMethod · 0.80
UpdateAudioBufferMethod · 0.80
UnlockMethod · 0.80
QueryInterfaceMethod · 0.45
ReleaseMethod · 0.45

Tested by

no test coverage detected