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