Git Inbox Mirror of the ffmpeg-devel mailing list - see https://ffmpeg.org/mailman/listinfo/ffmpeg-devel
 help / color / mirror / Atom feed
From: Mark Thompson <sw@jkqxz.net>
To: ffmpeg-devel@ffmpeg.org
Subject: Re: [FFmpeg-devel] [PATCH 06/16] avutil: add nvtegra hwcontext
Date: Wed, 5 Jun 2024 21:47:06 +0100
Message-ID: <000f9f24-a963-4a00-9a58-e78af043ee7b@jkqxz.net> (raw)
In-Reply-To: <bb17171cf16ebcb4d15d9b998bc955754b133bdf.1717083800.git.averne381@gmail.com>

On 30/05/2024 20:43, averne wrote:
> This includes hwdevice and hwframes objects.
> As the multimedia engines work with tiled surfaces (block linear in nvidia jargon), two frame transfer methods are implemented.
> The first makes use of the VIC to perform the copy. Since some revisions of the VIC (such as the one found in the tegra X1) did not support 10+ bit formats, these go through two separate copy steps for the luma and chroma planes.
> The second method copies on the CPU, and is used as a fallback if the VIC constraints are not satisfied.
> 
> Signed-off-by: averne <averne381@gmail.com>
> ---
>  libavutil/Makefile             |   7 +-
>  libavutil/hwcontext.c          |   4 +
>  libavutil/hwcontext.h          |   1 +
>  libavutil/hwcontext_internal.h |   1 +
>  libavutil/hwcontext_nvtegra.c  | 880 +++++++++++++++++++++++++++++++++
>  libavutil/hwcontext_nvtegra.h  |  85 ++++
>  6 files changed, 976 insertions(+), 2 deletions(-)
>  create mode 100644 libavutil/hwcontext_nvtegra.c
>  create mode 100644 libavutil/hwcontext_nvtegra.h
> 
> ...> +
> +static int nvtegra_transfer_data(AVHWFramesContext *ctx, AVFrame *dst, const AVFrame *src) {
> +    const AVFrame *swframe;
> +    bool from;
> +    int num_planes, i;
> +
> +    from    = !dst->hw_frames_ctx;
> +    swframe = from ? dst : src;
> +
> +    if (swframe->hw_frames_ctx)
> +        return AVERROR(ENOSYS);
> +
> +    num_planes = av_pix_fmt_count_planes(swframe->format);
> +
> +    for (i = 0; i < num_planes; ++i) {
> +        if (((uintptr_t)swframe->data[i] & 0xff) || (swframe->linesize[i] & 0xff)) {
> +            av_log(ctx, AV_LOG_WARNING, "Frame address/pitch not aligned to 256, "
> +                                        "falling back to cpu transfer\n");
> +            return nvtegra_cpu_transfer_data(ctx, dst, src, num_planes, from);

Are you doing something somewhere to avoid this case?  It seems like it should be the normal one (given alignment is typically set signficantly lower than 256), so this warning would be very spammy.

> +        }
> +    }
> +
> +    return nvtegra_vic_transfer_data(ctx, dst, src, num_planes, from);
> +}
> +
> +const HWContextType ff_hwcontext_type_nvtegra = {
> +    .type                   = AV_HWDEVICE_TYPE_NVTEGRA,
> +    .name                   = "nvtegra",
> +
> +    .device_hwctx_size      = sizeof(NVTegraDevicePriv),
> +    .device_hwconfig_size   = 0,
> +    .frames_hwctx_size      = 0,
> +
> +    .device_create          = &nvtegra_device_create,
> +    .device_init            = &nvtegra_device_init,
> +    .device_uninit          = &nvtegra_device_uninit,
> +
> +    .frames_get_constraints = &nvtegra_frames_get_constraints,
> +    .frames_init            = &nvtegra_frames_init,
> +    .frames_uninit          = &nvtegra_frames_uninit,
> +    .frames_get_buffer      = &nvtegra_get_buffer,
> +
> +    .transfer_get_formats   = &nvtegra_transfer_get_formats,
> +    .transfer_data_to       = &nvtegra_transfer_data,
> +    .transfer_data_from     = &nvtegra_transfer_data,
> +
> +    .pix_fmts = (const enum AVPixelFormat[]) {
> +        AV_PIX_FMT_NVTEGRA,
> +        AV_PIX_FMT_NONE,
> +    },
> +};

