AVSubtitle with indexed color conversion to AVFrame
| // 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