Framefiles can now contain videos without matching audio tracks.
This commit is contained in:
parent
c54101b14b
commit
57bb9c7703
1 changed files with 109 additions and 96 deletions
|
@ -235,17 +235,17 @@ int32_t _loadVideoAndAudio(char *vFilename, char *aFilename, char *indexPath, bo
|
||||||
|
|
||||||
// Find audio track
|
// Find audio track
|
||||||
v->audioTrack = FFMS_GetFirstTrackOfType(aIndex, FFMS_TYPE_AUDIO, &v->errInfo);
|
v->audioTrack = FFMS_GetFirstTrackOfType(aIndex, FFMS_TYPE_AUDIO, &v->errInfo);
|
||||||
if (v->audioTrack < 0) utilDie("%s", v->errInfo.Buffer);
|
if (v->audioTrack >= 0) {
|
||||||
v->audioSource = FFMS_CreateAudioSource(aFilename, v->audioTrack, aIndex, FFMS_DELAY_FIRST_VIDEO_TRACK, &v->errInfo);
|
v->audioSource = FFMS_CreateAudioSource(aFilename, v->audioTrack, aIndex, FFMS_DELAY_FIRST_VIDEO_TRACK, &v->errInfo);
|
||||||
if (v->audioSource == NULL) utilDie("%s", v->errInfo.Buffer);
|
if (v->audioSource == NULL) utilDie("%s", v->errInfo.Buffer);
|
||||||
|
|
||||||
// Get audio properties
|
// Get audio properties
|
||||||
v->audioProps = FFMS_GetAudioProperties(v->audioSource);
|
v->audioProps = FFMS_GetAudioProperties(v->audioSource);
|
||||||
|
}
|
||||||
|
|
||||||
// Indicies are now part of audioSource & videoSource, so release these
|
// Indicies are now part of audioSource & videoSource, so release these
|
||||||
FFMS_DestroyIndex(vIndex);
|
FFMS_DestroyIndex(vIndex);
|
||||||
vIndex = NULL;
|
vIndex = NULL;
|
||||||
if (aFilename != vFilename) {
|
if ((aFilename != vFilename) && (aIndex)) {
|
||||||
FFMS_DestroyIndex(aIndex);
|
FFMS_DestroyIndex(aIndex);
|
||||||
}
|
}
|
||||||
aIndex = NULL;
|
aIndex = NULL;
|
||||||
|
@ -258,6 +258,8 @@ int32_t _loadVideoAndAudio(char *vFilename, char *aFilename, char *indexPath, bo
|
||||||
SDL_RenderSetLogicalSize(renderer, v->propFrame->EncodedWidth, v->propFrame->EncodedHeight);
|
SDL_RenderSetLogicalSize(renderer, v->propFrame->EncodedWidth, v->propFrame->EncodedHeight);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Do we have audio?
|
||||||
|
if (v->audioSource) {
|
||||||
// Determine audio format
|
// Determine audio format
|
||||||
switch (v->audioProps->SampleFormat) {
|
switch (v->audioProps->SampleFormat) {
|
||||||
case FFMS_FMT_U8:
|
case FFMS_FMT_U8:
|
||||||
|
@ -308,6 +310,7 @@ int32_t _loadVideoAndAudio(char *vFilename, char *aFilename, char *indexPath, bo
|
||||||
|
|
||||||
// Register effect to provide video stream audio on this channel
|
// Register effect to provide video stream audio on this channel
|
||||||
Mix_RegisterEffect(v->audioSilenceChannel, _dequeueVideoAudio, NULL, v);
|
Mix_RegisterEffect(v->audioSilenceChannel, _dequeueVideoAudio, NULL, v);
|
||||||
|
}
|
||||||
|
|
||||||
// Default volume, in percent
|
// Default volume, in percent
|
||||||
v->volumeLeft = 100;
|
v->volumeLeft = 100;
|
||||||
|
@ -518,16 +521,17 @@ int32_t videoUnload(int32_t playerHandle) {
|
||||||
HASH_FIND_INT(_videoPlayerHash, &playerHandle, v);
|
HASH_FIND_INT(_videoPlayerHash, &playerHandle, v);
|
||||||
if (!v) utilDie("No video player at index %d in videoStop.", playerHandle);
|
if (!v) utilDie("No video player at index %d in videoStop.", playerHandle);
|
||||||
|
|
||||||
|
if (v->audioSource) {
|
||||||
Mix_HaltChannel(v->audioSilenceChannel);
|
Mix_HaltChannel(v->audioSilenceChannel);
|
||||||
Mix_UnregisterEffect(v->audioSilenceChannel, _dequeueVideoAudio);
|
Mix_UnregisterEffect(v->audioSilenceChannel, _dequeueVideoAudio);
|
||||||
Mix_FreeChunk(v->silenceChunk);
|
Mix_FreeChunk(v->silenceChunk);
|
||||||
free(v->audioSilenceRaw);
|
free(v->audioSilenceRaw);
|
||||||
SDL_FreeAudioStream(v->audioStream);
|
SDL_FreeAudioStream(v->audioStream);
|
||||||
free(v->audioBuffer);
|
free(v->audioBuffer);
|
||||||
|
|
||||||
FFMS_DestroyAudioSource(v->audioSource);
|
FFMS_DestroyAudioSource(v->audioSource);
|
||||||
FFMS_DestroyVideoSource(v->videoSource);
|
}
|
||||||
|
|
||||||
|
FFMS_DestroyVideoSource(v->videoSource);
|
||||||
SDL_DestroyTexture(v->videoTexture);
|
SDL_DestroyTexture(v->videoTexture);
|
||||||
|
|
||||||
#pragma GCC diagnostic push
|
#pragma GCC diagnostic push
|
||||||
|
@ -552,7 +556,11 @@ int32_t videoUpdate(int32_t playerHandle, SDL_Texture **texture) {
|
||||||
if (!v) utilDie("No video player at index %d in videoUpdate.", playerHandle);
|
if (!v) utilDie("No video player at index %d in videoUpdate.", playerHandle);
|
||||||
|
|
||||||
// Audio drift limit
|
// Audio drift limit
|
||||||
|
if (v->audioSource) {
|
||||||
threshold = (v->audioProps->SampleRate / 2);
|
threshold = (v->audioProps->SampleRate / 2);
|
||||||
|
} else {
|
||||||
|
threshold = 99999;
|
||||||
|
}
|
||||||
|
|
||||||
// Handle video frames (and time)
|
// Handle video frames (and time)
|
||||||
if ((SDL_GetTicks() - v->lastTickTime >= v->frameDeltaTime) || (v->audioDelta > threshold) || v->resetTime) {
|
if ((SDL_GetTicks() - v->lastTickTime >= v->frameDeltaTime) || (v->audioDelta > threshold) || v->resetTime) {
|
||||||
|
@ -567,6 +575,7 @@ int32_t videoUpdate(int32_t playerHandle, SDL_Texture **texture) {
|
||||||
result = v->frame;
|
result = v->frame;
|
||||||
v->framesPlayed++;
|
v->framesPlayed++;
|
||||||
|
|
||||||
|
if (v->audioSource) {
|
||||||
// Did we trip the audio sync compensation?
|
// Did we trip the audio sync compensation?
|
||||||
if (v->audioDelta > threshold) {
|
if (v->audioDelta > threshold) {
|
||||||
// Adjust frame rate to try and match
|
// Adjust frame rate to try and match
|
||||||
|
@ -576,9 +585,9 @@ int32_t videoUpdate(int32_t playerHandle, SDL_Texture **texture) {
|
||||||
v->audioAdjustment -= 0.000001;
|
v->audioAdjustment -= 0.000001;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Used to determine if we should play two frames rapidly to catch up to audio
|
// Used to determine if we should play two frames rapidly to catch up to audio
|
||||||
v->audioDelta = labs(v->audioPosition - (int64_t)((double)v->timestamp * 0.001 * (double)v->audioProps->SampleRate));
|
v->audioDelta = labs(v->audioPosition - (int64_t)((double)v->timestamp * 0.001 * (double)v->audioProps->SampleRate));
|
||||||
|
}
|
||||||
|
|
||||||
//utilSay("D %ld T %ld A %f", v->audioDelta, threshold, v->audioAdjustment);
|
//utilSay("D %ld T %ld A %f", v->audioDelta, threshold, v->audioAdjustment);
|
||||||
|
|
||||||
|
@ -598,17 +607,20 @@ int32_t videoUpdate(int32_t playerHandle, SDL_Texture **texture) {
|
||||||
}
|
}
|
||||||
|
|
||||||
if (v->resetTime) {
|
if (v->resetTime) {
|
||||||
|
if (v->audioSource) {
|
||||||
SDL_AudioStreamClear(v->audioStream);
|
SDL_AudioStreamClear(v->audioStream);
|
||||||
|
v->audioPosition = (int64_t)((double)v->timestamp * 0.001 * (double)v->audioProps->SampleRate);
|
||||||
|
v->audioDelta = 0;
|
||||||
|
}
|
||||||
v->lastTickTime = 0;
|
v->lastTickTime = 0;
|
||||||
v->frameDeltaTime = 0;
|
v->frameDeltaTime = 0;
|
||||||
v->audioPosition = (int64_t)((double)v->timestamp * 0.001 * (double)v->audioProps->SampleRate);
|
|
||||||
v->resetTime = false;
|
v->resetTime = false;
|
||||||
v->audioDelta = 0;
|
|
||||||
v->framesPlayed = 0;
|
v->framesPlayed = 0;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Handle audio samples
|
// Handle audio samples
|
||||||
|
if (v->audioSource) {
|
||||||
if ((v->playing) && (SDL_AudioStreamAvailable(v->audioStream) < AUDIO_STREAM_LOW_WATERMARK) && (v->audioPosition < v->audioProps->NumSamples)) {
|
if ((v->playing) && (SDL_AudioStreamAvailable(v->audioStream) < AUDIO_STREAM_LOW_WATERMARK) && (v->audioPosition < v->audioProps->NumSamples)) {
|
||||||
// Maximum samples we can read at a time
|
// Maximum samples we can read at a time
|
||||||
count = AUDIO_SAMPLE_PREREAD;
|
count = AUDIO_SAMPLE_PREREAD;
|
||||||
|
@ -625,6 +637,7 @@ int32_t videoUpdate(int32_t playerHandle, SDL_Texture **texture) {
|
||||||
v->audioPosition += count;
|
v->audioPosition += count;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
Loading…
Add table
Reference in a new issue