-
-
Save izacus/26a624df7b5536191c84 to your computer and use it in GitHub Desktop.
AVSubtitle with indexed color conversion to AVFrame
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// Colorspace conversion macro definitions from ffplay | |
#define RGBA_IN(r, g, b, a, s)\ | |
{\ | |
unsigned int v = ((const uint32_t *)(s))[0];\ | |
a = (v >> 24) & 0xff;\ | |
r = (v >> 16) & 0xff;\ | |
g = (v >> 8) & 0xff;\ | |
b = v & 0xff;\ | |
} | |
AVFrame* sub_to_frame(AVSubtitle* sub, int width, int height) | |
{ | |
if (sub->num_rects == 0) | |
return nullptr; | |
AVPicture rgba_picture; | |
avpicture_alloc(&rgba_picture, AV_PIX_FMT_RGBA, SUB_WINDOW_WIDTH, SUB_WINDOW_HEIGHT); | |
memset(rgba_picture.data[0], 0, SUB_WINDOW_WIDTH * SUB_WINDOW_HEIGHT * 4); | |
// Copy subtitle before conversion | |
int r, g, b, a; | |
for (unsigned int i = 0; i < sub->num_rects; i ++) | |
{ | |
for (int j = 0; j < sub->rects[i]->nb_colors; j++) | |
{ | |
AVSubtitleRect* rect = sub->rects[i]; | |
RGBA_IN(r, g, b, a, (uint32_t*)rect->pict.data[1] + j); | |
// Blend rectangle to frame | |
for (int y = rect->y; y < rect->y + rect->h; y++) | |
{ | |
uint8_t* pd = rgba_picture.data[0] + (y * rgba_picture.linesize[0]) + (rect->x * 4); | |
uint8_t* rd = rect->pict.data[0] + ((y - rect->y) * rect->pict.linesize[0]); | |
for (int k = 0; k < rect->w; k++) | |
{ | |
RGBA_IN(r, g, b, a, (uint32_t*)rect->pict.data[1] + rd[0]); | |
pd[0] = r; | |
pd[1] = g; | |
pd[2] = b; | |
pd[3] = a; | |
pd += 4; | |
rd ++; | |
} | |
} | |
} | |
} | |
AVFrame* sub_frame = avcodec_alloc_frame(); | |
avpicture_alloc((AVPicture*)sub_frame, AV_PIX_FMT_YUVA420P, width, height); | |
sub_rgba_to_yuva_ctx = sws_getCachedContext(sub_rgba_to_yuva_ctx, SUB_WINDOW_WIDTH, SUB_WINDOW_HEIGHT, AV_PIX_FMT_RGBA, | |
width, height, AV_PIX_FMT_YUVA420P, | |
SWS_LANCZOS, NULL, NULL, NULL); | |
sws_scale(sub_rgba_to_yuva_ctx, (const uint8_t* const*)rgba_picture.data, rgba_picture.linesize, 0, SUB_WINDOW_HEIGHT, sub_frame->data, sub_frame->linesize); | |
sub_frame->width = width; | |
sub_frame->height= height; | |
sub_frame->format = AV_PIX_FMT_YUVA420P; | |
avpicture_free(&rgba_picture); | |
return sub_frame; | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment