summaryrefslogtreecommitdiff
path: root/src/internal/subtitle/kitsubtitle.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/internal/subtitle/kitsubtitle.c')
-rw-r--r--src/internal/subtitle/kitsubtitle.c95
1 files changed, 20 insertions, 75 deletions
diff --git a/src/internal/subtitle/kitsubtitle.c b/src/internal/subtitle/kitsubtitle.c
index 38d4768..3185bcd 100644
--- a/src/internal/subtitle/kitsubtitle.c
+++ b/src/internal/subtitle/kitsubtitle.c
@@ -11,13 +11,14 @@
#include "kitchensink/internal/kitlibstate.h"
#include "kitchensink/internal/subtitle/kitsubtitlepacket.h"
#include "kitchensink/internal/subtitle/kitsubtitle.h"
+#include "kitchensink/internal/subtitle/kitatlas.h"
#include "kitchensink/internal/subtitle/renderers/kitsubimage.h"
#include "kitchensink/internal/subtitle/renderers/kitsubass.h"
#include "kitchensink/internal/subtitle/renderers/kitsubrenderer.h"
#include "kitchensink/internal/utils/kithelpers.h"
-#define KIT_SUBTITLE_OUT_SIZE 1024
+#define KIT_SUBTITLE_OUT_SIZE 64
typedef struct Kit_SubtitleDecoder {
Kit_SubtitleFormat *format;
@@ -25,8 +26,7 @@ typedef struct Kit_SubtitleDecoder {
AVSubtitle scratch_frame;
int w;
int h;
- int output_state;
- SDL_Surface *tmp_buffer;
+ Kit_TextureAtlas *atlas;
} Kit_SubtitleDecoder;
@@ -82,7 +82,7 @@ static int dec_decode_subtitle_cb(Kit_Decoder *dec, AVPacket *in_packet) {
static void dec_close_subtitle_cb(Kit_Decoder *dec) {
if(dec == NULL) return;
Kit_SubtitleDecoder *subtitle_dec = dec->userdata;
- SDL_FreeSurface(subtitle_dec->tmp_buffer);
+ Kit_FreeAtlas(subtitle_dec->atlas);
Kit_CloseSubtitleRenderer(subtitle_dec->renderer);
free(subtitle_dec);
}
@@ -146,21 +146,19 @@ Kit_Decoder* Kit_CreateSubtitleDecoder(const Kit_Source *src, Kit_SubtitleFormat
goto exit_2;
}
- // Allocate temporary screen-sized subtitle buffer
- SDL_Surface *tmp_buffer = SDL_CreateRGBSurfaceWithFormat(0, w, h, 32, SDL_PIXELFORMAT_RGBA32);
- if(tmp_buffer == NULL) {
- Kit_SetError("Unable to allocate subtitle buffer");
+ // Allocate texture atlas for subtitle rectangles
+ Kit_TextureAtlas *atlas = Kit_CreateAtlas(1024, 1024);
+ if(atlas == NULL) {
+ Kit_SetError("Unable to allocate subtitle texture atlas");
goto exit_3;
}
- SDL_FillRect(tmp_buffer, NULL, 0);
// Set callbacks and userdata, and we're go
subtitle_dec->format = format;
subtitle_dec->renderer = ren;
subtitle_dec->w = w;
subtitle_dec->h = h;
- subtitle_dec->tmp_buffer = tmp_buffer;
- subtitle_dec->output_state = 0;
+ subtitle_dec->atlas = atlas;
dec->dec_decode = dec_decode_subtitle_cb;
dec->dec_close = dec_close_subtitle_cb;
dec->userdata = subtitle_dec;
@@ -176,79 +174,26 @@ exit_0:
return NULL;
}
-
-typedef struct {
- double sync_ts;
- SDL_Surface *surface;
- int rendered;
-} tmp_sub_image;
-
-
-static void _merge_subtitle_texture(void *ptr, void *userdata) {
- tmp_sub_image *img = userdata;
- Kit_SubtitlePacket *packet = ptr;
-
- // Make sure current time is within presentation range
- if(packet->pts_start >= img->sync_ts)
- return;
- if(packet->pts_end <= img->sync_ts && packet->pts_end >= 0)
- return;
-
- // Tell the renderer function that we did something here
- img->rendered = 1;
-
- // Blit source whole source surface to target surface in requested coords
- SDL_Rect dst_rect;
- dst_rect.x = packet->x;
- dst_rect.y = packet->y;
- SDL_BlitSurface(packet->surface, NULL, img->surface, &dst_rect);
-}
-
-
-int Kit_GetSubtitleDecoderDataTexture(Kit_Decoder *dec, SDL_Texture *texture) {
+int Kit_GetSubtitleDecoderData(Kit_Decoder *dec, SDL_Texture *texture, SDL_Rect *sources, SDL_Rect *targets, int limit) {
assert(dec != NULL);
assert(texture != NULL);
Kit_SubtitleDecoder *subtitle_dec = dec->userdata;
-
double sync_ts = _GetSystemTime() - dec->clock_sync;
- // If we rendered on last frame, clear the buffer
- if(subtitle_dec->output_state == 1) {
- SDL_FillRect(subtitle_dec->tmp_buffer, NULL, 0);
- }
+ // Tell the renderer to render content to atlas
+ Kit_GetSubtitleRendererData(subtitle_dec->renderer, subtitle_dec->atlas, sync_ts);
- // Clear out old packets
- Kit_SubtitlePacket *packet = NULL;
- while((packet = Kit_PeekDecoderOutput(dec)) != NULL) {
- if(packet->pts_end >= sync_ts)
- break;
- if(packet->pts_end < 0)
- break;
- Kit_AdvanceDecoderOutput(dec);
- free_out_subtitle_packet_cb(packet);
+ // Next, update the actual atlas texture contents. This may force the atlas to do partial or complete reordering
+ // OR it may simply be a texture update from cache.
+ if(Kit_UpdateAtlasTexture(subtitle_dec->atlas, texture) != 0) {
+ return -1;
}
- // Blit all subtitle image rectangles to master buffer
- tmp_sub_image img;
- img.sync_ts = sync_ts;
- img.surface = subtitle_dec->tmp_buffer;
- img.rendered = 0;
- Kit_ForEachDecoderOutput(dec, _merge_subtitle_texture, (void*)&img);
+ // Next, get targets and sources of visible atlas items
+ int item_count = Kit_GetAtlasItems(subtitle_dec->atlas, sources, targets, limit);
- // If nothing was rendered now or last frame, just return. No need to update texture.
+ // All done
dec->clock_pos = sync_ts;
- if(img.rendered == 0 && subtitle_dec->output_state == 0) {
- return 1;
- }
- subtitle_dec->output_state = img.rendered;
-
- // Update output texture with current buffered image
- SDL_UpdateTexture(
- texture, NULL,
- subtitle_dec->tmp_buffer->pixels,
- subtitle_dec->tmp_buffer->pitch);
-
- // all done!
- return 0;
+ return item_count;
}