diff options
author | Didier Raboud <odyx@debian.org> | 2018-09-21 10:55:02 +0200 |
---|---|---|
committer | Didier Raboud <odyx@debian.org> | 2018-09-21 10:55:02 +0200 |
commit | 2a4137dbeeacbb042c23c56f5ef957f3a0c65c6c (patch) | |
tree | 73c9b7f2ead1845950786237e992b9c4f598b827 | |
parent | b47550a069ff077f0b8c3821bbf9465f71fdcc59 (diff) | |
parent | c678b8ac9c590326fc7e7aefd254c910297f2096 (diff) |
record new upstream branch and merge it
-rw-r--r-- | CMakeLists.txt | 4 | ||||
-rw-r--r-- | README.md | 3 | ||||
-rw-r--r-- | debian/.git-dpm | 14 | ||||
-rw-r--r-- | examples/example_complex.c | 3 | ||||
-rw-r--r-- | examples/example_custom.c | 2 | ||||
-rw-r--r-- | examples/example_rwops.c | 4 | ||||
-rw-r--r-- | examples/example_simple.c | 2 | ||||
-rw-r--r-- | include/kitchensink/internal/audio/kitaudio.h | 1 | ||||
-rw-r--r-- | include/kitchensink/internal/video/kitvideo.h | 1 | ||||
-rw-r--r-- | include/kitchensink/kitsource.h | 9 | ||||
-rw-r--r-- | src/internal/audio/kitaudio.c | 8 | ||||
-rw-r--r-- | src/internal/video/kitvideo.c | 10 | ||||
-rw-r--r-- | src/kitplayer.c | 102 |
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) @@ -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. |