summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDidier Raboud <odyx@debian.org>2018-09-21 10:55:02 +0200
committerDidier Raboud <odyx@debian.org>2018-09-21 10:55:02 +0200
commit2a4137dbeeacbb042c23c56f5ef957f3a0c65c6c (patch)
tree73c9b7f2ead1845950786237e992b9c4f598b827
parentb47550a069ff077f0b8c3821bbf9465f71fdcc59 (diff)
parentc678b8ac9c590326fc7e7aefd254c910297f2096 (diff)
record new upstream branch and merge it
-rw-r--r--CMakeLists.txt4
-rw-r--r--README.md3
-rw-r--r--debian/.git-dpm14
-rw-r--r--examples/example_complex.c3
-rw-r--r--examples/example_custom.c2
-rw-r--r--examples/example_rwops.c4
-rw-r--r--examples/example_simple.c2
-rw-r--r--include/kitchensink/internal/audio/kitaudio.h1
-rw-r--r--include/kitchensink/internal/video/kitvideo.h1
-rw-r--r--include/kitchensink/kitsource.h9
-rw-r--r--src/internal/audio/kitaudio.c8
-rw-r--r--src/internal/video/kitvideo.c10
-rw-r--r--src/kitplayer.c102
13 files changed, 111 insertions, 52 deletions
diff --git a/CMakeLists.txt b/CMakeLists.txt
index c89dbc3..bbe8fa0 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -5,7 +5,7 @@ set(CMAKE_MODULE_PATH ${PROJECT_SOURCE_DIR}/cmake)
set(KIT_VERSION_MAJOR "1")
set(KIT_VERSION_MINOR "0")
-set(KIT_VERSION_PATCH "4")
+set(KIT_VERSION_PATCH "5")
set(KIT_VERSION ${KIT_VERSION_MAJOR}.${KIT_VERSION_MINOR}.${KIT_VERSION_PATCH})
add_definitions(
-DKIT_VERSION_MAJOR=${KIT_VERSION_MAJOR}
@@ -20,7 +20,7 @@ set(CMAKE_C_FLAGS_RELEASE "${CMAKE_C_FLAGS_RELEASE} -O2 -DNDEBUG")
set(CMAKE_C_FLAGS_MINSIZEREL "${CMAKE_C_FLAGS_MINSIZEREL} -Os -DNDEBUG")
option(BUILD_EXAMPLES "Build examples" OFF)
-option(USE_DYNAMIC_LIBASS "Use dynamically loaded libass" ON)
+option(USE_DYNAMIC_LIBASS "Use dynamically loaded libass" OFF)
option(USE_ASAN "Use AddressSanitizer" OFF)
find_package(SDL2 REQUIRED)
diff --git a/README.md b/README.md
index 3b9b467..d2745ce 100644
--- a/README.md
+++ b/README.md
@@ -30,7 +30,6 @@ Library requirements:
* SDL2 (>=2.0.5)
* FFmpeg (>=3.0)
* libass (optional, supports runtime linking via SDL_LoadSO)
-* CUnit (optional, for unittests)
Note that Clang might work, but is not tested. Older SDL2 and FFmpeg library versions
may or may not work; versions noted here are the only ones tested.
@@ -92,7 +91,7 @@ After building, you can run with the following (make sure to set correct llvm-sy
ASAN_OPTIONS=symbolize=1 ASAN_SYMBOLIZER_PATH=/usr/bin/llvm-symbolizer ./examplevideo <my videofile>
```
-## 3. Why SDL_kitchensink
+## 3. Why the name SDL_kitchensink
Because pulling major blob of library code like ffmpeg feels like bringing in a whole house with its
kitchensink and everything to the project. Also, it sounded funny. Also, SDL_ffmpeg is already reserved :(
diff --git a/debian/.git-dpm b/debian/.git-dpm
index 9074f07..1fe78de 100644
--- a/debian/.git-dpm
+++ b/debian/.git-dpm
@@ -1,8 +1,8 @@
# see git-dpm(1) from git-dpm package
-4c38cd19867186bb97c179eab4cc72a426b795df
-4c38cd19867186bb97c179eab4cc72a426b795df
-4c38cd19867186bb97c179eab4cc72a426b795df
-4c38cd19867186bb97c179eab4cc72a426b795df
-sdl-kitchensink_1.0.4.orig.tar.gz
-e82045206e9ca1b9478a5488ea31d4e5016cc161
-67884
+c678b8ac9c590326fc7e7aefd254c910297f2096
+c678b8ac9c590326fc7e7aefd254c910297f2096
+c678b8ac9c590326fc7e7aefd254c910297f2096
+c678b8ac9c590326fc7e7aefd254c910297f2096
+sdl-kitchensink_1.0.5.orig.tar.gz
+3f041f644977d709b1d9647bba505c9f46396435
+68427
diff --git a/examples/example_complex.c b/examples/example_complex.c
index b8dc6ee..aeda110 100644
--- a/examples/example_complex.c
+++ b/examples/example_complex.c
@@ -88,7 +88,7 @@ int main(int argc, char *argv[]) {
}
// Create a resizable window.
- window = SDL_CreateWindow("Example Player", SDL_WINDOWPOS_UNDEFINED, SDL_WINDOWPOS_UNDEFINED, 1280, 720, SDL_WINDOW_RESIZABLE);
+ window = SDL_CreateWindow(filename, SDL_WINDOWPOS_UNDEFINED, SDL_WINDOWPOS_UNDEFINED, 1280, 720, SDL_WINDOW_RESIZABLE);
if(window == NULL) {
fprintf(stderr, "Unable to create a new window!\n");
return 1;
@@ -110,7 +110,6 @@ int main(int argc, char *argv[]) {
// Allow Kit to use more threads
Kit_SetHint(KIT_HINT_THREAD_COUNT, SDL_GetCPUCount() <= 8 ? SDL_GetCPUCount() : 8);
- Kit_SetHint(KIT_HINT_FONT_HINTING, KIT_FONT_HINTING_LIGHT);
// Open up the sourcefile.
// This can be a local file, network url, ...
diff --git a/examples/example_custom.c b/examples/example_custom.c
index f99c94e..8844b79 100644
--- a/examples/example_custom.c
+++ b/examples/example_custom.c
@@ -48,7 +48,7 @@ int main(int argc, char *argv[]) {
}
// Create a resizable window.
- window = SDL_CreateWindow("Example Player", SDL_WINDOWPOS_UNDEFINED, SDL_WINDOWPOS_UNDEFINED, 1280, 720, SDL_WINDOW_RESIZABLE);
+ window = SDL_CreateWindow(filename, SDL_WINDOWPOS_UNDEFINED, SDL_WINDOWPOS_UNDEFINED, 1280, 720, SDL_WINDOW_RESIZABLE);
if(window == NULL) {
fprintf(stderr, "Unable to create a new window!\n");
return 1;
diff --git a/examples/example_rwops.c b/examples/example_rwops.c
index 84370f1..96a3655 100644
--- a/examples/example_rwops.c
+++ b/examples/example_rwops.c
@@ -27,7 +27,7 @@ int main(int argc, char *argv[]) {
// Get filename to open
if(argc != 2) {
- fprintf(stderr, "Usage: custom <filename>\n");
+ fprintf(stderr, "Usage: rwops <filename>\n");
return 0;
}
filename = argv[1];
@@ -40,7 +40,7 @@ int main(int argc, char *argv[]) {
}
// Create a resizable window.
- window = SDL_CreateWindow("Example Player", SDL_WINDOWPOS_UNDEFINED, SDL_WINDOWPOS_UNDEFINED, 1280, 720, SDL_WINDOW_RESIZABLE);
+ window = SDL_CreateWindow(filename, SDL_WINDOWPOS_UNDEFINED, SDL_WINDOWPOS_UNDEFINED, 1280, 720, SDL_WINDOW_RESIZABLE);
if(window == NULL) {
fprintf(stderr, "Unable to create a new window!\n");
return 1;
diff --git a/examples/example_simple.c b/examples/example_simple.c
index 4c581c0..234a83d 100644
--- a/examples/example_simple.c
+++ b/examples/example_simple.c
@@ -39,7 +39,7 @@ int main(int argc, char *argv[]) {
}
// Create a resizable window.
- window = SDL_CreateWindow("Example Player", SDL_WINDOWPOS_UNDEFINED, SDL_WINDOWPOS_UNDEFINED, 1280, 720, SDL_WINDOW_RESIZABLE);
+ window = SDL_CreateWindow(filename, SDL_WINDOWPOS_UNDEFINED, SDL_WINDOWPOS_UNDEFINED, 1280, 720, SDL_WINDOW_RESIZABLE);
if(window == NULL) {
fprintf(stderr, "Unable to create a new window!\n");
return 1;
diff --git a/include/kitchensink/internal/audio/kitaudio.h b/include/kitchensink/internal/audio/kitaudio.h
index e42770b..c3db420 100644
--- a/include/kitchensink/internal/audio/kitaudio.h
+++ b/include/kitchensink/internal/audio/kitaudio.h
@@ -7,5 +7,6 @@
KIT_LOCAL Kit_Decoder* Kit_CreateAudioDecoder(const Kit_Source *src, int stream_index);
KIT_LOCAL int Kit_GetAudioDecoderData(Kit_Decoder *dec, unsigned char *buf, int len);
+KIT_LOCAL double Kit_GetAudioDecoderPTS(Kit_Decoder *dec);
#endif // KITAUDIO_H
diff --git a/include/kitchensink/internal/video/kitvideo.h b/include/kitchensink/internal/video/kitvideo.h
index 5c072ef..b393347 100644
--- a/include/kitchensink/internal/video/kitvideo.h
+++ b/include/kitchensink/internal/video/kitvideo.h
@@ -9,5 +9,6 @@
KIT_LOCAL Kit_Decoder* Kit_CreateVideoDecoder(const Kit_Source *src, int stream_index);
KIT_LOCAL int Kit_GetVideoDecoderData(Kit_Decoder *dec, SDL_Texture *texture);
+KIT_LOCAL double Kit_GetVideoDecoderPTS(Kit_Decoder *dec);
#endif // KITVIDEO_H
diff --git a/include/kitchensink/kitsource.h b/include/kitchensink/kitsource.h
index 9b744ca..c410be1 100644
--- a/include/kitchensink/kitsource.h
+++ b/include/kitchensink/kitsource.h
@@ -110,7 +110,8 @@ typedef int64_t (*Kit_SeekCallback)(void *userdata, int64_t offset, int whence);
*
* For example:
* ```
- * if(Kit_CreateSourceFromUrl(filename) == NULL) {
+ * Kit_Source *src = Kit_CreateSourceFromUrl(filename);
+ * if(src == NULL) {
* fprintf(stderr, "Error: %s\n", Kit_GetError());
* return 1;
* }
@@ -133,7 +134,8 @@ KIT_API Kit_Source* Kit_CreateSourceFromUrl(const char *url);
*
* For example:
* ```
- * if(Kit_CreateSourceFromCustom(read_fn, seek_fn, fp) == NULL) {
+ * Kit_Source *src = Kit_CreateSourceFromCustom(read_fn, seek_fn, fp);
+ * if(src == NULL) {
* fprintf(stderr, "Error: %s\n", Kit_GetError());
* return 1;
* }
@@ -162,7 +164,8 @@ KIT_API Kit_Source* Kit_CreateSourceFromCustom(Kit_ReadCallback read_cb, Kit_See
* For example:
* ```
* SDL_RWops *rw = SDL_RWFromFile("myvideo.mkv", "rb");
- * if(Kit_CreateSourceFromRW(rw) == NULL) {
+ * Kit_Source *src = Kit_CreateSourceFromRW(rw);
+ * if(src == NULL) {
* fprintf(stderr, "Error: %s\n", Kit_GetError());
* return 1;
* }
diff --git a/src/internal/audio/kitaudio.c b/src/internal/audio/kitaudio.c
index b1a0fdc..e399ff2 100644
--- a/src/internal/audio/kitaudio.c
+++ b/src/internal/audio/kitaudio.c
@@ -264,6 +264,14 @@ exit_0:
return NULL;
}
+double Kit_GetAudioDecoderPTS(Kit_Decoder *dec) {
+ Kit_AudioPacket *packet = Kit_PeekDecoderOutput(dec);
+ if(packet == NULL) {
+ return -1.0;
+ }
+ return packet->pts;
+}
+
int Kit_GetAudioDecoderData(Kit_Decoder *dec, unsigned char *buf, int len) {
assert(dec != NULL);
diff --git a/src/internal/video/kitvideo.c b/src/internal/video/kitvideo.c
index 1629b05..350d3c5 100644
--- a/src/internal/video/kitvideo.c
+++ b/src/internal/video/kitvideo.c
@@ -73,7 +73,7 @@ static enum AVPixelFormat _FindAVPixelFormat(unsigned int fmt) {
case SDL_PIXELFORMAT_UYVY: return AV_PIX_FMT_UYVY422;
case SDL_PIXELFORMAT_NV12: return AV_PIX_FMT_NV12;
case SDL_PIXELFORMAT_NV21: return AV_PIX_FMT_NV21;
- case SDL_PIXELFORMAT_ARGB32: return AV_PIX_FMT_BGRA;
+ case SDL_PIXELFORMAT_ARGB32: return AV_PIX_FMT_ARGB;
case SDL_PIXELFORMAT_RGBA32: return AV_PIX_FMT_RGBA;
case SDL_PIXELFORMAT_BGR24: return AV_PIX_FMT_BGR24;
case SDL_PIXELFORMAT_RGB24: return AV_PIX_FMT_RGB24;
@@ -236,6 +236,14 @@ exit_0:
return NULL;
}
+double Kit_GetVideoDecoderPTS(Kit_Decoder *dec) {
+ Kit_VideoPacket *packet = Kit_PeekDecoderOutput(dec);
+ if(packet == NULL) {
+ return -1.0;
+ }
+ return packet->pts;
+}
+
int Kit_GetVideoDecoderData(Kit_Decoder *dec, SDL_Texture *texture) {
assert(dec != NULL);
assert(texture != NULL);
diff --git a/src/kitplayer.c b/src/kitplayer.c
index 5220945..d2a4604 100644
--- a/src/kitplayer.c
+++ b/src/kitplayer.c
@@ -73,26 +73,32 @@ static bool _IsOutputEmpty(const Kit_Player *player) {
static int _RunDecoder(Kit_Player *player) {
int got;
- int ret = 0;
+ bool has_room = true;
- if(SDL_LockMutex(player->dec_lock) != 0) {
- return ret;
- }
+ do {
+ while((got = _DemuxStream(player)) == -1);
+ if(got == 1 && _IsOutputEmpty(player)) {
+ return 1;
+ }
- while((got = _DemuxStream(player)) == -1);
- if(got == 1 && _IsOutputEmpty(player)) {
- ret = 1;
- goto exit;
- }
+ for(int i = 0; i < KIT_DEC_COUNT; i++) {
+ while(Kit_RunDecoder(player->decoders[i]) == 1);
+ }
- // Run decoders for a bit
- for(int i = 0; i < KIT_DEC_COUNT; i++) {
- while(Kit_RunDecoder(player->decoders[i]) == 1);
- }
+ // If there is no room in any decoder input, just stop here since it likely means that
+ // at least some decoder output is full.
+ for(int i = 0; i < KIT_DEC_COUNT; i++) {
+ Kit_Decoder *dec = player->decoders[i];
+ if(dec == NULL)
+ continue;
+ if(!Kit_CanWriteDecoderInput(dec)) {
+ has_room = false;
+ break;
+ }
+ }
+ } while(has_room);
-exit:
- SDL_UnlockMutex(player->dec_lock);
- return ret;
+ return 0;
}
static int _DecoderThread(void *ptr) {
@@ -109,18 +115,26 @@ static int _DecoderThread(void *ptr) {
is_playing = true;
}
while(is_running && is_playing) {
- if(player->state == KIT_CLOSED) {
- is_running = false;
- continue;
- }
- if(player->state == KIT_STOPPED) {
- is_playing = false;
- continue;
- }
- if(_RunDecoder(player) == 1) {
- player->state = KIT_STOPPED;
- continue;
+ // Grab the decoder lock, and run demuxer & decoders for a bit.
+ if(SDL_LockMutex(player->dec_lock) == 0) {
+ if(player->state == KIT_CLOSED) {
+ is_running = false;
+ goto end_block;
+ }
+ if(player->state == KIT_STOPPED) {
+ is_playing = false;
+ goto end_block;
+ }
+ if(_RunDecoder(player) == 1) {
+ player->state = KIT_STOPPED;
+ goto end_block;
+ }
+
+end_block:
+ SDL_UnlockMutex(player->dec_lock);
}
+
+ // Delay to make sure this thread does not hog all cpu
SDL_Delay(2);
}
@@ -361,6 +375,7 @@ void Kit_PlayerPlay(Kit_Player *player) {
player->state = KIT_PLAYING;
break;
case KIT_STOPPED:
+ _RunDecoder(player); // Fill some buffers before starting playback
_SetClockSync(player);
player->state = KIT_PLAYING;
break;
@@ -379,6 +394,9 @@ void Kit_PlayerStop(Kit_Player *player) {
case KIT_PLAYING:
case KIT_PAUSED:
player->state = KIT_STOPPED;
+ for(int i = 0; i < KIT_DEC_COUNT; i++) {
+ Kit_ClearDecoderBuffers(player->decoders[i]);
+ }
break;
}
SDL_UnlockMutex(player->dec_lock);
@@ -414,15 +432,37 @@ int Kit_PlayerSeek(Kit_Player *player, double seek_set) {
if(seek_set < position) {
flags |= AVSEEK_FLAG_BACKWARD;
}
- if(avformat_seek_file(format_ctx, -1, 0, seek_target, seek_target, flags) < 0) {
+
+ // First, tell ffmpeg to seek stream. If not capable, stop here.
+ // Failure here probably means that stream is unseekable someway, eg. streamed media
+ if(avformat_seek_file(format_ctx, -1, INT64_MIN, seek_target, INT64_MAX, flags) < 0) {
Kit_SetError("Unable to seek source");
SDL_UnlockMutex(player->dec_lock);
return 1;
+ }
+
+ // Clean old buffers and try to fill them with new data
+ for(int i = 0; i < KIT_DEC_COUNT; i++) {
+ Kit_ClearDecoderBuffers(player->decoders[i]);
+ }
+ _RunDecoder(player);
+
+ // Try to get a precise seek position from the next audio/video frame
+ // (depending on which one is used to sync)
+ double precise_pts = -1.0F;
+ if(player->decoders[KIT_VIDEO_DEC] != NULL) {
+ precise_pts = Kit_GetVideoDecoderPTS(player->decoders[KIT_VIDEO_DEC]);
+ }
+ else if(player->decoders[KIT_AUDIO_DEC] != NULL) {
+ precise_pts = Kit_GetAudioDecoderPTS(player->decoders[KIT_AUDIO_DEC]);
+ }
+
+ // If we got a legit looking value, set it as seek value. Otherwise use
+ // the seek value we requested.
+ if(precise_pts >= 0) {
+ _ChangeClockSync(player, position - precise_pts);
} else {
_ChangeClockSync(player, position - seek_set);
- for(int i = 0; i < KIT_DEC_COUNT; i++) {
- Kit_ClearDecoderBuffers(player->decoders[i]);
- }
}
// That's it. Unlock and continue.