Another audio sync fix, Pi build, initial Sinden lightgun support, indexing display, and more.

This commit is contained in:
Scott Duensing 2020-02-16 17:33:08 -06:00
parent 57bb9c7703
commit fc859dc05c
18 changed files with 245 additions and 72 deletions

3
.gitignore vendored
View file

@ -39,5 +39,8 @@ singe/font.h
singe/icon.h singe/icon.h
singe/kangarooPunchLogo.h singe/kangarooPunchLogo.h
singe/singeLogo.h singe/singeLogo.h
singe/indexing.h
singe/laserDisc.h
singe/magnifyingGlass.h
videotest/indexing/ videotest/indexing/
Makefile.in Makefile.in

View file

@ -21,6 +21,8 @@
source source.inc.sh source source.inc.sh
G_L="-------------------------------------------------------------------------------"
function doBuild() { function doBuild() {
local TARGET=$1 local TARGET=$1
@ -32,6 +34,9 @@ function doBuild() {
local OFILES="" local OFILES=""
local O= 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}/.." pushd "${SOURCE_DIR}/.."
mkdir -p build/${OSNAME}/${OSARCH} mkdir -p build/${OSNAME}/${OSARCH}
cd build cd build
@ -66,24 +71,29 @@ function doBuild() {
} }
# 64 Bit Linux # 64 Bit Linux
echo -e "${G_L}\nLinux x86_64\n${G_L}"
CROSS="x86_64-linux-gnu" CROSS="x86_64-linux-gnu"
EXTRA_CFLAGS="-O2" EXTRA_CFLAGS="-O2"
EXTRA_OFILES="" EXTRA_OFILES=""
EXTRA_LD_FLAGS="-l:everything.a -lpthread -lXv -lX11 -lXext -lm -ldl -lrt" 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 # 64 Bit Windows
echo -e "${G_L}\nWindows x86_64\n${G_L}"
CROSS="x86_64-w64-mingw32" CROSS="x86_64-w64-mingw32"
EXTRA_CFLAGS="-O2" EXTRA_CFLAGS="-O2"
EXTRA_OFILES="/tmp/singe.res" 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" 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 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.ico
rm /tmp/icon.png
rm /tmp/singe.res rm /tmp/singe.res
# 32 Bit Raspbian # 32 Bit Raspbian
echo -e "${G_L}\nLinux armv6\n${G_L}"
SYSROOT="/opt/cross/pi/buster" SYSROOT="/opt/cross/pi/buster"
CROSS="/opt/cross/pi/tools/arm-bcm2708/gcc-linaro-arm-linux-gnueabihf-raspbian/bin/arm-linux-gnueabihf" CROSS="/opt/cross/pi/tools/arm-bcm2708/gcc-linaro-arm-linux-gnueabihf-raspbian/bin/arm-linux-gnueabihf"
EXTRA_CFLAGS="-O2 --sysroot ${SYSROOT}" EXTRA_CFLAGS="-O2 --sysroot ${SYSROOT}"

BIN
singe/font.png (Stored with Git LFS)

Binary file not shown.

BIN
singe/font.xcf (Stored with Git LFS) Normal file

Binary file not shown.

View file

@ -242,6 +242,7 @@ int32_t frameFileSeek(int32_t frameFileHandle, int64_t seekFrame, int32_t *video
/* /*
// Daphne-like framefile searching // Daphne-like framefile searching
found = f->count - 1;
for (i=f->count - 1; i>=0; i--) { for (i=f->count - 1; i>=0; i--) {
if (seekFrame <= f->files[i].frame) { if (seekFrame <= f->files[i].frame) {
found = i; found = i;

BIN
singe/icon.png (Stored with Git LFS)

Binary file not shown.

BIN
singe/icon.xcf (Stored with Git LFS) Normal file

Binary file not shown.

BIN
singe/indexing.xcf (Stored with Git LFS) Normal file

Binary file not shown.

BIN
singe/laserDisc.xcf (Stored with Git LFS) Normal file

Binary file not shown.

BIN
singe/magnifyingGlass.xcf (Stored with Git LFS) Normal file

Binary file not shown.

View file

@ -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 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 // -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 // -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 x = 0;
int32_t err = 0; int32_t err = 0;
@ -132,6 +133,7 @@ int main(int argc, const char *argv[]) {
SDL_Surface *icon = NULL; SDL_Surface *icon = NULL;
SDL_DisplayMode mode; SDL_DisplayMode mode;
const char *arg = NULL; const char *arg = NULL;
const char **cargv = (const char **)argv;
struct Arg_parser parser; struct Arg_parser parser;
static struct ap_Option options[] = { static struct ap_Option options[] = {
{ 'a', "aspect", ap_yes }, { 'a', "aspect", ap_yes },
@ -189,7 +191,7 @@ int main(int argc, const char *argv[]) {
// For that dumb OS // For that dumb OS
utilRedirectConsole(); utilRedirectConsole();
if (!ap_init(&parser, argc, argv, options, 0)) { if (!ap_init(&parser, argc, cargv, options, 0)) {
utilDie("Out of memory parsing arguments."); utilDie("Out of memory parsing arguments.");
} }
if (ap_error(&parser)) { if (ap_error(&parser)) {
@ -613,6 +615,7 @@ int main(int argc, const char *argv[]) {
if (_confVideoFile) free(_confVideoFile); if (_confVideoFile) free(_confVideoFile);
if (_confScriptFile) free(_confScriptFile); if (_confScriptFile) free(_confScriptFile);
utilTraceEnd(); utilTraceEnd();
ap_free(&parser);
#ifdef _WIN32 #ifdef _WIN32
getchar(); getchar();

View file

@ -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() { function createExtensionHeader() {
local FFMPEG=$1 local FFMPEG=$1
local a= local a=
@ -476,21 +487,22 @@ if [[ ! -e "${G_INSTALLED}/lib/everything.a" ]]; then
fi fi
# === Overlay Font === # === Overlay Font ===
createEmbeddedBinary font.png font.h FONT_H createEmbeddedImage font
# === Window Icon === # === Window Icon ===
createEmbeddedBinary icon.png icon.h ICON_H createEmbeddedImage icon
# === Kangaroo Punch Logo === # === Kangaroo Punch Logo ===
if [[ ! -e kangarooPunchLogo.h ]]; then createEmbeddedImage kangarooPunchLogo
xcf2png kangarooPunchLogo.xcf -o kangarooPunchLogo.png
createEmbeddedBinary kangarooPunchLogo.png kangarooPunchLogo.h KANGAROOPUNCHLOGO_H
rm kangarooPunchLogo.png
fi
# === Singe Logo === # === Singe Logo ===
if [[ ! -e singeLogo.h ]]; then createEmbeddedImage singeLogo
xcf2png singeLogo.xcf -o singeLogo.png
createEmbeddedBinary singeLogo.png singeLogo.h SINGELOGO_H # === Laser Disc ===
rm singeLogo.png createEmbeddedImage laserDisc
fi
# === Magnifying Glass ===
createEmbeddedImage magnifyingGlass
# === "Indexing" Text ===
createEmbeddedImage indexing

View file

@ -40,6 +40,9 @@
#include "font.h" #include "font.h"
#include "kangarooPunchLogo.h" #include "kangarooPunchLogo.h"
#include "singeLogo.h" #include "singeLogo.h"
#include "laserDisc.h"
#include "magnifyingGlass.h"
#include "indexing.h"
#define AUDIO_MAX_VOLUME 63 #define AUDIO_MAX_VOLUME 63
@ -309,6 +312,7 @@ int32_t apiSingeQuit(lua_State *L);
int32_t apiSingeVersion(lua_State *L); int32_t apiSingeVersion(lua_State *L);
int32_t apiSingeSetGameName(lua_State *L); int32_t apiSingeSetGameName(lua_State *L);
int32_t apiSingeGetScriptPath(lua_State *L); int32_t apiSingeGetScriptPath(lua_State *L);
void doIndexDisplay(int32_t percent);
void doLogos(void); void doLogos(void);
void callLua(const char *func, const char *sig, ...); void callLua(const char *func, const char *sig, ...);
void channelFinished(int channel); 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) { void doLogos(void) {
int32_t i = 0; int32_t i = 0;
int32_t w = 0; int32_t w = 0;
@ -1878,10 +1992,10 @@ void doLogos(void) {
SDL_SetTextureAlphaMod(texKangaroo, i); SDL_SetTextureAlphaMod(texKangaroo, i);
SDL_RenderCopy(_renderer, texKangaroo, NULL, NULL); SDL_RenderCopy(_renderer, texKangaroo, NULL, NULL);
SDL_RenderPresent(_renderer); SDL_RenderPresent(_renderer);
SDL_Delay(5); SDL_Delay(3);
} }
SDL_Delay(1000); SDL_Delay(750);
// Cross fade to Singe logo // Cross fade to Singe logo
for (i=0; i<256; i++) { for (i=0; i<256; i++) {
@ -1891,10 +2005,10 @@ void doLogos(void) {
SDL_SetTextureAlphaMod(texSinge, i); SDL_SetTextureAlphaMod(texSinge, i);
SDL_RenderCopy(_renderer, texSinge, NULL, NULL); SDL_RenderCopy(_renderer, texSinge, NULL, NULL);
SDL_RenderPresent(_renderer); SDL_RenderPresent(_renderer);
SDL_Delay(5); SDL_Delay(3);
} }
SDL_Delay(1000); SDL_Delay(750);
// Fade to black // Fade to black
SDL_RenderSetLogicalSize(_renderer, surfSinge->w, surfSinge->h); SDL_RenderSetLogicalSize(_renderer, surfSinge->w, surfSinge->h);
@ -1904,7 +2018,7 @@ void doLogos(void) {
SDL_SetTextureAlphaMod(texSinge, i); SDL_SetTextureAlphaMod(texSinge, i);
SDL_RenderCopy(_renderer, texSinge, NULL, NULL); SDL_RenderCopy(_renderer, texSinge, NULL, NULL);
SDL_RenderPresent(_renderer); SDL_RenderPresent(_renderer);
SDL_Delay(5); SDL_Delay(3);
} }
SDL_DestroyTexture(texSinge); SDL_DestroyTexture(texSinge);
@ -2166,6 +2280,8 @@ void singe(SDL_Window *window, SDL_Renderer *renderer) {
lua_register(_luaContext, "singeGetScriptPath", apiSingeGetScriptPath); lua_register(_luaContext, "singeGetScriptPath", apiSingeGetScriptPath);
// Open main video file // Open main video file
doIndexDisplay(-1);
videoSetIndexCallback(doIndexDisplay);
if (_confIsFrameFile) { if (_confIsFrameFile) {
_frameFileHandle = frameFileLoad(_confVideoFile, _confDataDir, (bool)_confStretchVideo, _renderer); _frameFileHandle = frameFileLoad(_confVideoFile, _confDataDir, (bool)_confStretchVideo, _renderer);
if (_frameFileHandle < 0) utilDie("Unable to load framefile: %s", _confVideoFile); 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); if (_videoHandle < 0) utilDie("Unable to load video file: %s", _confVideoFile);
videoSetVolume(_videoHandle, _confVolumeVldp, _confVolumeVldp); videoSetVolume(_videoHandle, _confVolumeVldp, _confVolumeVldp);
videoSetIndexCallback(NULL);
doIndexDisplay(-2);
// Should we resize the window? // Should we resize the window?
//***TODO*** //***TODO***

View file

@ -31,7 +31,7 @@
// Don't forget to update singe.rc! // Don't forget to update singe.rc!
#define SINGE_VERSION 2.00 #define SINGE_VERSION 2.00
#define VERSION_STRING "v2.00b8" #define VERSION_STRING "v2.00b9"
#define COPYRIGHT_END_YEAR "2020" #define COPYRIGHT_END_YEAR "2020"

View file

@ -119,7 +119,10 @@ HEADERS += \
extensions.h \ extensions.h \
font.h \ font.h \
singeLogo.h \ singeLogo.h \
kangarooPunchLogo.h kangarooPunchLogo.h \
laserDisc.h \
magnifyingGlass.h \
indexing.h
SOURCES += \ SOURCES += \
$$ARGPARSER_SOURCES \ $$ARGPARSER_SOURCES \

View file

@ -1,7 +1,7 @@
101 ICON "/tmp/icon.ico" 101 ICON "/tmp/icon.ico"
1 VERSIONINFO 1 VERSIONINFO
FILEVERSION 2,0,0,8 FILEVERSION 2,0,0,9
PRODUCTVERSION 2,0,0,8 PRODUCTVERSION 2,0,0,9
BEGIN BEGIN
BLOCK "StringFileInfo" BLOCK "StringFileInfo"
BEGIN BEGIN
@ -9,12 +9,12 @@ BEGIN
BEGIN BEGIN
VALUE "CompanyName", "Kangaroo Punch Studios" VALUE "CompanyName", "Kangaroo Punch Studios"
VALUE "FileDescription", "Somewhat Interactive Nostalgic Game Engine" VALUE "FileDescription", "Somewhat Interactive Nostalgic Game Engine"
VALUE "FileVersion", "2.00b8" VALUE "FileVersion", "2.00b9"
VALUE "InternalName", "Singe" VALUE "InternalName", "Singe"
VALUE "LegalCopyright", "Copyright 2006-2020 Scott C. Duensing" VALUE "LegalCopyright", "Copyright 2006-2020 Scott C. Duensing"
VALUE "OriginalFilename", "singe.exe" VALUE "OriginalFilename", "singe.exe"
VALUE "ProductName", "Singe" VALUE "ProductName", "Singe"
VALUE "ProductVersion", "2.00b8" VALUE "ProductVersion", "2.00b9"
END END
END END
BLOCK "VarFileInfo" BLOCK "VarFileInfo"

View file

@ -62,7 +62,7 @@ typedef struct VideoPlayerS {
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;
@ -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); int32_t _loadVideoAndAudio(char *vFilename, char *aFilename, char *indexPath, bool stretchVideo, SDL_Renderer *renderer);
static VideoPlayerT *_videoPlayerHash = NULL; static videoIndexingCallback _indexingFunction = NULL;
static int32_t _nextId = 0; static VideoPlayerT *_videoPlayerHash = NULL;
static int32_t _mixRate = -1; static int32_t _nextId = 0;
static Uint8 _mixChannels = 0; static int32_t _mixRate = -1;
static SDL_AudioFormat _mixFormat = 0; static Uint8 _mixChannels = 0;
static SDL_AudioFormat _mixFormat = 0;
void _dequeueVideoAudio(int channel, void *stream, int bytes, void *udata) { // Callback. Not changing ints. 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. int FFMS_CC _indexCallBack(int64_t current, int64_t total, void *ICPrivate) { // Callback. Not changing int.
static int32_t lastPercent = 0; static int32_t lastPercent = 0;
int32_t thisPercent = 0; int32_t thisPercent = 0;
VideoPlayerT *v = (VideoPlayerT *)ICPrivate;
(void)ICPrivate; // Contains current VideoPlayerT (void)v;
if ((current == 0) && (total == 0)) { if ((current == 0) && (total == 0)) {
lastPercent = 0; // Reset 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); thisPercent = (int32_t)((double)current / (double)total * 100.0);
if (thisPercent != lastPercent) { if (thisPercent != lastPercent) {
lastPercent = thisPercent; lastPercent = thisPercent;
utilSay("Indexing: %d%%", thisPercent); //utilSay("Indexing: %d%%", thisPercent);
//***TODO*** GUI // GUI
if (_indexingFunction) {
_indexingFunction(thisPercent);
}
} }
} }
@ -170,7 +175,7 @@ FFMS_Index *_createIndex(char *filename, char *indexPath, bool hasVideo, bool ha
} }
} }
if (!index) { if (!index) {
utilSay("Creating new index."); //utilSay("Creating new index.");
indexer = FFMS_CreateIndexer(filename, &v->errInfo); indexer = FFMS_CreateIndexer(filename, &v->errInfo);
if (indexer == NULL) utilDie("%s", v->errInfo.Buffer); if (indexer == NULL) utilDie("%s", v->errInfo.Buffer);
if (hasAudio) FFMS_TrackTypeIndexSettings(indexer, FFMS_TYPE_AUDIO, 1, 0); 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) { int32_t videoSetVolume(int32_t playerHandle, int32_t leftPercent, int32_t rightPercent) {
VideoPlayerT *v = NULL; VideoPlayerT *v = NULL;
@ -550,22 +561,16 @@ int32_t videoUpdate(int32_t playerHandle, SDL_Texture **texture) {
int64_t threshold = 0; int64_t threshold = 0;
VideoPlayerT *v = NULL; VideoPlayerT *v = NULL;
// 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 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->audioSource ? (v->audioProps->SampleRate / 2) : 99999;
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) {
if ((SDL_GetTicks() - v->lastTickTime >= v->frameDeltaTime) || v->resetTime) {
v->lastTickTime = SDL_GetTicks();
if (v->frameData) { if (v->frameData) {
SDL_UpdateTexture(v->videoTexture, NULL, v->frameData->Data[0], v->frameData->Linesize[0]); 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; result = v->frame;
v->framesPlayed++; 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); v->frameData = FFMS_GetFrame(v->videoSource, v->frame, &v->errInfo);
if (v->frameData == NULL) utilDie("%s", v->errInfo.Buffer); if (v->frameData == NULL) utilDie("%s", v->errInfo.Buffer);
v->frameInfo = FFMS_GetFrameInfo(FFMS_GetTrackFromVideo(v->videoSource), v->frame); 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->playing) {
if (++v->frame >= v->videoProps->NumFrames) { if (++v->frame >= v->videoProps->NumFrames) {
v->frame = 0; v->frame = 0;
v->timestamp = 0; v->timestamp = 0;
v->resetTime = true; v->resetTime = true;
} }
} }
v->lastTickTime = SDL_GetTicks();
if (v->resetTime) { if (v->resetTime) {
if (v->audioSource) { if (v->audioSource) {
SDL_AudioStreamClear(v->audioStream); SDL_AudioStreamClear(v->audioStream);
@ -621,6 +612,7 @@ int32_t videoUpdate(int32_t playerHandle, SDL_Texture **texture) {
// Handle audio samples // Handle audio samples
if (v->audioSource) { if (v->audioSource) {
// 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->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;
@ -637,6 +629,24 @@ int32_t videoUpdate(int32_t playerHandle, SDL_Texture **texture) {
v->audioPosition += count; 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; return result;

View file

@ -29,6 +29,9 @@
#include "common.h" #include "common.h"
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);
int64_t videoGetFrame(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 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 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);
int32_t videoUpdate(int32_t playerHandle, SDL_Texture **texture); int32_t videoUpdate(int32_t playerHandle, SDL_Texture **texture);