Git Inbox Mirror of the ffmpeg-devel mailing list - see https://ffmpeg.org/mailman/listinfo/ffmpeg-devel
 help / color / mirror / Atom feed
From: "Carotti, Elias" <eliascrt@amazon.it>
To: "ffmpeg-devel@ffmpeg.org" <ffmpeg-devel@ffmpeg.org>
Subject: Re: [FFmpeg-devel] [PATCH] lavu: add AVVideoHint API
Date: Wed, 26 Jul 2023 10:52:57 +0000
Message-ID: <bac659153fdf89f21a9538b5a3a29bc6fd575912.camel@amazon.it> (raw)
In-Reply-To: <20230723232727.GB10927@mariano>

[-- Attachment #1: Type: text/plain, Size: 4318 bytes --]

On Mon, 2023-07-24 at 01:27 +0200, Stefano Sabatini wrote:
> CAUTION: This email originated from outside of the organization. Do
> not click links or open attachments unless you can confirm the sender
> and know the content is safe.
> 
> 
<snip>

> > 
> > sorry to nitpick, but if we have this information in the single
> > rect
> > should not we use that instead?
> > 
> > Basically I see two options:
> > 1. generic VideoHint, storing single hint type and rects
> > 
> > for example we might have type=changed, and the rects storing only
> > the
> > changed rects
> > 
> > If we want to extend this then we need to add a new type. The
> > problem
> > might be if we want to store more than one VideoHint in the side
> > data
> > (it it possible to store more than one AVVideoHint, each one with a
> > different type, as side data?). Suppose for example we want to add
> > a
> > new hint type, e.g. ROI, then we can add a new AVHideoHint with
> > type=roi - but I don't know if we can have several frame hint side
> > data (each one with different individual types).
> > 
> > 2. generic VideoHint, storing rects each one containing the hint
> > type
> > 
> > for example we might have a list of rects, each one with
> > type=changed|constant|roi. This would allow one to store different
> > kind of hints in the same AVVideoHint structure, but at the same
> > time
> > would enable inconsistent data (for example we might have changed
> > and
> > unchanged rects in the same list of rects)
> > 

I don't think it allowed such inconsistency the way it was made.
Basically, the semantics was that the Hint type could be either
CONSTANT or CHANGED and that was the basis to interpret the rects with
type DAMAGE. 

> > In each case, storing the type in the generic AVVideHint and in
> > each
> > rect might lead to inconsistent states (e.g. you might have generic
> > type=damage, and have type=roi and type=changed in the rects), in
> > this
> > case having the type in both the general structure and in each
> > rects
> > seems redundant and leads to possible data inconsistencies.
> > 
> > ...
> > 
> 
> > I would rather go to solution 1, but I'm not sure if having more
> > than
> > one hint in the side data (with different subtypes) is possible and
> > wanted. If this is the case, probably the best solution would be to
> > store more than one AVVideoHint (each one with an individual type
> > and
> > list of rects) in the single side data object.
> 
> Elaborating on this.
> 
> 1. Ideally we might want to extend the av_frame_get_side_data API to
> be able to store more than one entry per side data, by adding a
> unique
> label to the side data, but this requires probably more effort and
> extends the scope even further.
> 
> 2. Alternatively, we might extend the hint API like this:
> 
> AVVideoHint *av_video_hint_create_side_data(AVFrame *frame,
>                                             size_t nb_rects);
> 
> AVVideoHint *av_video_hint_extend_side_data(AVFrame *frame,
>                                             size_t nb_rects);
> 
> by marking the continuation on the previous hint (but this would
> complicate deserialization as you need then to iterate to get all the
> side data).
> 
> Or we could make a variadic function like this:
> AVVideoHint *av_video_hint_create_side_data(AVFrame *frame, size_t
> nb_rects, ...);
> 
> Alternatively, we might store in AVVideoHint more than one hint, but
> this somehow conflict with the general design.
> 
> ...
> 
> As a low effort approach, I would keep the initial design of a single
> hint type per side-data (dropping the possibility of having more than
> one hint type in the same side data), which should be fixed
> generically by implementing 1.

Agreed.
For clarity I am attaching again the patch with Anton's changes just
rebased on the current master branch.
Anton, is this still ok to be merged?


Best, 
Elias







NICE SRL, viale Monte Grappa 3/5, 20124 Milano, Italia, Registro delle Imprese di Milano Monza Brianza Lodi REA n. 2096882, Capitale Sociale: 10.329,14 EUR i.v., Cod. Fisc. e P.IVA 01133050052, Societa con Socio Unico



[-- Warning: decoded text below may be mangled, UTF-8 assumed --]
[-- Attachment #2: 0001-Add-side-data-type-to-provide-hint-to-the-video-enco.patch --]
[-- Type: text/x-patch; name="0001-Add-side-data-type-to-provide-hint-to-the-video-enco.patch", Size: 9775 bytes --]

From fcd9051a9167f48083f0edc4bf44b3d09e568091 Mon Sep 17 00:00:00 2001
From: Elias Carotti <eliascrt _at_ amazon _dot_ it>
Date: Mon, 10 Jul 2023 14:34:53 +0200
Subject: [PATCH] Add side data type to provide hint to the video encoders
 about unchanged portions of each frame.

Signed-off-by: Anton Khirnov <anton@khirnov.net>
---
 doc/APIchanges         |   3 ++
 libavutil/Makefile     |   2 +
 libavutil/frame.h      |  10 ++++
 libavutil/version.h    |   2 +-
 libavutil/video_hint.c |  82 ++++++++++++++++++++++++++++++++
 libavutil/video_hint.h | 105 +++++++++++++++++++++++++++++++++++++++++
 6 files changed, 203 insertions(+), 1 deletion(-)
 create mode 100644 libavutil/video_hint.c
 create mode 100644 libavutil/video_hint.h

diff --git a/doc/APIchanges b/doc/APIchanges
index 5afe8bcb75..2adc7b5225 100644
--- a/doc/APIchanges
+++ b/doc/APIchanges
@@ -2,6 +2,9 @@ The last version increases of all libraries were on 2023-02-09
 
 API changes, most recent first:
 
+2023-07-xx - xxxxxxxxxx - lavu 58.15.100 - video_hint.h
+  Add AVVideoHint API.
+
 2023-07-xx - xxxxxxxxxx - lavc 60 - avcodec.h
   Deprecate AV_CODEC_FLAG_DROPCHANGED without replacement.
 
diff --git a/libavutil/Makefile b/libavutil/Makefile
index bd9c6f9e32..7828c94dc5 100644
--- a/libavutil/Makefile
+++ b/libavutil/Makefile
@@ -91,6 +91,7 @@ HEADERS = adler32.h                                                     \
           tea.h                                                         \
           tx.h                                                          \
           film_grain_params.h                                           \
+          video_hint.h
 
 ARCH_HEADERS = bswap.h                                                  \
                intmath.h                                                \
@@ -181,6 +182,7 @@ OBJS = adler32.o                                                        \
        uuid.o                                                           \
        version.o                                                        \
        video_enc_params.o                                               \
+       video_hint.o                                                     \
        film_grain_params.o                                              \
 
 
diff --git a/libavutil/frame.h b/libavutil/frame.h
index a491315f25..c0c1b23db7 100644
--- a/libavutil/frame.h
+++ b/libavutil/frame.h
@@ -214,6 +214,16 @@ enum AVFrameSideDataType {
      * Ambient viewing environment metadata, as defined by H.274.
      */
     AV_FRAME_DATA_AMBIENT_VIEWING_ENVIRONMENT,
+
+    /**
+     * Provide encoder-specific hinting information about changed/unchanged
+     * portions of a frame.  It can be used to pass information about which
+     * macroblocks can be skipped because they didn't change from the
+     * corresponding ones in the previous frame. This could be useful for
+     * applications which know this information in advance to speed up
+     * encoding.
+     */
+    AV_FRAME_DATA_VIDEO_HINT,
 };
 
 enum AVActiveFormatDescription {
diff --git a/libavutil/version.h b/libavutil/version.h
index 24af520e08..9e798b0e3f 100644
--- a/libavutil/version.h
+++ b/libavutil/version.h
@@ -79,7 +79,7 @@
  */
 
 #define LIBAVUTIL_VERSION_MAJOR  58
-#define LIBAVUTIL_VERSION_MINOR  14
+#define LIBAVUTIL_VERSION_MINOR  15
 #define LIBAVUTIL_VERSION_MICRO 100
 
 #define LIBAVUTIL_VERSION_INT   AV_VERSION_INT(LIBAVUTIL_VERSION_MAJOR, \
diff --git a/libavutil/video_hint.c b/libavutil/video_hint.c
new file mode 100644
index 0000000000..5730ed6cfb
--- /dev/null
+++ b/libavutil/video_hint.c
@@ -0,0 +1,82 @@
+/*
+ * Copyright 2023 Elias Carotti <eliascrt at amazon dot it>
+ *
+ * This file is part of FFmpeg.
+ *
+ * FFmpeg is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * FFmpeg is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with FFmpeg; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+#include <string.h>
+
+#include "avstring.h"
+#include "frame.h"
+#include "macros.h"
+#include "mem.h"
+#include "video_hint.h"
+
+AVVideoHint *av_video_hint_alloc(size_t nb_rects,
+                                 size_t *out_size)
+{
+    struct TestStruct {
+        AVVideoHint    hint;
+        AVVideoRect    rect;
+    };
+    const size_t rect_offset = offsetof(struct TestStruct, rect);
+    size_t size = rect_offset;
+    AVVideoHint *hint;
+
+    *out_size = 0;
+    if (nb_rects > (SIZE_MAX - size) / sizeof(AVVideoRect))
+        return NULL;
+    size += sizeof(AVVideoRect) * nb_rects;
+
+    hint = av_mallocz(size);
+    if (!hint)
+        return NULL;
+
+    hint->nb_rects    = nb_rects;
+    hint->rect_offset = rect_offset;
+    hint->rect_size   = sizeof(AVVideoRect);
+
+    *out_size = size;
+
+    return hint;
+}
+
+AVVideoHint *av_video_hint_create_side_data(AVFrame *frame,
+                                            size_t nb_rects)
+{
+    AVVideoHint *hint;
+    AVBufferRef *buf;
+    size_t size = 0;
+
+    hint = av_video_hint_alloc(nb_rects, &size);
+    if (!hint)
+        return NULL;
+
+    buf = av_buffer_create((uint8_t *)hint, size, NULL, NULL, 0);
+    if (!buf) {
+        av_freep(&hint);
+        return NULL;
+    }
+
+    if (!av_frame_new_side_data_from_buf(frame, AV_FRAME_DATA_VIDEO_HINT, buf)) {
+        av_buffer_unref(&buf);
+        return NULL;
+    }
+
+    return hint;
+}
+
diff --git a/libavutil/video_hint.h b/libavutil/video_hint.h
new file mode 100644
index 0000000000..0442d635c9
--- /dev/null
+++ b/libavutil/video_hint.h
@@ -0,0 +1,105 @@
+/**
+ * Copyright 2023 Elias Carotti <eliascrt at amazon dot it>
+ *
+ * This file is part of FFmpeg.
+ *
+ * FFmpeg is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * FFmpeg is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with FFmpeg; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+#ifndef AVUTIL_VIDEO_HINT_H
+#define AVUTIL_VIDEO_HINT_H
+
+#include <stddef.h>
+#include <stdint.h>
+#include "libavutil/avassert.h"
+#include "libavutil/frame.h"
+
+typedef struct AVVideoRect {
+    uint32_t x, y;
+    uint32_t width, height;
+} AVVideoRect;
+
+typedef enum AVVideoHintType {
+    /* rectangled delimit the constant areas (unchanged), default is changed */
+    AV_VIDEO_HINT_CONSTANT,
+
+    /* rectangled delimit the constant areas (changed), default is not changed */
+    AV_VIDEO_HINT_CHANGED,
+} AVVideoHintType;
+
+typedef struct AVVideoHint {
+    /**
+     * Number of AVVideoRect present.
+     *
+     * May be 0, in which case no per-rectangle information is present. In this
+     * case the values of rect_offset / rect_size are unspecified and should
+     * not be accessed.
+     */
+    size_t nb_rects;
+
+    /**
+     * Offset in bytes from the beginning of this structure at which the array
+     * of AVVideoRect starts.
+     */
+    size_t rect_offset;
+
+    /**
+     * Size in bytes of AVVideoRect.
+     */
+    size_t rect_size;
+
+    AVVideoHintType type;
+} AVVideoHint;
+
+static av_always_inline AVVideoRect*
+av_video_hint_rects(const AVVideoHint *hints) {
+    return (AVVideoRect *)((uint8_t *)hints + hints->rect_offset); }
+
+static av_always_inline AVVideoRect*
+av_video_hint_get_rect(const AVVideoHint *hints, size_t idx) {
+    return (AVVideoRect *)((uint8_t *)hints + hints->rect_offset + idx
+* hints->rect_size); }
+
+/**
+ * Allocate memory for the AVVideoHint struct along with an nb_rects-sized
+ * arrays of AVVideoRect.
+ *
+ * The side data contains a list of rectangles for the portions of the frame
+ * which changed from the last encoded one (and the remainder are assumed to be
+ * changed), or, alternately (depending on the type parameter) the unchanged
+ * ones (and the remanining ones are those which changed).
+ * Macroblocks will thus be hinted either to be P_SKIP-ped or go through the
+ * regular encoding procedure.
+ *
+ * It's responsibility of the caller to fill the AVRects accordingly, and to set
+ * the proper AVVideoHintType field.
+ *
+ * @param out_size if non-NULL, the size in bytes of the resulting data array is
+ *                 written here
+ *
+ * @return newly allocated AVVideoHint struct (must be freed by the caller using
+ *         av_free()) on success, NULL on memory allocation failure
+ */
+AVVideoHint *av_video_hint_alloc(size_t nb_rects,
+                                 size_t *out_size);
+/**
+ * Same as av_video_hint_alloc(), except newly-allocated AVVideoHint is attached
+ * as side data of type AV_FRAME_DATA_VIDEO_HINT_INFO to frame.
+ */
+AVVideoHint *av_video_hint_create_side_data(AVFrame *frame,
+                                            size_t nb_rects);
+
+
+#endif /* AVUTIL_VIDEO_HINT_H */
-- 
2.34.1


[-- Attachment #3: Type: text/plain, Size: 251 bytes --]

_______________________________________________
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".

  reply	other threads:[~2023-07-26 10:53 UTC|newest]

Thread overview: 33+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2023-05-19 10:19 [FFmpeg-devel] [PATCH] Optimization: support for libx264's mb_info Carotti, Elias
2023-05-21 23:17 ` Stefano Sabatini
2023-05-22  9:19   ` Carotti, Elias
2023-05-29 17:56     ` Carotti, Elias
2023-06-04 15:29       ` Stefano Sabatini
2023-06-05 15:32         ` Carotti, Elias
2023-06-11 17:15           ` Stefano Sabatini
2023-06-12  8:23             ` Kieran Kunhya
2023-06-12 17:38               ` Carotti, Elias
2023-06-18 10:04                 ` Stefano Sabatini
2023-06-12 17:28             ` Carotti, Elias
2023-06-18 10:18               ` Stefano Sabatini
2023-06-21 15:53                 ` Carotti, Elias
2023-06-22  8:44                   ` Anton Khirnov
2023-06-22 17:23                     ` Carotti, Elias
2023-06-24 11:01                       ` Anton Khirnov
2023-06-26  9:50                         ` Carotti, Elias
2023-06-28 12:55                           ` Anton Khirnov
2023-06-30 17:40                             ` Carotti, Elias
2023-07-01  8:33                               ` Anton Khirnov
2023-07-03 15:51                                 ` Carotti, Elias
2023-07-07 16:27                                   ` Carotti, Elias
2023-07-09 11:05                                     ` [FFmpeg-devel] [PATCH] lavu: add AVVideoHint API Anton Khirnov
2023-07-09 13:10                                       ` Lynne
2023-07-10  8:13                                         ` Carotti, Elias
2023-07-10 12:51                                           ` Carotti, Elias
2023-07-17 22:19                                             ` Stefano Sabatini
2023-07-23 23:27                                               ` Stefano Sabatini
2023-07-26 10:52                                                 ` Carotti, Elias [this message]
2023-07-28  7:44                                                   ` Stefano Sabatini
2023-08-02  5:36                                                     ` Stefano Sabatini
2023-08-08  8:16                                                       ` Stefano Sabatini
2023-07-10  8:09                                       ` Carotti, Elias

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=bac659153fdf89f21a9538b5a3a29bc6fd575912.camel@amazon.it \
    --to=eliascrt@amazon.it \
    --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