Another audio sync fix, Pi build, initial Sinden lightgun support, indexing display, and more.
This commit is contained in:
parent
57bb9c7703
commit
fc859dc05c
18 changed files with 245 additions and 72 deletions
3
.gitignore
vendored
3
.gitignore
vendored
|
@ -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
|
||||
|
|
|
@ -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}"
|
||||
|
|
BIN
singe/font.png
(Stored with Git LFS)
BIN
singe/font.png
(Stored with Git LFS)
Binary file not shown.
BIN
singe/font.xcf
(Stored with Git LFS)
Normal file
BIN
singe/font.xcf
(Stored with Git LFS)
Normal file
Binary file not shown.
|
@ -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;
|
||||
|
|
BIN
singe/icon.png
(Stored with Git LFS)
BIN
singe/icon.png
(Stored with Git LFS)
Binary file not shown.
BIN
singe/icon.xcf
(Stored with Git LFS)
Normal file
BIN
singe/icon.xcf
(Stored with Git LFS)
Normal file
Binary file not shown.
BIN
singe/indexing.xcf
(Stored with Git LFS)
Normal file
BIN
singe/indexing.xcf
(Stored with Git LFS)
Normal file
Binary file not shown.
BIN
singe/laserDisc.xcf
(Stored with Git LFS)
Normal file
BIN
singe/laserDisc.xcf
(Stored with Git LFS)
Normal file
Binary file not shown.
BIN
singe/magnifyingGlass.xcf
(Stored with Git LFS)
Normal file
BIN
singe/magnifyingGlass.xcf
(Stored with Git LFS)
Normal file
Binary file not shown.
|
@ -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();
|
||||
|
|
|
@ -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
|
||||
|
|
128
singe/singe.c
128
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***
|
||||
|
|
|
@ -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"
|
||||
|
||||
|
||||
|
|
|
@ -119,7 +119,10 @@ HEADERS += \
|
|||
extensions.h \
|
||||
font.h \
|
||||
singeLogo.h \
|
||||
kangarooPunchLogo.h
|
||||
kangarooPunchLogo.h \
|
||||
laserDisc.h \
|
||||
magnifyingGlass.h \
|
||||
indexing.h
|
||||
|
||||
SOURCES += \
|
||||
$$ARGPARSER_SOURCES \
|
||||
|
|
|
@ -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"
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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);
|
||||
|
|
Loading…
Add table
Reference in a new issue