829
834
#define ALPHA_BLEND(a, oldp, newp, s)\
830
835
((((oldp << s) * (255 - (a))) + (newp * (a))) / (255 << s))
832
#define RGBA_IN(r, g, b, a, s)\
834
unsigned int v = ((const uint32_t *)(s))[0];\
835
a = (v >> 24) & 0xff;\
836
r = (v >> 16) & 0xff;\
837
g = (v >> 8) & 0xff;\
841
#define YUVA_IN(y, u, v, a, s, pal)\
843
unsigned int val = ((const uint32_t *)(pal))[*(const uint8_t*)(s)];\
844
a = (val >> 24) & 0xff;\
845
y = (val >> 16) & 0xff;\
846
u = (val >> 8) & 0xff;\
850
#define YUVA_OUT(d, y, u, v, a)\
852
((uint32_t *)(d))[0] = (a << 24) | (y << 16) | (u << 8) | v;\
858
841
static void blend_subrect(AVPicture *dst, const AVSubtitleRect *rect, int imgw, int imgh)
860
int wrap, wrap3, width2, skip2;
861
int y, u, v, a, u1, v1, a1, w, h;
843
int x, y, Y, U, V, A;
862
844
uint8_t *lum, *cb, *cr;
865
845
int dstx, dsty, dstw, dsth;
846
const AVPicture *src = &rect->pict;
867
848
dstw = av_clip(rect->w, 0, imgw);
868
849
dsth = av_clip(rect->h, 0, imgh);
869
850
dstx = av_clip(rect->x, 0, imgw - dstw);
870
851
dsty = av_clip(rect->y, 0, imgh - dsth);
871
lum = dst->data[0] + dsty * dst->linesize[0];
872
cb = dst->data[1] + (dsty >> 1) * dst->linesize[1];
873
cr = dst->data[2] + (dsty >> 1) * dst->linesize[2];
875
width2 = ((dstw + 1) >> 1) + (dstx & ~dstw & 1);
877
wrap = dst->linesize[0];
878
wrap3 = rect->pict.linesize[0];
879
p = rect->pict.data[0];
880
pal = (const uint32_t *)rect->pict.data[1]; /* Now in YCrCb! */
888
YUVA_IN(y, u, v, a, p, pal);
889
lum[0] = ALPHA_BLEND(a, lum[0], y, 0);
890
cb[0] = ALPHA_BLEND(a >> 2, cb[0], u, 0);
891
cr[0] = ALPHA_BLEND(a >> 2, cr[0], v, 0);
897
for (w = dstw - (dstx & 1); w >= 2; w -= 2) {
898
YUVA_IN(y, u, v, a, p, pal);
902
lum[0] = ALPHA_BLEND(a, lum[0], y, 0);
904
YUVA_IN(y, u, v, a, p + BPP, pal);
908
lum[1] = ALPHA_BLEND(a, lum[1], y, 0);
909
cb[0] = ALPHA_BLEND(a1 >> 2, cb[0], u1, 1);
910
cr[0] = ALPHA_BLEND(a1 >> 2, cr[0], v1, 1);
917
YUVA_IN(y, u, v, a, p, pal);
918
lum[0] = ALPHA_BLEND(a, lum[0], y, 0);
919
cb[0] = ALPHA_BLEND(a >> 2, cb[0], u, 0);
920
cr[0] = ALPHA_BLEND(a >> 2, cr[0], v, 0);
924
p += wrap3 - dstw * BPP;
925
lum += wrap - dstw - dstx;
926
cb += dst->linesize[1] - width2 - skip2;
927
cr += dst->linesize[2] - width2 - skip2;
929
for (h = dsth - (dsty & 1); h >= 2; h -= 2) {
935
YUVA_IN(y, u, v, a, p, pal);
939
lum[0] = ALPHA_BLEND(a, lum[0], y, 0);
942
YUVA_IN(y, u, v, a, p, pal);
946
lum[0] = ALPHA_BLEND(a, lum[0], y, 0);
947
cb[0] = ALPHA_BLEND(a1 >> 2, cb[0], u1, 1);
948
cr[0] = ALPHA_BLEND(a1 >> 2, cr[0], v1, 1);
954
for (w = dstw - (dstx & 1); w >= 2; w -= 2) {
955
YUVA_IN(y, u, v, a, p, pal);
959
lum[0] = ALPHA_BLEND(a, lum[0], y, 0);
961
YUVA_IN(y, u, v, a, p + BPP, pal);
965
lum[1] = ALPHA_BLEND(a, lum[1], y, 0);
969
YUVA_IN(y, u, v, a, p, pal);
973
lum[0] = ALPHA_BLEND(a, lum[0], y, 0);
975
YUVA_IN(y, u, v, a, p + BPP, pal);
979
lum[1] = ALPHA_BLEND(a, lum[1], y, 0);
981
cb[0] = ALPHA_BLEND(a1 >> 2, cb[0], u1, 2);
982
cr[0] = ALPHA_BLEND(a1 >> 2, cr[0], v1, 2);
986
p += -wrap3 + 2 * BPP;
990
YUVA_IN(y, u, v, a, p, pal);
994
lum[0] = ALPHA_BLEND(a, lum[0], y, 0);
997
YUVA_IN(y, u, v, a, p, pal);
1001
lum[0] = ALPHA_BLEND(a, lum[0], y, 0);
1002
cb[0] = ALPHA_BLEND(a1 >> 2, cb[0], u1, 1);
1003
cr[0] = ALPHA_BLEND(a1 >> 2, cr[0], v1, 1);
1009
p += wrap3 + (wrap3 - dstw * BPP);
1010
lum += wrap + (wrap - dstw - dstx);
1011
cb += dst->linesize[1] - width2 - skip2;
1012
cr += dst->linesize[2] - width2 - skip2;
1014
/* handle odd height */
1021
YUVA_IN(y, u, v, a, p, pal);
1022
lum[0] = ALPHA_BLEND(a, lum[0], y, 0);
1023
cb[0] = ALPHA_BLEND(a >> 2, cb[0], u, 0);
1024
cr[0] = ALPHA_BLEND(a >> 2, cr[0], v, 0);
1030
for (w = dstw - (dstx & 1); w >= 2; w -= 2) {
1031
YUVA_IN(y, u, v, a, p, pal);
1035
lum[0] = ALPHA_BLEND(a, lum[0], y, 0);
1037
YUVA_IN(y, u, v, a, p + BPP, pal);
1041
lum[1] = ALPHA_BLEND(a, lum[1], y, 0);
1042
cb[0] = ALPHA_BLEND(a1 >> 2, cb[0], u, 1);
1043
cr[0] = ALPHA_BLEND(a1 >> 2, cr[0], v, 1);
1050
YUVA_IN(y, u, v, a, p, pal);
1051
lum[0] = ALPHA_BLEND(a, lum[0], y, 0);
1052
cb[0] = ALPHA_BLEND(a >> 2, cb[0], u, 0);
1053
cr[0] = ALPHA_BLEND(a >> 2, cr[0], v, 0);
852
lum = dst->data[0] + dstx + dsty * dst->linesize[0];
853
cb = dst->data[1] + dstx/2 + (dsty >> 1) * dst->linesize[1];
854
cr = dst->data[2] + dstx/2 + (dsty >> 1) * dst->linesize[2];
856
for (y = 0; y<dsth; y++) {
857
for (x = 0; x<dstw; x++) {
858
Y = src->data[0][x + y*src->linesize[0]];
859
A = src->data[3][x + y*src->linesize[3]];
860
lum[0] = ALPHA_BLEND(A, lum[0], Y, 0);
863
lum += dst->linesize[0] - dstw;
866
for (y = 0; y<dsth/2; y++) {
867
for (x = 0; x<dstw/2; x++) {
868
U = src->data[1][x + y*src->linesize[1]];
869
V = src->data[2][x + y*src->linesize[2]];
870
A = src->data[3][2*x + 2*y *src->linesize[3]]
871
+ src->data[3][2*x + 1 + 2*y *src->linesize[3]]
872
+ src->data[3][2*x + 1 + (2*y+1)*src->linesize[3]]
873
+ src->data[3][2*x + (2*y+1)*src->linesize[3]];
874
cb[0] = ALPHA_BLEND(A>>2, cb[0], U, 0);
875
cr[0] = ALPHA_BLEND(A>>2, cr[0], V, 0);
879
cb += dst->linesize[1] - dstw/2;
880
cr += dst->linesize[2] - dstw/2;
2349
2197
for (i = 0; i < sp->sub.num_rects; i++)
2351
for (j = 0; j < sp->sub.rects[i]->nb_colors; j++)
2353
RGBA_IN(r, g, b, a, (uint32_t*)sp->sub.rects[i]->pict.data[1] + j);
2354
y = RGB_TO_Y_CCIR(r, g, b);
2355
u = RGB_TO_U_CCIR(r, g, b, 0);
2356
v = RGB_TO_V_CCIR(r, g, b, 0);
2357
YUVA_OUT((uint32_t*)sp->sub.rects[i]->pict.data[1] + j, y, u, v, a);
2199
int in_w = sp->sub.rects[i]->w;
2200
int in_h = sp->sub.rects[i]->h;
2201
int subw = is->subdec.avctx->width ? is->subdec.avctx->width : is->viddec_width;
2202
int subh = is->subdec.avctx->height ? is->subdec.avctx->height : is->viddec_height;
2203
int out_w = is->viddec_width ? in_w * is->viddec_width / subw : in_w;
2204
int out_h = is->viddec_height ? in_h * is->viddec_height / subh : in_h;
2207
//can not use avpicture_alloc as it is not compatible with avsubtitle_free()
2208
av_image_fill_linesizes(newpic.linesize, AV_PIX_FMT_YUVA420P, out_w);
2209
newpic.data[0] = av_malloc(newpic.linesize[0] * out_h);
2210
newpic.data[3] = av_malloc(newpic.linesize[3] * out_h);
2211
newpic.data[1] = av_malloc(newpic.linesize[1] * ((out_h+1)/2));
2212
newpic.data[2] = av_malloc(newpic.linesize[2] * ((out_h+1)/2));
2214
is->sub_convert_ctx = sws_getCachedContext(is->sub_convert_ctx,
2215
in_w, in_h, AV_PIX_FMT_PAL8, out_w, out_h,
2216
AV_PIX_FMT_YUVA420P, sws_flags, NULL, NULL, NULL);
2217
if (!is->sub_convert_ctx || !newpic.data[0] || !newpic.data[3] ||
2218
!newpic.data[1] || !newpic.data[2]
2220
av_log(NULL, AV_LOG_FATAL, "Cannot initialize the sub conversion context\n");
2223
sws_scale(is->sub_convert_ctx,
2224
(void*)sp->sub.rects[i]->pict.data, sp->sub.rects[i]->pict.linesize,
2225
0, in_h, newpic.data, newpic.linesize);
2227
av_free(sp->sub.rects[i]->pict.data[0]);
2228
av_free(sp->sub.rects[i]->pict.data[1]);
2229
sp->sub.rects[i]->pict = newpic;
2230
sp->sub.rects[i]->w = out_w;
2231
sp->sub.rects[i]->h = out_h;
2232
sp->sub.rects[i]->x = sp->sub.rects[i]->x * out_w / in_w;
2233
sp->sub.rects[i]->y = sp->sub.rects[i]->y * out_h / in_h;
2361
2236
/* now we can update the picture count */