What controls whether frames are linear or not?

It seems like the linear case could be exposed directly to the user rather than having to wrap it like this - the decoder could return read-only NV12 (or whatever) frames directly and they would work with other components.

> diff --git a/libavutil/hwcontext_nvtegra.h b/libavutil/hwcontext_nvtegra.h
> new file mode 100644
> index 0000000000..8a2383d304
> --- /dev/null
> +++ b/libavutil/hwcontext_nvtegra.h
> @@ -0,0 +1,85 @@
> +/*
> + * Copyright (c) 2024 averne <averne381@gmail.com>
> + *
> + * This file is part of FFmpeg.
> + *
> + * FFmpeg is free software; you can redistribute it and/or modify
> + * it under the terms of the GNU General Public License as published by
> + * the Free Software Foundation; either version 2 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 General Public License for more details.
> + *
> + * You should have received a copy of the GNU 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_HWCONTEXT_NVTEGRA_H
> +#define AVUTIL_HWCONTEXT_NVTEGRA_H
> +
> +#include <stdint.h>
> +
> +#include "hwcontext.h"
> +#include "buffer.h"
> +#include "frame.h"
> +#include "pixfmt.h"
> +
> +#include "nvtegra.h"
> +
> +/*
> + * Encode a hardware revision into a version number
> + */
> +#define AV_NVTEGRA_ENCODE_REV(maj, min) (((maj & 0xff) << 8) | (min & 0xff))
> +
> +/*
> + * Decode a version number
> + */
> +static inline void av_nvtegra_decode_rev(int rev, int *maj, int *min) {
> +    *maj = (rev >> 8) & 0xff;
> +    *min = (rev >> 0) & 0xff;
> +}
> +
> +/**
> + * @file
> + * API-specific header for AV_HWDEVICE_TYPE_NVTEGRA.
> + *
> + * For user-allocated pools, AVHWFramesContext.pool must return AVBufferRefs
> + * with the data pointer set to an AVNVTegraMap.
> + */
> +
> +typedef struct AVNVTegraDeviceContext {
> +    /*
> +     * Hardware multimedia engines
> +     */
> +    AVNVTegraChannel nvdec_channel, nvenc_channel, nvjpg_channel, vic_channel;

Does a user need to supply all of these when making a device?

> +
> +    /*
> +     * Hardware revisions for associated engines, or 0 if invalid
> +     */
> +    int nvdec_version, nvenc_version, nvjpg_version, vic_version;

Why does a user setting up a device context need to supply the version numbers for each thing?

> +} AVNVTegraDeviceContext;
> +
> +typedef struct AVNVTegraFrame {
> +    /*
> +     * Reference to an AVNVTegraMap object
> +     */
> +    AVBufferRef *map_ref;
> +} AVNVTegraFrame;

What is the indirection doing here?  Can't it return the buffer inside this structure instead of making an intermediate structure?

> +
> +/*
> + * Helper to retrieve a map object from the corresponding frame
> + */
> +static inline AVNVTegraMap *av_nvtegra_frame_get_fbuf_map(const AVFrame *frame) {
> +    return (AVNVTegraMap *)((AVNVTegraFrame *)frame->buf[0]->data)->map_ref->data;
> +}
> +
> +/*
> + * Converts a pixel format to the equivalent code for the VIC engine
> + */
> +int av_nvtegra_pixfmt_to_vic(enum AVPixelFormat fmt);
> +
> +#endif /* AVUTIL_HWCONTEXT_NVTEGRA_H */

