summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorTuomas Virtanen <katajakasa@gmail.com>2018-06-24 17:53:04 +0300
committerTuomas Virtanen <katajakasa@gmail.com>2018-06-24 17:53:04 +0300
commit1d06ec23f264e18a188bf46b72c8794c82c4b89e (patch)
tree95f6922c38bd9a461f3799736240783ead60b9ea
parentdc193d1fd246af68488aa678d620e2cad7140cbd (diff)
Cleanup and fix bitmap subtitle rendering
-rw-r--r--include/kitchensink/internal/subtitle/kitsubtitle.h6
-rw-r--r--include/kitchensink/internal/subtitle/renderers/kitsubass.h3
-rw-r--r--include/kitchensink/internal/subtitle/renderers/kitsubimage.h3
-rw-r--r--src/internal/subtitle/kitsubtitle.c18
-rw-r--r--src/internal/subtitle/renderers/kitsubass.c11
-rw-r--r--src/internal/subtitle/renderers/kitsubimage.c59
-rw-r--r--src/kitplayer.c2
7 files changed, 71 insertions, 31 deletions
diff --git a/include/kitchensink/internal/subtitle/kitsubtitle.h b/include/kitchensink/internal/subtitle/kitsubtitle.h
index 34b8103..9f83e3d 100644
--- a/include/kitchensink/internal/subtitle/kitsubtitle.h
+++ b/include/kitchensink/internal/subtitle/kitsubtitle.h
@@ -8,8 +8,10 @@
#include "kitchensink/kitplayer.h"
#include "kitchensink/internal/kitdecoder.h"
-KIT_LOCAL Kit_Decoder* Kit_CreateSubtitleDecoder(const Kit_Source *src, int stream_index, Kit_SubtitleFormat *format, int w, int h);
-KIT_LOCAL int Kit_GetSubtitleDecoderData(Kit_Decoder *dec, SDL_Texture *texture, SDL_Rect *sources, SDL_Rect *targets, int limit);
+KIT_LOCAL Kit_Decoder* Kit_CreateSubtitleDecoder(
+ const Kit_Source *src, int stream_index, Kit_SubtitleFormat *format, int video_w, int video_h, int screen_w, int screen_h);
+KIT_LOCAL int Kit_GetSubtitleDecoderData(
+ Kit_Decoder *dec, SDL_Texture *texture, SDL_Rect *sources, SDL_Rect *targets, int limit);
KIT_LOCAL void Kit_SetSubtitleDecoderSize(Kit_Decoder *dec, int w, int h);
#endif // KITSUBTITLE_H
diff --git a/include/kitchensink/internal/subtitle/renderers/kitsubass.h b/include/kitchensink/internal/subtitle/renderers/kitsubass.h
index e78e208..6dff50c 100644
--- a/include/kitchensink/internal/subtitle/renderers/kitsubass.h
+++ b/include/kitchensink/internal/subtitle/renderers/kitsubass.h
@@ -5,6 +5,7 @@
#include "kitchensink/internal/kitdecoder.h"
#include "kitchensink/internal/subtitle/renderers/kitsubrenderer.h"
-KIT_LOCAL Kit_SubtitleRenderer* Kit_CreateASSSubtitleRenderer(Kit_Decoder *dec, int w, int h);
+KIT_LOCAL Kit_SubtitleRenderer* Kit_CreateASSSubtitleRenderer(
+ Kit_Decoder *dec, int video_w, int video_h, int screen_w, int screen_h);
#endif // KITSUBASS_H
diff --git a/include/kitchensink/internal/subtitle/renderers/kitsubimage.h b/include/kitchensink/internal/subtitle/renderers/kitsubimage.h
index 43e30bc..883fde3 100644
--- a/include/kitchensink/internal/subtitle/renderers/kitsubimage.h
+++ b/include/kitchensink/internal/subtitle/renderers/kitsubimage.h
@@ -5,6 +5,7 @@
#include "kitchensink/internal/kitdecoder.h"
#include "kitchensink/internal/subtitle/renderers/kitsubrenderer.h"
-KIT_LOCAL Kit_SubtitleRenderer* Kit_CreateImageSubtitleRenderer(Kit_Decoder *dec, int w, int h);
+KIT_LOCAL Kit_SubtitleRenderer* Kit_CreateImageSubtitleRenderer(
+ Kit_Decoder *dec, int video_w, int video_h, int screen_w, int screen_h);
#endif // KITSUBIMAGE_H
diff --git a/src/internal/subtitle/kitsubtitle.c b/src/internal/subtitle/kitsubtitle.c
index d6641fc..d778903 100644
--- a/src/internal/subtitle/kitsubtitle.c
+++ b/src/internal/subtitle/kitsubtitle.c
@@ -24,8 +24,6 @@ typedef struct Kit_SubtitleDecoder {
Kit_SubtitleFormat *format;
Kit_SubtitleRenderer *renderer;
AVSubtitle scratch_frame;
- int w;
- int h;
Kit_TextureAtlas *atlas;
} Kit_SubtitleDecoder;
@@ -83,7 +81,7 @@ static void dec_close_subtitle_cb(Kit_Decoder *dec) {
free(subtitle_dec);
}
-Kit_Decoder* Kit_CreateSubtitleDecoder(const Kit_Source *src, int stream_index, Kit_SubtitleFormat *format, int w, int h) {
+Kit_Decoder* Kit_CreateSubtitleDecoder(const Kit_Source *src, int stream_index, Kit_SubtitleFormat *format, int video_w, int video_h, int screen_w, int screen_h) {
assert(src != NULL);
assert(format != NULL);
if(stream_index < 0) {
@@ -99,6 +97,7 @@ Kit_Decoder* Kit_CreateSubtitleDecoder(const Kit_Source *src, int stream_index,
KIT_SUBTITLE_OUT_SIZE,
free_out_subtitle_packet_cb);
if(dec == NULL) {
+ Kit_SetError("Unable to allocate subtitle decoder");
goto exit_0;
}
@@ -110,6 +109,7 @@ Kit_Decoder* Kit_CreateSubtitleDecoder(const Kit_Source *src, int stream_index,
// ... then allocate the subtitle decoder
Kit_SubtitleDecoder *subtitle_dec = calloc(1, sizeof(Kit_SubtitleDecoder));
if(subtitle_dec == NULL) {
+ Kit_SetError("Unable to allocate subtitle decoder");
goto exit_1;
}
@@ -123,7 +123,7 @@ Kit_Decoder* Kit_CreateSubtitleDecoder(const Kit_Source *src, int stream_index,
case AV_CODEC_ID_SSA:
case AV_CODEC_ID_ASS:
if(library_state->init_flags & KIT_INIT_ASS) {
- ren = Kit_CreateASSSubtitleRenderer(dec, w, h);
+ ren = Kit_CreateASSSubtitleRenderer(dec, video_w, video_h, screen_w, screen_h);
} else {
format->is_enabled = false;
}
@@ -132,7 +132,7 @@ Kit_Decoder* Kit_CreateSubtitleDecoder(const Kit_Source *src, int stream_index,
case AV_CODEC_ID_DVB_SUBTITLE:
case AV_CODEC_ID_HDMV_PGS_SUBTITLE:
case AV_CODEC_ID_XSUB:
- ren = Kit_CreateImageSubtitleRenderer(dec, w, h);
+ ren = Kit_CreateImageSubtitleRenderer(dec, video_w, video_h, screen_w, screen_h);
break;
default:
format->is_enabled = false;
@@ -153,8 +153,6 @@ Kit_Decoder* Kit_CreateSubtitleDecoder(const Kit_Source *src, int stream_index,
// 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->atlas = atlas;
dec->dec_decode = dec_decode_subtitle_cb;
dec->dec_close = dec_close_subtitle_cb;
@@ -171,12 +169,10 @@ exit_0:
return NULL;
}
-void Kit_SetSubtitleDecoderSize(Kit_Decoder *dec, int w, int h) {
+void Kit_SetSubtitleDecoderSize(Kit_Decoder *dec, int screen_w, int screen_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);
+ Kit_SetSubtitleRendererSize(subtitle_dec->renderer, screen_w, screen_h);
}
int Kit_GetSubtitleDecoderData(Kit_Decoder *dec, SDL_Texture *texture, SDL_Rect *sources, SDL_Rect *targets, int limit) {
diff --git a/src/internal/subtitle/renderers/kitsubass.c b/src/internal/subtitle/renderers/kitsubass.c
index fa0112b..4115c7d 100644
--- a/src/internal/subtitle/renderers/kitsubass.c
+++ b/src/internal/subtitle/renderers/kitsubass.c
@@ -110,10 +110,12 @@ static void ren_set_ass_size_cb(Kit_SubtitleRenderer *ren, int w, int h) {
ass_set_frame_size(ass_ren->renderer, w, h);
}
-Kit_SubtitleRenderer* Kit_CreateASSSubtitleRenderer(Kit_Decoder *dec, int w, int h) {
+Kit_SubtitleRenderer* Kit_CreateASSSubtitleRenderer(Kit_Decoder *dec, int video_w, int video_h, int screen_w, int screen_h) {
assert(dec != NULL);
- assert(w >= 0);
- assert(h >= 0);
+ assert(video_w >= 0);
+ assert(video_h >= 0);
+ assert(screen_w >= 0);
+ assert(screen_h >= 0);
// Make sure that libass library has been initialized + get handle
Kit_LibraryState *state = Kit_GetLibraryState();
@@ -166,7 +168,8 @@ Kit_SubtitleRenderer* Kit_CreateASSSubtitleRenderer(Kit_Decoder *dec, int w, int
NULL, "sans-serif",
ASS_FONTPROVIDER_AUTODETECT,
NULL, 1);
- ass_set_frame_size(ass_renderer, w, h);
+ ass_set_storage_size(ass_renderer, video_w, video_h);
+ ass_set_frame_size(ass_renderer, screen_w, screen_h);
ass_set_hinting(ass_renderer, ASS_HINTING_LIGHT);
// Initialize libass track
diff --git a/src/internal/subtitle/renderers/kitsubimage.c b/src/internal/subtitle/renderers/kitsubimage.c
index 318c389..2d77c51 100644
--- a/src/internal/subtitle/renderers/kitsubimage.c
+++ b/src/internal/subtitle/renderers/kitsubimage.c
@@ -9,6 +9,14 @@
#include "kitchensink/internal/subtitle/kitsubtitlepacket.h"
#include "kitchensink/internal/subtitle/renderers/kitsubimage.h"
+
+typedef struct Kit_ImageSubtitleRenderer {
+ int video_w;
+ int video_h;
+ float scale_x;
+ float scale_y;
+} Kit_ImageSubtitleRenderer;
+
static void ren_render_image_cb(Kit_SubtitleRenderer *ren, void *sub_src, double start_pts, double end_pts) {
assert(ren != NULL);
assert(sub_src != NULL);
@@ -50,7 +58,7 @@ static void ren_render_image_cb(Kit_SubtitleRenderer *ren, void *sub_src, double
}
static int ren_get_img_data_cb(Kit_SubtitleRenderer *ren, Kit_TextureAtlas *atlas, double current_pts) {
- // Read any new packets to atlas
+ Kit_ImageSubtitleRenderer *img_ren = ren->userdata;
Kit_SubtitlePacket *packet = NULL;
// Clean dead packets
@@ -66,10 +74,10 @@ static int ren_get_img_data_cb(Kit_SubtitleRenderer *ren, Kit_TextureAtlas *atla
}
if(packet->surface != NULL) {
SDL_Rect target;
- target.x = packet->x;
- target.y = packet->y;
- target.w = packet->surface->w;
- target.h = packet->surface->h;
+ target.x = packet->x * img_ren->scale_x;
+ target.y = packet->y * img_ren->scale_y;
+ target.w = packet->surface->w * img_ren->scale_x;
+ target.h = packet->surface->h * img_ren->scale_y;
Kit_AddAtlasItem(atlas, packet->surface, &target);
}
Kit_AdvanceDecoderOutput(ren->dec);
@@ -83,21 +91,50 @@ static int ren_get_img_data_cb(Kit_SubtitleRenderer *ren, Kit_TextureAtlas *atla
return 0;
}
-Kit_SubtitleRenderer* Kit_CreateImageSubtitleRenderer(Kit_Decoder *dec, int w, int h) {
+static void ren_set_img_size_cb(Kit_SubtitleRenderer *ren, int w, int h) {
+ Kit_ImageSubtitleRenderer *img_ren = ren->userdata;
+ img_ren->scale_x = (float)w / (float)img_ren->video_w;
+ img_ren->scale_y = (float)h / (float)img_ren->video_h;
+}
+
+static void ren_close_ass_cb(Kit_SubtitleRenderer *ren) {
+ if(ren == NULL) return;
+ free(ren->userdata);
+}
+
+Kit_SubtitleRenderer* Kit_CreateImageSubtitleRenderer(Kit_Decoder *dec, int video_w, int video_h, int screen_w, int screen_h) {
assert(dec != NULL);
- assert(w >= 0);
- assert(h >= 0);
+ assert(video_w >= 0);
+ assert(video_h >= 0);
+ assert(screen_w >= 0);
+ assert(screen_h >= 0);
// Allocate a new renderer
Kit_SubtitleRenderer *ren = Kit_CreateSubtitleRenderer(dec);
if(ren == NULL) {
- return NULL;
+ goto exit_0;
+ }
+
+ // Allocate image renderer internal context
+ Kit_ImageSubtitleRenderer *img_ren = calloc(1, sizeof(Kit_ImageSubtitleRenderer));
+ if(img_ren == NULL) {
+ goto exit_1;
}
// Only renderer required, no other data.
+ img_ren->video_w = video_w;
+ img_ren->video_h = video_h;
+ img_ren->scale_x = (float)screen_w / (float)video_w;
+ img_ren->scale_y = (float)screen_h / (float)video_h;
ren->ren_render = ren_render_image_cb;
ren->ren_get_data = ren_get_img_data_cb;
- ren->ren_close = NULL;
- ren->userdata = NULL;
+ ren->ren_set_size = ren_set_img_size_cb;
+ ren->ren_close = ren_close_ass_cb;
+ ren->userdata = img_ren;
return ren;
+
+exit_1:
+ Kit_CloseSubtitleRenderer(ren);
+exit_0:
+ return NULL;
}
diff --git a/src/kitplayer.c b/src/kitplayer.c
index 45488d4..192ec21 100644
--- a/src/kitplayer.c
+++ b/src/kitplayer.c
@@ -153,7 +153,7 @@ Kit_Player* Kit_CreatePlayer(const Kit_Source *src,
// Initialize subtitle decoder
player->subtitle_dec = Kit_CreateSubtitleDecoder(
- src, subtitle_stream_index, &player->sformat, screen_w, screen_h);
+ src, subtitle_stream_index, &player->sformat, player->vformat.width, player->vformat.height, screen_w, screen_h);
if(player->subtitle_dec == NULL && subtitle_stream_index >= 0) {
goto exit_2;
}