From 59c32a04b04dc42dd17665834a9f2ce35a48eeaf Mon Sep 17 00:00:00 2001
From: "Avi Halachmi (:avih)" <avihpit@yahoo.com>
Date: Thu, 26 Nov 2020 23:25:07 +0200
Subject: [PATCH] vo_sixel: fix the image corruption with mlterm

The issue was that we only uploaded the palette to the terminal when it
changed (once on init with fixed palette, every frame with dynamic
palette with trheshold=-1, only on scene change with threshold >= 0).

Now we upload it on every frame, and it seems to fix the mlterm image
corruption both with fixed palette and also with dynamic palette with
threshold (i.e. at frames which did not upload a palette).

It's not entirely clear why it's required with mlterm.

It would seem that the palette which libsixel uses with fixed palette
matches the built in default palette in xterm, but not in mlterm.
With dynamic palette we can guess that mlterm resets the palette after a
sixel image, but that's not confirmed.

Uploading the palette on every frame doesn't seem to slow down xterm
when using fixed palette - not clear yet why uploading a different
palette (when using fixedpalette=no) slows it down while same palette
on every frame doesn't.

In mlterm there's no slowdown either way - and now also no corruption.
---
 DOCS/man/vo.rst      | 16 +++++++---------
 video/out/vo_sixel.c | 11 +++++------
 2 files changed, 12 insertions(+), 15 deletions(-)

diff --git a/DOCS/man/vo.rst b/DOCS/man/vo.rst
index 4a1ffd4579..2802ce914c 100644
--- a/DOCS/man/vo.rst
+++ b/DOCS/man/vo.rst
@@ -448,20 +448,18 @@ Available video output drivers are:
         using ``no`` (at the time of writing) will slow down ``xterm``.
 
     ``--vo-sixel-reqcolors=<colors>`` (default: 256)
-        Set up libsixel to use required number of colors for dynamic palette.
-        This value depends on the terminal emulator as well. Xterm supports
-        256 colors.  Can set this to a lower value for faster performance.
-        This option has no effect if fixed palette is used.
+        Has no effect with fixed palette. Set up libsixel to use required
+        number of colors for dynamic palette. This value depends on the
+        terminal emulator as well. Xterm supports 256 colors. Can set this to
+        a lower value for faster performance.
 
     ``--vo-sixel-threshold=<threshold>`` (default: -1)
-        When using a dynamic palette, defines the threshold to change the
+        Has no effect with fixed palette. Defines the threshold to change the
         palette - as percentage of the number of colors, e.g. 20 will change
         the palette when the number of colors changed by 20%. It's a simple
         measure to reduce the number of palette changes, because it can be slow
-        in some terminals (``xterm``), however, it seems that in ``mlterm`` it
-        causes image corruption. The default (-1) will change the palette
-        on every frame and will have better quality, and no corruption in
-        ``mlterm``.
+        in some terminals (``xterm``). The default (-1) will choose a palette
+        on every frame and will have better quality.
 
 ``image``
     Output each frame into an image file in the current directory. Each file
diff --git a/video/out/vo_sixel.c b/video/out/vo_sixel.c
index a1fb04bd59..dff20f716d 100644
--- a/video/out/vo_sixel.c
+++ b/video/out/vo_sixel.c
@@ -140,15 +140,15 @@ static SIXELSTATUS prepare_static_palette(struct vo* vo)
 {
     struct priv* priv = vo->priv;
 
-    if (priv->dither) {
-        sixel_dither_set_body_only(priv->dither, 1);
-    } else {
+    if (!priv->dither) {
         priv->dither = sixel_dither_get(BUILTIN_XTERM256);
         if (priv->dither == NULL)
             return SIXEL_FALSE;
 
         sixel_dither_set_diffusion_type(priv->dither, priv->opt_diffuse);
     }
+
+    sixel_dither_set_body_only(priv->dither, 0);
     return SIXEL_OK;
 }
 
@@ -180,12 +180,11 @@ static SIXELSTATUS prepare_dynamic_palette(struct vo *vo)
 
         sixel_dither_set_diffusion_type(priv->dither, priv->opt_diffuse);
     } else {
-        if (priv->dither == NULL) {
+        if (priv->dither == NULL)
             return SIXEL_FALSE;
-        }
-        sixel_dither_set_body_only(priv->dither, 1);
     }
 
+    sixel_dither_set_body_only(priv->dither, 0);
     return status;
 }
 