The mix of normal implementation code and weird specific detail for the particular platform is pretty nasty.  It does seem like exporting more of this into a separate library rather than embedding it in ffmpeg would be a good idea.

Thanks,

- Mark
_______________________________________________
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:[~2024-06-05 20:46 UTC|newest]

Thread overview: 37+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2024-05-30 19:43 [FFmpeg-devel] [PATCH 00/16] NVidia Tegra hardware decoding backend averne
2024-05-30 19:43 ` [FFmpeg-devel] [PATCH 01/16] avutil/buffer: add helper to allocate aligned memory averne
2024-05-30 20:38   ` Rémi Denis-Courmont
2024-05-31 21:06     ` averne
2024-05-31 21:44       ` Michael Niedermayer
2024-06-02 18:37         ` averne
2024-06-01  6:59       ` Rémi Denis-Courmont
2024-05-30 19:43 ` [FFmpeg-devel] [PATCH 02/16] configure, avutil: add support for HorizonOS averne
2024-05-30 20:37   ` Rémi Denis-Courmont
2024-05-31 21:06     ` averne
2024-05-30 19:43 ` [FFmpeg-devel] [PATCH 03/16] avutil: add ioctl definitions for tegra devices averne
2024-05-30 20:42   ` Rémi Denis-Courmont
2024-05-31 21:06     ` averne
2024-05-31 21:16       ` Timo Rothenpieler
2024-06-02 18:37         ` averne
2024-05-30 19:43 ` [FFmpeg-devel] [PATCH 04/16] avutil: add hardware definitions for NVDEC, NVJPG and VIC averne
2024-05-30 19:43 ` [FFmpeg-devel] [PATCH 05/16] avutil: add common code for nvtegra averne
2024-05-31  8:32   ` Rémi Denis-Courmont
2024-05-31 21:06     ` averne
2024-06-01  7:29       ` Rémi Denis-Courmont
2024-06-05 20:29   ` Mark Thompson
2024-06-29 19:35     ` averne
2024-05-30 19:43 ` [FFmpeg-devel] [PATCH 06/16] avutil: add nvtegra hwcontext averne
2024-06-05 20:47   ` Mark Thompson [this message]
2024-06-29 19:35     ` averne
2024-05-30 19:43 ` [FFmpeg-devel] [PATCH 07/16] hwcontext_nvtegra: add dynamic frequency scaling routines averne
2024-06-05 20:50   ` Mark Thompson
2024-06-29 19:35     ` averne
2024-05-30 19:43 ` [FFmpeg-devel] [PATCH 08/16] nvtegra: add common hardware decoding code averne
2024-05-30 19:43 ` [FFmpeg-devel] [PATCH 09/16] nvtegra: add mpeg1/2 hardware decoding averne
2024-05-30 19:43 ` [FFmpeg-devel] [PATCH 10/16] nvtegra: add mpeg4 " averne
2024-05-30 19:43 ` [FFmpeg-devel] [PATCH 11/16] nvtegra: add vc1 " averne
2024-05-30 19:43 ` [FFmpeg-devel] [PATCH 12/16] nvtegra: add h264 " averne
2024-05-30 19:43 ` [FFmpeg-devel] [PATCH 13/16] nvtegra: add hevc " averne
2024-05-30 19:43 ` [FFmpeg-devel] [PATCH 14/16] nvtegra: add vp8 " averne
2024-05-30 19:43 ` [FFmpeg-devel] [PATCH 15/16] nvtegra: add vp9 " averne
2024-05-30 19:43 ` [FFmpeg-devel] [PATCH 16/16] nvtegra: add mjpeg " averne

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=000f9f24-a963-4a00-9a58-e78af043ee7b@jkqxz.net \
    --to=sw@jkqxz.net \
    --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