[FFmpeg-devel,3/2] Re: deduplicated [PATCH] Cinepak: speed up decoding several-fold, depending on the scenario, by supporting multiple output pixel formats.

Submitted by u-9iep@aetey.se on Feb. 26, 2017, 11:36 a.m.

Details

Message ID 20170226113651.GJ32749@example.net
State New
Headers show

Commit Message

u-9iep@aetey.se Feb. 26, 2017, 11:36 a.m.
This extra patch "beyond the series" is being posted for the benefit
of a casual reader who needs extremely fast/lightweight video decoding
of prearranged videos, with existing or/and mainstream applications
(e.g. like mplayer).

This patch is vital to make the cinepak decoding speedup (the matter
of the series) usable in practice.

(Otherwise you will have to modify the corresponding applications,
separately each of them, or if applicable build and use a preload hack
implementing an equivalent of this patch, as was suggested elsewhere on
this list.)

Such an out-of-band control was not welcome in ffmpeg even if disabled
by default, the project decision makers did not see the need.

That's why this patch is being posted separately, for those who do.

Enjoy!
Rune
From 43aaba5a7fbf5f97fb7f50c4d1f48363d74332f8 Mon Sep 17 00:00:00 2001
From: Rl <addr-see-the-website@aetey.se>
Date: Sat, 25 Feb 2017 15:35:44 +0100
Subject: [PATCH] Cinepak decoding: provide out-of-band control of output pixel
 format.

Allow the output pixel format to be chosen at runtime
by setting CINEPAK_DECODE_SET_PIXFMT envvar to the needed value.

This works with any application and complements the functionality
of get_format() API.

The existing applications are not prepared and generally are
not capable to choose the decoder output format correctly.
They often lack the information needed to be able to pick the format.
That's why get_format() is not sufficient.

Note that the proper choice of the most efficient output format is
not decoder- nor application-specific but usage-case-specific.

The only alternative to implementing this out-of-band format control
in the decoder library would be to modify every application
to include
 - either additional logic, reflecting a specific usage case
 - or an out-of-band control channel
neither of which is efficient or possibly not even feasible.
---
 libavcodec/cinepak.c | 35 +++++++++++++++++++++++++++++++++++
 1 file changed, 35 insertions(+)

Patch hide | download patch | download mbox

diff --git a/libavcodec/cinepak.c b/libavcodec/cinepak.c
index e32b07ce8a..d18b455589 100644
--- a/libavcodec/cinepak.c
+++ b/libavcodec/cinepak.c
@@ -916,6 +916,9 @@  static const enum AVPixelFormat pixfmt_list_2[] = {
 static av_cold int cinepak_decode_init(AVCodecContext *avctx)
 {
     CinepakContext *s = avctx->priv_data;
+#ifndef DISABLE_CINEPAK_DECODE_SET_PIXFMT
+    char *out_fmt_override = getenv("CINEPAK_DECODE_SET_PIXFMT");
+#endif
 
 /* we take advantage of VQ to efficiently support
  * multiple output formats */
@@ -929,6 +932,38 @@  static av_cold int cinepak_decode_init(AVCodecContext *avctx)
     /* check for paletted data */
     s->palette_video = (avctx->bits_per_coded_sample == 8);
 
+#ifndef DISABLE_CINEPAK_DECODE_SET_PIXFMT
+/*
+ * Checking an environment variable for out-of-band control
+ * of the output pixel format:
+ *
+ * get_format() does _not_ help when you can not modify the applications
+ * to use it, let alone to use it appropriately under varying practical
+ * curcumstances, there is no general criteria capable to choose
+ * the most suitable pixel format for each case;
+ * that's why the availability of an out-of-band control channel
+ * is important, sometimes there is no alternative at all -- rl
+ */
+
+    if (out_fmt_override && *out_fmt_override) {
+        if (       !strcmp(out_fmt_override, "rgb32")) {
+            avctx->pix_fmt = AV_PIX_FMT_RGB32;
+        } else if (!strcmp(out_fmt_override, "rgb24")) {
+            avctx->pix_fmt = AV_PIX_FMT_RGB24;
+        } else if (!strcmp(out_fmt_override, "rgb565")) {
+            avctx->pix_fmt = AV_PIX_FMT_RGB565;
+        } else if (!strcmp(out_fmt_override, "yuv420p")) {
+            avctx->pix_fmt = AV_PIX_FMT_YUV420P;
+        } else if (!strcmp(out_fmt_override, "pal8")) {
+            avctx->pix_fmt = AV_PIX_FMT_PAL8;
+        } else {
+            av_log(avctx, AV_LOG_ERROR, "Unsupported pixel format override '%s'\n",
+                                        out_fmt_override);
+            return AVERROR(EINVAL);
+        }
+    } else
+#endif
+
     if (s->out_pixfmt != AV_PIX_FMT_NONE) /* the option is set to something */
         avctx->pix_fmt = s->out_pixfmt;
     else