On Sun, 26 Jul 2015, Michael Niedermayer wrote:

From: Michael Niedermayer <mich...@niedermayer.cc>

Fixes some files from Ticket679

This also changes subtitles to 4:2:0 matching the output format and thus
simplifying the blend code.
This restricts placement to the chroma sample resolution though, speak up
if you consider this a problem, say so, the code could be changed to use
YUV444 for subtitles and scaling them down while blending, this would be
slower though.
The current code only uses a single swscale context and reinitializes it
as needed, this could be changed as well if needed

It is fine by me as it is.

Signed-off-by: Michael Niedermayer <mich...@niedermayer.cc>
---
ffplay.c |  275 ++++++++++++++------------------------------------------------
1 file changed, 62 insertions(+), 213 deletions(-)


[...]

    for (;;) {
        if (!(sp = frame_queue_peek_writable(&is->subpq)))
@@ -2348,14 +2170,41 @@ static int subtitle_thread(void *arg)

            for (i = 0; i < sp->sub.num_rects; i++)
            {
-                for (j = 0; j < sp->sub.rects[i]->nb_colors; j++)
-                {
-                    RGBA_IN(r, g, b, a, 
(uint32_t*)sp->sub.rects[i]->pict.data[1] + j);
-                    y = RGB_TO_Y_CCIR(r, g, b);
-                    u = RGB_TO_U_CCIR(r, g, b, 0);
-                    v = RGB_TO_V_CCIR(r, g, b, 0);
-                    YUVA_OUT((uint32_t*)sp->sub.rects[i]->pict.data[1] + j, y, 
u, v, a);
+                int in_w = sp->sub.rects[i]->w;
+                int in_h = sp->sub.rects[i]->h;
+                int subw = is->subdec.avctx->width  ? is->subdec.avctx->width  : 
is->viddec.avctx->width;
+                int subh = is->subdec.avctx->height ? is->subdec.avctx->height : 
is->viddec.avctx->height;
+                int out_w = in_w * is->viddec.avctx->width  / subw;
+                int out_h = in_h * is->viddec.avctx->height / subh;

viddec.avctx may not be set here. I see no better way but to add two extra fields to VideoState and update them when opening a video stream and when decoding a new picture.

+                AVPicture newpic;
+
+                //cant use avpicture_alloc as it is not compatible with 
avsubtitle_free()
+                av_image_fill_linesizes(newpic.linesize, AV_PIX_FMT_YUVA420P, 
out_w);
+                newpic.data[0] = av_malloc(newpic.linesize[0] * out_h);
+                newpic.data[3] = av_malloc(newpic.linesize[3] * out_h);
+                newpic.data[1] = av_malloc(newpic.linesize[1] * ((out_h+1)/2));
+                newpic.data[2] = av_malloc(newpic.linesize[2] * ((out_h+1)/2));
+
+                is->sub_convert_ctx = sws_getCachedContext(is->sub_convert_ctx,
+                    in_w, in_h, AV_PIX_FMT_PAL8, out_w, out_h,
+                    AV_PIX_FMT_YUVA420P, sws_flags, NULL, NULL, NULL);
+                if (!is->sub_convert_ctx || !newpic.data[0] || !newpic.data[3] 
||
+                    !newpic.data[1] || !newpic.data[2]
+                ) {
+                    av_log(NULL, AV_LOG_FATAL, "Cannot initialize the sub 
conversion context\n");
+                    exit(1);
                }
+                sws_scale(is->sub_convert_ctx,
+                          sp->sub.rects[i]->pict.data, 
sp->sub.rects[i]->pict.linesize,
+                          0, in_h, newpic.data, newpic.linesize);
+
+                av_free(sp->sub.rects[i]->pict.data[0]);
+                av_free(sp->sub.rects[i]->pict.data[1]);
+                sp->sub.rects[i]->pict = newpic;
+                sp->sub.rects[i]->w = out_w;
+                sp->sub.rects[i]->h = out_h;
+                sp->sub.rects[i]->x = sp->sub.rects[i]->x * out_w / in_w;
+                sp->sub.rects[i]->y = sp->sub.rects[i]->y * out_h / in_h;
            }


Regards,
Marton
_______________________________________________
ffmpeg-devel mailing list
ffmpeg-devel@ffmpeg.org
http://ffmpeg.org/mailman/listinfo/ffmpeg-devel

Reply via email to