summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--sub/draw_bmp.c13
-rw-r--r--video/mp_image.c4
-rw-r--r--video/sws_utils.c45
3 files changed, 61 insertions, 1 deletions
diff --git a/sub/draw_bmp.c b/sub/draw_bmp.c
index 96d87eec0c..a0c58324da 100644
--- a/sub/draw_bmp.c
+++ b/sub/draw_bmp.c
@@ -307,7 +307,14 @@ static void draw_ass(struct mp_draw_sub_cache **cache, struct mp_rect bb,
int b = (sb->libass.color >> 8) & 0xFF;
int a = 255 - (sb->libass.color & 0xFF);
int color_yuv[3] = {r, g, b};
- mp_map_int_color(rgb2yuv, bits, color_yuv);
+ if (dst.flags & MP_IMGFLAG_YUV) {
+ mp_map_int_color(rgb2yuv, bits, color_yuv);
+ } else {
+ assert(dst.imgfmt == IMGFMT_GBRP);
+ color_yuv[0] = g;
+ color_yuv[1] = b;
+ color_yuv[2] = r;
+ }
int bytes = (bits + 7) / 8;
uint8_t *alpha_p = (uint8_t *)sb->bitmap + src_y * sb->stride + src_x;
@@ -411,6 +418,10 @@ static void get_closest_y444_format(int imgfmt, int *out_format, int *out_bits)
return;
}
}
+ } else {
+ *out_format = IMGFMT_GBRP;
+ *out_bits = 8;
+ return;
}
*out_format = IMGFMT_444P16;
*out_bits = 16;
diff --git a/video/mp_image.c b/video/mp_image.c
index 73164fdc59..25b84641a7 100644
--- a/video/mp_image.c
+++ b/video/mp_image.c
@@ -149,6 +149,10 @@ void mp_image_setfmt(mp_image_t* mpi,unsigned int out_fmt){
if (out_fmt == IMGFMT_GBRP) {
mpi->bpp=24;
mpi->flags|=MP_IMGFLAG_PLANAR;
+ mpi->chroma_x_shift = 0;
+ mpi->chroma_y_shift = 0;
+ mpi->chroma_width=mpi->width;
+ mpi->chroma_height=mpi->height;
return;
}
mpi->flags|=MP_IMGFLAG_YUV;
diff --git a/video/sws_utils.c b/video/sws_utils.c
index 951e101066..7d1845f431 100644
--- a/video/sws_utils.c
+++ b/video/sws_utils.c
@@ -151,9 +151,54 @@ static int mp_csp_to_sws_colorspace(enum mp_csp csp)
}
}
+// component_offset[]: byte index of each r (0), g (1), b (2), a (3) component
+static void planarize32(struct mp_image *dst, struct mp_image *src,
+ int component_offset[4])
+{
+ for (int y = 0; y < dst->h; y++) {
+ for (int p = 0; p < 3; p++) {
+ uint8_t *d_line = dst->planes[p] + y * dst->stride[p];
+ uint8_t *s_line = src->planes[0] + y * src->stride[0];
+ s_line += component_offset[(p + 1) % 3]; // GBR => RGB
+ for (int x = 0; x < dst->w; x++) {
+ d_line[x] = s_line[x * 4];
+ }
+ }
+ }
+}
+
+#define SET_COMPS(comp, r, g, b, a) \
+ { (comp)[0] = (r); (comp)[1] = (g); (comp)[2] = (b); (comp)[3] = (a); }
+
+static void to_gbrp(struct mp_image *dst, struct mp_image *src,
+ int my_sws_flags)
+{
+ struct mp_image *temp = NULL;
+ int comp[4];
+
+ switch (src->imgfmt) {
+ case IMGFMT_ABGR: SET_COMPS(comp, 3, 2, 1, 0); break;
+ case IMGFMT_BGRA: SET_COMPS(comp, 2, 1, 0, 3); break;
+ case IMGFMT_ARGB: SET_COMPS(comp, 1, 2, 3, 0); break;
+ case IMGFMT_RGBA: SET_COMPS(comp, 0, 1, 2, 3); break;
+ default:
+ temp = alloc_mpi(dst->w, dst->h, IMGFMT_RGBA);
+ mp_image_swscale(temp, src, my_sws_flags);
+ src = temp;
+ SET_COMPS(comp, 0, 1, 2, 3);
+ }
+
+ planarize32(dst, src, comp);
+
+ talloc_free(temp);
+}
+
void mp_image_swscale(struct mp_image *dst, struct mp_image *src,
int my_sws_flags)
{
+ if (dst->imgfmt == IMGFMT_GBRP)
+ return to_gbrp(dst, src, my_sws_flags);
+
enum PixelFormat s_fmt = imgfmt2pixfmt(src->imgfmt);
if (src->imgfmt == IMGFMT_RGB8 || src->imgfmt == IMGFMT_BGR8)
s_fmt = PIX_FMT_PAL8;