summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--CMakeLists.txt2
-rw-r--r--debian/.git-dpm14
-rw-r--r--include/kitchensink/internal/kitdecoder.h1
-rw-r--r--include/kitchensink/internal/subtitle/renderers/kitsubrenderer.h4
-rw-r--r--include/kitchensink/internal/utils/kitbuffer.h1
-rw-r--r--src/internal/audio/kitaudio.c55
-rw-r--r--src/internal/kitdecoder.c41
-rw-r--r--src/internal/subtitle/kitsubtitle.c6
-rw-r--r--src/internal/subtitle/renderers/kitsubass.c33
-rw-r--r--src/internal/subtitle/renderers/kitsubimage.c4
-rw-r--r--src/internal/subtitle/renderers/kitsubrenderer.c4
-rw-r--r--src/internal/utils/kitbuffer.c4
-rw-r--r--src/internal/utils/kitringbuffer.c33
-rw-r--r--src/internal/video/kitvideo.c41
-rw-r--r--src/kitplayer.c2
-rw-r--r--src/kitsource.c8
16 files changed, 153 insertions, 100 deletions
diff --git a/CMakeLists.txt b/CMakeLists.txt
index bbe8fa0..0922eaa 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 "5")
+set(KIT_VERSION_PATCH "6")
set(KIT_VERSION ${KIT_VERSION_MAJOR}.${KIT_VERSION_MINOR}.${KIT_VERSION_PATCH})
add_definitions(
-DKIT_VERSION_MAJOR=${KIT_VERSION_MAJOR}
diff --git a/debian/.git-dpm b/debian/.git-dpm
index 1fe78de..2ac5733 100644
--- a/debian/.git-dpm
+++ b/debian/.git-dpm
@@ -1,8 +1,8 @@
# see git-dpm(1) from git-dpm package
-c678b8ac9c590326fc7e7aefd254c910297f2096
-c678b8ac9c590326fc7e7aefd254c910297f2096
-c678b8ac9c590326fc7e7aefd254c910297f2096
-c678b8ac9c590326fc7e7aefd254c910297f2096
-sdl-kitchensink_1.0.5.orig.tar.gz
-3f041f644977d709b1d9647bba505c9f46396435
-68427
+25747441205f7973ea8815f1014372378ff34858
+25747441205f7973ea8815f1014372378ff34858
+25747441205f7973ea8815f1014372378ff34858
+25747441205f7973ea8815f1014372378ff34858
+sdl-kitchensink_1.0.6.orig.tar.gz
+bd681b4c4913077449985126cc9ec71546164a88
+69103
diff --git a/include/kitchensink/internal/kitdecoder.h b/include/kitchensink/internal/kitdecoder.h
index ef3edb7..74134b0 100644
--- a/include/kitchensink/internal/kitdecoder.h
+++ b/include/kitchensink/internal/kitdecoder.h
@@ -70,6 +70,7 @@ KIT_LOCAL void Kit_ForEachDecoderOutput(Kit_Decoder *dec, Kit_ForEachItemCallbac
KIT_LOCAL int Kit_LockDecoderOutput(Kit_Decoder *dec);
KIT_LOCAL void Kit_UnlockDecoderOutput(Kit_Decoder *dec);
KIT_LOCAL void Kit_ClearDecoderOutput(Kit_Decoder *dec);
+KIT_LOCAL unsigned int Kit_GetDecoderOutputLength(Kit_Decoder *dec);
#endif // KITDECODER_H
diff --git a/include/kitchensink/internal/subtitle/renderers/kitsubrenderer.h b/include/kitchensink/internal/subtitle/renderers/kitsubrenderer.h
index 3c37b00..8b35c2b 100644
--- a/include/kitchensink/internal/subtitle/renderers/kitsubrenderer.h
+++ b/include/kitchensink/internal/subtitle/renderers/kitsubrenderer.h
@@ -9,7 +9,7 @@ typedef struct Kit_SubtitleRenderer Kit_SubtitleRenderer;
typedef struct Kit_TextureAtlas Kit_TextureAtlas;
typedef struct Kit_Decoder Kit_Decoder;
-typedef void (*ren_render_cb)(Kit_SubtitleRenderer *ren, void *src, double start_pts, double end_pts);
+typedef void (*ren_render_cb)(Kit_SubtitleRenderer *ren, void *src, double pts, double start, double end);
typedef int (*ren_get_data_cb)(Kit_SubtitleRenderer *ren, Kit_TextureAtlas *atlas, SDL_Texture *texture, double current_pts);
typedef void (*ren_set_size_cb)(Kit_SubtitleRenderer *ren, int w, int h);
typedef void (*ren_close_cb)(Kit_SubtitleRenderer *ren);
@@ -24,7 +24,7 @@ struct Kit_SubtitleRenderer {
};
KIT_LOCAL Kit_SubtitleRenderer* Kit_CreateSubtitleRenderer(Kit_Decoder *dec);
-KIT_LOCAL void Kit_RunSubtitleRenderer(Kit_SubtitleRenderer *ren, void *src, double start_pts, double end_pts);
+KIT_LOCAL void Kit_RunSubtitleRenderer(Kit_SubtitleRenderer *ren, void *src, double pts, double start, double end);
KIT_LOCAL int Kit_GetSubtitleRendererData(Kit_SubtitleRenderer *ren, Kit_TextureAtlas *atlas, SDL_Texture *texture, double current_pts);
KIT_LOCAL void Kit_SetSubtitleRendererSize(Kit_SubtitleRenderer *ren, int w, int h);
KIT_LOCAL void Kit_CloseSubtitleRenderer(Kit_SubtitleRenderer *ren);
diff --git a/include/kitchensink/internal/utils/kitbuffer.h b/include/kitchensink/internal/utils/kitbuffer.h
index 67d93c3..95d75b5 100644
--- a/include/kitchensink/internal/utils/kitbuffer.h
+++ b/include/kitchensink/internal/utils/kitbuffer.h
@@ -19,6 +19,7 @@ struct Kit_Buffer {
KIT_LOCAL Kit_Buffer* Kit_CreateBuffer(unsigned int size, Kit_BufferFreeCallback free_cb);
KIT_LOCAL void Kit_DestroyBuffer(Kit_Buffer *buffer);
+KIT_LOCAL unsigned int Kit_GetBufferLength(const Kit_Buffer *buffer);
KIT_LOCAL void Kit_ClearBuffer(Kit_Buffer *buffer);
KIT_LOCAL void* Kit_ReadBuffer(Kit_Buffer *buffer);
KIT_LOCAL void* Kit_PeekBuffer(const Kit_Buffer *buffer);
diff --git a/src/internal/audio/kitaudio.c b/src/internal/audio/kitaudio.c
index e399ff2..3a534bb 100644
--- a/src/internal/audio/kitaudio.c
+++ b/src/internal/audio/kitaudio.c
@@ -15,7 +15,7 @@
#include "kitchensink/internal/utils/kitringbuffer.h"
#include "kitchensink/internal/utils/kitlog.h"
-#define AUDIO_SYNC_THRESHOLD 0.05
+#define KIT_AUDIO_SYNC_THRESHOLD 0.05
typedef struct Kit_AudioDecoder {
SwrContext *swr;
@@ -275,36 +275,30 @@ double Kit_GetAudioDecoderPTS(Kit_Decoder *dec) {
int Kit_GetAudioDecoderData(Kit_Decoder *dec, unsigned char *buf, int len) {
assert(dec != NULL);
- Kit_AudioPacket *packet = Kit_PeekDecoderOutput(dec);
+ Kit_AudioPacket *packet = NULL;
+ int ret = 0;
+ int bytes_per_sample = 0;
+ double bytes_per_second = 0;
+ double sync_ts = 0;
+
+ // First, peek the next packet. Make sure we have something to read.
+ packet = Kit_PeekDecoderOutput(dec);
if(packet == NULL) {
return 0;
}
- int ret = 0;
- int bytes_per_sample = dec->output.bytes * dec->output.channels;
- double bytes_per_second = bytes_per_sample * dec->output.samplerate;
- double sync_ts = _GetSystemTime() - dec->clock_sync;
-
- if(packet->pts > sync_ts + AUDIO_SYNC_THRESHOLD) {
+ // If packet should not yet be played, stop here and wait.
+ // If packet should have already been played, skip it and try to find a better packet.
+ // For audio, it is possible that we cannot find good packet. Then just don't read anything.
+ sync_ts = _GetSystemTime() - dec->clock_sync;
+ if(packet->pts > sync_ts + KIT_AUDIO_SYNC_THRESHOLD) {
return 0;
- } else if(packet->pts < sync_ts - AUDIO_SYNC_THRESHOLD) {
- // Audio is lagging, skip until good pts is found
- while(1) {
- Kit_AdvanceDecoderOutput(dec);
- free_out_audio_packet_cb(packet);
- packet = Kit_PeekDecoderOutput(dec);
- if(packet == NULL) {
- break;
- } else {
- dec->clock_pos = packet->pts;
- }
- if(packet->pts > sync_ts - AUDIO_SYNC_THRESHOLD) {
- break;
- }
- }
}
-
- // If we have no viable packet, just skip
+ while(packet != NULL && packet->pts < sync_ts - KIT_AUDIO_SYNC_THRESHOLD) {
+ Kit_AdvanceDecoderOutput(dec);
+ free_out_audio_packet_cb(packet);
+ packet = Kit_PeekDecoderOutput(dec);
+ }
if(packet == NULL) {
return 0;
}
@@ -312,18 +306,19 @@ int Kit_GetAudioDecoderData(Kit_Decoder *dec, unsigned char *buf, int len) {
// Read data from packet ringbuffer
if(len > 0) {
ret = Kit_ReadRingBuffer(packet->rb, (char*)buf, len);
+ if(ret) {
+ bytes_per_sample = dec->output.bytes * dec->output.channels;
+ bytes_per_second = bytes_per_sample * dec->output.samplerate;
+ packet->pts += ((double)ret) / bytes_per_second;
+ }
}
+ dec->clock_pos = packet->pts;
// If ringbuffer is cleared, kill packet and advance buffer.
// Otherwise forward the pts value for the current packet.
if(Kit_GetRingBufferLength(packet->rb) == 0) {
Kit_AdvanceDecoderOutput(dec);
- dec->clock_pos = packet->pts;
free_out_audio_packet_cb(packet);
- } else {
- packet->pts += ((double)ret) / bytes_per_second;
- dec->clock_pos = packet->pts;
}
-
return ret;
}
diff --git a/src/internal/kitdecoder.c b/src/internal/kitdecoder.c
index 0855eee..09e46d3 100644
--- a/src/internal/kitdecoder.c
+++ b/src/internal/kitdecoder.c
@@ -20,6 +20,7 @@ Kit_Decoder* Kit_CreateDecoder(const Kit_Source *src, int stream_index,
assert(thread_count > 0);
AVCodecContext *codec_ctx = NULL;
+ AVDictionary *codec_opts = NULL;
AVCodec *codec = NULL;
AVFormatContext *format_ctx = src->format_ctx;
int bsizes[2] = {BUFFER_IN_SIZE, out_b_size};
@@ -39,8 +40,12 @@ Kit_Decoder* Kit_CreateDecoder(const Kit_Source *src, int stream_index,
}
// Find audio decoder
+#if LIBAVCODEC_VERSION_INT < AV_VERSION_INT(57, 48, 101)
codec = avcodec_find_decoder(format_ctx->streams[stream_index]->codec->codec_id);
- if(!codec) {
+#else
+ codec = avcodec_find_decoder(format_ctx->streams[stream_index]->codecpar->codec_id);
+#endif
+ if(codec == NULL) {
Kit_SetError("No suitable decoder found for stream %d", stream_index);
goto exit_1;
}
@@ -52,18 +57,33 @@ Kit_Decoder* Kit_CreateDecoder(const Kit_Source *src, int stream_index,
goto exit_1;
}
- // Copy context from stream to target codec context
- if(avcodec_copy_context(codec_ctx, format_ctx->streams[stream_index]->codec) != 0) {
+ // Copy params
+#if LIBAVCODEC_VERSION_INT < AV_VERSION_INT(57, 48, 101)
+ if(avcodec_copy_context(codec_ctx, format_ctx->streams[stream_index]->codec) != 0)
+#else
+ if(avcodec_parameters_to_context(codec_ctx, format_ctx->streams[stream_index]->codecpar) < 0)
+#endif
+ {
Kit_SetError("Unable to copy codec context for stream %d", stream_index);
goto exit_2;
}
+ // Required by ffmpeg for now when using the new API.
+#if LIBAVCODEC_VERSION_INT >= AV_VERSION_INT(57, 48, 101)
+ codec_ctx->pkt_timebase = format_ctx->streams[stream_index]->time_base;
+#endif
+
// Set thread count
codec_ctx->thread_count = thread_count;
- codec_ctx->thread_type = FF_THREAD_SLICE;
+ codec_ctx->thread_type = FF_THREAD_SLICE|FF_THREAD_FRAME;
+
+ // This is required for ass_process_chunk() support
+ if(LIBAVCODEC_VERSION_INT >= AV_VERSION_INT(57, 25, 100)) {
+ av_dict_set(&codec_opts, "sub_text_format", "ass", 0);
+ }
// Open the stream
- if(avcodec_open2(codec_ctx, codec, NULL) < 0) {
+ if(avcodec_open2(codec_ctx, codec, &codec_opts) < 0) {
Kit_SetError("Unable to open codec for stream %d", stream_index);
goto exit_2;
}
@@ -98,6 +118,7 @@ exit_3:
}
avcodec_close(codec_ctx);
exit_2:
+ av_dict_free(&codec_opts);
avcodec_free_context(&codec_ctx);
exit_1:
free(dec);
@@ -266,6 +287,16 @@ void Kit_AdvanceDecoderOutput(Kit_Decoder *dec) {
}
}
+unsigned int Kit_GetDecoderOutputLength(Kit_Decoder *dec) {
+ assert(dec != NULL);
+ unsigned int len = 0;
+ if(SDL_LockMutex(dec->output_lock) == 0) {
+ len = Kit_GetBufferLength(dec->buffer[KIT_DEC_BUF_OUT]);
+ SDL_UnlockMutex(dec->output_lock);
+ }
+ return len;
+}
+
void Kit_ClearDecoderBuffers(Kit_Decoder *dec) {
if(dec == NULL) return;
Kit_ClearDecoderInput(dec);
diff --git a/src/internal/subtitle/kitsubtitle.c b/src/internal/subtitle/kitsubtitle.c
index d6bed5d..417b338 100644
--- a/src/internal/subtitle/kitsubtitle.c
+++ b/src/internal/subtitle/kitsubtitle.c
@@ -59,12 +59,12 @@ static void dec_decode_subtitle_cb(Kit_Decoder *dec, AVPacket *in_packet) {
subtitle_dec->scratch_frame.end_display_time = 30000;
}
- start = pts + subtitle_dec->scratch_frame.start_display_time / 1000.0F;
- end = pts + subtitle_dec->scratch_frame.end_display_time / 1000.0F;
+ start = subtitle_dec->scratch_frame.start_display_time / 1000.0F;
+ end = subtitle_dec->scratch_frame.end_display_time / 1000.0F;
// Create a packet. This should be filled by renderer.
Kit_RunSubtitleRenderer(
- subtitle_dec->renderer, &subtitle_dec->scratch_frame, start, end);
+ subtitle_dec->renderer, &subtitle_dec->scratch_frame, pts, start, end);
// Free subtitle since it has now been handled
avsubtitle_free(&subtitle_dec->scratch_frame);
diff --git a/src/internal/subtitle/renderers/kitsubass.c b/src/internal/subtitle/renderers/kitsubass.c
index 7db72dd..c229406 100644
--- a/src/internal/subtitle/renderers/kitsubass.c
+++ b/src/internal/subtitle/renderers/kitsubass.c
@@ -2,6 +2,7 @@
#include <stdlib.h>
#include <SDL_surface.h>
+#include <libavcodec/version.h>
#include "kitchensink/kiterror.h"
#include "kitchensink/internal/utils/kitlog.h"
@@ -40,7 +41,7 @@ static void Kit_ProcessAssImage(SDL_Surface *surface, const ASS_Image *img) {
}
}
-static void ren_render_ass_cb(Kit_SubtitleRenderer *ren, void *src, double start_pts, double end_pts) {
+static void ren_render_ass_cb(Kit_SubtitleRenderer *ren, void *src, double pts, double start, double end) {
assert(ren != NULL);
assert(src != NULL);
@@ -48,11 +49,26 @@ static void ren_render_ass_cb(Kit_SubtitleRenderer *ren, void *src, double start
AVSubtitle *sub = src;
// Read incoming subtitle packets to libASS
+ long long start_ms = (start + pts) * 1000;
+ long long end_ms = end * 1000;
if(Kit_LockDecoderOutput(ren->dec) == 0) {
for(int r = 0; r < sub->num_rects; r++) {
if(sub->rects[r]->ass == NULL)
continue;
- ass_process_data(ass_ren->track, sub->rects[r]->ass, strlen(sub->rects[r]->ass));
+ if(LIBAVCODEC_VERSION_INT < AV_VERSION_INT(57,25,100)) {
+ ass_process_data(
+ ass_ren->track,
+ sub->rects[r]->ass,
+ strlen(sub->rects[r]->ass));
+ } else {
+ // This requires the sub_text_format codec_opt set for ffmpeg
+ ass_process_chunk(
+ ass_ren->track,
+ sub->rects[r]->ass,
+ strlen(sub->rects[r]->ass),
+ start_ms,
+ end_ms);
+ }
}
Kit_UnlockDecoderOutput(ren->dec);
}
@@ -150,7 +166,12 @@ Kit_SubtitleRenderer* Kit_CreateASSSubtitleRenderer(Kit_Decoder *dec, int video_
// Read fonts from attachment streams and give them to libass
for(int j = 0; j < dec->format_ctx->nb_streams; j++) {
AVStream *st = dec->format_ctx->streams[j];
- if(st->codec->codec_type == AVMEDIA_TYPE_ATTACHMENT && attachment_is_font(st)) {
+#if LIBAVCODEC_VERSION_INT < AV_VERSION_INT(57, 48, 101)
+ AVCodecContext *codec = st->codec;
+#else
+ AVCodecParameters *codec = st->codecpar;
+#endif
+ if(codec->codec_type == AVMEDIA_TYPE_ATTACHMENT && attachment_is_font(st)) {
const AVDictionaryEntry *tag = av_dict_get(
st->metadata,
"filename",
@@ -159,9 +180,9 @@ Kit_SubtitleRenderer* Kit_CreateASSSubtitleRenderer(Kit_Decoder *dec, int video_
if(tag) {
ass_add_font(
state->libass_handle,
- tag->value,
- (char*)st->codec->extradata,
- st->codec->extradata_size);
+ tag->value,
+ (char*)codec->extradata,
+ codec->extradata_size);
}
}
}
diff --git a/src/internal/subtitle/renderers/kitsubimage.c b/src/internal/subtitle/renderers/kitsubimage.c
index 0cd0cce..b9a8e48 100644
--- a/src/internal/subtitle/renderers/kitsubimage.c
+++ b/src/internal/subtitle/renderers/kitsubimage.c
@@ -17,13 +17,15 @@ typedef struct Kit_ImageSubtitleRenderer {
float scale_y;
} Kit_ImageSubtitleRenderer;
-static void ren_render_image_cb(Kit_SubtitleRenderer *ren, void *sub_src, double start_pts, double end_pts) {
+static void ren_render_image_cb(Kit_SubtitleRenderer *ren, void *sub_src, double pts, double start, double end) {
assert(ren != NULL);
assert(sub_src != NULL);
AVSubtitle *sub = sub_src;
SDL_Surface *dst = NULL;
SDL_Surface *src = NULL;
+ double start_pts = pts + start;
+ double end_pts = pts + end;
// If this subtitle has no rects, we still need to clear screen from old subs
if(sub->num_rects == 0) {
diff --git a/src/internal/subtitle/renderers/kitsubrenderer.c b/src/internal/subtitle/renderers/kitsubrenderer.c
index 77ad201..d41d61d 100644
--- a/src/internal/subtitle/renderers/kitsubrenderer.c
+++ b/src/internal/subtitle/renderers/kitsubrenderer.c
@@ -17,11 +17,11 @@ Kit_SubtitleRenderer* Kit_CreateSubtitleRenderer(Kit_Decoder *dec) {
return ren;
}
-void Kit_RunSubtitleRenderer(Kit_SubtitleRenderer *ren, void *src, double start_pts, double end_pts) {
+void Kit_RunSubtitleRenderer(Kit_SubtitleRenderer *ren, void *src, double pts, double start, double end) {
if(ren == NULL)
return;
if(ren->ren_render != NULL)
- ren->ren_render(ren, src, start_pts, end_pts);
+ ren->ren_render(ren, src, pts, start, end);
}
int Kit_GetSubtitleRendererData(Kit_SubtitleRenderer *ren, Kit_TextureAtlas *atlas, SDL_Texture *texture, double current_pts) {
diff --git a/src/internal/utils/kitbuffer.c b/src/internal/utils/kitbuffer.c
index 0133154..60ca831 100644
--- a/src/internal/utils/kitbuffer.c
+++ b/src/internal/utils/kitbuffer.c
@@ -18,6 +18,10 @@ Kit_Buffer* Kit_CreateBuffer(unsigned int size, Kit_BufferFreeCallback free_cb)
return b;
}
+unsigned int Kit_GetBufferLength(const Kit_Buffer *buffer) {
+ return buffer->write_p - buffer->read_p;
+}
+
void Kit_DestroyBuffer(Kit_Buffer *buffer) {
if(buffer == NULL) return;
Kit_ClearBuffer(buffer);
diff --git a/src/internal/utils/kitringbuffer.c b/src/internal/utils/kitringbuffer.c
index 70fd24f..e6fa136 100644
--- a/src/internal/utils/kitringbuffer.c
+++ b/src/internal/utils/kitringbuffer.c
@@ -68,6 +68,17 @@ int Kit_WriteRingBuffer(Kit_RingBuffer *rb, const char* data, int len) {
return 0;
}
+static void _ReadRingBufferData(const Kit_RingBuffer *rb, char *data, const int len) {
+ int k;
+ if(len + rb->rpos > rb->size) {
+ k = (len + rb->rpos) % rb->size;
+ memcpy(data, rb->data + rb->rpos, len - k);
+ memcpy(data + (len - k), rb->data, k);
+ } else {
+ memcpy(data, rb->data + rb->rpos, len);
+ }
+}
+
/**
* Reads data from ringbuffer. If ringbuffer has less data than was requested,
* only the available data will be read.
@@ -76,17 +87,10 @@ int Kit_WriteRingBuffer(Kit_RingBuffer *rb, const char* data, int len) {
* @param len How much data do we want
* @return Amount of data that was actually read.
*/
-int Kit_ReadRingBuffer(Kit_RingBuffer *rb, char* data, int len) {
- int k;
+int Kit_ReadRingBuffer(Kit_RingBuffer *rb, char *data, int len) {
len = (len > rb->len) ? rb->len : len;
if(rb->len > 0) {
- if(len + rb->rpos > rb->size) {
- k = (len + rb->rpos) % rb->size;
- memcpy(data, (rb->data + rb->rpos), len-k);
- memcpy(data+(len-k), (rb->data), k);
- } else {
- memcpy(data, (rb->data + rb->rpos), len);
- }
+ _ReadRingBufferData(rb, data, len);
rb->len -= len;
rb->rpos += len;
if(rb->rpos >= rb->size) {
@@ -106,17 +110,10 @@ int Kit_ReadRingBuffer(Kit_RingBuffer *rb, char* data, int len) {
* @param len How much data do we need
* @return Amount of data actually read
*/
-int Kit_PeekRingBuffer(const Kit_RingBuffer *rb, char* data, int len) {
- int k;
+int Kit_PeekRingBuffer(const Kit_RingBuffer *rb, char *data, int len) {
len = (len > rb->len) ? rb->len : len;
if(rb->len > 0) {
- if(len + rb->rpos > rb->size) {
- k = (len + rb->rpos) % rb->size;
- memcpy(data, (rb->data + rb->rpos), len-k);
- memcpy(data+(len-k), (rb->data), k);
- } else {
- memcpy(data, (rb->data + rb->rpos), len);
- }
+ _ReadRingBufferData(rb, data, len);
return len;
}
return 0;
diff --git a/src/internal/video/kitvideo.c b/src/internal/video/kitvideo.c
index 350d3c5..568c178 100644
--- a/src/internal/video/kitvideo.c
+++ b/src/internal/video/kitvideo.c
@@ -12,7 +12,7 @@
#include "kitchensink/internal/video/kitvideo.h"
#include "kitchensink/internal/utils/kitlog.h"
-#define KIT_VIDEO_SYNC_THRESHOLD 0.01
+#define KIT_VIDEO_SYNC_THRESHOLD 0.02
enum AVPixelFormat supported_list[] = {
AV_PIX_FMT_YUV420P,
@@ -248,35 +248,30 @@ int Kit_GetVideoDecoderData(Kit_Decoder *dec, SDL_Texture *texture) {
assert(dec != NULL);
assert(texture != NULL);
- Kit_VideoPacket *packet = Kit_PeekDecoderOutput(dec);
+ Kit_VideoPacket *packet = NULL;
+ double sync_ts = 0;
+ unsigned int limit_rounds = 0;
+
+ // First, peek the next packet. Make sure we have something to read.
+ packet = Kit_PeekDecoderOutput(dec);
if(packet == NULL) {
return 0;
}
- double sync_ts = _GetSystemTime() - dec->clock_sync;
-
- // Check if we want the packet
+ // If packet should not yet be played, stop here and wait.
+ // If packet should have already been played, skip it and try to find a better packet.
+ // For video, we *try* to return a frame, even if we are out of sync. It is better than
+ // not showing anything.
+ sync_ts = _GetSystemTime() - dec->clock_sync;
if(packet->pts > sync_ts + KIT_VIDEO_SYNC_THRESHOLD) {
- // Video is ahead, don't show yet.
return 0;
- } else if(packet->pts < sync_ts - KIT_VIDEO_SYNC_THRESHOLD) {
- // Video is lagging, skip until we find a good PTS to continue from.
- while(packet != NULL) {
- Kit_AdvanceDecoderOutput(dec);
- free_out_video_packet_cb(packet);
- packet = Kit_PeekDecoderOutput(dec);
- if(packet == NULL) {
- break;
- } else {
- dec->clock_pos = packet->pts;
- }
- if(packet->pts > sync_ts - KIT_VIDEO_SYNC_THRESHOLD) {
- break;
- }
- }
}
-
- // If we have no viable packet, just skip
+ limit_rounds = Kit_GetDecoderOutputLength(dec);
+ while(packet != NULL && packet->pts < sync_ts - KIT_VIDEO_SYNC_THRESHOLD && --limit_rounds) {
+ Kit_AdvanceDecoderOutput(dec);
+ free_out_video_packet_cb(packet);
+ packet = Kit_PeekDecoderOutput(dec);
+ }
if(packet == NULL) {
return 0;
}
diff --git a/src/kitplayer.c b/src/kitplayer.c
index d2a4604..0baf57b 100644
--- a/src/kitplayer.c
+++ b/src/kitplayer.c
@@ -435,7 +435,7 @@ int Kit_PlayerSeek(Kit_Player *player, double seek_set) {
// 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) {
+ if(avformat_seek_file(format_ctx, -1, seek_target, seek_target, INT64_MAX, flags) < 0) {
Kit_SetError("Unable to seek source");
SDL_UnlockMutex(player->dec_lock);
return 1;
diff --git a/src/kitsource.c b/src/kitsource.c
index 588f829..1a3bb00 100644
--- a/src/kitsource.c
+++ b/src/kitsource.c
@@ -177,7 +177,13 @@ int Kit_GetSourceStreamInfo(const Kit_Source *src, Kit_SourceStreamInfo *info, i
}
AVStream *stream = format_ctx->streams[index];
- switch(stream->codec->codec_type) {
+ enum AVMediaType codec_type;
+#if LIBAVCODEC_VERSION_INT < AV_VERSION_INT(57, 48, 101)
+ codec_type = stream->codec->codec_type;
+#else
+ codec_type = stream->codecpar->codec_type;
+#endif
+ switch(codec_type) {
case AVMEDIA_TYPE_UNKNOWN: info->type = KIT_STREAMTYPE_UNKNOWN; break;
case AVMEDIA_TYPE_DATA: info->type = KIT_STREAMTYPE_DATA; break;
case AVMEDIA_TYPE_VIDEO: info->type = KIT_STREAMTYPE_VIDEO; break;