From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: from ffbox0-bg.mplayerhq.hu (ffbox0-bg.ffmpeg.org [79.124.17.100]) by master.gitmailbox.com (Postfix) with ESMTP id CD9614B1DA for ; Thu, 30 May 2024 19:45:36 +0000 (UTC) Received: from [127.0.1.1] (localhost [127.0.0.1]) by ffbox0-bg.mplayerhq.hu (Postfix) with ESMTP id C516B68D5BF; Thu, 30 May 2024 22:44:43 +0300 (EEST) Received: from mail-wr1-f54.google.com (mail-wr1-f54.google.com [209.85.221.54]) by ffbox0-bg.mplayerhq.hu (Postfix) with ESMTPS id 8C02268D5B2 for ; Thu, 30 May 2024 22:44:39 +0300 (EEST) Received: by mail-wr1-f54.google.com with SMTP id ffacd0b85a97d-354cd8da8b9so1161831f8f.0 for ; Thu, 30 May 2024 12:44:39 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20230601; t=1717098279; x=1717703079; darn=ffmpeg.org; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:from:to:cc:subject:date :message-id:reply-to; bh=p0lpSmUb/EKhQbpFi7rFvT7XJjGwa8W2+vCjuXFLVnk=; b=KRxRFOfLZcuxl1ms3r/PoiEDNRq2vn4E9E+d3BWUsmz8qEabBgd/Z70UnjlYCxb0WL FuFhg0k+GJ5yvD+thRtdIEnYwmh1zftnBwRilYMxxVg+Z5IC1lTcbCuKkFdLOI9j3mq2 Fe2VIN+YLmfz6YsWA8bkKcOj3Lmvc8fns7bYliOEqI9O/Goi8dQdL18phkzLcufuraMj 6H6ALAsJu2EBb4GahwS7T7X7Kau2kmD14xXHKfSVLBryaGLfvTOdUTsL7kvpxxrvfzXd l3FVMyw+Z44ieiUSowj0reIxckR2qkGqGvkeeYc4o4LBjormMs4r+9ares7UXcI+rVTD wUig== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1717098279; x=1717703079; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:x-gm-message-state:from:to:cc :subject:date:message-id:reply-to; bh=p0lpSmUb/EKhQbpFi7rFvT7XJjGwa8W2+vCjuXFLVnk=; b=RjOkDOLtnVzLlvzTkcSa7j8c0gYZ+W9gvwuCcGM+nWQoFozHmtV54P9NFsmKRyaErs MylfRJttq3XDSzGK3tW/K93edZaZHxGwOrWLrlXVwEX3RfTz5iwHmGkJrfIOtC70oFNY Scp0H6MF4ZIZTdQuwbaT8AQWCtutIFduzF+YtkkPPdCWxaLCNDI/w7JO6NxVFkJctHPx eREFHPOmocVW5wuIwLfA3IGoaw8SodFQyZoES8tPMs5vptOj4CLsbiHNCKev7uFzGUCQ PXBCHphsKgVASl9OghI8BMItS5L5UUOCAX8LKXQdjULOkk+JvbeXncbqP9ng/6r0uD/3 DZhw== X-Gm-Message-State: AOJu0YydErJCdAEYosVPYVR+mH3h6vdGfnal37IPus0WM2VPkdw/9ja0 pyHDgIkxhOpI4HepuDg9qZM6wiDsUypmfLwLKLeivO+TFjykyRev3coV1w== X-Google-Smtp-Source: AGHT+IGGixu3B7kI9L8lbRCKY9aNlamZMInVmJiqGio0J9jYKrJ+X99gMU+GV03E80BDKYcrU4b5qA== X-Received: by 2002:adf:f852:0:b0:35d:a660:4dfc with SMTP id ffacd0b85a97d-35dc00c74f9mr2395845f8f.60.1717098278661; Thu, 30 May 2024 12:44:38 -0700 (PDT) Received: from fractale.lan ([2001:861:5102:3290:f88d:fc8b:a14:3fcb]) by smtp.gmail.com with ESMTPSA id ffacd0b85a97d-35dd04c0de3sm225126f8f.9.2024.05.30.12.44.37 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Thu, 30 May 2024 12:44:38 -0700 (PDT) From: averne To: ffmpeg-devel@ffmpeg.org Date: Thu, 30 May 2024 21:43:11 +0200 Message-ID: <97094c8a0d54f2122f7eb9e49d5fd3ca39ac9156.1717083800.git.averne381@gmail.com> X-Mailer: git-send-email 2.45.1 In-Reply-To: References: MIME-Version: 1.0 Subject: [FFmpeg-devel] [PATCH 09/16] nvtegra: add mpeg1/2 hardware decoding X-BeenThere: ffmpeg-devel@ffmpeg.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: FFmpeg development discussions and patches List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Reply-To: FFmpeg development discussions and patches Cc: averne Content-Type: text/plain; charset="us-ascii" Content-Transfer-Encoding: 7bit Errors-To: ffmpeg-devel-bounces@ffmpeg.org Sender: "ffmpeg-devel" Archived-At: List-Archive: List-Post: This is probably the most straightforward codec to implement on NVDEC. Since mpeg2 is a superset of mpeg1, both are supported by the same backend. Signed-off-by: averne --- configure | 4 + libavcodec/Makefile | 2 + libavcodec/hwaccels.h | 2 + libavcodec/mpeg12dec.c | 12 ++ libavcodec/nvtegra_mpeg12.c | 319 ++++++++++++++++++++++++++++++++++++ 5 files changed, 339 insertions(+) create mode 100644 libavcodec/nvtegra_mpeg12.c diff --git a/configure b/configure index 566bb37b8c..67db4a2ed2 100755 --- a/configure +++ b/configure @@ -3221,6 +3221,8 @@ mpeg1_vdpau_hwaccel_deps="vdpau" mpeg1_vdpau_hwaccel_select="mpeg1video_decoder" mpeg1_videotoolbox_hwaccel_deps="videotoolbox" mpeg1_videotoolbox_hwaccel_select="mpeg1video_decoder" +mpeg1_nvtegra_hwaccel_deps="nvtegra" +mpeg1_nvtegra_hwaccel_select="mpeg1video_decoder" mpeg2_d3d11va_hwaccel_deps="d3d11va" mpeg2_d3d11va_hwaccel_select="mpeg2video_decoder" mpeg2_d3d11va2_hwaccel_deps="d3d11va" @@ -3237,6 +3239,8 @@ mpeg2_vdpau_hwaccel_deps="vdpau" mpeg2_vdpau_hwaccel_select="mpeg2video_decoder" mpeg2_videotoolbox_hwaccel_deps="videotoolbox" mpeg2_videotoolbox_hwaccel_select="mpeg2video_decoder" +mpeg2_nvtegra_hwaccel_deps="nvtegra" +mpeg2_nvtegra_hwaccel_select="mpeg2video_decoder" mpeg4_nvdec_hwaccel_deps="nvdec" mpeg4_nvdec_hwaccel_select="mpeg4_decoder" mpeg4_vaapi_hwaccel_deps="vaapi" diff --git a/libavcodec/Makefile b/libavcodec/Makefile index f1e2dc6625..e4dfcbce6c 100644 --- a/libavcodec/Makefile +++ b/libavcodec/Makefile @@ -1026,6 +1026,7 @@ OBJS-$(CONFIG_MJPEG_VAAPI_HWACCEL) += vaapi_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 +OBJS-$(CONFIG_MPEG1_NVTEGRA_HWACCEL) += nvtegra_mpeg12.o OBJS-$(CONFIG_MPEG2_D3D11VA_HWACCEL) += dxva2_mpeg2.o OBJS-$(CONFIG_MPEG2_DXVA2_HWACCEL) += dxva2_mpeg2.o OBJS-$(CONFIG_MPEG2_D3D12VA_HWACCEL) += dxva2_mpeg2.o d3d12va_mpeg2.o @@ -1034,6 +1035,7 @@ OBJS-$(CONFIG_MPEG2_QSV_HWACCEL) += qsvdec.o OBJS-$(CONFIG_MPEG2_VAAPI_HWACCEL) += vaapi_mpeg2.o OBJS-$(CONFIG_MPEG2_VDPAU_HWACCEL) += vdpau_mpeg12.o OBJS-$(CONFIG_MPEG2_VIDEOTOOLBOX_HWACCEL) += videotoolbox.o +OBJS-$(CONFIG_MPEG2_NVTEGRA_HWACCEL) += nvtegra_mpeg12.o OBJS-$(CONFIG_MPEG4_NVDEC_HWACCEL) += nvdec_mpeg4.o OBJS-$(CONFIG_MPEG4_VAAPI_HWACCEL) += vaapi_mpeg4.o OBJS-$(CONFIG_MPEG4_VDPAU_HWACCEL) += vdpau_mpeg4.o diff --git a/libavcodec/hwaccels.h b/libavcodec/hwaccels.h index 5171e4c7d7..ad9e9366f2 100644 --- a/libavcodec/hwaccels.h +++ b/libavcodec/hwaccels.h @@ -52,6 +52,7 @@ extern const struct FFHWAccel ff_mjpeg_vaapi_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; +extern const struct FFHWAccel ff_mpeg1_nvtegra_hwaccel; extern const struct FFHWAccel ff_mpeg2_d3d11va_hwaccel; extern const struct FFHWAccel ff_mpeg2_d3d11va2_hwaccel; extern const struct FFHWAccel ff_mpeg2_d3d12va_hwaccel; @@ -60,6 +61,7 @@ extern const struct FFHWAccel ff_mpeg2_nvdec_hwaccel; extern const struct FFHWAccel ff_mpeg2_vaapi_hwaccel; extern const struct FFHWAccel ff_mpeg2_vdpau_hwaccel; extern const struct FFHWAccel ff_mpeg2_videotoolbox_hwaccel; +extern const struct FFHWAccel ff_mpeg2_nvtegra_hwaccel; extern const struct FFHWAccel ff_mpeg4_nvdec_hwaccel; extern const struct FFHWAccel ff_mpeg4_vaapi_hwaccel; extern const struct FFHWAccel ff_mpeg4_vdpau_hwaccel; diff --git a/libavcodec/mpeg12dec.c b/libavcodec/mpeg12dec.c index 9fd765f030..7d8ecae542 100644 --- a/libavcodec/mpeg12dec.c +++ b/libavcodec/mpeg12dec.c @@ -835,6 +835,9 @@ static const enum AVPixelFormat mpeg1_hwaccel_pixfmt_list_420[] = { #endif #if CONFIG_MPEG1_VDPAU_HWACCEL AV_PIX_FMT_VDPAU, +#endif +#if CONFIG_MPEG1_NVTEGRA_HWACCEL + AV_PIX_FMT_NVTEGRA, #endif AV_PIX_FMT_YUV420P, AV_PIX_FMT_NONE @@ -862,6 +865,9 @@ static const enum AVPixelFormat mpeg2_hwaccel_pixfmt_list_420[] = { #endif #if CONFIG_MPEG2_VIDEOTOOLBOX_HWACCEL AV_PIX_FMT_VIDEOTOOLBOX, +#endif +#if CONFIG_MPEG2_NVTEGRA_HWACCEL + AV_PIX_FMT_NVTEGRA, #endif AV_PIX_FMT_YUV420P, AV_PIX_FMT_NONE @@ -2624,6 +2630,9 @@ const FFCodec ff_mpeg1video_decoder = { #endif #if CONFIG_MPEG1_VIDEOTOOLBOX_HWACCEL HWACCEL_VIDEOTOOLBOX(mpeg1), +#endif +#if CONFIG_MPEG1_NVTEGRA_HWACCEL + HWACCEL_NVTEGRA(mpeg1), #endif NULL }, @@ -2696,6 +2705,9 @@ const FFCodec ff_mpeg2video_decoder = { #endif #if CONFIG_MPEG2_VIDEOTOOLBOX_HWACCEL HWACCEL_VIDEOTOOLBOX(mpeg2), +#endif +#if CONFIG_MPEG2_NVTEGRA_HWACCEL + HWACCEL_NVTEGRA(mpeg2), #endif NULL }, diff --git a/libavcodec/nvtegra_mpeg12.c b/libavcodec/nvtegra_mpeg12.c new file mode 100644 index 0000000000..2206635a7d --- /dev/null +++ b/libavcodec/nvtegra_mpeg12.c @@ -0,0 +1,319 @@ +/* + * Copyright (c) 2024 averne + * + * 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 + +#include "avcodec.h" +#include "hwaccel_internal.h" +#include "internal.h" +#include "hwconfig.h" +#include "mpegvideo.h" +#include "mpegutils.h" +#include "decode.h" +#include "nvtegra_decode.h" + +#include "libavutil/pixdesc.h" +#include "libavutil/nvtegra_host1x.h" + +typedef struct NVTegraMPEG12DecodeContext { + FFNVTegraDecodeContext core; + + AVFrame *prev_frame, *next_frame; +} NVTegraMPEG12DecodeContext; + +/* Size (width, height) of a macroblock */ +#define MB_SIZE 16 + +static const uint8_t bitstream_end_sequence[16] = { + 0x00, 0x00, 0x01, 0xb7, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0xb7, 0x00, 0x00, 0x00, 0x00, +}; + +static int nvtegra_mpeg12_decode_uninit(AVCodecContext *avctx) { + NVTegraMPEG12DecodeContext *ctx = avctx->internal->hwaccel_priv_data; + + int err; + + av_log(avctx, AV_LOG_DEBUG, "Deinitializing NVTEGRA MPEG12 decoder\n"); + + err = ff_nvtegra_decode_uninit(avctx, &ctx->core); + if (err < 0) + return err; + + return 0; +} + +static int nvtegra_mpeg12_decode_init(AVCodecContext *avctx) { + NVTegraMPEG12DecodeContext *ctx = avctx->internal->hwaccel_priv_data; + + uint32_t num_slices; + int err; + + av_log(avctx, AV_LOG_DEBUG, "Initializing NVTEGRA MPEG12 decoder\n"); + + num_slices = (FFALIGN(avctx->coded_width, MB_SIZE) / MB_SIZE) * + (FFALIGN(avctx->coded_height, MB_SIZE) / MB_SIZE); + num_slices = FFMIN(num_slices, 8160); + + /* Ignored: histogram map, size 0x400 */ + ctx->core.pic_setup_off = 0; + ctx->core.status_off = FFALIGN(ctx->core.pic_setup_off + sizeof(nvdec_mpeg2_pic_s), + AV_NVTEGRA_MAP_ALIGN); + ctx->core.cmdbuf_off = FFALIGN(ctx->core.status_off + sizeof(nvdec_status_s), + AV_NVTEGRA_MAP_ALIGN); + ctx->core.slice_offsets_off = FFALIGN(ctx->core.cmdbuf_off + AV_NVTEGRA_MAP_ALIGN, + AV_NVTEGRA_MAP_ALIGN); + ctx->core.bitstream_off = FFALIGN(ctx->core.slice_offsets_off + num_slices * sizeof(uint32_t), + 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_num_slices = (ctx->core.bitstream_off - ctx->core.slice_offsets_off) / sizeof(uint32_t); + ctx->core.max_bitstream_size = ctx->core.input_map_size - ctx->core.bitstream_off; + + err = ff_nvtegra_decode_init(avctx, &ctx->core); + if (err < 0) + goto fail; + + return 0; + +fail: + nvtegra_mpeg12_decode_uninit(avctx); + return err; +} + +static void nvtegra_mpeg12_prepare_frame_setup(nvdec_mpeg2_pic_s *setup, MpegEncContext *s, + NVTegraMPEG12DecodeContext *ctx) +{ + *setup = (nvdec_mpeg2_pic_s){ + .gptimer_timeout_value = 0, /* Default value */ + + .FrameWidth = FFALIGN(s->width, MB_SIZE), + .FrameHeight = FFALIGN(s->height, MB_SIZE), + + .picture_structure = s->picture_structure, + .picture_coding_type = s->pict_type, + .intra_dc_precision = s->intra_dc_precision, + .frame_pred_frame_dct = s->frame_pred_frame_dct, + .concealment_motion_vectors = s->concealment_motion_vectors, + .intra_vlc_format = s->intra_vlc_format, + + .tileFormat = 0, /* TBL */ + .gob_height = 0, /* GOB_2 */ + + .f_code = { + s->mpeg_f_code[0][0], s->mpeg_f_code[0][1], + s->mpeg_f_code[1][0], s->mpeg_f_code[1][1], + }, + + .PicWidthInMbs = FFALIGN(s->width, MB_SIZE) / MB_SIZE, + .FrameHeightInMbs = FFALIGN(s->height, MB_SIZE) / MB_SIZE, + .pitch_luma = s->current_picture.f->linesize[0], + .pitch_chroma = s->current_picture.f->linesize[1], + .luma_top_offset = 0, + .luma_bot_offset = 0, + .luma_frame_offset = 0, + .chroma_top_offset = 0, + .chroma_bot_offset = 0, + .chroma_frame_offset = 0, + .alternate_scan = s->alternate_scan, + .secondfield = s->picture_structure != PICT_FRAME && !s->first_field, + .rounding_type = 0, + .q_scale_type = s->q_scale_type, + .top_field_first = s->top_field_first, + .full_pel_fwd_vector = (s->codec_id != AV_CODEC_ID_MPEG2VIDEO) ? s->full_pel[0] : 0, + .full_pel_bwd_vector = (s->codec_id != AV_CODEC_ID_MPEG2VIDEO) ? s->full_pel[1] : 0, + .output_memory_layout = 0, /* NV12 */ + .ref_memory_layout = { 0, 0 }, /* NV12 */ + }; + + for (int i = 0; i < FF_ARRAY_ELEMS(setup->quant_mat_8x8intra); ++i) { + setup->quant_mat_8x8intra [i] = (NvU8)s->intra_matrix[i]; + setup->quant_mat_8x8nonintra[i] = (NvU8)s->inter_matrix[i]; + } +} + +static int nvtegra_mpeg12_prepare_cmdbuf(AVNVTegraCmdbuf *cmdbuf, MpegEncContext *s, NVTegraMPEG12DecodeContext *ctx, + AVFrame *current_frame, AVFrame *prev_frame, AVFrame *next_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, codec_id; + + err = av_nvtegra_cmdbuf_begin(cmdbuf, HOST1X_CLASS_NVDEC); + if (err < 0) + return err; + + switch (s->codec_id) { + case AV_CODEC_ID_MPEG1VIDEO: + codec_id = NVC5B0_SET_CONTROL_PARAMS_CODEC_TYPE_MPEG1; + break; + case AV_CODEC_ID_MPEG2VIDEO: + codec_id = NVC5B0_SET_CONTROL_PARAMS_CODEC_TYPE_MPEG2; + break; + default: + return AVERROR(EINVAL); + } + + AV_NVTEGRA_PUSH_VALUE(cmdbuf, NVC5B0_SET_APPLICATION_ID, + AV_NVTEGRA_ENUM(NVC5B0_SET_APPLICATION_ID, ID, MPEG12)); + AV_NVTEGRA_PUSH_VALUE(cmdbuf, NVC5B0_SET_CONTROL_PARAMS, codec_id | + AV_NVTEGRA_VALUE(NVC5B0_SET_CONTROL_PARAMS, ERR_CONCEAL_ON, 1) | + AV_NVTEGRA_VALUE(NVC5B0_SET_CONTROL_PARAMS, GPTIMER_ON, 1)); + AV_NVTEGRA_PUSH_VALUE(cmdbuf, NVC5B0_SET_PICTURE_INDEX, + AV_NVTEGRA_VALUE(NVC5B0_SET_PICTURE_INDEX, INDEX, ctx->core.frame_idx)); + + AV_NVTEGRA_PUSH_RELOC(cmdbuf, NVC5B0_SET_DRV_PIC_SETUP_OFFSET, + input_map, ctx->core.pic_setup_off, NVHOST_RELOC_TYPE_DEFAULT); + AV_NVTEGRA_PUSH_RELOC(cmdbuf, NVC5B0_SET_IN_BUF_BASE_OFFSET, + input_map, ctx->core.bitstream_off, NVHOST_RELOC_TYPE_DEFAULT); + AV_NVTEGRA_PUSH_RELOC(cmdbuf, NVC5B0_SET_SLICE_OFFSETS_BUF_OFFSET, + input_map, ctx->core.slice_offsets_off, NVHOST_RELOC_TYPE_DEFAULT); + AV_NVTEGRA_PUSH_RELOC(cmdbuf, NVC5B0_SET_NVDEC_STATUS_OFFSET, + input_map, ctx->core.status_off, NVHOST_RELOC_TYPE_DEFAULT); + +#define PUSH_FRAME(fr, offset) ({ \ + AV_NVTEGRA_PUSH_RELOC(cmdbuf, NVC5B0_SET_PICTURE_LUMA_OFFSET0 + offset * 4, \ + av_nvtegra_frame_get_fbuf_map(fr), 0, NVHOST_RELOC_TYPE_DEFAULT); \ + AV_NVTEGRA_PUSH_RELOC(cmdbuf, NVC5B0_SET_PICTURE_CHROMA_OFFSET0 + offset * 4, \ + av_nvtegra_frame_get_fbuf_map(fr), fr->data[1] - fr->data[0], \ + NVHOST_RELOC_TYPE_DEFAULT); \ +}) + + PUSH_FRAME(current_frame, 0); + PUSH_FRAME(prev_frame, 1); + PUSH_FRAME(next_frame, 2); + + AV_NVTEGRA_PUSH_VALUE(cmdbuf, NVC5B0_EXECUTE, + AV_NVTEGRA_ENUM(NVC5B0_EXECUTE, AWAKEN, ENABLE)); + + err = av_nvtegra_cmdbuf_end(cmdbuf); + if (err < 0) + return err; + + return 0; +} + +static int nvtegra_mpeg12_start_frame(AVCodecContext *avctx, const uint8_t *buf, uint32_t buf_size) { + MpegEncContext *s = avctx->priv_data; + AVFrame *frame = s->current_picture.f; + FrameDecodeData *fdd = (FrameDecodeData *)frame->private_ref->data; + NVTegraMPEG12DecodeContext *ctx = avctx->internal->hwaccel_priv_data; + + FFNVTegraDecodeFrame *tf; + AVNVTegraMap *input_map; + uint8_t *mem; + int err; + + av_log(avctx, AV_LOG_DEBUG, "Starting MPEG12-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; + + tf = fdd->hwaccel_priv; + input_map = (AVNVTegraMap *)tf->input_map_ref->data; + mem = av_nvtegra_map_get_addr(input_map); + + nvtegra_mpeg12_prepare_frame_setup((nvdec_mpeg2_pic_s *)(mem + ctx->core.pic_setup_off), s, ctx); + + ctx->prev_frame = (s->pict_type != AV_PICTURE_TYPE_I) ? s->last_picture.f : frame; + ctx->next_frame = (s->pict_type == AV_PICTURE_TYPE_B) ? s->next_picture.f : frame; + + return 0; +} + +static int nvtegra_mpeg12_end_frame(AVCodecContext *avctx) { + MpegEncContext *s = avctx->priv_data; + NVTegraMPEG12DecodeContext *ctx = avctx->internal->hwaccel_priv_data; + AVFrame *frame = s->current_picture.f; + FrameDecodeData *fdd = (FrameDecodeData *)frame->private_ref->data; + FFNVTegraDecodeFrame *tf = fdd->hwaccel_priv; + + nvdec_mpeg2_pic_s *setup; + uint8_t *mem; + int err; + + av_log(avctx, AV_LOG_DEBUG, "Ending MPEG12-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 = (nvdec_mpeg2_pic_s *)(mem + ctx->core.pic_setup_off); + setup->stream_len = ctx->core.bitstream_len + sizeof(bitstream_end_sequence); + setup->slice_count = ctx->core.num_slices; + + err = nvtegra_mpeg12_prepare_cmdbuf(&ctx->core.cmdbuf, s, ctx, frame, + ctx->prev_frame, ctx->next_frame); + if (err < 0) + return err; + + return ff_nvtegra_end_frame(avctx, frame, &ctx->core, bitstream_end_sequence, + sizeof(bitstream_end_sequence)); +} + +static int nvtegra_mpeg12_decode_slice(AVCodecContext *avctx, const uint8_t *buf, uint32_t buf_size) { + MpegEncContext *s = avctx->priv_data; + AVFrame *frame = s->current_picture.f; + + return ff_nvtegra_decode_slice(avctx, frame, buf, buf_size, false); +} + +#if CONFIG_MPEG1_NVTEGRA_HWACCEL +const FFHWAccel ff_mpeg1_nvtegra_hwaccel = { + .p.name = "mpeg1_nvtegra", + .p.type = AVMEDIA_TYPE_VIDEO, + .p.id = AV_CODEC_ID_MPEG1VIDEO, + .p.pix_fmt = AV_PIX_FMT_NVTEGRA, + .start_frame = &nvtegra_mpeg12_start_frame, + .end_frame = &nvtegra_mpeg12_end_frame, + .decode_slice = &nvtegra_mpeg12_decode_slice, + .init = &nvtegra_mpeg12_decode_init, + .uninit = &nvtegra_mpeg12_decode_uninit, + .frame_params = &ff_nvtegra_frame_params, + .priv_data_size = sizeof(NVTegraMPEG12DecodeContext), + .caps_internal = HWACCEL_CAP_ASYNC_SAFE, +}; +#endif + +#if CONFIG_MPEG2_NVTEGRA_HWACCEL +const FFHWAccel ff_mpeg2_nvtegra_hwaccel = { + .p.name = "mpeg2_nvtegra", + .p.type = AVMEDIA_TYPE_VIDEO, + .p.id = AV_CODEC_ID_MPEG2VIDEO, + .p.pix_fmt = AV_PIX_FMT_NVTEGRA, + .start_frame = &nvtegra_mpeg12_start_frame, + .end_frame = &nvtegra_mpeg12_end_frame, + .decode_slice = &nvtegra_mpeg12_decode_slice, + .init = &nvtegra_mpeg12_decode_init, + .uninit = &nvtegra_mpeg12_decode_uninit, + .frame_params = &ff_nvtegra_frame_params, + .priv_data_size = sizeof(NVTegraMPEG12DecodeContext), + .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".