summaryrefslogtreecommitdiff
path: root/src/internal
diff options
context:
space:
mode:
authorTuomas Virtanen <katajakasa@gmail.com>2018-06-23 17:53:11 +0300
committerTuomas Virtanen <katajakasa@gmail.com>2018-06-23 17:53:11 +0300
commit60dd75397f1ce9c4a56e74ee0bb94cebd4ab831c (patch)
tree03b39dc8f6f1b2167971dd6b3a7fa89a3ee29bda /src/internal
parent329de67ea44552c1d08e23203daee7e878ffd759 (diff)
Implement new API for subtitle screen size and stream indexes
Diffstat (limited to 'src/internal')
-rw-r--r--src/internal/audio/kitaudio.c9
-rw-r--r--src/internal/kitdecoder.c13
-rw-r--r--src/internal/subtitle/kitatlas.c31
-rw-r--r--src/internal/subtitle/kitsubtitle.c19
-rw-r--r--src/internal/subtitle/renderers/kitsubass.c65
-rw-r--r--src/internal/subtitle/renderers/kitsubimage.c4
-rw-r--r--src/internal/subtitle/renderers/kitsubrenderer.c7
-rw-r--r--src/internal/video/kitvideo.c9
8 files changed, 96 insertions, 61 deletions
diff --git a/src/internal/audio/kitaudio.c b/src/internal/audio/kitaudio.c
index 74fd024..2071bc5 100644
--- a/src/internal/audio/kitaudio.c
+++ b/src/internal/audio/kitaudio.c
@@ -168,16 +168,17 @@ static void dec_close_audio_cb(Kit_Decoder *dec) {
free(audio_dec);
}
-Kit_Decoder* Kit_CreateAudioDecoder(const Kit_Source *src, Kit_AudioFormat *format) {
+Kit_Decoder* Kit_CreateAudioDecoder(const Kit_Source *src, int stream_index, Kit_AudioFormat *format) {
assert(src != NULL);
assert(format != NULL);
- if(src->audio_stream_index < 0) {
+ if(stream_index < 0) {
return NULL;
}
// First the generic decoder component ...
Kit_Decoder *dec = Kit_CreateDecoder(
- src, src->audio_stream_index,
+ src,
+ stream_index,
KIT_AUDIO_OUT_SIZE,
free_out_audio_packet_cb);
if(dec == NULL) {
@@ -187,7 +188,7 @@ Kit_Decoder* Kit_CreateAudioDecoder(const Kit_Source *src, Kit_AudioFormat *form
// Find formats
format->samplerate = dec->codec_ctx->sample_rate;
format->is_enabled = true;
- format->stream_index = src->audio_stream_index;
+ format->stream_index = stream_index;
format->channels = _FindChannelLayout(dec->codec_ctx->channel_layout);
_FindAudioFormat(dec->codec_ctx->sample_fmt, &format->bytes, &format->is_signed, &format->format);
diff --git a/src/internal/kitdecoder.c b/src/internal/kitdecoder.c
index a16663e..63cbb58 100644
--- a/src/internal/kitdecoder.c
+++ b/src/internal/kitdecoder.c
@@ -93,13 +93,22 @@ exit_0:
return NULL;
}
+int Kit_SetDecoderStreamIndex(Kit_Decoder *dec, int stream_index) {
+ if(dec == NULL)
+ return 1;
+ dec->stream_index = stream_index;
+ return 0;
+}
+
void Kit_SetDecoderClockSync(Kit_Decoder *dec, double sync) {
- if(dec == NULL) return;
+ if(dec == NULL)
+ return;
dec->clock_sync = sync;
}
void Kit_ChangeDecoderClockSync(Kit_Decoder *dec, double sync) {
- if(dec == NULL) return;
+ if(dec == NULL)
+ return;
dec->clock_sync += sync;
}
diff --git a/src/internal/subtitle/kitatlas.c b/src/internal/subtitle/kitatlas.c
index 34c88a8..42ddb43 100644
--- a/src/internal/subtitle/kitatlas.c
+++ b/src/internal/subtitle/kitatlas.c
@@ -10,10 +10,7 @@ static int min(int a, int b) {
}
-Kit_TextureAtlas* Kit_CreateAtlas(int w, int h) {
- assert(w >= 1024);
- assert(h >= 1024);
-
+Kit_TextureAtlas* Kit_CreateAtlas() {
Kit_TextureAtlas *atlas = calloc(1, sizeof(Kit_TextureAtlas));
if(atlas == NULL) {
goto exit_0;
@@ -21,9 +18,8 @@ Kit_TextureAtlas* Kit_CreateAtlas(int w, int h) {
atlas->cur_items = 0;
atlas->max_items = 1024;
atlas->max_shelves = 256;
- atlas->border = 1;
- atlas->w = w;
- atlas->h = h;
+ atlas->w = 0;
+ atlas->h = 0;
// Allocate items. These hold the surfaces that should be in atlas
atlas->items = calloc(atlas->max_items, sizeof(Kit_TextureAtlasItem));
@@ -115,7 +111,7 @@ int Kit_FindFreeAtlasSlot(Kit_TextureAtlas *atlas, Kit_TextureAtlasItem *item) {
total_reserved_h += shelf_h;
// If the item fits, check if the space is better than previous one
- if(item->surface->w <= (atlas->w - shelf_w) && (item->surface->h + atlas->border) <= shelf_h) {
+ if(item->surface->w <= (atlas->w - shelf_w) && (item->surface->h) <= shelf_h) {
if(shelf_h < best_shelf_h) {
best_shelf_h = shelf_h;
best_shelf_idx = shelf_idx;
@@ -130,21 +126,21 @@ int Kit_FindFreeAtlasSlot(Kit_TextureAtlas *atlas, Kit_TextureAtlasItem *item) {
item,
best_shelf_idx,
atlas->shelves[best_shelf_idx].count,
- atlas->shelves[best_shelf_idx].width + atlas->border,
+ atlas->shelves[best_shelf_idx].width,
best_shelf_y);
- atlas->shelves[best_shelf_idx].width += item->surface->w + atlas->border;
+ atlas->shelves[best_shelf_idx].width += item->surface->w;
atlas->shelves[best_shelf_idx].count += 1;
return 0;
} else if(total_remaining_h >= item->surface->h) {
- atlas->shelves[shelf_idx].width = item->surface->w + atlas->border;
- atlas->shelves[shelf_idx].height = item->surface->h + atlas->border;
+ atlas->shelves[shelf_idx].width = item->surface->w;
+ atlas->shelves[shelf_idx].height = item->surface->h;
atlas->shelves[shelf_idx].count = 1;
Kit_SetItemAllocation(
item,
shelf_idx,
0,
- atlas->border,
- total_reserved_h + atlas->border);
+ 0,
+ total_reserved_h);
return 0;
}
@@ -188,6 +184,7 @@ void Kit_BlitAtlasSurfaces(Kit_TextureAtlas *atlas, SDL_Texture *texture) {
int Kit_UpdateAtlasTexture(Kit_TextureAtlas *atlas, SDL_Texture *texture) {
assert(atlas != NULL);
assert(texture != NULL);
+ int ret = 0;
// Check if texture size has changed
int texture_w, texture_h;
@@ -199,13 +196,15 @@ int Kit_UpdateAtlasTexture(Kit_TextureAtlas *atlas, SDL_Texture *texture) {
atlas->h = texture_h;
}
+ // Allocate spots for all surfaces in the result texture. If there is not enough room for
+ // everything, we need to show it to the caller.
if(Kit_AllocateAtlasSurfaces(atlas) != 0) {
- LOG("WARNING! FULL ATLAS, CANNOT MAKE MORE ROOM!\n");
+ ret = 1;
}
// Blit unblitted surfaces to texture
Kit_BlitAtlasSurfaces(atlas, texture);
- return 0;
+ return ret;
}
int Kit_GetAtlasItems(const Kit_TextureAtlas *atlas, SDL_Rect *sources, SDL_Rect *targets, int limit) {
diff --git a/src/internal/subtitle/kitsubtitle.c b/src/internal/subtitle/kitsubtitle.c
index 8935efc..d6641fc 100644
--- a/src/internal/subtitle/kitsubtitle.c
+++ b/src/internal/subtitle/kitsubtitle.c
@@ -83,10 +83,10 @@ static void dec_close_subtitle_cb(Kit_Decoder *dec) {
free(subtitle_dec);
}
-Kit_Decoder* Kit_CreateSubtitleDecoder(const Kit_Source *src, Kit_SubtitleFormat *format, int w, int h) {
+Kit_Decoder* Kit_CreateSubtitleDecoder(const Kit_Source *src, int stream_index, Kit_SubtitleFormat *format, int w, int h) {
assert(src != NULL);
assert(format != NULL);
- if(src->subtitle_stream_index < 0) {
+ if(stream_index < 0) {
return NULL;
}
@@ -94,7 +94,8 @@ Kit_Decoder* Kit_CreateSubtitleDecoder(const Kit_Source *src, Kit_SubtitleFormat
// First the generic decoder component
Kit_Decoder *dec = Kit_CreateDecoder(
- src, src->subtitle_stream_index,
+ src,
+ stream_index,
KIT_SUBTITLE_OUT_SIZE,
free_out_subtitle_packet_cb);
if(dec == NULL) {
@@ -103,7 +104,7 @@ Kit_Decoder* Kit_CreateSubtitleDecoder(const Kit_Source *src, Kit_SubtitleFormat
// Set format. Note that is_enabled may be changed below ...
format->is_enabled = true;
- format->stream_index = src->subtitle_stream_index;
+ format->stream_index = stream_index;
format->format = SDL_PIXELFORMAT_RGBA32; // Always this
// ... then allocate the subtitle decoder
@@ -143,7 +144,7 @@ Kit_Decoder* Kit_CreateSubtitleDecoder(const Kit_Source *src, Kit_SubtitleFormat
}
// Allocate texture atlas for subtitle rectangles
- Kit_TextureAtlas *atlas = Kit_CreateAtlas(1024, 1024);
+ Kit_TextureAtlas *atlas = Kit_CreateAtlas();
if(atlas == NULL) {
Kit_SetError("Unable to allocate subtitle texture atlas");
goto exit_3;
@@ -170,6 +171,14 @@ exit_0:
return NULL;
}
+void Kit_SetSubtitleDecoderSize(Kit_Decoder *dec, int w, int h) {
+ assert(dec != NULL);
+ Kit_SubtitleDecoder *subtitle_dec = dec->userdata;
+ subtitle_dec->w = w;
+ subtitle_dec->h = h;
+ Kit_SetSubtitleRendererSize(subtitle_dec->renderer, w, h);
+}
+
int Kit_GetSubtitleDecoderData(Kit_Decoder *dec, SDL_Texture *texture, SDL_Rect *sources, SDL_Rect *targets, int limit) {
assert(dec != NULL);
assert(texture != NULL);
diff --git a/src/internal/subtitle/renderers/kitsubass.c b/src/internal/subtitle/renderers/kitsubass.c
index 88efcb6..9be834f 100644
--- a/src/internal/subtitle/renderers/kitsubass.c
+++ b/src/internal/subtitle/renderers/kitsubass.c
@@ -23,14 +23,15 @@ static void Kit_ProcessAssImage(SDL_Surface *surface, const ASS_Image *img) {
unsigned char a = (img->color) & 0xFF;
unsigned char *src = img->bitmap;
unsigned char *dst = surface->pixels;
- unsigned int x, y;
+ unsigned int x, y, rx;
for(y = 0; y < img->h; y++) {
for(x = 0; x < img->w; x++) {
- dst[x * 4 + 0] = r;
- dst[x * 4 + 1] = g;
- dst[x * 4 + 2] = b;
- dst[x * 4 + 3] = ((255 - a) * src[x]) >> 8;
+ rx = x * 4;
+ dst[rx + 0] = r;
+ dst[rx + 1] = g;
+ dst[rx + 2] = b;
+ dst[rx + 3] = ((255 - a) * src[x]) >> 8;
}
src += img->stride;
dst += surface->pitch;
@@ -64,44 +65,51 @@ static void ren_close_ass_cb(Kit_SubtitleRenderer *ren) {
free(ass_ren);
}
-static int ren_get_data_cb(Kit_SubtitleRenderer *ren, Kit_TextureAtlas *atlas, double current_pts) {
+static int ren_get_ass_data_cb(Kit_SubtitleRenderer *ren, Kit_TextureAtlas *atlas, double current_pts) {
Kit_ASSSubtitleRenderer *ass_ren = ren->userdata;
SDL_Surface *dst = NULL;
ASS_Image *src = NULL;
int change = 0;
unsigned int now = current_pts * 1000;
- // First, we tell ASS to render images for us
if(Kit_LockDecoderOutput(ren->dec) == 0) {
+ // Tell ASS to render some images
src = ass_render_frame(ass_ren->renderer, ass_ren->track, now, &change);
- Kit_UnlockDecoderOutput(ren->dec);
- }
- // If there was no change, stop here
- if(change == 0) {
- return 0;
- }
+ // If there was no change, stop here
+ if(change == 0) {
+ Kit_UnlockDecoderOutput(ren->dec);
+ return 0;
+ }
- // There was some change, process images and add them to atlas
- Kit_ClearAtlasContent(atlas);
- for(; src; src = src->next) {
- if(src->w == 0 || src->h == 0)
- continue;
- dst = SDL_CreateRGBSurfaceWithFormat(0, src->w, src->h, 32, SDL_PIXELFORMAT_RGBA32);
- Kit_ProcessAssImage(dst, src);
- SDL_Rect target;
- target.x = src->dst_x;
- target.y = src->dst_y;
- target.w = src->w;
- target.h = src->h;
- Kit_AddAtlasItem(atlas, dst, &target);
- SDL_FreeSurface(dst);
+ // There was some change, process images and add them to atlas
+ Kit_ClearAtlasContent(atlas);
+ for(; src; src = src->next) {
+ if(src->w == 0 || src->h == 0)
+ continue;
+ dst = SDL_CreateRGBSurfaceWithFormat(0, src->w, src->h, 32, SDL_PIXELFORMAT_RGBA32);
+ Kit_ProcessAssImage(dst, src);
+ SDL_Rect target;
+ target.x = src->dst_x;
+ target.y = src->dst_y;
+ target.w = dst->w;
+ target.h = dst->h;
+ Kit_AddAtlasItem(atlas, dst, &target);
+ SDL_FreeSurface(dst);
+ }
+
+ Kit_UnlockDecoderOutput(ren->dec);
}
ren->dec->clock_pos = current_pts;
return 0;
}
+static void ren_set_ass_size_cb(Kit_SubtitleRenderer *ren, int w, int h) {
+ Kit_ASSSubtitleRenderer *ass_ren = ren->userdata;
+ ass_set_frame_size(ass_ren->renderer, w, h);
+}
+
Kit_SubtitleRenderer* Kit_CreateASSSubtitleRenderer(Kit_Decoder *dec, int w, int h) {
assert(dec != NULL);
assert(w >= 0);
@@ -181,7 +189,8 @@ Kit_SubtitleRenderer* Kit_CreateASSSubtitleRenderer(Kit_Decoder *dec, int w, int
ass_ren->track = ass_track;
ren->ren_render = ren_render_ass_cb;
ren->ren_close = ren_close_ass_cb;
- ren->ren_get_data = ren_get_data_cb;
+ ren->ren_get_data = ren_get_ass_data_cb;
+ ren->ren_set_size = ren_set_ass_size_cb;
ren->userdata = ass_ren;
return ren;
diff --git a/src/internal/subtitle/renderers/kitsubimage.c b/src/internal/subtitle/renderers/kitsubimage.c
index 4cc14c4..318c389 100644
--- a/src/internal/subtitle/renderers/kitsubimage.c
+++ b/src/internal/subtitle/renderers/kitsubimage.c
@@ -49,7 +49,7 @@ static void ren_render_image_cb(Kit_SubtitleRenderer *ren, void *sub_src, double
}
}
-static int ren_get_data_cb(Kit_SubtitleRenderer *ren, Kit_TextureAtlas *atlas, double current_pts) {
+static int ren_get_img_data_cb(Kit_SubtitleRenderer *ren, Kit_TextureAtlas *atlas, double current_pts) {
// Read any new packets to atlas
Kit_SubtitlePacket *packet = NULL;
@@ -96,7 +96,7 @@ Kit_SubtitleRenderer* Kit_CreateImageSubtitleRenderer(Kit_Decoder *dec, int w, i
// Only renderer required, no other data.
ren->ren_render = ren_render_image_cb;
- ren->ren_get_data = ren_get_data_cb;
+ ren->ren_get_data = ren_get_img_data_cb;
ren->ren_close = NULL;
ren->userdata = NULL;
return ren;
diff --git a/src/internal/subtitle/renderers/kitsubrenderer.c b/src/internal/subtitle/renderers/kitsubrenderer.c
index e63cad1..f998899 100644
--- a/src/internal/subtitle/renderers/kitsubrenderer.c
+++ b/src/internal/subtitle/renderers/kitsubrenderer.c
@@ -32,6 +32,13 @@ int Kit_GetSubtitleRendererData(Kit_SubtitleRenderer *ren, Kit_TextureAtlas *atl
return 0;
}
+void Kit_SetSubtitleRendererSize(Kit_SubtitleRenderer *ren, int w, int h) {
+ if(ren == NULL)
+ return;
+ if(ren->ren_set_size != NULL)
+ ren->ren_set_size(ren, w, h);
+}
+
void Kit_CloseSubtitleRenderer(Kit_SubtitleRenderer *ren) {
if(ren == NULL)
return;
diff --git a/src/internal/video/kitvideo.c b/src/internal/video/kitvideo.c
index 5254d9e..e41614b 100644
--- a/src/internal/video/kitvideo.c
+++ b/src/internal/video/kitvideo.c
@@ -132,16 +132,17 @@ static void dec_close_video_cb(Kit_Decoder *dec) {
free(video_dec);
}
-Kit_Decoder* Kit_CreateVideoDecoder(const Kit_Source *src, Kit_VideoFormat *format) {
+Kit_Decoder* Kit_CreateVideoDecoder(const Kit_Source *src, int stream_index, Kit_VideoFormat *format) {
assert(src != NULL);
assert(format != NULL);
- if(src->video_stream_index < 0) {
+ if(stream_index < 0) {
return NULL;
}
// First the generic decoder component ...
Kit_Decoder *dec = Kit_CreateDecoder(
- src, src->video_stream_index,
+ src,
+ stream_index,
KIT_VIDEO_OUT_SIZE,
free_out_video_packet_cb);
if(dec == NULL) {
@@ -152,7 +153,7 @@ Kit_Decoder* Kit_CreateVideoDecoder(const Kit_Source *src, Kit_VideoFormat *form
format->is_enabled = true;
format->width = dec->codec_ctx->width;
format->height = dec->codec_ctx->height;
- format->stream_index = src->video_stream_index;
+ format->stream_index = stream_index;
format->format = _FindPixelFormat(dec->codec_ctx->pix_fmt);
// ... then allocate the video decoder