Git Inbox Mirror of the ffmpeg-devel mailing list - see https://ffmpeg.org/mailman/listinfo/ffmpeg-devel
 help / color / mirror / Atom feed
From: Andreas Rheinhardt <andreas.rheinhardt@outlook.com>
To: ffmpeg-devel@ffmpeg.org
Cc: Andreas Rheinhardt <andreas.rheinhardt@outlook.com>
Subject: [FFmpeg-devel] [PATCH 5/5] avcodec/clearvideo: Avoid allocations when decoding tiles
Date: Mon,  7 Nov 2022 02:49:22 +0100
Message-ID: <GV1P250MB073719F573DE68FB1A7D54188F3C9@GV1P250MB0737.EURP250.PROD.OUTLOOK.COM> (raw)
In-Reply-To: <GV1P250MB07375837F2A522ABDA22803E8F3C9@GV1P250MB0737.EURP250.PROD.OUTLOOK.COM>

Up until now, the ClearVideo decoder separates parsing tiles
and actually using the parsed information: The information is
instead stored in structures which are constantly allocated
and freed. This commit changes this to use the information
immediately, avoiding said allocations. This e.g. reduced
the amount of allocations for [1] from 2,866,462 to 24,720.
For said sample decoding speed improved by 143%.

[1]: https://samples.ffmpeg.org/V-codecs/UCOD/AccordianDance-300.avi

Signed-off-by: Andreas Rheinhardt <andreas.rheinhardt@outlook.com>
---
 libavcodec/clearvideo.c | 99 +++++++++++++----------------------------
 1 file changed, 31 insertions(+), 68 deletions(-)

diff --git a/libavcodec/clearvideo.c b/libavcodec/clearvideo.c
index d3cbd71f72..e77661d187 100644
--- a/libavcodec/clearvideo.c
+++ b/libavcodec/clearvideo.c
@@ -59,13 +59,6 @@ typedef struct MVInfo {
     MV  *mv;
 } MVInfo;
 
-typedef struct TileInfo {
-    uint16_t        flags;
-    int16_t         bias;
-    MV              mv;
-    struct TileInfo *child[4];
-} TileInfo;
-
 typedef struct CLVContext {
     AVCodecContext *avctx;
     IDCTDSPContext idsp;
@@ -383,12 +376,16 @@ static int tile_do_block(AVCodecContext *avctx, AVFrame *dst, const AVFrame *src
     return ret;
 }
 
-static TileInfo *decode_tile_info(GetBitContext *gb, const LevelCodes *lc)
+static int decode_tile(AVCodecContext *avctx, GetBitContext *gb,
+                       const LevelCodes *lc,
+                       AVFrame *dst, const AVFrame *src,
+                       int plane, int x, int y, int size,
+                       MV root_mv, MV *pred)
 {
-    TileInfo *ti;
     int i, flags = 0;
     int16_t bias = 0;
     MV mv = { 0 };
+    int err;
 
     if (lc->flags_cb.table)
         flags = get_vlc2(gb, lc->flags_cb.table, CLV_VLC_BITS, 2);
@@ -403,7 +400,11 @@ static TileInfo *decode_tile_info(GetBitContext *gb, const LevelCodes *lc)
             mv.x = get_sbits(gb, 8);
             mv.y = get_sbits(gb, 8);
         }
+        if (pred)
+            mvi_update_prediction(pred, mv);
     }
+    mv.x += root_mv.x;
+    mv.y += root_mv.y;
 
     if (lc->bias_cb.table) {
         uint16_t bias_val = get_vlc2(gb, lc->bias_cb.table, CLV_VLC_BITS, 2);
@@ -415,55 +416,29 @@ static TileInfo *decode_tile_info(GetBitContext *gb, const LevelCodes *lc)
         }
     }
 
