[FFmpeg-cvslog] avcodec/dvbsubdec: Compute default CLUT based on bitmap analysis

Michael Niedermayer git at videolan.org
Sun Jul 26 14:41:07 CEST 2015


ffmpeg | branch: master | Michael Niedermayer <michael at niedermayer.cc> | Sun Jul 26 14:22:41 2015 +0200| [4b90dcb8493552c17a811c8b1e6538dae4061f9d] | committer: Michael Niedermayer

avcodec/dvbsubdec: Compute default CLUT based on bitmap analysis

Fixes displaying subtitles before any CLUT has been received
Fixes Ticket153

This will of course not display these initial subtitles in the correct
color (as that is not known at that point) but they should look clean
and not corrupted

Signed-off-by: Michael Niedermayer <michael at niedermayer.cc>

> http://git.videolan.org/gitweb.cgi/ffmpeg.git/?a=commit;h=4b90dcb8493552c17a811c8b1e6538dae4061f9d
---

 libavcodec/dvbsubdec.c |   60 ++++++++++++++++++++++++++++++++++++++++++++++++
 1 file changed, 60 insertions(+)

diff --git a/libavcodec/dvbsubdec.c b/libavcodec/dvbsubdec.c
index e268e2a..9f59b72 100644
--- a/libavcodec/dvbsubdec.c
+++ b/libavcodec/dvbsubdec.c
@@ -754,6 +754,63 @@ static int dvbsub_read_8bit_string(AVCodecContext *avctx,
     return pixels_read;
 }
 
+static void compute_default_clut(AVPicture *frame, int w, int h)
+{
+    uint8_t list[256] = {0};
+    uint8_t list_inv[256];
+    int counttab[256] = {0};
+    int count, i, x, y;
+
+#define V(x,y) frame->data[0][(x) + (y)*frame->linesize[0]]
+    for (y = 0; y<h; y++) {
+        for (x = 0; x<w; x++) {
+            int v = V(x,y) + 1;
+            int vl = x     ? V(x-1,y) + 1 : 0;
+            int vr = x+1<w ? V(x+1,y) + 1 : 0;
+            int vt = y     ? V(x,y-1) + 1 : 0;
+            int vb = y+1<h ? V(x,y+1) + 1 : 0;
+            counttab[v-1] += !!((v!=vl) + (v!=vr) + (v!=vt) + (v!=vb));
+        }
+    }
+#define L(x,y) list[ frame->data[0][(x) + (y)*frame->linesize[0]] ]
+
+    for (i = 0; i<256; i++) {
+        int scoretab[256] = {0};
+        int bestscore = 0;
+        int bestv = 0;
+        for (y = 0; y<h; y++) {
+            for (x = 0; x<w; x++) {
+                int v = frame->data[0][x + y*frame->linesize[0]];
+                int l_m = list[v];
+                int l_l = x     ? L(x-1, y) : 1;
+                int l_r = x+1<w ? L(x+1, y) : 1;
+                int l_t = y     ? L(x, y-1) : 1;
+                int l_b = y+1<h ? L(x, y+1) : 1;
+                int score;
+                if (l_m)
+                    continue;
+                scoretab[v] += l_l + l_r + l_t + l_b;
+                score = 1024LL*scoretab[v] / counttab[v];
+                if (score > bestscore) {
+                    bestscore = score;
+                    bestv = v;
+                }
+            }
+        }
+        if (!bestscore)
+            break;
+        list    [ bestv ] = 1;
+        list_inv[     i ] = bestv;
+    }
+
+    count = i - 1;
+    for (i--; i>=0; i--) {
+        int v = i*255/count;
+        AV_WN32(frame->data[1] + 4*list_inv[i], RGBA(v/2,v,v/2,v));
+    }
+}
+
+
 static int save_subtitle_set(AVCodecContext *avctx, AVSubtitle *sub, int *got_output)
 {
     DVBSubContext *ctx = avctx->priv_data;
@@ -855,6 +912,9 @@ static int save_subtitle_set(AVCodecContext *avctx, AVSubtitle *sub, int *got_ou
 
             memcpy(rect->pict.data[0], region->pbuf, region->buf_size);
 
+            if (clut == &default_clut)
+                compute_default_clut(&rect->pict, rect->w, rect->h);
+
             i++;
         }
     }



More information about the ffmpeg-cvslog mailing list