summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--examples/example_audio.c8
-rw-r--r--examples/example_video.c13
-rw-r--r--include/kitchensink/kitplayer.h2
-rw-r--r--src/internal/subtitle/kitatlas.c10
-rw-r--r--src/internal/subtitle/renderers/kitsubimage.c3
-rw-r--r--src/kitplayer.c24
6 files changed, 42 insertions, 18 deletions
diff --git a/examples/example_audio.c b/examples/example_audio.c
index 45cf43d..dae252a 100644
--- a/examples/example_audio.c
+++ b/examples/example_audio.c
@@ -125,13 +125,11 @@ int main(int argc, char *argv[]) {
}
// Refresh audio
- ret = SDL_GetQueuedAudioSize(audio_dev);
- if(ret < AUDIOBUFFER_SIZE) {
- ret = Kit_GetAudioData(player, (unsigned char*)audiobuf, AUDIOBUFFER_SIZE);
+ int queued = SDL_GetQueuedAudioSize(audio_dev);
+ if(queued < AUDIOBUFFER_SIZE) {
+ ret = Kit_GetAudioData(player, (unsigned char*)audiobuf, AUDIOBUFFER_SIZE - queued);
if(ret > 0) {
- SDL_LockAudio();
SDL_QueueAudio(audio_dev, audiobuf, ret);
- SDL_UnlockAudio();
}
}
diff --git a/examples/example_video.c b/examples/example_video.c
index 72467ab..cef613d 100644
--- a/examples/example_video.c
+++ b/examples/example_video.c
@@ -253,6 +253,7 @@ int main(int argc, char *argv[]) {
if(Kit_PlayerSeek(player, m_time) != 0) {
fprintf(stderr, "%s\n", Kit_GetError());
}
+ SDL_ClearQueuedAudio(audio_dev);
} else {
// Handle pause
if(Kit_GetPlayerState(player) == KIT_PAUSED) {
@@ -274,10 +275,10 @@ int main(int argc, char *argv[]) {
gui_enabled = (mouse_y >= limit);
// Refresh audio
- if(SDL_GetQueuedAudioSize(audio_dev) < AUDIOBUFFER_SIZE) {
- int need = AUDIOBUFFER_SIZE - ret;
+ int queued = SDL_GetQueuedAudioSize(audio_dev);
+ if(queued < AUDIOBUFFER_SIZE) {
+ int need = AUDIOBUFFER_SIZE - queued;
- SDL_LockAudio();
while(need > 0) {
ret = Kit_GetAudioData(
player,
@@ -290,8 +291,10 @@ int main(int argc, char *argv[]) {
break;
}
}
- SDL_UnlockAudio();
- SDL_PauseAudioDevice(audio_dev, 0);
+ // If we now have data, start playback (again)
+ if(SDL_GetQueuedAudioSize(audio_dev) > 0) {
+ SDL_PauseAudioDevice(audio_dev, 0);
+ }
}
// Clear screen with black
diff --git a/include/kitchensink/kitplayer.h b/include/kitchensink/kitplayer.h
index e9f7dbf..b38385a 100644
--- a/include/kitchensink/kitplayer.h
+++ b/include/kitchensink/kitplayer.h
@@ -23,7 +23,7 @@ typedef enum Kit_PlayerState {
KIT_STOPPED = 0, ///< Playback stopped or has not started yet.
KIT_PLAYING, ///< Playback started & player is actively decoding.
KIT_PAUSED, ///< Playback paused; player is actively decoding but no new data is given out.
- KIT_CLOSED ///< Playback is stopped and player is closing.
+ KIT_CLOSED, ///< Playback is stopped and player is closing.
} Kit_PlayerState;
typedef struct Kit_Player {
diff --git a/src/internal/subtitle/kitatlas.c b/src/internal/subtitle/kitatlas.c
index a62690e..f9da36c 100644
--- a/src/internal/subtitle/kitatlas.c
+++ b/src/internal/subtitle/kitatlas.c
@@ -3,6 +3,8 @@
#include "kitchensink/internal/subtitle/kitatlas.h"
#include "kitchensink/internal/utils/kitlog.h"
+#define BORDER 2
+
static int min(int a, int b) {
if(a < b)
return a;
@@ -50,12 +52,11 @@ void Kit_ResetAtlasContent(Kit_TextureAtlas *atlas) {
}
void Kit_ClearAtlasContent(Kit_TextureAtlas *atlas) {
- Kit_TextureAtlasItem *item;
for(int i = 0; i < atlas->cur_items; i++) {
- item = &atlas->items[i];
- SDL_FreeSurface(item->surface);
+ SDL_FreeSurface(atlas->items[i].surface);
}
atlas->cur_items = 0;
+ memset(atlas->items, 0, atlas->max_items * sizeof(Kit_TextureAtlasItem));
memset(atlas->shelf, 0, sizeof(atlas->shelf));
}
@@ -82,7 +83,8 @@ int Kit_FindFreeAtlasSlot(Kit_TextureAtlas *atlas, Kit_TextureAtlasItem *item) {
assert(atlas != NULL);
assert(item != NULL);
- int shelf_w, shelf_h;
+ int shelf_w;
+ int shelf_h;
int total_remaining_h = atlas->h;
int total_reserved_h = 0;
diff --git a/src/internal/subtitle/renderers/kitsubimage.c b/src/internal/subtitle/renderers/kitsubimage.c
index 2edafc9..4cc14c4 100644
--- a/src/internal/subtitle/renderers/kitsubimage.c
+++ b/src/internal/subtitle/renderers/kitsubimage.c
@@ -14,7 +14,8 @@ static void ren_render_image_cb(Kit_SubtitleRenderer *ren, void *sub_src, double
assert(sub_src != NULL);
AVSubtitle *sub = sub_src;
- SDL_Surface *dst = NULL, *src = NULL;
+ SDL_Surface *dst = NULL;
+ SDL_Surface *src = NULL;
// If this subtitle has no rects, we still need to clear screen from old subs
if(sub->num_rects == 0) {
diff --git a/src/kitplayer.c b/src/kitplayer.c
index 6c20282..bf48d52 100644
--- a/src/kitplayer.c
+++ b/src/kitplayer.c
@@ -57,6 +57,21 @@ static int _DemuxStream(const Kit_Player *player) {
return -1;
}
+static bool _IsOutputEmpty(const Kit_Player *player) {
+ Kit_Decoder *decoders[] = {
+ player->video_dec,
+ player->audio_dec,
+ player->subtitle_dec
+ };
+ for(int i = 0; i < 3; i++) {
+ if(decoders[i] == NULL)
+ continue;
+ if(Kit_PeekDecoderOutput(decoders[i]))
+ return false;
+ }
+ return true;
+}
+
static int _DecoderThread(void *ptr) {
Kit_Player *player = ptr;
bool is_running = true;
@@ -84,8 +99,9 @@ static int _DecoderThread(void *ptr) {
// Get more data from demuxer, decode. Wait a bit if there's no more work for now.
if(SDL_LockMutex(player->dec_lock) == 0) {
while((ret = _DemuxStream(player)) == -1);
- if(ret == 1) {
+ if(ret == 1 && _IsOutputEmpty(player)) {
player->state = KIT_STOPPED;
+ SDL_UnlockMutex(player->dec_lock);
continue;
}
@@ -340,6 +356,7 @@ int Kit_PlayerSeek(Kit_Player *player, double seek_set) {
assert(player != NULL);
double position, duration;
int64_t seek_target;
+ int flags = AVSEEK_FLAG_ANY;
if(SDL_LockMutex(player->dec_lock) == 0) {
duration = Kit_GetPlayerDuration(player);
@@ -354,7 +371,10 @@ int Kit_PlayerSeek(Kit_Player *player, double seek_set) {
// Set source to timestamp
AVFormatContext *format_ctx = player->src->format_ctx;
seek_target = seek_set * AV_TIME_BASE;
- if(avformat_seek_file(format_ctx, -1, seek_target, seek_target, seek_target, AVSEEK_FLAG_ANY) < 0) {
+ if(seek_set < position) {
+ flags |= AVSEEK_FLAG_BACKWARD;
+ }
+ if(avformat_seek_file(format_ctx, -1, 0, seek_target, seek_target, flags) < 0) {
Kit_SetError("Unable to seek source");
SDL_UnlockMutex(player->dec_lock);
return 1;