-    ti = av_calloc(1, sizeof(*ti));
-    if (!ti)
-        return NULL;
-
-    ti->flags = flags;
-    ti->mv = mv;
-    ti->bias = bias;
-
-    if (ti->flags) {
-        for (i = 0; i < 4; i++) {
-            if (ti->flags & (1 << i)) {
-                TileInfo *subti = decode_tile_info(gb, lc + 1);
-                ti->child[i] = subti;
-            }
-        }
-    }
-
-    return ti;
-}
-
-static int restore_tree(AVCodecContext *avctx, AVFrame *dst, AVFrame *src,
-                        int plane, int x, int y, int size,
-                        TileInfo *tile, MV root_mv)
-{
-    int ret;
-    MV mv;
-
-    mv.x = root_mv.x + tile->mv.x;
-    mv.y = root_mv.y + tile->mv.y;
-
-    if (!tile->flags) {
-        ret = tile_do_block(avctx, dst, src, plane, x, y, mv.x, mv.y, size, tile->bias);
-    } else {
-        int i, hsize = size >> 1;
-
+    if (flags) {
+        int hsize = size >> 1;
         for (i = 0; i < 4; i++) {
             int xoff = (i & 2) == 0 ? 0 : hsize;
             int yoff = (i & 1) == 0 ? 0 : hsize;
 
-            if (tile->child[i]) {
-                ret = restore_tree(avctx, dst, src, plane, x + xoff, y + yoff, hsize, tile->child[i], root_mv);
-                av_freep(&tile->child[i]);
+            if (flags & (1 << i)) {
+                err = decode_tile(avctx, gb, lc + 1, dst, src, plane,
+                                  x + xoff, y + yoff, hsize, root_mv, NULL);
             } else {
-                ret = tile_do_block(avctx, dst, src, plane, x + xoff, y + yoff, mv.x, mv.y, hsize, tile->bias);
+                err = tile_do_block(avctx, dst, src, plane, x + xoff, y + yoff,
+                                    mv.x, mv.y, hsize, bias);
             }
+            if (err < 0)
+                return err;
         }
+    } else {
+        err = tile_do_block(avctx, dst, src, plane, x, y, mv.x, mv.y, size, bias);
+        if (err < 0)
+            return err;
     }
 
-    return ret;
+    return 0;
 }
 
 static void extend_edges(AVFrame *buf, int tile_size)
@@ -604,38 +579,26 @@ static int clv_decode_frame(AVCodecContext *avctx, AVFrame *rframe,
                     int x = i << c->tile_shift;
                     int y = j << c->tile_shift;
                     int size = 1 << c->tile_shift;
-                    TileInfo *tile;
                     MV cmv;
 
-                    tile = decode_tile_info(&c->gb, &lev[0]); // Y
-                    if (!tile)
-                        return AVERROR(ENOMEM);
-                    ret = restore_tree(avctx, c->pic, c->prev, 0, x, y, size, tile, mv);
+                    ret = decode_tile(avctx, &c->gb, &lev[0], c->pic, c->prev,  // Y
+                                      0, x, y, size, mv, mvp);
                     if (ret < 0)
                         mb_ret = ret;
-                    mvi_update_prediction(mvp, tile->mv);
                     x = i << (c->tile_shift - 1);
                     y = j << (c->tile_shift - 1);
                     size = 1 << (c->tile_shift - 1);
-                    cmv.x = mv.x + tile->mv.x;
-                    cmv.y = mv.y + tile->mv.y;
+                    cmv = *mvp;
                     cmv.x /= 2;
                     cmv.y /= 2;
-                    av_freep(&tile);
-                    tile = decode_tile_info(&c->gb, &lev[4]); // U
-                    if (!tile)
-                        return AVERROR(ENOMEM);
-                    ret = restore_tree(avctx, c->pic, c->prev, 1, x, y, size, tile, cmv);
+                    ret = decode_tile(avctx, &c->gb, &lev[4], c->pic, c->prev,  // U
+                                      1, x, y, size, cmv, NULL);
                     if (ret < 0)
                         mb_ret = ret;
-                    av_freep(&tile);
-                    tile = decode_tile_info(&c->gb, &lev[7]); // V
-                    if (!tile)
-                        return AVERROR(ENOMEM);
-                    ret = restore_tree(avctx, c->pic, c->prev, 2, x, y, size, tile, cmv);
+                    ret = decode_tile(avctx, &c->gb, &lev[7], c->pic, c->prev,  // U
+                                      2, x, y, size, cmv, NULL);
                     if (ret < 0)
                         mb_ret = ret;
-                    av_freep(&tile);
                 }
             }
             mvi_update_row(&c->mvi);
-- 
2.34.1

_______________________________________________
ffmpeg-devel mailing list
ffmpeg-devel@ffmpeg.org
https://ffmpeg.org/mailman/listinfo/ffmpeg-devel

To unsubscribe, visit link above, or email
ffmpeg-devel-request@ffmpeg.org with subject "unsubscribe".

  parent reply	other threads:[~2022-11-07  1:50 UTC|newest]

Thread overview: 6+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2022-11-07  1:48 [FFmpeg-devel] [PATCH 1/5] avcodec/clearvideo: Remove unnecessary level parameter Andreas Rheinhardt
2022-11-07  1:49 ` [FFmpeg-devel] [PATCH 2/5] avcodec/clearvideo: Move tile_do_block() upwards Andreas Rheinhardt
2022-11-07  1:49 ` [FFmpeg-devel] [PATCH 3/5] avcodec/clearvideo: Redo updating predicition Andreas Rheinhardt
2022-11-07  1:49 ` [FFmpeg-devel] [PATCH 4/5] avcodec/clearvideo: Use const where appropriate Andreas Rheinhardt
2022-11-07  1:49 ` Andreas Rheinhardt [this message]
2022-11-09 14:41 ` [FFmpeg-devel] [PATCH 1/5] avcodec/clearvideo: Remove unnecessary level parameter Andreas Rheinhardt

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=GV1P250MB073719F573DE68FB1A7D54188F3C9@GV1P250MB0737.EURP250.PROD.OUTLOOK.COM \
    --to=andreas.rheinhardt@outlook.com \
    --cc=ffmpeg-devel@ffmpeg.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link

Git Inbox Mirror of the ffmpeg-devel mailing list - see https://ffmpeg.org/mailman/listinfo/ffmpeg-devel

This inbox may be cloned and mirrored by anyone:

	git clone --mirror https://master.gitmailbox.com/ffmpegdev/0 ffmpegdev/git/0.git

	# If you have public-inbox 1.1+ installed, you may
	# initialize and index your mirror using the following commands:
	public-inbox-init -V2 ffmpegdev ffmpegdev/ https://master.gitmailbox.com/ffmpegdev \
		ffmpegdev@gitmailbox.com
	public-inbox-index ffmpegdev

Example config snippet for mirrors.


AGPL code for this site: git clone https://public-inbox.org/public-inbox.git