diff --git a/.gitignore b/.gitignore index 32a7ab91b..b7c76731e 100644 --- a/.gitignore +++ b/.gitignore @@ -39,5 +39,8 @@ singe/font.h singe/icon.h singe/kangarooPunchLogo.h singe/singeLogo.h +singe/indexing.h +singe/laserDisc.h +singe/magnifyingGlass.h videotest/indexing/ Makefile.in diff --git a/singe/buildRelease.sh b/singe/buildRelease.sh index ecdbf4a56..4487cea3e 100755 --- a/singe/buildRelease.sh +++ b/singe/buildRelease.sh @@ -21,6 +21,8 @@ source source.inc.sh +G_L="-------------------------------------------------------------------------------" + function doBuild() { local TARGET=$1 @@ -32,6 +34,9 @@ function doBuild() { local OFILES="" local O= + # Override this + QMAKE_CFLAGS="-isystem ../../thirdparty-build/${OSNAME}/${OSARCH}/installed/include -isystem ../../singe/thirdparty/arg_parser -isystem ../../singe/thirdparty/manymouse" + pushd "${SOURCE_DIR}/.." mkdir -p build/${OSNAME}/${OSARCH} cd build @@ -66,24 +71,29 @@ function doBuild() { } # 64 Bit Linux +echo -e "${G_L}\nLinux x86_64\n${G_L}" CROSS="x86_64-linux-gnu" EXTRA_CFLAGS="-O2" EXTRA_OFILES="" EXTRA_LD_FLAGS="-l:everything.a -lpthread -lXv -lX11 -lXext -lm -ldl -lrt" -#doBuild Singe-Linux-x86_64 linux 64 +doBuild Singe-Linux-x86_64 linux 64 # 64 Bit Windows +echo -e "${G_L}\nWindows x86_64\n${G_L}" CROSS="x86_64-w64-mingw32" EXTRA_CFLAGS="-O2" EXTRA_OFILES="/tmp/singe.res" EXTRA_LD_FLAGS="-mwindows -static -lmingw32 -l:everything.a -lm -lbcrypt -ldinput8 -ldxguid -ldxerr8 -luser32 -lgdi32 -lwinmm -limm32 -lole32 -loleaut32 -lshell32 -lsetupapi -lversion -luuid -Dmain=SDL_main" -icotool -c -o /tmp/icon.ico icon.png +xcf2png icon.xcf -o /tmp/icon.png +icotool -c -o /tmp/icon.ico /tmp/icon.png x86_64-w64-mingw32-windres singe.rc -O coff -o /tmp/singe.res -#doBuild Singe-Windows-x86_64 mingw 64 .exe +doBuild Singe-Windows-x86_64 mingw 64 .exe rm /tmp/icon.ico +rm /tmp/icon.png rm /tmp/singe.res # 32 Bit Raspbian +echo -e "${G_L}\nLinux armv6\n${G_L}" SYSROOT="/opt/cross/pi/buster" CROSS="/opt/cross/pi/tools/arm-bcm2708/gcc-linaro-arm-linux-gnueabihf-raspbian/bin/arm-linux-gnueabihf" EXTRA_CFLAGS="-O2 --sysroot ${SYSROOT}" diff --git a/singe/font.png b/singe/font.png deleted file mode 100644 index f554637e7..000000000 --- a/singe/font.png +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:fff0ade85b8e318948635bd74816df53b059d0446e330a9cf878325785934528 -size 1191 diff --git a/singe/font.xcf b/singe/font.xcf new file mode 100644 index 000000000..3985564af --- /dev/null +++ b/singe/font.xcf @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:c884168ed14ff9a97811d15a4f0582b08a88e15632d1a93cd0e216b0e2ee9df2 +size 5172 diff --git a/singe/frameFile.c b/singe/frameFile.c index f3eb9bc1c..f0564bfa5 100644 --- a/singe/frameFile.c +++ b/singe/frameFile.c @@ -242,6 +242,7 @@ int32_t frameFileSeek(int32_t frameFileHandle, int64_t seekFrame, int32_t *video /* // Daphne-like framefile searching + found = f->count - 1; for (i=f->count - 1; i>=0; i--) { if (seekFrame <= f->files[i].frame) { found = i; diff --git a/singe/icon.png b/singe/icon.png deleted file mode 100644 index 568aec5b3..000000000 --- a/singe/icon.png +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:13034fd263b97f9e51c77a00cd5791606005a97e32998307f6de966d34bc41eb -size 3392 diff --git a/singe/icon.xcf b/singe/icon.xcf new file mode 100644 index 000000000..14c711ca6 --- /dev/null +++ b/singe/icon.xcf @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:4da9618f19e12da35ecde1cae13f59ada65541ecacfe1ebd6717d1962b33fc06 +size 5928 diff --git a/singe/indexing.xcf b/singe/indexing.xcf new file mode 100644 index 000000000..a86da9de2 --- /dev/null +++ b/singe/indexing.xcf @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:4b71d81e254244c616fdbc92271a862c0a8d627c652206f83e620e69e1f5284d +size 54489 diff --git a/singe/laserDisc.xcf b/singe/laserDisc.xcf new file mode 100644 index 000000000..2d0b85150 --- /dev/null +++ b/singe/laserDisc.xcf @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:e97f93b37f6ce29820c110cc7c25b89110aa0292df5bb28feb982b395537cf21 +size 986516 diff --git a/singe/magnifyingGlass.xcf b/singe/magnifyingGlass.xcf new file mode 100644 index 000000000..1503cf523 --- /dev/null +++ b/singe/magnifyingGlass.xcf @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:578e3ab359346a7d889aa610377a1237b0a8b117ca401798760ab57db52d12a6 +size 214488 diff --git a/singe/main.c b/singe/main.c index bf4857919..6befd53f5 100644 --- a/singe/main.c +++ b/singe/main.c @@ -22,6 +22,7 @@ // -c -x 720 -y 480 -d data/maddog_dvd -v maddog_dvd/frame_maddog_dvd.txt maddog_dvd/maddog_dvd.singe // -c -x 640 -y 480 -v ActionMax/frame_SonicFury.txt ActionMax/SonicFury.singe +// -x 640 -y 480 -d data/ActionMax ActionMax/BlueThunder.singe // -v ActionMax/BlueThunder.mp4 test.singe @@ -108,7 +109,7 @@ void showUsage(char *name, char *message) { } -int main(int argc, const char *argv[]) { +int main(int argc, char *argv[]) { int32_t x = 0; int32_t err = 0; @@ -132,6 +133,7 @@ int main(int argc, const char *argv[]) { SDL_Surface *icon = NULL; SDL_DisplayMode mode; const char *arg = NULL; + const char **cargv = (const char **)argv; struct Arg_parser parser; static struct ap_Option options[] = { { 'a', "aspect", ap_yes }, @@ -189,7 +191,7 @@ int main(int argc, const char *argv[]) { // For that dumb OS utilRedirectConsole(); - if (!ap_init(&parser, argc, argv, options, 0)) { + if (!ap_init(&parser, argc, cargv, options, 0)) { utilDie("Out of memory parsing arguments."); } if (ap_error(&parser)) { @@ -613,6 +615,7 @@ int main(int argc, const char *argv[]) { if (_confVideoFile) free(_confVideoFile); if (_confScriptFile) free(_confScriptFile); utilTraceEnd(); + ap_free(&parser); #ifdef _WIN32 getchar(); diff --git a/singe/preBuild.sh b/singe/preBuild.sh index 8b448b7eb..9eca7aa23 100755 --- a/singe/preBuild.sh +++ b/singe/preBuild.sh @@ -200,6 +200,17 @@ function createEmbeddedBinary() { } +function createEmbeddedImage() { + local BASENAME=$1 + + if [[ ! -e ${BASENAME}.h ]]; then + xcf2png ${BASENAME}.xcf -o ${BASENAME}.png + createEmbeddedBinary ${BASENAME}.png ${BASENAME}.h ${BASENAME^^}_H + rm ${BASENAME}.png + fi +} + + function createExtensionHeader() { local FFMPEG=$1 local a= @@ -476,21 +487,22 @@ if [[ ! -e "${G_INSTALLED}/lib/everything.a" ]]; then fi # === Overlay Font === -createEmbeddedBinary font.png font.h FONT_H +createEmbeddedImage font # === Window Icon === -createEmbeddedBinary icon.png icon.h ICON_H +createEmbeddedImage icon # === Kangaroo Punch Logo === -if [[ ! -e kangarooPunchLogo.h ]]; then - xcf2png kangarooPunchLogo.xcf -o kangarooPunchLogo.png - createEmbeddedBinary kangarooPunchLogo.png kangarooPunchLogo.h KANGAROOPUNCHLOGO_H - rm kangarooPunchLogo.png -fi +createEmbeddedImage kangarooPunchLogo # === Singe Logo === -if [[ ! -e singeLogo.h ]]; then - xcf2png singeLogo.xcf -o singeLogo.png - createEmbeddedBinary singeLogo.png singeLogo.h SINGELOGO_H - rm singeLogo.png -fi +createEmbeddedImage singeLogo + +# === Laser Disc === +createEmbeddedImage laserDisc + +# === Magnifying Glass === +createEmbeddedImage magnifyingGlass + +# === "Indexing" Text === +createEmbeddedImage indexing diff --git a/singe/singe.c b/singe/singe.c index b672bf37b..f67ff35fd 100644 --- a/singe/singe.c +++ b/singe/singe.c @@ -40,6 +40,9 @@ #include "font.h" #include "kangarooPunchLogo.h" #include "singeLogo.h" +#include "laserDisc.h" +#include "magnifyingGlass.h" +#include "indexing.h" #define AUDIO_MAX_VOLUME 63 @@ -309,6 +312,7 @@ int32_t apiSingeQuit(lua_State *L); int32_t apiSingeVersion(lua_State *L); int32_t apiSingeSetGameName(lua_State *L); int32_t apiSingeGetScriptPath(lua_State *L); +void doIndexDisplay(int32_t percent); void doLogos(void); void callLua(const char *func, const char *sig, ...); void channelFinished(int channel); @@ -1849,6 +1853,116 @@ void channelFinished(int channel) { } +void doIndexDisplay(int32_t percent) { + + static int32_t oldW = 0; + static int32_t oldH = 0; + static int32_t screenW = 1280; + static int32_t screenH = 720; + static int32_t radius = 0; + static int32_t angle = 0; + static uint32_t nextUpdate = 0; + static uint32_t updateTicks = 0; + static SDL_Surface *surfDisc = NULL; + static SDL_Surface *surfGlass = NULL; + static SDL_Surface *surfIndex = NULL; + static SDL_Texture *texDisc = NULL; + static SDL_Texture *texGlass = NULL; + static SDL_Texture *texIndex = NULL; + + SDL_Rect target; + int32_t vShift; + + // If 'percent' is -1, we're setting this display up. + // 'percent' 0 to 100 is the actual display. + // 'percent' -2 shuts the display down. + + if (percent == -1) { + // Setup + SDL_RenderGetLogicalSize(_renderer, &oldW, &oldH); + SDL_RenderSetLogicalSize(_renderer, screenW, screenH); + + surfGlass = IMG_LoadPNG_RW(SDL_RWFromMem(magnifyingGlass_png, magnifyingGlass_png_len)); + if (!surfGlass) utilDie("%s", IMG_GetError()); + surfDisc = IMG_LoadPNG_RW(SDL_RWFromMem(laserDisc_png, laserDisc_png_len)); + if (!surfDisc) utilDie("%s", IMG_GetError()); + surfIndex = IMG_LoadPNG_RW(SDL_RWFromMem(indexing_png, indexing_png_len)); + if (!surfIndex) utilDie("%s", IMG_GetError()); + + texDisc = SDL_CreateTextureFromSurface(_renderer, surfDisc); + if (!texDisc) utilDie("%s", SDL_GetError()); + texGlass = SDL_CreateTextureFromSurface(_renderer, surfGlass); + if (!texGlass) utilDie("%s", SDL_GetError()); + texIndex = SDL_CreateTextureFromSurface(_renderer, surfIndex); + if (!texIndex) utilDie("%s", SDL_GetError()); + + radius = surfDisc->w * 0.3; + updateTicks = 5; + nextUpdate = SDL_GetTicks() + updateTicks; + return; + } + + if (percent == -2) { + // Shutdown + SDL_DestroyTexture(texDisc); + SDL_DestroyTexture(texGlass); + SDL_DestroyTexture(texIndex); + texDisc = NULL; + texGlass = NULL; + texIndex = NULL; + + SDL_FreeSurface(surfDisc); + SDL_FreeSurface(surfGlass); + SDL_FreeSurface(surfIndex); + surfDisc = NULL; + surfGlass = NULL; + surfIndex = NULL; + + SDL_RenderSetLogicalSize(_renderer, oldW, oldH); + + SDL_SetRenderDrawColor(_renderer, 0, 0, 0, 255); + SDL_RenderClear(_renderer); + SDL_RenderPresent(_renderer); + return; + } + + // Display animation + SDL_SetRenderDrawColor(_renderer, 0, 0, 0, 255); + SDL_RenderClear(_renderer); + + // Draw "Indexing" text + vShift = surfIndex->h - 5; + target.x = (screenW * 0.5) - (surfIndex->w * 0.5); + target.y = screenH - vShift; + target.w = surfIndex->w; + target.h = surfIndex->h; + SDL_RenderCopy(_renderer, texIndex, NULL, &target); + + // Draw laserdisc + target.x = (screenW * 0.5) - (surfDisc->w * 0.5); + target.y = (screenH * 0.5) - (surfDisc->h * 0.5) - vShift; + target.w = surfDisc->w; + target.h = surfDisc->h; + SDL_RenderCopy(_renderer, texDisc, NULL, &target); + + // Draw magnifying glass + target.x = (surfDisc->w * 0.15) + (screenW * 0.5) - (surfGlass->w * 0.5) + cos(angle * M_PI / 180) * radius; + target.y = (surfDisc->h * 0.1) + (screenH * 0.5) - vShift - (surfGlass->h * 0.5) + sin(angle * M_PI / 180) * radius; + target.w = surfGlass->w; + target.h = surfGlass->h; + SDL_RenderCopy(_renderer, texGlass, NULL, &target); + + // Update animation + if (SDL_GetTicks() > nextUpdate) { + angle++; + if (angle > 359) angle = 0; + nextUpdate = SDL_GetTicks() + updateTicks; + } + + SDL_RenderPresent(_renderer); +} + + void doLogos(void) { int32_t i = 0; int32_t w = 0; @@ -1878,10 +1992,10 @@ void doLogos(void) { SDL_SetTextureAlphaMod(texKangaroo, i); SDL_RenderCopy(_renderer, texKangaroo, NULL, NULL); SDL_RenderPresent(_renderer); - SDL_Delay(5); + SDL_Delay(3); } - SDL_Delay(1000); + SDL_Delay(750); // Cross fade to Singe logo for (i=0; i<256; i++) { @@ -1891,10 +2005,10 @@ void doLogos(void) { SDL_SetTextureAlphaMod(texSinge, i); SDL_RenderCopy(_renderer, texSinge, NULL, NULL); SDL_RenderPresent(_renderer); - SDL_Delay(5); + SDL_Delay(3); } - SDL_Delay(1000); + SDL_Delay(750); // Fade to black SDL_RenderSetLogicalSize(_renderer, surfSinge->w, surfSinge->h); @@ -1904,7 +2018,7 @@ void doLogos(void) { SDL_SetTextureAlphaMod(texSinge, i); SDL_RenderCopy(_renderer, texSinge, NULL, NULL); SDL_RenderPresent(_renderer); - SDL_Delay(5); + SDL_Delay(3); } SDL_DestroyTexture(texSinge); @@ -2166,6 +2280,8 @@ void singe(SDL_Window *window, SDL_Renderer *renderer) { lua_register(_luaContext, "singeGetScriptPath", apiSingeGetScriptPath); // Open main video file + doIndexDisplay(-1); + videoSetIndexCallback(doIndexDisplay); if (_confIsFrameFile) { _frameFileHandle = frameFileLoad(_confVideoFile, _confDataDir, (bool)_confStretchVideo, _renderer); if (_frameFileHandle < 0) utilDie("Unable to load framefile: %s", _confVideoFile); @@ -2175,6 +2291,8 @@ void singe(SDL_Window *window, SDL_Renderer *renderer) { } if (_videoHandle < 0) utilDie("Unable to load video file: %s", _confVideoFile); videoSetVolume(_videoHandle, _confVolumeVldp, _confVolumeVldp); + videoSetIndexCallback(NULL); + doIndexDisplay(-2); // Should we resize the window? //***TODO*** diff --git a/singe/singe.h b/singe/singe.h index 72fe1d7ee..2c1b03211 100644 --- a/singe/singe.h +++ b/singe/singe.h @@ -31,7 +31,7 @@ // Don't forget to update singe.rc! #define SINGE_VERSION 2.00 -#define VERSION_STRING "v2.00b8" +#define VERSION_STRING "v2.00b9" #define COPYRIGHT_END_YEAR "2020" diff --git a/singe/singe.pro b/singe/singe.pro index fccd4138f..69e8ab12d 100644 --- a/singe/singe.pro +++ b/singe/singe.pro @@ -119,7 +119,10 @@ HEADERS += \ extensions.h \ font.h \ singeLogo.h \ - kangarooPunchLogo.h + kangarooPunchLogo.h \ + laserDisc.h \ + magnifyingGlass.h \ + indexing.h SOURCES += \ $$ARGPARSER_SOURCES \ diff --git a/singe/singe.rc b/singe/singe.rc index 83e2810ff..85c2e4e9b 100644 --- a/singe/singe.rc +++ b/singe/singe.rc @@ -1,7 +1,7 @@ 101 ICON "/tmp/icon.ico" 1 VERSIONINFO -FILEVERSION 2,0,0,8 -PRODUCTVERSION 2,0,0,8 +FILEVERSION 2,0,0,9 +PRODUCTVERSION 2,0,0,9 BEGIN BLOCK "StringFileInfo" BEGIN @@ -9,12 +9,12 @@ BEGIN BEGIN VALUE "CompanyName", "Kangaroo Punch Studios" VALUE "FileDescription", "Somewhat Interactive Nostalgic Game Engine" - VALUE "FileVersion", "2.00b8" + VALUE "FileVersion", "2.00b9" VALUE "InternalName", "Singe" VALUE "LegalCopyright", "Copyright 2006-2020 Scott C. Duensing" VALUE "OriginalFilename", "singe.exe" VALUE "ProductName", "Singe" - VALUE "ProductVersion", "2.00b8" + VALUE "ProductVersion", "2.00b9" END END BLOCK "VarFileInfo" diff --git a/singe/videoPlayer.c b/singe/videoPlayer.c index c36921827..debd70441 100644 --- a/singe/videoPlayer.c +++ b/singe/videoPlayer.c @@ -62,7 +62,7 @@ typedef struct VideoPlayerS { Uint16 audioFormat; Uint32 lastTickTime; Uint32 audioSilenceSize; - double audioAdjustment; + //double audioAdjustment; Mix_Chunk *silenceChunk; SDL_AudioStream *audioStream; SDL_Texture *videoTexture; @@ -86,11 +86,12 @@ int FFMS_CC _indexCallBack(int64_t Current, int64_t Total, void *ICPrivate); int32_t _loadVideoAndAudio(char *vFilename, char *aFilename, char *indexPath, bool stretchVideo, SDL_Renderer *renderer); -static VideoPlayerT *_videoPlayerHash = NULL; -static int32_t _nextId = 0; -static int32_t _mixRate = -1; -static Uint8 _mixChannels = 0; -static SDL_AudioFormat _mixFormat = 0; +static videoIndexingCallback _indexingFunction = NULL; +static VideoPlayerT *_videoPlayerHash = NULL; +static int32_t _nextId = 0; +static int32_t _mixRate = -1; +static Uint8 _mixChannels = 0; +static SDL_AudioFormat _mixFormat = 0; void _dequeueVideoAudio(int channel, void *stream, int bytes, void *udata) { // Callback. Not changing ints. @@ -135,10 +136,11 @@ void _dequeueVideoAudio(int channel, void *stream, int bytes, void *udata) { / int FFMS_CC _indexCallBack(int64_t current, int64_t total, void *ICPrivate) { // Callback. Not changing int. - static int32_t lastPercent = 0; - int32_t thisPercent = 0; + static int32_t lastPercent = 0; + int32_t thisPercent = 0; + VideoPlayerT *v = (VideoPlayerT *)ICPrivate; - (void)ICPrivate; // Contains current VideoPlayerT + (void)v; if ((current == 0) && (total == 0)) { lastPercent = 0; // Reset @@ -146,8 +148,11 @@ int FFMS_CC _indexCallBack(int64_t current, int64_t total, void *ICPrivate) { thisPercent = (int32_t)((double)current / (double)total * 100.0); if (thisPercent != lastPercent) { lastPercent = thisPercent; - utilSay("Indexing: %d%%", thisPercent); - //***TODO*** GUI + //utilSay("Indexing: %d%%", thisPercent); + // GUI + if (_indexingFunction) { + _indexingFunction(thisPercent); + } } } @@ -170,7 +175,7 @@ FFMS_Index *_createIndex(char *filename, char *indexPath, bool hasVideo, bool ha } } if (!index) { - utilSay("Creating new index."); + //utilSay("Creating new index."); indexer = FFMS_CreateIndexer(filename, &v->errInfo); if (indexer == NULL) utilDie("%s", v->errInfo.Buffer); if (hasAudio) FFMS_TrackTypeIndexSettings(indexer, FFMS_TYPE_AUDIO, 1, 0); @@ -500,6 +505,12 @@ int32_t videoSeek(int32_t playerHandle, int64_t seekFrame) { } +int32_t videoSetIndexCallback(videoIndexingCallback callback) { + _indexingFunction = callback; + return 0; +} + + int32_t videoSetVolume(int32_t playerHandle, int32_t leftPercent, int32_t rightPercent) { VideoPlayerT *v = NULL; @@ -550,22 +561,16 @@ int32_t videoUpdate(int32_t playerHandle, SDL_Texture **texture) { int64_t threshold = 0; VideoPlayerT *v = NULL; - // Get our player structure HASH_FIND_INT(_videoPlayerHash, &playerHandle, v); if (!v) utilDie("No video player at index %d in videoUpdate.", playerHandle); // Audio drift limit - if (v->audioSource) { - threshold = (v->audioProps->SampleRate / 2); - } else { - threshold = 99999; - } + threshold = v->audioSource ? (v->audioProps->SampleRate / 2) : 99999; // Handle video frames (and time) - if ((SDL_GetTicks() - v->lastTickTime >= v->frameDeltaTime) || (v->audioDelta > threshold) || v->resetTime) { - - v->lastTickTime = SDL_GetTicks(); + //if ((SDL_GetTicks() - v->lastTickTime >= v->frameDeltaTime) || (v->audioDelta > threshold) || v->resetTime) { + if ((SDL_GetTicks() - v->lastTickTime >= v->frameDeltaTime) || v->resetTime) { if (v->frameData) { SDL_UpdateTexture(v->videoTexture, NULL, v->frameData->Data[0], v->frameData->Linesize[0]); @@ -575,22 +580,6 @@ int32_t videoUpdate(int32_t playerHandle, SDL_Texture **texture) { result = v->frame; v->framesPlayed++; - if (v->audioSource) { - // Did we trip the audio sync compensation? - if (v->audioDelta > threshold) { - // Adjust frame rate to try and match - if (v->audioDelta > 0) { - v->audioAdjustment += 0.000001; - } else { - v->audioAdjustment -= 0.000001; - } - } - // 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)); - } - - //utilSay("D %ld T %ld A %f", v->audioDelta, threshold, v->audioAdjustment); - v->frameData = FFMS_GetFrame(v->videoSource, v->frame, &v->errInfo); if (v->frameData == NULL) utilDie("%s", v->errInfo.Buffer); v->frameInfo = FFMS_GetFrameInfo(FFMS_GetTrackFromVideo(v->videoSource), v->frame); @@ -600,12 +589,14 @@ int32_t videoUpdate(int32_t playerHandle, SDL_Texture **texture) { if (v->playing) { if (++v->frame >= v->videoProps->NumFrames) { - v->frame = 0; + v->frame = 0; v->timestamp = 0; v->resetTime = true; } } + v->lastTickTime = SDL_GetTicks(); + if (v->resetTime) { if (v->audioSource) { SDL_AudioStreamClear(v->audioStream); @@ -621,6 +612,7 @@ int32_t videoUpdate(int32_t playerHandle, SDL_Texture **texture) { // Handle audio samples if (v->audioSource) { + // Add more samples to queue? if ((v->playing) && (SDL_AudioStreamAvailable(v->audioStream) < AUDIO_STREAM_LOW_WATERMARK) && (v->audioPosition < v->audioProps->NumSamples)) { // Maximum samples we can read at a time count = AUDIO_SAMPLE_PREREAD; @@ -637,6 +629,24 @@ int32_t videoUpdate(int32_t playerHandle, SDL_Texture **texture) { v->audioPosition += count; } } + + // 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)); + + // Did we trip the audio sync compensation? + if (v->audioDelta > threshold) { + v->frameDeltaTime *= 0.5; + //utilSay("Adjusting delta %f", v->frameDeltaTime); + /* + // Adjust frame rate to try and match + if (v->audioDelta > 0) { + v->audioAdjustment += 0.000001; + } else { + v->audioAdjustment -= 0.000001; + } + */ + } + //utilSay("D %ld T %ld A %f F %f", v->audioDelta, threshold, v->audioAdjustment, v->frameDeltaTime); } return result; diff --git a/singe/videoPlayer.h b/singe/videoPlayer.h index fb3e5b58f..3bbb62c05 100644 --- a/singe/videoPlayer.h +++ b/singe/videoPlayer.h @@ -29,6 +29,9 @@ #include "common.h" +typedef void (*videoIndexingCallback)(int32_t); + + int32_t videoInit(void); int32_t videoIsPlaying(int32_t playerHandle); int64_t videoGetFrame(int32_t playerHandle); @@ -42,6 +45,7 @@ int32_t videoPause(int32_t playerHandle); int32_t videoPlay(int32_t playerHandle); int32_t videoQuit(void); int32_t videoSeek(int32_t playerHandle, int64_t seekFrame); +int32_t videoSetIndexCallback(videoIndexingCallback callback); int32_t videoSetVolume(int32_t playerHandle, int32_t leftPercent, int32_t rightPercent); int32_t videoUnload(int32_t playerHandle); int32_t videoUpdate(int32_t playerHandle, SDL_Texture **texture);