Fixes for audio playback in videos
This commit is contained in:
@@ -330,7 +330,11 @@ namespace MF
|
||||
if (sample)
|
||||
sample->Release();
|
||||
if (isGoodSample)
|
||||
{
|
||||
goodSamplesLeft--;
|
||||
if (!sample)
|
||||
return true; // Got good sample but without data so seek
|
||||
}
|
||||
|
||||
if (flags & MF_SOURCE_READERF_ENDOFSTREAM)
|
||||
{
|
||||
@@ -392,6 +396,7 @@ namespace MF
|
||||
}
|
||||
|
||||
// Update current position
|
||||
bool canSeek = true;
|
||||
SEEK_START:
|
||||
if (playerMF.Seek)
|
||||
{
|
||||
@@ -418,7 +423,12 @@ namespace MF
|
||||
{
|
||||
// Failed to pick a valid sample so try again with seeking
|
||||
playerMF.Seek = 1;
|
||||
goto SEEK_START;
|
||||
if (canSeek)
|
||||
{
|
||||
// Prevent deadlock on sync
|
||||
canSeek = false;
|
||||
goto SEEK_START;
|
||||
}
|
||||
}
|
||||
if (player.AudioInfo.BitDepth != 0)
|
||||
ReadStream(player, playerMF, MF_SOURCE_READER_FIRST_AUDIO_STREAM, dt);
|
||||
@@ -497,6 +507,7 @@ void VideoBackendMF::Player_Play(VideoBackendPlayer& player)
|
||||
PROFILE_CPU();
|
||||
auto& playerMF = player.GetBackendState<VideoPlayerMF>();
|
||||
playerMF.Playing = 1;
|
||||
player.PlayAudio();
|
||||
}
|
||||
|
||||
void VideoBackendMF::Player_Pause(VideoBackendPlayer& player)
|
||||
@@ -504,6 +515,7 @@ void VideoBackendMF::Player_Pause(VideoBackendPlayer& player)
|
||||
PROFILE_CPU();
|
||||
auto& playerMF = player.GetBackendState<VideoPlayerMF>();
|
||||
playerMF.Playing = 0;
|
||||
player.PauseAudio();
|
||||
}
|
||||
|
||||
void VideoBackendMF::Player_Stop(VideoBackendPlayer& player)
|
||||
@@ -514,14 +526,19 @@ void VideoBackendMF::Player_Stop(VideoBackendPlayer& player)
|
||||
playerMF.Playing = 0;
|
||||
playerMF.FirstFrame = 1;
|
||||
playerMF.Seek = 1;
|
||||
player.StopAudio();
|
||||
}
|
||||
|
||||
void VideoBackendMF::Player_Seek(VideoBackendPlayer& player, TimeSpan time)
|
||||
{
|
||||
PROFILE_CPU();
|
||||
auto& playerMF = player.GetBackendState<VideoPlayerMF>();
|
||||
playerMF.Time = time;
|
||||
playerMF.Seek = 1;
|
||||
if (playerMF.Time != time)
|
||||
{
|
||||
playerMF.Time = time;
|
||||
playerMF.Seek = 1;
|
||||
player.StopAudio();
|
||||
}
|
||||
}
|
||||
|
||||
TimeSpan VideoBackendMF::Player_GetTime(const VideoBackendPlayer& player)
|
||||
|
||||
@@ -35,6 +35,7 @@ struct VideoBackendPlayer
|
||||
int32 VideoFrameWidth, VideoFrameHeight;
|
||||
PixelFormat Format;
|
||||
float FrameRate;
|
||||
uint8 IsAudioPlayPending : 1;
|
||||
TimeSpan Duration;
|
||||
TimeSpan VideoFrameTime, VideoFrameDuration;
|
||||
TimeSpan AudioBufferTime, AudioBufferDuration;
|
||||
@@ -67,6 +68,9 @@ struct VideoBackendPlayer
|
||||
}
|
||||
|
||||
void Created(const VideoBackendPlayerInfo& info);
|
||||
void PlayAudio();
|
||||
void PauseAudio();
|
||||
void StopAudio();
|
||||
void InitVideoFrame();
|
||||
void UpdateVideoFrame(Span<byte> data, TimeSpan time, TimeSpan duration);
|
||||
void UpdateAudioBuffer(Span<byte> data, TimeSpan time, TimeSpan duration);
|
||||
|
||||
@@ -214,6 +214,33 @@ void VideoBackendPlayer::Created(const VideoBackendPlayerInfo& info)
|
||||
#endif
|
||||
}
|
||||
|
||||
void VideoBackendPlayer::PlayAudio()
|
||||
{
|
||||
if (AudioSource)
|
||||
{
|
||||
IsAudioPlayPending = 0;
|
||||
AudioBackend::Source::Play(AudioSource);
|
||||
}
|
||||
}
|
||||
|
||||
void VideoBackendPlayer::PauseAudio()
|
||||
{
|
||||
if (AudioSource)
|
||||
{
|
||||
IsAudioPlayPending = 0;
|
||||
AudioBackend::Source::Pause(AudioSource);
|
||||
}
|
||||
}
|
||||
|
||||
void VideoBackendPlayer::StopAudio()
|
||||
{
|
||||
if (AudioSource)
|
||||
{
|
||||
AudioBackend::Source::Stop(AudioSource);
|
||||
IsAudioPlayPending = 1;
|
||||
}
|
||||
}
|
||||
|
||||
void VideoBackendPlayer::InitVideoFrame()
|
||||
{
|
||||
if (!GPUDevice::Instance)
|
||||
@@ -282,12 +309,12 @@ void VideoBackendPlayer::UpdateAudioBuffer(Span<byte> data, TimeSpan time, TimeS
|
||||
return;
|
||||
|
||||
// Setup audio source
|
||||
bool newSource = AudioSource == 0;
|
||||
if (newSource)
|
||||
if (AudioSource == 0)
|
||||
{
|
||||
// TODO: spatial video player
|
||||
// TODO: video player volume/pan control
|
||||
AudioSource = AudioBackend::Source::Add(AudioInfo, Vector3::Zero, Quaternion::Identity, 1.0f, 1.0f, 0.0f, false, false, 1.0f, 1000.0f, 1.0f);
|
||||
IsAudioPlayPending = 1;
|
||||
}
|
||||
else
|
||||
{
|
||||
@@ -320,8 +347,9 @@ void VideoBackendPlayer::UpdateAudioBuffer(Span<byte> data, TimeSpan time, TimeS
|
||||
|
||||
// Append audio buffer
|
||||
AudioBackend::Source::QueueBuffer(AudioSource, bufferId);
|
||||
if (newSource)
|
||||
if (IsAudioPlayPending)
|
||||
{
|
||||
IsAudioPlayPending = 0;
|
||||
AudioBackend::Source::Play(AudioSource);
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user