Multiple audio tracks now supported.
This commit is contained in:
parent
191001e3a6
commit
b0a66bf4a4
4 changed files with 353 additions and 77 deletions
|
@ -48,7 +48,7 @@ function buildAll() {
|
||||||
|
|
||||||
mkdir -p ${G_GENERATED}
|
mkdir -p ${G_GENERATED}
|
||||||
|
|
||||||
if [[ 1 == 1 ]]; then
|
if [[ 0 == 1 ]]; then
|
||||||
pushd thirdparty/bzip2
|
pushd thirdparty/bzip2
|
||||||
clearAndEnterBuild
|
clearAndEnterBuild
|
||||||
cmake ${COMMON} \
|
cmake ${COMMON} \
|
||||||
|
@ -94,7 +94,6 @@ if [[ 1 == 1 ]]; then
|
||||||
..
|
..
|
||||||
make install
|
make install
|
||||||
popd
|
popd
|
||||||
fi
|
|
||||||
|
|
||||||
pushd thirdparty/SDL2_image
|
pushd thirdparty/SDL2_image
|
||||||
clearAndEnterBuild
|
clearAndEnterBuild
|
||||||
|
@ -132,7 +131,6 @@ fi
|
||||||
cp -f external/libwebp/libwebpdemux.a "${G_TARGET}/lib/."
|
cp -f external/libwebp/libwebpdemux.a "${G_TARGET}/lib/."
|
||||||
popd
|
popd
|
||||||
|
|
||||||
if [[ 1 == 1 ]]; then
|
|
||||||
pushd thirdparty/SDL2_mixer
|
pushd thirdparty/SDL2_mixer
|
||||||
clearAndEnterBuild
|
clearAndEnterBuild
|
||||||
cmake ${COMMON} \
|
cmake ${COMMON} \
|
||||||
|
@ -503,7 +501,7 @@ sudo apt-get install -y \
|
||||||
|
|
||||||
|
|
||||||
buildAll linux x86_64 2>&1 | tee ${G_BUILDDIR}/linux-x86_64.log
|
buildAll linux x86_64 2>&1 | tee ${G_BUILDDIR}/linux-x86_64.log
|
||||||
buildAll windows x86_64 2>&1 | tee ${G_BUILDDIR}/windows-x86_64.log
|
#buildAll windows x86_64 2>&1 | tee ${G_BUILDDIR}/windows-x86_64.log
|
||||||
|
|
||||||
#buildAll linux x86
|
#buildAll linux x86
|
||||||
#buildAll macos aarch64
|
#buildAll macos aarch64
|
||||||
|
|
199
src/singe.c
199
src/singe.c
|
@ -63,6 +63,9 @@ LSEC_API int luaopen_ssl_config(lua_State *L);
|
||||||
|
|
||||||
//#define DEBUG_TOOLS
|
//#define DEBUG_TOOLS
|
||||||
|
|
||||||
|
#define INDEX_DISPLAY_START -1
|
||||||
|
#define INDEX_DISPLAY_STOP -2
|
||||||
|
|
||||||
#define AUDIO_MAX_VOLUME 63
|
#define AUDIO_MAX_VOLUME 63
|
||||||
#define MAX_TITLE_LENGTH 1024
|
#define MAX_TITLE_LENGTH 1024
|
||||||
#define MAX_MICE 4
|
#define MAX_MICE 4
|
||||||
|
@ -197,7 +200,7 @@ enum {
|
||||||
INPUT_QUIT,
|
INPUT_QUIT,
|
||||||
INPUT_PAUSE,
|
INPUT_PAUSE,
|
||||||
INPUT_CONSOLE,
|
INPUT_CONSOLE,
|
||||||
// Added in Singe 2.x
|
// Added in Singe 2.00
|
||||||
INPUT_ACTION_4,
|
INPUT_ACTION_4,
|
||||||
INPUT_TILT,
|
INPUT_TILT,
|
||||||
INPUT_GRAB,
|
INPUT_GRAB,
|
||||||
|
@ -304,6 +307,8 @@ int32_t apiDebugPrint(lua_State *L);
|
||||||
|
|
||||||
int32_t apiDiscAudio(lua_State *L);
|
int32_t apiDiscAudio(lua_State *L);
|
||||||
int32_t apiDiscChangeSpeed(lua_State *L);
|
int32_t apiDiscChangeSpeed(lua_State *L);
|
||||||
|
int32_t apiDiscGetAudioTrack(lua_State *L);
|
||||||
|
int32_t apiDiscGetAudioTracks(lua_State *L);
|
||||||
int32_t apiDiscGetFrame(lua_State *L);
|
int32_t apiDiscGetFrame(lua_State *L);
|
||||||
int32_t apiDiscGetHeight(lua_State *L);
|
int32_t apiDiscGetHeight(lua_State *L);
|
||||||
int32_t apiDiscGetState(lua_State *L);
|
int32_t apiDiscGetState(lua_State *L);
|
||||||
|
@ -313,6 +318,7 @@ int32_t apiDiscPauseAtFrame(lua_State *L);
|
||||||
int32_t apiDiscPlay(lua_State *L);
|
int32_t apiDiscPlay(lua_State *L);
|
||||||
int32_t apiDiscSearch(lua_State *L);
|
int32_t apiDiscSearch(lua_State *L);
|
||||||
int32_t apiDiscSearchBlanking(lua_State *L);
|
int32_t apiDiscSearchBlanking(lua_State *L);
|
||||||
|
int32_t apiDiscSetAudioTrack(lua_State *L);
|
||||||
int32_t apiDiscSetFps(lua_State *L);
|
int32_t apiDiscSetFps(lua_State *L);
|
||||||
int32_t apiDiscSkipBackward(lua_State *L);
|
int32_t apiDiscSkipBackward(lua_State *L);
|
||||||
int32_t apiDiscSkipBlanking(lua_State *L);
|
int32_t apiDiscSkipBlanking(lua_State *L);
|
||||||
|
@ -389,6 +395,8 @@ int32_t apiSpriteScale(lua_State *L);
|
||||||
int32_t apiSpriteUnload(lua_State *L);
|
int32_t apiSpriteUnload(lua_State *L);
|
||||||
|
|
||||||
int32_t apiVideoDraw(lua_State *L);
|
int32_t apiVideoDraw(lua_State *L);
|
||||||
|
int32_t apiVideoGetAudioTrack(lua_State *L);
|
||||||
|
int32_t apiVideoGetAudioTracks(lua_State *L);
|
||||||
int32_t apiVideoGetFrame(lua_State *L);
|
int32_t apiVideoGetFrame(lua_State *L);
|
||||||
int32_t apiVideoGetFrameCount(lua_State *L);
|
int32_t apiVideoGetFrameCount(lua_State *L);
|
||||||
int32_t apiVideoGetHeight(lua_State *L);
|
int32_t apiVideoGetHeight(lua_State *L);
|
||||||
|
@ -399,6 +407,7 @@ int32_t apiVideoLoad(lua_State *L);
|
||||||
int32_t apiVideoPause(lua_State *L);
|
int32_t apiVideoPause(lua_State *L);
|
||||||
int32_t apiVideoPlay(lua_State *L);
|
int32_t apiVideoPlay(lua_State *L);
|
||||||
int32_t apiVideoSeek(lua_State *L);
|
int32_t apiVideoSeek(lua_State *L);
|
||||||
|
int32_t apiVideoSetAudioTrack(lua_State *L);
|
||||||
int32_t apiVideoSetVolume(lua_State *L);
|
int32_t apiVideoSetVolume(lua_State *L);
|
||||||
int32_t apiVideoUnload(lua_State *L);
|
int32_t apiVideoUnload(lua_State *L);
|
||||||
|
|
||||||
|
@ -621,6 +630,50 @@ int32_t apiDiscChangeSpeed(lua_State *L) {
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
int32_t apiDiscGetAudioTrack(lua_State *L) {
|
||||||
|
bool result = false;
|
||||||
|
int64_t r = 0;
|
||||||
|
|
||||||
|
(void)L;
|
||||||
|
|
||||||
|
if (_global.videoHandle >= 0) {
|
||||||
|
r = videoGetAudioTrack(_global.videoHandle);
|
||||||
|
result = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (result) {
|
||||||
|
luaTrace(L, "discGetAudioTrack", "%ld", r);
|
||||||
|
} else {
|
||||||
|
luaDie(L, "discGetAudioTrack", "Failed!");
|
||||||
|
}
|
||||||
|
|
||||||
|
lua_pushnumber(L, r);
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
int32_t apiDiscGetAudioTracks(lua_State *L) {
|
||||||
|
bool result = false;
|
||||||
|
int64_t r = 0;
|
||||||
|
|
||||||
|
(void)L;
|
||||||
|
|
||||||
|
if (_global.videoHandle >= 0) {
|
||||||
|
r = videoGetAudioTracks(_global.videoHandle);
|
||||||
|
result = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (result) {
|
||||||
|
luaTrace(L, "discGetAudioTracks", "%ld", r);
|
||||||
|
} else {
|
||||||
|
luaDie(L, "discGetAudioTracks", "Failed!");
|
||||||
|
}
|
||||||
|
|
||||||
|
lua_pushnumber(L, r);
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
int32_t apiDiscGetFrame(lua_State *L) {
|
int32_t apiDiscGetFrame(lua_State *L) {
|
||||||
int64_t frame = 0;
|
int64_t frame = 0;
|
||||||
|
|
||||||
|
@ -707,6 +760,36 @@ int32_t apiDiscSearchBlanking(lua_State *L) {
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
int32_t apiDiscSetAudioTrack(lua_State *L) {
|
||||||
|
int32_t n = lua_gettop(L);
|
||||||
|
bool result = false;
|
||||||
|
int64_t track = 0;
|
||||||
|
double d;
|
||||||
|
|
||||||
|
if (n == 1) {
|
||||||
|
if (lua_isnumber(L, 1)) {
|
||||||
|
d = lua_tonumber(L, 1); track = (int32_t)d;
|
||||||
|
if (_global.videoHandle >= 0) {
|
||||||
|
if ((track >= 0) && (track < videoGetAudioTracks(_global.videoHandle))) {
|
||||||
|
videoSetAudioTrack(_global.videoHandle, track);
|
||||||
|
} else {
|
||||||
|
luaDie(L, "discSetAudioTrack", "Invalid audio track in apiDiscSetAudioTrack.");
|
||||||
|
}
|
||||||
|
result = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (result) {
|
||||||
|
luaTrace(L, "discSetAudioTrack", "%d", track);
|
||||||
|
} else {
|
||||||
|
luaDie(L, "discSetAudioTrack", "Failed!");
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
int32_t apiDiscSetFps(lua_State *L) {
|
int32_t apiDiscSetFps(lua_State *L) {
|
||||||
(void)L;
|
(void)L;
|
||||||
//***REMOVED***
|
//***REMOVED***
|
||||||
|
@ -2251,6 +2334,66 @@ int32_t apiVideoDraw(lua_State *L) {
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
int32_t apiVideoGetAudioTrack(lua_State *L) {
|
||||||
|
int32_t n = lua_gettop(L);
|
||||||
|
bool result = false;
|
||||||
|
int64_t r = 0;
|
||||||
|
int32_t id = -1;
|
||||||
|
double d;
|
||||||
|
VideoT *video = NULL;
|
||||||
|
|
||||||
|
if (n == 1) {
|
||||||
|
if (lua_isnumber(L, 1)) {
|
||||||
|
d = lua_tonumber(L, 1); id = (int32_t)d;
|
||||||
|
// Get our video structure
|
||||||
|
HASH_FIND_INT(_global.videoList, &id, video);
|
||||||
|
if (!video) luaDie(L, "videoGetAudioTrack", "No video at index %d in apiVideoGetAudioTrack.", id);
|
||||||
|
r = videoGetAudioTrack(video->handle);
|
||||||
|
result = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (result) {
|
||||||
|
luaTrace(L, "videoGetAudioTrack", "%d %ld", id, r);
|
||||||
|
} else {
|
||||||
|
luaDie(L, "videoGetAudioTrack", "Failed!");
|
||||||
|
}
|
||||||
|
|
||||||
|
lua_pushnumber(L, r);
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
int32_t apiVideoGetAudioTracks(lua_State *L) {
|
||||||
|
int32_t n = lua_gettop(L);
|
||||||
|
bool result = false;
|
||||||
|
int64_t r = 0;
|
||||||
|
int32_t id = -1;
|
||||||
|
double d;
|
||||||
|
VideoT *video = NULL;
|
||||||
|
|
||||||
|
if (n == 1) {
|
||||||
|
if (lua_isnumber(L, 1)) {
|
||||||
|
d = lua_tonumber(L, 1); id = (int32_t)d;
|
||||||
|
// Get our video structure
|
||||||
|
HASH_FIND_INT(_global.videoList, &id, video);
|
||||||
|
if (!video) luaDie(L, "videoGetAudioTracks", "No video at index %d in apiVideoGetAudioTracks.", id);
|
||||||
|
r = videoGetAudioTracks(video->handle);
|
||||||
|
result = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (result) {
|
||||||
|
luaTrace(L, "videoGetAudioTracks", "%d %ld", id, r);
|
||||||
|
} else {
|
||||||
|
luaDie(L, "videoGetAudioTracks", "Failed!");
|
||||||
|
}
|
||||||
|
|
||||||
|
lua_pushnumber(L, r);
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
int32_t apiVideoGetFrame(lua_State *L) {
|
int32_t apiVideoGetFrame(lua_State *L) {
|
||||||
int32_t n = lua_gettop(L);
|
int32_t n = lua_gettop(L);
|
||||||
bool result = false;
|
bool result = false;
|
||||||
|
@ -2536,7 +2679,7 @@ int32_t apiVideoPlay(lua_State *L) {
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
int32_t apiVideoSeek(lua_State *L) {
|
int32_t apiVideoSeek(lua_State *L) {
|
||||||
int32_t n = lua_gettop(L);
|
int32_t n = lua_gettop(L);
|
||||||
bool result = false;
|
bool result = false;
|
||||||
int32_t id = -1;
|
int32_t id = -1;
|
||||||
|
@ -2568,7 +2711,43 @@ int32_t apiVideoSeek(lua_State *L) {
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
int32_t apiVideoSetVolume(lua_State *L) {
|
int32_t apiVideoSetAudioTrack(lua_State *L) {
|
||||||
|
int32_t n = lua_gettop(L);
|
||||||
|
bool result = false;
|
||||||
|
int32_t id = -1;
|
||||||
|
int64_t track = 0;
|
||||||
|
double d;
|
||||||
|
VideoT *video = NULL;
|
||||||
|
|
||||||
|
if (n == 2) {
|
||||||
|
if (lua_isnumber(L, 1)) {
|
||||||
|
if (lua_isnumber(L, 2)) {
|
||||||
|
d = lua_tonumber(L, 1); id = (int32_t)d;
|
||||||
|
d = lua_tonumber(L, 2); track = (int32_t)d;
|
||||||
|
// Get our video structure
|
||||||
|
HASH_FIND_INT(_global.videoList, &id, video);
|
||||||
|
if (!video) luaDie(L, "videoSetAudioTrack", "No video at index %d in apiVideoSetAudioTrack.", id);
|
||||||
|
if ((track >= 0) && (track < videoGetAudioTracks(video->handle))) {
|
||||||
|
videoSetAudioTrack(video->handle, track);
|
||||||
|
} else {
|
||||||
|
luaDie(L, "videoSetAudioTrack", "Invalid audio track in video at index %d in apiVideoSetAudioTrack.", id);
|
||||||
|
}
|
||||||
|
result = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (result) {
|
||||||
|
luaTrace(L, "videoSetAudioTrack", "%d %d", id, track);
|
||||||
|
} else {
|
||||||
|
luaDie(L, "videoSetAudioTrack", "Failed!");
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
int32_t apiVideoSetVolume(lua_State *L) {
|
||||||
int32_t n = lua_gettop(L);
|
int32_t n = lua_gettop(L);
|
||||||
bool result = false;
|
bool result = false;
|
||||||
int32_t id = -1;
|
int32_t id = -1;
|
||||||
|
@ -3303,7 +3482,7 @@ void doIndexDisplay(int32_t percent) {
|
||||||
// 'percent' 0 to 100 is the actual display.
|
// 'percent' 0 to 100 is the actual display.
|
||||||
// 'percent' -2 shuts the display down.
|
// 'percent' -2 shuts the display down.
|
||||||
|
|
||||||
if (percent == -1) {
|
if (percent == INDEX_DISPLAY_START) {
|
||||||
// Setup
|
// Setup
|
||||||
SDL_RenderGetLogicalSize(_global.renderer, &oldW, &oldH);
|
SDL_RenderGetLogicalSize(_global.renderer, &oldW, &oldH);
|
||||||
SDL_RenderSetLogicalSize(_global.renderer, screenW, screenH);
|
SDL_RenderSetLogicalSize(_global.renderer, screenW, screenH);
|
||||||
|
@ -3328,7 +3507,7 @@ void doIndexDisplay(int32_t percent) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (percent == -2) {
|
if (percent == INDEX_DISPLAY_STOP) {
|
||||||
// Shutdown
|
// Shutdown
|
||||||
SDL_DestroyTexture(texDisc);
|
SDL_DestroyTexture(texDisc);
|
||||||
SDL_DestroyTexture(texGlass);
|
SDL_DestroyTexture(texGlass);
|
||||||
|
@ -3949,6 +4128,8 @@ void singe(SDL_Window *window, SDL_Renderer *renderer, ConfigT *conf) {
|
||||||
|
|
||||||
lua_register(_global.luaContext, "discAudio", apiDiscAudio);
|
lua_register(_global.luaContext, "discAudio", apiDiscAudio);
|
||||||
lua_register(_global.luaContext, "discChangeSpeed", apiDiscChangeSpeed);
|
lua_register(_global.luaContext, "discChangeSpeed", apiDiscChangeSpeed);
|
||||||
|
lua_register(_global.luaContext, "discGetAudioTrack", apiDiscGetAudioTrack);
|
||||||
|
lua_register(_global.luaContext, "discGetAudioTracks", apiDiscGetAudioTracks);
|
||||||
lua_register(_global.luaContext, "discGetFrame", apiDiscGetFrame);
|
lua_register(_global.luaContext, "discGetFrame", apiDiscGetFrame);
|
||||||
lua_register(_global.luaContext, "discGetHeight", apiDiscGetHeight);
|
lua_register(_global.luaContext, "discGetHeight", apiDiscGetHeight);
|
||||||
lua_register(_global.luaContext, "discGetState", apiDiscGetState);
|
lua_register(_global.luaContext, "discGetState", apiDiscGetState);
|
||||||
|
@ -3958,6 +4139,7 @@ void singe(SDL_Window *window, SDL_Renderer *renderer, ConfigT *conf) {
|
||||||
lua_register(_global.luaContext, "discPlay", apiDiscPlay);
|
lua_register(_global.luaContext, "discPlay", apiDiscPlay);
|
||||||
lua_register(_global.luaContext, "discSearch", apiDiscSearch);
|
lua_register(_global.luaContext, "discSearch", apiDiscSearch);
|
||||||
lua_register(_global.luaContext, "discSearchBlanking", apiDiscSearchBlanking);
|
lua_register(_global.luaContext, "discSearchBlanking", apiDiscSearchBlanking);
|
||||||
|
lua_register(_global.luaContext, "discSetAudioTrack", apiDiscSetAudioTrack);
|
||||||
lua_register(_global.luaContext, "discSetFPS", apiDiscSetFps);
|
lua_register(_global.luaContext, "discSetFPS", apiDiscSetFps);
|
||||||
lua_register(_global.luaContext, "discSkipBackward", apiDiscSkipBackward);
|
lua_register(_global.luaContext, "discSkipBackward", apiDiscSkipBackward);
|
||||||
lua_register(_global.luaContext, "discSkipBlanking", apiDiscSkipBlanking);
|
lua_register(_global.luaContext, "discSkipBlanking", apiDiscSkipBlanking);
|
||||||
|
@ -4034,6 +4216,8 @@ void singe(SDL_Window *window, SDL_Renderer *renderer, ConfigT *conf) {
|
||||||
lua_register(_global.luaContext, "spriteUnload", apiSpriteUnload);
|
lua_register(_global.luaContext, "spriteUnload", apiSpriteUnload);
|
||||||
|
|
||||||
lua_register(_global.luaContext, "videoDraw", apiVideoDraw);
|
lua_register(_global.luaContext, "videoDraw", apiVideoDraw);
|
||||||
|
lua_register(_global.luaContext, "videoGetAudioTrack", apiVideoGetAudioTrack);
|
||||||
|
lua_register(_global.luaContext, "videoGetAudioTracks", apiVideoGetAudioTracks);
|
||||||
lua_register(_global.luaContext, "videoGetFrame", apiVideoGetFrame);
|
lua_register(_global.luaContext, "videoGetFrame", apiVideoGetFrame);
|
||||||
lua_register(_global.luaContext, "videoGetFrameCount", apiVideoGetFrameCount);
|
lua_register(_global.luaContext, "videoGetFrameCount", apiVideoGetFrameCount);
|
||||||
lua_register(_global.luaContext, "videoGetHeight", apiVideoGetHeight);
|
lua_register(_global.luaContext, "videoGetHeight", apiVideoGetHeight);
|
||||||
|
@ -4044,6 +4228,7 @@ void singe(SDL_Window *window, SDL_Renderer *renderer, ConfigT *conf) {
|
||||||
lua_register(_global.luaContext, "videoPause", apiVideoPause);
|
lua_register(_global.luaContext, "videoPause", apiVideoPause);
|
||||||
lua_register(_global.luaContext, "videoPlay", apiVideoPlay);
|
lua_register(_global.luaContext, "videoPlay", apiVideoPlay);
|
||||||
lua_register(_global.luaContext, "videoSeek", apiVideoSeek);
|
lua_register(_global.luaContext, "videoSeek", apiVideoSeek);
|
||||||
|
lua_register(_global.luaContext, "videoSetAudioTrack", apiVideoSetAudioTrack);
|
||||||
lua_register(_global.luaContext, "videoSetVolume", apiVideoSetVolume);
|
lua_register(_global.luaContext, "videoSetVolume", apiVideoSetVolume);
|
||||||
lua_register(_global.luaContext, "videoUnload", apiVideoUnload);
|
lua_register(_global.luaContext, "videoUnload", apiVideoUnload);
|
||||||
|
|
||||||
|
@ -4054,7 +4239,7 @@ void singe(SDL_Window *window, SDL_Renderer *renderer, ConfigT *conf) {
|
||||||
|
|
||||||
// Open main video file
|
// Open main video file
|
||||||
progTrace("Opening main video file");
|
progTrace("Opening main video file");
|
||||||
doIndexDisplay(-1);
|
doIndexDisplay(INDEX_DISPLAY_START);
|
||||||
videoSetIndexCallback(doIndexDisplay);
|
videoSetIndexCallback(doIndexDisplay);
|
||||||
if (_global.conf->isFrameFile) {
|
if (_global.conf->isFrameFile) {
|
||||||
_global.frameFileHandle = frameFileLoad(_global.conf->videoFile, _global.conf->dataDir, (bool)_global.conf->stretchVideo, _global.renderer, _global.conf->showCalculated);
|
_global.frameFileHandle = frameFileLoad(_global.conf->videoFile, _global.conf->dataDir, (bool)_global.conf->stretchVideo, _global.renderer, _global.conf->showCalculated);
|
||||||
|
@ -4066,7 +4251,7 @@ void singe(SDL_Window *window, SDL_Renderer *renderer, ConfigT *conf) {
|
||||||
if (_global.videoHandle < 0) utilDie("Unable to load video file: %s", _global.conf->videoFile);
|
if (_global.videoHandle < 0) utilDie("Unable to load video file: %s", _global.conf->videoFile);
|
||||||
videoSetVolume(_global.videoHandle, _global.conf->volumeVldp, _global.conf->volumeVldp);
|
videoSetVolume(_global.videoHandle, _global.conf->volumeVldp, _global.conf->volumeVldp);
|
||||||
videoSetIndexCallback(NULL);
|
videoSetIndexCallback(NULL);
|
||||||
doIndexDisplay(-2);
|
doIndexDisplay(INDEX_DISPLAY_STOP);
|
||||||
|
|
||||||
// Should we resize the window?
|
// Should we resize the window?
|
||||||
if (conf->resolutionWasCalculated && !conf->fullScreen && !conf->fullScreenWindow) {
|
if (conf->resolutionWasCalculated && !conf->fullScreen && !conf->fullScreenWindow) {
|
||||||
|
|
|
@ -33,48 +33,53 @@
|
||||||
#define AUDIO_SILENCE_SECONDS 2
|
#define AUDIO_SILENCE_SECONDS 2
|
||||||
|
|
||||||
|
|
||||||
|
typedef struct AudioStreamS {
|
||||||
|
FFMS_AudioSource *audioSource;
|
||||||
|
const FFMS_AudioProperties *audioProps;
|
||||||
|
} AudioStreamT;
|
||||||
|
|
||||||
#pragma GCC diagnostic push
|
#pragma GCC diagnostic push
|
||||||
#pragma GCC diagnostic ignored "-Wpadded"
|
#pragma GCC diagnostic ignored "-Wpadded"
|
||||||
typedef struct VideoPlayerS {
|
typedef struct VideoPlayerS {
|
||||||
int32_t id;
|
int32_t id;
|
||||||
bool playing;
|
bool playing;
|
||||||
bool resetTime;
|
bool resetTime;
|
||||||
byte *audioBuffer;
|
byte *audioBuffer;
|
||||||
byte audioSampleBytes;
|
byte audioSampleBytes;
|
||||||
byte *audioSilenceRaw;
|
byte *audioSilenceRaw;
|
||||||
char errMsg[1024];
|
char errMsg[1024];
|
||||||
int32_t volumeLeft;
|
int32_t volumeLeft;
|
||||||
int32_t volumeRight;
|
int32_t volumeRight;
|
||||||
int32_t audioTrack;
|
int32_t videoTrack;
|
||||||
int32_t videoTrack;
|
int32_t audioSampleSize;
|
||||||
int32_t audioSampleSize;
|
int32_t mixSampleSize;
|
||||||
int32_t mixSampleSize;
|
int32_t audioSilenceChannel;
|
||||||
int32_t audioSilenceChannel;
|
int64_t frame;
|
||||||
int64_t frame;
|
int64_t audioBufferSize;
|
||||||
int64_t audioBufferSize;
|
int64_t frameDeltaTime;
|
||||||
int64_t frameDeltaTime;
|
int64_t lastFrameTime;
|
||||||
int64_t lastFrameTime;
|
int64_t timestamp;
|
||||||
int64_t timestamp;
|
int64_t audioDelta;
|
||||||
int64_t audioDelta;
|
int64_t audioPosition;
|
||||||
int64_t audioPosition;
|
int64_t framesPlayed;
|
||||||
int64_t framesPlayed;
|
Uint16 audioFormat;
|
||||||
Uint16 audioFormat;
|
Uint32 lastTickTime;
|
||||||
Uint32 lastTickTime;
|
Uint32 audioSilenceSize;
|
||||||
Uint32 audioSilenceSize;
|
//double audioAdjustment;
|
||||||
//double audioAdjustment;
|
Mix_Chunk *silenceChunk;
|
||||||
Mix_Chunk *silenceChunk;
|
SDL_AudioStream *audioStream;
|
||||||
SDL_AudioStream *audioStream;
|
SDL_Texture *videoTexture;
|
||||||
SDL_Texture *videoTexture;
|
FFMS_ErrorInfo errInfo;
|
||||||
FFMS_ErrorInfo errInfo;
|
int32_t currentAudioTrack;
|
||||||
FFMS_AudioSource *audioSource;
|
int32_t audioSourceCount;
|
||||||
FFMS_VideoSource *videoSource;
|
AudioStreamT *audio;
|
||||||
const FFMS_AudioProperties *audioProps;
|
FFMS_VideoSource *videoSource;
|
||||||
const FFMS_VideoProperties *videoProps;
|
const FFMS_VideoProperties *videoProps;
|
||||||
const FFMS_Frame *propFrame;
|
const FFMS_Frame *propFrame;
|
||||||
const FFMS_TrackTimeBase *videoTimeBase;
|
const FFMS_TrackTimeBase *videoTimeBase;
|
||||||
const FFMS_Frame *frameData;
|
const FFMS_Frame *frameData;
|
||||||
const FFMS_FrameInfo *frameInfo;
|
const FFMS_FrameInfo *frameInfo;
|
||||||
UT_hash_handle hh;
|
UT_hash_handle hh;
|
||||||
} VideoPlayerT;
|
} VideoPlayerT;
|
||||||
#pragma GCC diagnostic pop
|
#pragma GCC diagnostic pop
|
||||||
|
|
||||||
|
@ -196,13 +201,18 @@ int32_t _loadVideoAndAudio(char *vFilename, char *aFilename, char *indexPath, bo
|
||||||
FFMS_Index *vIndex = NULL;
|
FFMS_Index *vIndex = NULL;
|
||||||
FFMS_Index *aIndex = NULL;
|
FFMS_Index *aIndex = NULL;
|
||||||
VideoPlayerT *v = NULL;
|
VideoPlayerT *v = NULL;
|
||||||
|
int32_t x = 0;
|
||||||
|
int32_t count = 0;
|
||||||
|
FFMS_Track *track = NULL;
|
||||||
|
int32_t ttype = FFMS_TYPE_UNKNOWN;
|
||||||
|
|
||||||
// Create new videoPlayer
|
// Create new videoPlayer
|
||||||
v = calloc(1, sizeof(VideoPlayerT));
|
v = calloc(1, sizeof(VideoPlayerT));
|
||||||
if (!v) utilDie("Unable to allocate new video player.");
|
if (!v) utilDie("Unable to allocate new video player.");
|
||||||
|
|
||||||
// Set some starting values
|
// Set some starting values
|
||||||
v->audioTrack = -1;
|
v->audioSourceCount = 0;
|
||||||
|
v->currentAudioTrack = -1;
|
||||||
v->videoTrack = -1;
|
v->videoTrack = -1;
|
||||||
v->audioSilenceChannel = -1;
|
v->audioSilenceChannel = -1;
|
||||||
v->playing = false; // Start paused
|
v->playing = false; // Start paused
|
||||||
|
@ -215,8 +225,8 @@ int32_t _loadVideoAndAudio(char *vFilename, char *aFilename, char *indexPath, bo
|
||||||
vIndex = _createIndex(vFilename, indexPath, true, false, v);
|
vIndex = _createIndex(vFilename, indexPath, true, false, v);
|
||||||
aIndex = _createIndex(aFilename, indexPath, false, true, v);
|
aIndex = _createIndex(aFilename, indexPath, false, true, v);
|
||||||
} else {
|
} else {
|
||||||
vIndex = _createIndex(vFilename, indexPath, true, true, v);
|
vIndex = _createIndex(vFilename, indexPath, true, true, v);
|
||||||
aIndex = vIndex;
|
aIndex = vIndex;
|
||||||
aFilename = vFilename;
|
aFilename = vFilename;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -237,13 +247,50 @@ int32_t _loadVideoAndAudio(char *vFilename, char *aFilename, char *indexPath, bo
|
||||||
pixelFormats[1] = -1;
|
pixelFormats[1] = -1;
|
||||||
if (FFMS_SetOutputFormatV2(v->videoSource, pixelFormats, v->propFrame->EncodedWidth, v->propFrame->EncodedHeight, FFMS_RESIZER_BICUBIC, &v->errInfo)) utilDie("%s", v->errInfo.Buffer);
|
if (FFMS_SetOutputFormatV2(v->videoSource, pixelFormats, v->propFrame->EncodedWidth, v->propFrame->EncodedHeight, FFMS_RESIZER_BICUBIC, &v->errInfo)) utilDie("%s", v->errInfo.Buffer);
|
||||||
|
|
||||||
// Find audio track
|
// Find audio track(s)
|
||||||
v->audioTrack = FFMS_GetFirstTrackOfType(aIndex, FFMS_TYPE_AUDIO, &v->errInfo);
|
//utilSay("Tracks in file: %d", FFMS_GetNumTracks(aIndex));
|
||||||
if (v->audioTrack >= 0) {
|
for (x=0; x<FFMS_GetNumTracks(aIndex); x++) {
|
||||||
v->audioSource = FFMS_CreateAudioSource(aFilename, v->audioTrack, aIndex, FFMS_DELAY_FIRST_VIDEO_TRACK, &v->errInfo);
|
track = FFMS_GetTrackFromIndex(aIndex, x);
|
||||||
if (v->audioSource == NULL) utilDie("%s", v->errInfo.Buffer);
|
ttype = FFMS_GetTrackType(track);
|
||||||
// Get audio properties
|
// Just count the tracks for now.
|
||||||
v->audioProps = FFMS_GetAudioProperties(v->audioSource);
|
if (ttype == FFMS_TYPE_AUDIO) count++;
|
||||||
|
/*
|
||||||
|
switch (ttype) {
|
||||||
|
case FFMS_TYPE_UNKNOWN:
|
||||||
|
utilSay("Track %d is FFMS_TYPE_UNKNOWN", x);
|
||||||
|
break;
|
||||||
|
case FFMS_TYPE_VIDEO:
|
||||||
|
utilSay("Track %d is FFMS_TYPE_VIDEO", x);
|
||||||
|
break;
|
||||||
|
case FFMS_TYPE_AUDIO:
|
||||||
|
utilSay("Track %d is FFMS_TYPE_AUDIO", x);
|
||||||
|
break;
|
||||||
|
case FFMS_TYPE_DATA:
|
||||||
|
utilSay("Track %d is FFMS_TYPE_DATA", x);
|
||||||
|
break;
|
||||||
|
case FFMS_TYPE_SUBTITLE:
|
||||||
|
utilSay("Track %d is FFMS_TYPE_SUBTITLE", x);
|
||||||
|
break;
|
||||||
|
case FFMS_TYPE_ATTACHMENT:
|
||||||
|
utilSay("Track %d is FFMS_TYPE_ATTACHMENT", x);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
*/
|
||||||
|
}
|
||||||
|
if (count > 0) {
|
||||||
|
// Allocate space for the tracks.
|
||||||
|
v->audio = (AudioStreamT *)calloc(count, sizeof(AudioStreamT));
|
||||||
|
// Now create them.
|
||||||
|
for (x=0; x<FFMS_GetNumTracks(aIndex); x++) {
|
||||||
|
if (FFMS_GetTrackType(FFMS_GetTrackFromIndex(aIndex, x)) == FFMS_TYPE_AUDIO) {
|
||||||
|
v->audio[v->audioSourceCount].audioSource = FFMS_CreateAudioSource(aFilename, x, aIndex, FFMS_DELAY_FIRST_VIDEO_TRACK, &v->errInfo);
|
||||||
|
if (v->audio[v->audioSourceCount].audioSource == NULL) utilDie("%s", v->errInfo.Buffer);
|
||||||
|
v->audio[v->audioSourceCount].audioProps = FFMS_GetAudioProperties(v->audio[v->audioSourceCount].audioSource);
|
||||||
|
v->audioSourceCount++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// Current audio track.
|
||||||
|
v->currentAudioTrack = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Indicies are now part of audioSource & videoSource, so release these
|
// Indicies are now part of audioSource & videoSource, so release these
|
||||||
|
@ -263,10 +310,10 @@ 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?
|
// Do we have audio? All audio streams must have the same format!
|
||||||
if (v->audioSource) {
|
if (v->audioSourceCount > 0) {
|
||||||
// Determine audio format
|
// Determine audio format
|
||||||
switch (v->audioProps->SampleFormat) {
|
switch (v->audio[0].audioProps->SampleFormat) {
|
||||||
case FFMS_FMT_U8:
|
case FFMS_FMT_U8:
|
||||||
v->audioFormat = AUDIO_U8;
|
v->audioFormat = AUDIO_U8;
|
||||||
v->audioSampleBytes = 1;
|
v->audioSampleBytes = 1;
|
||||||
|
@ -287,15 +334,15 @@ int32_t _loadVideoAndAudio(char *vFilename, char *aFilename, char *indexPath, bo
|
||||||
utilDie("Unknown audio sample format.");
|
utilDie("Unknown audio sample format.");
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
if (v->audioProps->Channels > 2) utilDie("Only mono and stereo audio are supported.");
|
if (v->audio[0].audioProps->Channels > 2) utilDie("Only mono and stereo audio are supported.");
|
||||||
|
|
||||||
// Create audio stream to convert audio to our desired format
|
// Create audio stream to convert audio to our desired format
|
||||||
v->audioStream = SDL_NewAudioStream(v->audioFormat, (Uint8)v->audioProps->Channels, v->audioProps->SampleRate, _mixFormat, _mixChannels, _mixRate);
|
v->audioStream = SDL_NewAudioStream(v->audioFormat, (Uint8)v->audio[0].audioProps->Channels, v->audio[0].audioProps->SampleRate, _mixFormat, _mixChannels, _mixRate);
|
||||||
if (!v->audioStream) utilDie("%s", SDL_GetError());
|
if (!v->audioStream) utilDie("%s", SDL_GetError());
|
||||||
|
|
||||||
// Create a buffer to read audio into before conversion
|
// Create a buffer to read audio into before conversion
|
||||||
v->mixSampleSize = SDL_AUDIO_BITSIZE(_mixFormat) / 8 * _mixChannels;
|
v->mixSampleSize = SDL_AUDIO_BITSIZE(_mixFormat) / 8 * _mixChannels;
|
||||||
v->audioSampleSize = v->audioSampleBytes * v->audioProps->Channels;
|
v->audioSampleSize = v->audioSampleBytes * v->audio[0].audioProps->Channels;
|
||||||
v->audioBufferSize = v->audioSampleSize * AUDIO_SAMPLE_PREREAD;
|
v->audioBufferSize = v->audioSampleSize * AUDIO_SAMPLE_PREREAD;
|
||||||
v->audioBuffer = (byte *)malloc((size_t)v->audioBufferSize * sizeof(byte));
|
v->audioBuffer = (byte *)malloc((size_t)v->audioBufferSize * sizeof(byte));
|
||||||
if (!v->audioBuffer) utilDie("Unable to allocate %ld byte audio buffer.", (size_t)v->audioBufferSize * sizeof(byte));
|
if (!v->audioBuffer) utilDie("Unable to allocate %ld byte audio buffer.", (size_t)v->audioBufferSize * sizeof(byte));
|
||||||
|
@ -371,6 +418,28 @@ int32_t videoIsPlaying(int32_t playerHandle) {
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
int32_t videoGetAudioTrack(int32_t playerHandle) {
|
||||||
|
VideoPlayerT *v = NULL;
|
||||||
|
|
||||||
|
// Get our player structure
|
||||||
|
HASH_FIND_INT(_videoPlayerHash, &playerHandle, v);
|
||||||
|
if (!v) utilDie("No video player at index %d in videoGetAudioTrack.", playerHandle);
|
||||||
|
|
||||||
|
return v->currentAudioTrack;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
int32_t videoGetAudioTracks(int32_t playerHandle) {
|
||||||
|
VideoPlayerT *v = NULL;
|
||||||
|
|
||||||
|
// Get our player structure
|
||||||
|
HASH_FIND_INT(_videoPlayerHash, &playerHandle, v);
|
||||||
|
if (!v) utilDie("No video player at index %d in videoGetAudioTracks.", playerHandle);
|
||||||
|
|
||||||
|
return v->audioSourceCount;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
int64_t videoGetFrame(int32_t playerHandle) {
|
int64_t videoGetFrame(int32_t playerHandle) {
|
||||||
VideoPlayerT *v = NULL;
|
VideoPlayerT *v = NULL;
|
||||||
|
|
||||||
|
@ -505,6 +574,23 @@ int32_t videoSeek(int32_t playerHandle, int64_t seekFrame) {
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
int32_t videoSetAudioTrack(int32_t playerHandle, int32_t track) {
|
||||||
|
VideoPlayerT *v = NULL;
|
||||||
|
|
||||||
|
// Get our player structure
|
||||||
|
HASH_FIND_INT(_videoPlayerHash, &playerHandle, v);
|
||||||
|
if (!v) utilDie("No video player at index %d in videoSetAudioTrack.", playerHandle);
|
||||||
|
|
||||||
|
if ((track >= 0) && (track < v->audioSourceCount)) {
|
||||||
|
v->currentAudioTrack = track;
|
||||||
|
} else {
|
||||||
|
utilDie("Invalid audio track in videoSetAudioTrack.");
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
int32_t videoSetIndexCallback(videoIndexingCallback callback) {
|
int32_t videoSetIndexCallback(videoIndexingCallback callback) {
|
||||||
_indexingFunction = callback;
|
_indexingFunction = callback;
|
||||||
return 0;
|
return 0;
|
||||||
|
@ -527,19 +613,23 @@ int32_t videoSetVolume(int32_t playerHandle, int32_t leftPercent, int32_t rightP
|
||||||
|
|
||||||
int32_t videoUnload(int32_t playerHandle) {
|
int32_t videoUnload(int32_t playerHandle) {
|
||||||
VideoPlayerT *v = NULL;
|
VideoPlayerT *v = NULL;
|
||||||
|
int32_t x = 0;
|
||||||
|
|
||||||
// Get our player structure
|
// Get our player structure
|
||||||
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) {
|
if (v->audioSourceCount > 0) {
|
||||||
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);
|
for (x=0; x<v->audioSourceCount; x++) {
|
||||||
|
FFMS_DestroyAudioSource(v->audio[x].audioSource);
|
||||||
|
}
|
||||||
|
free(v->audio);
|
||||||
}
|
}
|
||||||
|
|
||||||
FFMS_DestroyVideoSource(v->videoSource);
|
FFMS_DestroyVideoSource(v->videoSource);
|
||||||
|
@ -566,7 +656,7 @@ 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
|
||||||
threshold = v->audioSource ? (v->audioProps->SampleRate / 2) : 99999;
|
threshold = v->audio[v->currentAudioTrack].audioSource ? (v->audio[v->currentAudioTrack].audioProps->SampleRate / 2) : 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) {
|
||||||
|
@ -598,9 +688,9 @@ int32_t videoUpdate(int32_t playerHandle, SDL_Texture **texture) {
|
||||||
v->lastTickTime = SDL_GetTicks();
|
v->lastTickTime = SDL_GetTicks();
|
||||||
|
|
||||||
if (v->resetTime) {
|
if (v->resetTime) {
|
||||||
if (v->audioSource) {
|
if (v->audioSourceCount > 0) {
|
||||||
SDL_AudioStreamClear(v->audioStream);
|
SDL_AudioStreamClear(v->audioStream);
|
||||||
v->audioPosition = (int64_t)((double)v->timestamp * 0.001 * (double)v->audioProps->SampleRate);
|
v->audioPosition = (int64_t)((double)v->timestamp * 0.001 * (double)v->audio[v->currentAudioTrack].audioProps->SampleRate);
|
||||||
v->audioDelta = 0;
|
v->audioDelta = 0;
|
||||||
}
|
}
|
||||||
v->lastTickTime = 0;
|
v->lastTickTime = 0;
|
||||||
|
@ -611,19 +701,19 @@ int32_t videoUpdate(int32_t playerHandle, SDL_Texture **texture) {
|
||||||
}
|
}
|
||||||
|
|
||||||
// Handle audio samples
|
// Handle audio samples
|
||||||
if (v->audioSource) {
|
if (v->audioSourceCount > 0) {
|
||||||
// Add more samples to queue?
|
// Add more samples to queue?
|
||||||
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->audio[v->currentAudioTrack].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;
|
||||||
// Don't read past end of audio data
|
// Don't read past end of audio data
|
||||||
if (v->audioPosition + count >= v->audioProps->NumSamples) {
|
if (v->audioPosition + count >= v->audio[v->currentAudioTrack].audioProps->NumSamples) {
|
||||||
count = v->audioProps->NumSamples - v->audioPosition - 1;
|
count = v->audio[v->currentAudioTrack].audioProps->NumSamples - v->audioPosition - 1;
|
||||||
}
|
}
|
||||||
// Are we reading anything?
|
// Are we reading anything?
|
||||||
if (count > 0) {
|
if (count > 0) {
|
||||||
// Get audio from video stream
|
// Get audio from video stream
|
||||||
if (FFMS_GetAudio(v->audioSource, v->audioBuffer, v->audioPosition, count, &v->errInfo)) utilDie("%s", v->errInfo.Buffer);
|
if (FFMS_GetAudio(v->audio[v->currentAudioTrack].audioSource, v->audioBuffer, v->audioPosition, count, &v->errInfo)) utilDie("%s", v->errInfo.Buffer);
|
||||||
// Feed it to the mixer stream
|
// Feed it to the mixer stream
|
||||||
if (SDL_AudioStreamPut(v->audioStream, v->audioBuffer, (int32_t)(count * v->audioSampleSize)) < 0) utilDie("%s", SDL_GetError());
|
if (SDL_AudioStreamPut(v->audioStream, v->audioBuffer, (int32_t)(count * v->audioSampleSize)) < 0) utilDie("%s", SDL_GetError());
|
||||||
v->audioPosition += count;
|
v->audioPosition += count;
|
||||||
|
@ -631,7 +721,7 @@ int32_t videoUpdate(int32_t playerHandle, SDL_Texture **texture) {
|
||||||
}
|
}
|
||||||
|
|
||||||
// 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((long)(v->audioPosition - (int64_t)((double)v->timestamp * 0.001 * (double)v->audioProps->SampleRate)));
|
v->audioDelta = labs((long)(v->audioPosition - (int64_t)((double)v->timestamp * 0.001 * (double)v->audio[v->currentAudioTrack].audioProps->SampleRate)));
|
||||||
|
|
||||||
// Did we trip the audio sync compensation?
|
// Did we trip the audio sync compensation?
|
||||||
if (v->audioDelta > threshold) {
|
if (v->audioDelta > threshold) {
|
||||||
|
|
|
@ -34,6 +34,8 @@ typedef void (*videoIndexingCallback)(int32_t);
|
||||||
|
|
||||||
int32_t videoInit(void);
|
int32_t videoInit(void);
|
||||||
int32_t videoIsPlaying(int32_t playerHandle);
|
int32_t videoIsPlaying(int32_t playerHandle);
|
||||||
|
int32_t videoGetAudioTrack(int32_t playerHandle);
|
||||||
|
int32_t videoGetAudioTracks(int32_t playerHandle);
|
||||||
int64_t videoGetFrame(int32_t playerHandle);
|
int64_t videoGetFrame(int32_t playerHandle);
|
||||||
int64_t videoGetFrameCount(int32_t playerHandle);
|
int64_t videoGetFrameCount(int32_t playerHandle);
|
||||||
int32_t videoGetHeight(int32_t playerHandle);
|
int32_t videoGetHeight(int32_t playerHandle);
|
||||||
|
@ -45,6 +47,7 @@ int32_t videoPause(int32_t playerHandle);
|
||||||
int32_t videoPlay(int32_t playerHandle);
|
int32_t videoPlay(int32_t playerHandle);
|
||||||
int32_t videoQuit(void);
|
int32_t videoQuit(void);
|
||||||
int32_t videoSeek(int32_t playerHandle, int64_t seekFrame);
|
int32_t videoSeek(int32_t playerHandle, int64_t seekFrame);
|
||||||
|
int32_t videoSetAudioTrack(int32_t playerHandle, int32_t track);
|
||||||
int32_t videoSetIndexCallback(videoIndexingCallback callback);
|
int32_t videoSetIndexCallback(videoIndexingCallback callback);
|
||||||
int32_t videoSetVolume(int32_t playerHandle, int32_t leftPercent, int32_t rightPercent);
|
int32_t videoSetVolume(int32_t playerHandle, int32_t leftPercent, int32_t rightPercent);
|
||||||
int32_t videoUnload(int32_t playerHandle);
|
int32_t videoUnload(int32_t playerHandle);
|
||||||
|
|
Loading…
Add table
Reference in a new issue