Skip to content

Commit

Permalink
video/out/vo_sixel.c: Implement sixel as a output device
Browse files Browse the repository at this point in the history
Based on the implementation of ffmpeg's sixel backend output written by Hayaki Saito
https://github.com/saitoha/FFmpeg-SIXEL/blob/sixel/libavdevice/sixel.c

Sixel is a protocol to display graphics in a terminal. This commit adds support to
play videos on a sixel enabled terminal using libsixel. With --vo=sixel, the
output will be in sixel format.

The input frame will be scaled to the user specified resolution
(--vo-sixel-width and --vo-sixel-height) using swscaler and then encoded using
libsixel and output to the terminal. This method requires high cpu and there are
high frame drops for 720p and higher resolution videos and might require
using lesser colors and have drop in quality. Docs have all the supported options
listed to fine tune the output quality.

Things to improve: A few parameters of libsixel such as the sixel_encode_policy
and the SIXEL_XTERM16 variables are hardcoded, might want to expose them
as command line options. Also the initialization resolution is not automatic
and if the user doesn't specify the dimensions, it picks 320x240 as the default
resolution which is not optimal. So need to automatically pick the best fit
resolution for the current open terminal window size.

video/out/vo_sixel.c: Add command line options --vo-sixel- for the sixel output device
Added width, height, dither-algo, threshold, colors, pallete-type, offset-top and offset-left as configurable parameters.
Reordered the sixel implementation to resemble vo_tct's implementation.

video/out/vo_sixel: Fix review issues; Add docs for sixel; Remove scroll_on_demand scrolling code

video/out/vo_sixel.c: Avoid static variables, group deallocations, remove DCS Terminating sequence

video/out/vo_sixel.c: remove unused headers, remove empty line from docs
  • Loading branch information
tantei3 committed Nov 5, 2020
1 parent 73be201 commit ba14910
Show file tree
Hide file tree
Showing 5 changed files with 504 additions and 0 deletions.
68 changes: 68 additions & 0 deletions DOCS/man/vo.rst
Original file line number Diff line number Diff line change
Expand Up @@ -363,6 +363,74 @@ Available video output drivers are:
``--vo-tct-256=<yes|no>`` (default: no)
Use 256 colors - for terminals which don't support true color.

``sixel``
Sixel graphics video output driver based on libsixel that works on a
console that has sixel graphics enabled such as ``xterm`` or ``mlterm``.
Additionally some terminals have limitation on the dimensions, so may
not display images bigger than 1000x1000 for example. Make sure that
``img2sixel`` can display images of the corresponding resolution.
You may need to use ``--profile=sw-fast`` to get decent performance.

Note: the Sixel image output is not synchronized with other terminal output
from mpv, which can lead to broken images. The option ``--really-quiet``
can help with that, and is recommended.

``--vo-sixel-diffusion=<algo>``
Selects the diffusion algorithm for dithering used by libsixel.
Can be one of the below list as per libsixel's documentation.

auto
Choose diffuse type automatically
none
Don't diffuse
atkinson
Diffuse with Bill Atkinson's method. (Default)
fs
Diffuse with Floyd-Steinberg method
jajuni
Diffuse with Jarvis, Judice & Ninke method
stucki
Diffuse with Stucki's method
burkes
Diffuse with Burkes' method
arithmetic
Positionally stable arithmetic dither
xor
Positionally stable arithmetic xor based dither

``--vo-sixel-width=<width>`` ``--vo-sixel-height=<height>``
The output video resolution will be set to width and height
These default to 320x240 if not set. The terminal window must
be bigger than this resolution to have smooth playback.
Additionally the last row will be a blank line and can't be
used to display pixel data.

``--vo-sixel-fixedpalette=<0|1>`` (default: 0)
Use libsixel's built-in static palette using the XTERM256 profile
for dither. Fixed palette uses 256 colors for dithering.

``--vo-sixel-reqcolors=<colors>`` (default: 256)
Setup libsixel to use required number of colors for dynamic palette.
This value depends on the console as well. Xterm supports 256.
Can set this to a lower value for faster performance.
This option has no effect if fixed palette is used.

``--vo-sixel-color-threshold=<threshold>`` (default: 0)
This threshold value is used in dynamic palette mode to
recompute the palette based on the scene changes.

``--vo-sixel-offset-top=<top>`` (default: 1)
The output video playback will start from the specified row number.
If this is greater than 1, then those many rows will be skipped.
This option can be used to shift video below in the terminal.
If it is greater than number of rows in terminal, then it is ignored.

``--vo-sixel-offset-left=<left>`` (default: 1)
The output video playback will start from the specified column number.
If this is greater than 1, then those many columns will be skipped.
This option can be used to shift video to the right in the terminal.
If it is greater than number of columns in terminal, then it is ignored.

``image``
Output each frame into an image file in the current directory. Each file
takes the frame number padded with leading zeros as name.
Expand Down
4 changes: 4 additions & 0 deletions video/out/vo.c
Original file line number Diff line number Diff line change
Expand Up @@ -64,6 +64,7 @@ extern const struct vo_driver video_out_vaapi;
extern const struct vo_driver video_out_wlshm;
extern const struct vo_driver video_out_rpi;
extern const struct vo_driver video_out_tct;
extern const struct vo_driver video_out_sixel;

const struct vo_driver *const video_out_drivers[] =
{
Expand Down Expand Up @@ -105,6 +106,9 @@ const struct vo_driver *const video_out_drivers[] =
#endif
#if HAVE_RPI_MMAL
&video_out_rpi,
#endif
#if HAVE_SIXEL
&video_out_sixel,
#endif
&video_out_lavc,
NULL
Expand Down
Loading

0 comments on commit ba14910

Please sign in to comment.