Git Inbox Mirror of the ffmpeg-devel mailing list - see https://ffmpeg.org/mailman/listinfo/ffmpeg-devel
 help / color / mirror / Atom feed
From: averne <averne381@gmail.com>
To: ffmpeg-devel@ffmpeg.org
Cc: averne <averne381@gmail.com>
Subject: [FFmpeg-devel] [PATCH 16/16] nvtegra: add mjpeg hardware decoding
Date: Thu, 30 May 2024 21:43:18 +0200
Message-ID: <9fd169524a21cb2a4bef2673147b791c7cbc2209.1717083800.git.averne381@gmail.com> (raw)
In-Reply-To: <cover.1717083799.git.averne381@gmail.com>

This uses NVJPG, a hardware engine separate from NVDEC. On the tegra 210 (and possibly later hardware), it has the specificity of being unable to decode to tiled surfaces, along with some quirks that have been observed to hang the hardware.

Signed-off-by: averne <averne381@gmail.com>
---
 configure                  |   2 +
 libavcodec/Makefile        |   1 +
 libavcodec/hwaccels.h      |   1 +
 libavcodec/mjpegdec.c      |   6 +
 libavcodec/nvtegra_mjpeg.c | 336 +++++++++++++++++++++++++++++++++++++
 5 files changed, 346 insertions(+)
 create mode 100644 libavcodec/nvtegra_mjpeg.c

diff --git a/configure b/configure
index 3fe948d9ab..1d885ed655 100755
--- a/configure
+++ b/configure
@@ -3219,6 +3219,8 @@ mjpeg_nvdec_hwaccel_deps="nvdec"
 mjpeg_nvdec_hwaccel_select="mjpeg_decoder"
 mjpeg_vaapi_hwaccel_deps="vaapi"
 mjpeg_vaapi_hwaccel_select="mjpeg_decoder"
+mjpeg_nvtegra_hwaccel_deps="nvtegra"
+mjpeg_nvtegra_hwaccel_select="mjpeg_decoder"
 mpeg1_nvdec_hwaccel_deps="nvdec"
 mpeg1_nvdec_hwaccel_select="mpeg1video_decoder"
 mpeg1_vdpau_hwaccel_deps="vdpau"
diff --git a/libavcodec/Makefile b/libavcodec/Makefile
index 914995558e..6a773f8d3e 100644
--- a/libavcodec/Makefile
+++ b/libavcodec/Makefile
@@ -1025,6 +1025,7 @@ OBJS-$(CONFIG_HEVC_VULKAN_HWACCEL)        += vulkan_decode.o vulkan_hevc.o
 OBJS-$(CONFIG_HEVC_NVTEGRA_HWACCEL)       += nvtegra_hevc.o
 OBJS-$(CONFIG_MJPEG_NVDEC_HWACCEL)        += nvdec_mjpeg.o
 OBJS-$(CONFIG_MJPEG_VAAPI_HWACCEL)        += vaapi_mjpeg.o
+OBJS-$(CONFIG_MJPEG_NVTEGRA_HWACCEL)      += nvtegra_mjpeg.o
 OBJS-$(CONFIG_MPEG1_NVDEC_HWACCEL)        += nvdec_mpeg12.o
 OBJS-$(CONFIG_MPEG1_VDPAU_HWACCEL)        += vdpau_mpeg12.o
 OBJS-$(CONFIG_MPEG1_VIDEOTOOLBOX_HWACCEL) += videotoolbox.o
diff --git a/libavcodec/hwaccels.h b/libavcodec/hwaccels.h
index a3babfc309..f5a121d23f 100644
--- a/libavcodec/hwaccels.h
+++ b/libavcodec/hwaccels.h
@@ -51,6 +51,7 @@ extern const struct FFHWAccel ff_hevc_nvtegra_hwaccel;
 extern const struct FFHWAccel ff_hevc_vulkan_hwaccel;
 extern const struct FFHWAccel ff_mjpeg_nvdec_hwaccel;
 extern const struct FFHWAccel ff_mjpeg_vaapi_hwaccel;
+extern const struct FFHWAccel ff_mjpeg_nvtegra_hwaccel;
 extern const struct FFHWAccel ff_mpeg1_nvdec_hwaccel;
 extern const struct FFHWAccel ff_mpeg1_vdpau_hwaccel;
 extern const struct FFHWAccel ff_mpeg1_videotoolbox_hwaccel;
diff --git a/libavcodec/mjpegdec.c b/libavcodec/mjpegdec.c
index 1481a7f285..f8b00a92d6 100644
--- a/libavcodec/mjpegdec.c
+++ b/libavcodec/mjpegdec.c
@@ -733,6 +733,9 @@ int ff_mjpeg_decode_sof(MJpegDecodeContext *s)
 #endif
 #if CONFIG_MJPEG_VAAPI_HWACCEL
                 AV_PIX_FMT_VAAPI,
+#endif
+#if CONFIG_MJPEG_NVTEGRA_HWACCEL
+                AV_PIX_FMT_NVTEGRA,
 #endif
                 s->avctx->pix_fmt,
                 AV_PIX_FMT_NONE,
@@ -3021,6 +3024,9 @@ const FFCodec ff_mjpeg_decoder = {
 #endif
 #if CONFIG_MJPEG_VAAPI_HWACCEL
                         HWACCEL_VAAPI(mjpeg),
+#endif
+#if CONFIG_MJPEG_NVTEGRA_HWACCEL
+                        HWACCEL_NVTEGRA(mjpeg),
 #endif
                         NULL
                     },
diff --git a/libavcodec/nvtegra_mjpeg.c b/libavcodec/nvtegra_mjpeg.c
new file mode 100644
index 0000000000..9139116159
--- /dev/null
+++ b/libavcodec/nvtegra_mjpeg.c
@@ -0,0 +1,336 @@
+/*
+ * 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.
+ */
+
+#include "config_components.h"
+
+#include "avcodec.h"
+#include "hwaccel_internal.h"
+#include "internal.h"
+#include "hwconfig.h"
+#include "mjpegdec.h"
+#include "decode.h"
+#include "nvtegra_decode.h"
+
+#include "libavutil/pixdesc.h"
+#include "libavutil/nvtegra_host1x.h"
+
+typedef struct NVTegraMJPEGDecodeContext {
+    FFNVTegraDecodeContext core;
+} NVTegraMJPEGDecodeContext;
+
+static int nvtegra_mjpeg_decode_uninit(AVCodecContext *avctx) {
+    NVTegraMJPEGDecodeContext *ctx = avctx->internal->hwaccel_priv_data;
+
+    int err;
+
+    av_log(avctx, AV_LOG_DEBUG, "Deinitializing NVTEGRA MJPEG decoder\n");
+
+    err = ff_nvtegra_decode_uninit(avctx, &ctx->core);
+    if (err < 0)
+        return err;
+
+    return 0;
+}
+
+static int nvtegra_mjpeg_decode_init(AVCodecContext *avctx) {
+    MJpegDecodeContext          *s = avctx->priv_data;
+    NVTegraMJPEGDecodeContext *ctx = avctx->internal->hwaccel_priv_data;
+
+
+    enum AVPixelFormat fmt;
+    int luma, err;
+
+    av_log(avctx, AV_LOG_DEBUG, "Initializing NVTEGRA MJPEG decoder\n");
+
+    /* Reject encodes with known hardware issues */
+    if (avctx->profile != AV_PROFILE_MJPEG_HUFFMAN_BASELINE_DCT) {
+        av_log(avctx, AV_LOG_ERROR, "Non-baseline encoded jpegs are not supported by NVJPG\n");
+        return AVERROR(EINVAL);
+    }
+
+    fmt = s->avctx->pix_fmt, luma = s->comp_index[0];
+    if ((fmt == AV_PIX_FMT_YUV444P || fmt == AV_PIX_FMT_YUVJ444P)
+            && (s->h_count[luma] != 1 || s->v_count[luma] != 1)) {
+        av_log(avctx, AV_LOG_ERROR, "Subsampled YUV444 is not supported by NVJPG\n");
+        return AVERROR(EINVAL);
+    }
+
+    ctx->core.pic_setup_off  = 0;
+    ctx->core.status_off     = FFALIGN(ctx->core.pic_setup_off + sizeof(nvjpg_dec_drv_pic_setup_s),
+                                       AV_NVTEGRA_MAP_ALIGN);
+    ctx->core.cmdbuf_off     = FFALIGN(ctx->core.status_off    + sizeof(nvjpg_dec_status),
+                                       AV_NVTEGRA_MAP_ALIGN);
+    ctx->core.bitstream_off  = FFALIGN(ctx->core.cmdbuf_off    + AV_NVTEGRA_MAP_ALIGN,
+                                       AV_NVTEGRA_MAP_ALIGN);
+    ctx->core.input_map_size = FFALIGN(ctx->core.bitstream_off + ff_nvtegra_decode_pick_bitstream_buffer_size(avctx),
+                                       0x1000);
+
+    ctx->core.max_cmdbuf_size    =  ctx->core.slice_offsets_off - ctx->core.cmdbuf_off;
+    ctx->core.max_bitstream_size =  ctx->core.input_map_size    - ctx->core.bitstream_off;
+
+    ctx->core.is_nvjpg = true;
+
+    err = ff_nvtegra_decode_init(avctx, &ctx->core);
+    if (err < 0)
+        goto fail;
+
+    return 0;
+
+fail:
+    nvtegra_mjpeg_decode_uninit(avctx);
+    return err;
+}
+
+static void nvtegra_mjpeg_prepare_frame_setup(nvjpg_dec_drv_pic_setup_s *setup, MJpegDecodeContext *s,
+                                              NVTegraMJPEGDecodeContext *ctx)
+{
+    int input_chroma_mode, output_chroma_mode, memory_mode;
+    int i, j;
+
+    switch (s->hwaccel_sw_pix_fmt) {
+        case AV_PIX_FMT_GRAY8:
+            input_chroma_mode  = 0; /* Monochrome */
+            output_chroma_mode = 0; /* Monochrome */
+            memory_mode        = 3; /* YUV420, for some reason decoding fails with NV12 */
+            break;
+        default:
+        case AV_PIX_FMT_YUV420P:
+        case AV_PIX_FMT_YUVJ420P:
+            input_chroma_mode  = 1; /* YUV420 */
+            output_chroma_mode = 1; /* YUV420 */
+            memory_mode        = 0; /* NV12 */
+            break;
+        case AV_PIX_FMT_YUV422P:
+        case AV_PIX_FMT_YUVJ422P:
+            input_chroma_mode  = 2; /* YUV422H (not sure what nvidia means by that) */
+            output_chroma_mode = 1; /* YUV420 */
+            memory_mode        = 0; /* NV12 */
+            break;
+        case AV_PIX_FMT_YUV440P:
+        case AV_PIX_FMT_YUVJ440P:
+            input_chroma_mode  = 3; /* YUV422V (ditto) */
+            output_chroma_mode = 1; /* YUV420 */
+            memory_mode        = 0; /* NV12 */
+            break;
+        case AV_PIX_FMT_YUV444P:
+        case AV_PIX_FMT_YUVJ444P:
+            input_chroma_mode  = 4; /* YUV444 */
+            output_chroma_mode = 1; /* YUV420 */
+            memory_mode        = 0; /* NV12 */
+            break;
+    }
+
+    *setup = (nvjpg_dec_drv_pic_setup_s){
+        .restart_interval     = s->restart_interval,
+        .frame_width          = s->width,
+        .frame_height         = s->height,
+        .mcu_width            = s->mb_width,
+        .mcu_height           = s->mb_height,
+        .comp                 = s->nb_components,
+
+        .stream_chroma_mode   = input_chroma_mode,
+        .output_chroma_mode   = output_chroma_mode,
+        .output_pixel_format  = 0,  /* YUV */
+        .output_stride_luma   = s->picture->linesize[0],
+        .output_stride_chroma = s->picture->linesize[1],
+
+        .tile_mode            = 0,  /* Pitch linear (tiled formats are unsupported by the T210) */
+        .memory_mode          = memory_mode,
+        .power2_downscale     = 0,
+        .motion_jpeg_type     = 0,  /* Type A */
+
+        .start_mcu_x          = 0,
+        .start_mcu_y          = 0,
+    };
+
+    for (i = 0; i < 4; ++i) {
+        for (j = 0; j < 16; ++j) {
+            setup->huffTab[0][i].codeNum[j] = s->raw_huffman_lengths[0][i][j];
+            setup->huffTab[1][i].codeNum[j] = s->raw_huffman_lengths[1][i][j];
+        }
+
+        memcpy(setup->huffTab[0][i].symbol, s->raw_huffman_values[0][i], sizeof(setup->huffTab[0][i].symbol));
+        memcpy(setup->huffTab[1][i].symbol, s->raw_huffman_values[1][i], sizeof(setup->huffTab[1][i].symbol));
+    }
+
+    for (i = 0; i < s->nb_components; ++i) {
+        j = s->comp_index[i];
+        setup->blkPar[j].ac     = s->ac_index   [i];
+        setup->blkPar[j].dc     = s->dc_index   [i];
+        setup->blkPar[j].hblock = s->h_count    [i];
+        setup->blkPar[j].vblock = s->v_count    [i];
+        setup->blkPar[j].quant  = s->quant_index[i];
+    }
+
+    for (i = 0; i < 4; ++i) {
+        for (j = 0; j < 64; ++j)
+            setup->quant[i][j] = s->quant_matrixes[i][j];
+    }
+}
+
+static int nvtegra_mjpeg_prepare_cmdbuf(AVNVTegraCmdbuf *cmdbuf, MJpegDecodeContext *s,
+                                        NVTegraMJPEGDecodeContext *ctx, AVFrame *current_frame)
+{
+    FrameDecodeData     *fdd = (FrameDecodeData *)current_frame->private_ref->data;
+    FFNVTegraDecodeFrame *tf = fdd->hwaccel_priv;
+    AVNVTegraMap  *input_map = (AVNVTegraMap *)tf->input_map_ref->data;
+
+    int err;
+
+    err = av_nvtegra_cmdbuf_begin(cmdbuf, HOST1X_CLASS_NVJPG);
+    if (err < 0)
+        return err;
+
+    AV_NVTEGRA_PUSH_VALUE(cmdbuf, NVE7D0_SET_APPLICATION_ID,
+                          AV_NVTEGRA_ENUM(NVE7D0_SET_APPLICATION_ID, ID, NVJPG_DECODER));
+    AV_NVTEGRA_PUSH_VALUE(cmdbuf, NVE7D0_SET_CONTROL_PARAMS,
+                          AV_NVTEGRA_VALUE(NVE7D0_SET_CONTROL_PARAMS, DUMP_CYCLE_COUNT, 1) |
+                          AV_NVTEGRA_VALUE(NVE7D0_SET_CONTROL_PARAMS, GPTIMER_ON,       1));
+    AV_NVTEGRA_PUSH_VALUE(cmdbuf, NVE7D0_SET_PICTURE_INDEX,
+                          AV_NVTEGRA_VALUE(NVE7D0_SET_PICTURE_INDEX, INDEX, ctx->core.frame_idx));
+
+    AV_NVTEGRA_PUSH_RELOC(cmdbuf, NVE7D0_SET_IN_DRV_PIC_SETUP,
+                          input_map, ctx->core.pic_setup_off, NVHOST_RELOC_TYPE_DEFAULT);
+    AV_NVTEGRA_PUSH_RELOC(cmdbuf, NVE7D0_SET_BITSTREAM,
+                          input_map, ctx->core.bitstream_off, NVHOST_RELOC_TYPE_DEFAULT);
+    AV_NVTEGRA_PUSH_RELOC(cmdbuf, NVE7D0_SET_OUT_STATUS,
+                          input_map, ctx->core.status_off,    NVHOST_RELOC_TYPE_DEFAULT);
+
+    AV_NVTEGRA_PUSH_RELOC(cmdbuf, NVE7D0_SET_CUR_PIC, av_nvtegra_frame_get_fbuf_map(current_frame),
+                          0, NVHOST_RELOC_TYPE_DEFAULT);
+    AV_NVTEGRA_PUSH_RELOC(cmdbuf, NVE7D0_SET_CUR_PIC_CHROMA_U, av_nvtegra_frame_get_fbuf_map(current_frame),
+                          current_frame->data[1] - current_frame->data[0], NVHOST_RELOC_TYPE_DEFAULT);
+
+    AV_NVTEGRA_PUSH_VALUE(cmdbuf, NVE7D0_EXECUTE,
+                          AV_NVTEGRA_ENUM(NVE7D0_EXECUTE, AWAKEN, ENABLE));
+
+    err = av_nvtegra_cmdbuf_end(cmdbuf);
+    if (err < 0)
+        return err;
+
+    return 0;
+}
+
+static int nvtegra_mjpeg_start_frame(AVCodecContext *avctx, const uint8_t *buf, uint32_t buf_size) {
+    MJpegDecodeContext          *s = avctx->priv_data;
+    AVFrame                 *frame = s->picture;
+    NVTegraMJPEGDecodeContext *ctx = avctx->internal->hwaccel_priv_data;
+
+    int err;
+
+    av_log(avctx, AV_LOG_DEBUG, "Starting MJPEG-NVTEGRA frame with pixel format %s\n",
+           av_get_pix_fmt_name(avctx->sw_pix_fmt));
+
+    err = ff_nvtegra_start_frame(avctx, frame, &ctx->core);
+    if (err < 0)
+        return err;
+
+    return 0;
+}
+
+static int nvtegra_mjpeg_end_frame(AVCodecContext *avctx) {
+    MJpegDecodeContext          *s = avctx->priv_data;
+    NVTegraMJPEGDecodeContext *ctx = avctx->internal->hwaccel_priv_data;
+    AVFrame                 *frame = s->picture;
+    FrameDecodeData           *fdd = (FrameDecodeData *)frame->private_ref->data;
+    FFNVTegraDecodeFrame       *tf = fdd->hwaccel_priv;
+
+    nvjpg_dec_drv_pic_setup_s *setup;
+    uint8_t *mem;
+    AVNVTegraMap *output_map;
+    int err;
+
+    av_log(avctx, AV_LOG_DEBUG, "Ending MJPEG-NVTEGRA frame with %u slices -> %u bytes\n",
+           ctx->core.num_slices, ctx->core.bitstream_len);
+
+    if (!tf || !ctx->core.num_slices)
+        return 0;
+
+    mem = av_nvtegra_map_get_addr((AVNVTegraMap *)tf->input_map_ref->data);
+
+    setup = (nvjpg_dec_drv_pic_setup_s *)(mem + ctx->core.pic_setup_off);
+    setup->bitstream_offset = 0;
+    setup->bitstream_size   = ctx->core.bitstream_len;
+
+    err = nvtegra_mjpeg_prepare_cmdbuf(&ctx->core.cmdbuf, s, ctx, frame);
+    if (err < 0)
+        return err;
+
+    output_map = av_nvtegra_frame_get_fbuf_map(frame);
+    output_map->is_linear = true;
+
+    return ff_nvtegra_end_frame(avctx, frame, &ctx->core, NULL, 0);
+}
+
+static int nvtegra_mjpeg_decode_slice(AVCodecContext *avctx, const uint8_t *buf, uint32_t buf_size) {
+    MJpegDecodeContext          *s = avctx->priv_data;
+    NVTegraMJPEGDecodeContext *ctx = avctx->internal->hwaccel_priv_data;
+    AVFrame                 *frame = s->picture;
+    FrameDecodeData           *fdd = (FrameDecodeData *)frame->private_ref->data;
+
+    FFNVTegraDecodeFrame *tf;
+    AVNVTegraMap *input_map;
+    uint8_t *mem;
+
+    tf = fdd->hwaccel_priv;
+    input_map = (AVNVTegraMap *)tf->input_map_ref->data;
+    mem = av_nvtegra_map_get_addr(input_map);
+
+    /* In nvtegra_mjpeg_start_frame the JFIF headers haven't been entirely parsed yet */
+    nvtegra_mjpeg_prepare_frame_setup((nvjpg_dec_drv_pic_setup_s *)(mem + ctx->core.pic_setup_off), s, ctx);
+
+    return ff_nvtegra_decode_slice(avctx, frame, buf, buf_size, false);
+}
+
+static int nvtegra_mjpeg_frame_params(AVCodecContext *avctx, AVBufferRef *hw_frames_ctx) {
+    AVHWFramesContext *frames_ctx = (AVHWFramesContext *)hw_frames_ctx->data;
+
+    int err;
+
+    err = ff_nvtegra_frame_params(avctx, hw_frames_ctx);
+    if (err < 0)
+        return err;
+
+    /*
+     * NVJPG1 can only decode to pitch linear surfaces, which have a
+     * 256b alignment requirement in VIC.
+     */
+    frames_ctx->width  = FFALIGN(frames_ctx->width,  256);
+    frames_ctx->height = FFALIGN(frames_ctx->height, 4);
+
+    return 0;
+}
+
+#if CONFIG_MJPEG_NVTEGRA_HWACCEL
+const FFHWAccel ff_mjpeg_nvtegra_hwaccel = {
+    .p.name         = "mjpeg_nvtegra",
+    .p.type         = AVMEDIA_TYPE_VIDEO,
+    .p.id           = AV_CODEC_ID_MJPEG,
+    .p.pix_fmt      = AV_PIX_FMT_NVTEGRA,
+    .start_frame    = &nvtegra_mjpeg_start_frame,
+    .end_frame      = &nvtegra_mjpeg_end_frame,
+    .decode_slice   = &nvtegra_mjpeg_decode_slice,
+    .init           = &nvtegra_mjpeg_decode_init,
+    .uninit         = &nvtegra_mjpeg_decode_uninit,
+    .frame_params   = &nvtegra_mjpeg_frame_params,
+    .priv_data_size = sizeof(NVTegraMJPEGDecodeContext),
+    .caps_internal  = HWACCEL_CAP_ASYNC_SAFE,
+};
+#endif
-- 
2.45.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:[~2024-05-30 19: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
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 ` averne [this message]

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=9fd169524a21cb2a4bef2673147b791c7cbc2209.1717083800.git.averne381@gmail.com \
    --to=averne381@gmail.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