FFmpeg
Loading...
Searching...
No Matches
nvdec_vc1.c
Go to the documentation of this file.
1/*
2 * VC1 HW decode acceleration through NVDEC
3 *
4 * Copyright (c) 2017 Philip Langdale
5 *
6 * This file is part of FFmpeg.
7 *
8 * FFmpeg is free software; you can redistribute it and/or
9 * modify it under the terms of the GNU Lesser General Public
10 * License as published by the Free Software Foundation; either
11 * version 2.1 of the License, or (at your option) any later version.
12 *
13 * FFmpeg is distributed in the hope that it will be useful,
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
16 * Lesser General Public License for more details.
17 *
18 * You should have received a copy of the GNU Lesser General Public
19 * License along with FFmpeg; if not, write to the Free Software
20 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
21 */
22
23#include "config_components.h"
24
25#include "libavutil/mem.h"
26#include "avcodec.h"
27#include "hwaccel_internal.h"
28#include "internal.h"
29#include "nvdec.h"
30#include "decode.h"
31#include "vc1.h"
32
34 const AVBufferRef *buffer_ref,
35 const uint8_t *buffer, uint32_t size)
36{
37 VC1Context *v = avctx->priv_data;
38 MpegEncContext *s = &v->s;
39
41 CUVIDPICPARAMS *pp = &ctx->pic_params;
42 FrameDecodeData *fdd;
43 NVDECFrame *cf;
44 AVFrame *cur_frame = s->cur_pic.ptr->f;
45
46 int ret;
47
48 ret = ff_nvdec_start_frame(avctx, cur_frame);
49 if (ret < 0)
50 return ret;
51
52 fdd = cur_frame->private_ref;
53 cf = (NVDECFrame*)fdd->hwaccel_priv;
54
55 *pp = (CUVIDPICPARAMS) {
56 .PicWidthInMbs = (cur_frame->width + 15) / 16,
57 .FrameHeightInMbs = (cur_frame->height + 15) / 16,
58 .CurrPicIdx = cf->idx,
59 .field_pic_flag = v->field_mode,
60 .bottom_field_flag = v->cur_field_type,
61 .second_field = v->second_field,
62
63 .intra_pic_flag = s->pict_type == AV_PICTURE_TYPE_I ||
64 s->pict_type == AV_PICTURE_TYPE_BI,
65 .ref_pic_flag = s->pict_type == AV_PICTURE_TYPE_I ||
66 s->pict_type == AV_PICTURE_TYPE_P,
67
68 .CodecSpecific.vc1 = {
69 .ForwardRefIdx = ff_nvdec_get_ref_idx(s->last_pic.ptr ? s->last_pic.ptr->f : NULL),
70 .BackwardRefIdx = ff_nvdec_get_ref_idx(s->next_pic.ptr ? s->next_pic.ptr->f : NULL),
71 .FrameWidth = cur_frame->width,
72 .FrameHeight = cur_frame->height,
73
74 .intra_pic_flag = s->pict_type == AV_PICTURE_TYPE_I ||
75 s->pict_type == AV_PICTURE_TYPE_BI,
76 .ref_pic_flag = s->pict_type == AV_PICTURE_TYPE_I ||
77 s->pict_type == AV_PICTURE_TYPE_P,
78 .progressive_fcm = v->fcm == 0,
79
80 .profile = v->profile,
81 .postprocflag = v->postprocflag,
82 .pulldown = v->broadcast,
83 .interlace = v->interlace,
84 .tfcntrflag = v->tfcntrflag,
85 .finterpflag = v->finterpflag,
86 .psf = v->psf,
87 .multires = v->multires,
88 .syncmarker = v->resync_marker,
89 .rangered = v->rangered,
90 .maxbframes = v->max_b_frames,
91
92 .panscan_flag = v->panscanflag,
93 .refdist_flag = v->refdist_flag,
94 .extended_mv = v->extended_mv,
95 .dquant = v->dquant,
96 .vstransform = v->vstransform,
97 .loopfilter = v->loop_filter,
98 .fastuvmc = v->fastuvmc,
99 .overlap = v->overlap,
100 .quantizer = v->quantizer_mode,
101 .extended_dmv = v->extended_dmv,
102 .range_mapy_flag = v->range_mapy_flag,
103 .range_mapy = v->range_mapy,
104 .range_mapuv_flag = v->range_mapuv_flag,
105 .range_mapuv = v->range_mapuv,
106 .rangeredfrm = v->rangeredfrm,
107 }
108 };
109
110 return 0;
111}
112
113static int nvdec_vc1_decode_slice(AVCodecContext *avctx, const uint8_t *buffer,
114 uint32_t size)
115{
117 const VC1Context *v = avctx->priv_data;
118 uint32_t marker;
119 int marker_size;
120 void *tmp;
121
122 if (ctx->bitstream_len)
123 marker = VC1_CODE_SLICE;
124 else if (v->profile == PROFILE_ADVANCED && v->fcm == ILACE_FIELD && v->second_field)
125 marker = VC1_CODE_FIELD;
126 else
127 marker = VC1_CODE_FRAME;
128
129 /* Only insert the marker if not already present in the bitstream */
130 marker_size = (size >= sizeof(marker) && AV_RB32(buffer) != marker) ? sizeof(marker) : 0;
131
132 tmp = av_fast_realloc(ctx->bitstream_internal, &ctx->bitstream_allocated,
133 ctx->bitstream_len + size + marker_size);
134 if (!tmp)
135 return AVERROR(ENOMEM);
136 ctx->bitstream = ctx->bitstream_internal = tmp;
137
138 tmp = av_fast_realloc(ctx->slice_offsets, &ctx->slice_offsets_allocated,
139 (ctx->nb_slices + 1) * sizeof(*ctx->slice_offsets));
140 if (!tmp)
141 return AVERROR(ENOMEM);
142 ctx->slice_offsets = tmp;
143
144 if (marker_size)
145 AV_WB32(ctx->bitstream_internal + ctx->bitstream_len, marker);
146
147 memcpy(ctx->bitstream_internal + ctx->bitstream_len + marker_size, buffer, size);
148 ctx->slice_offsets[ctx->nb_slices] = ctx->bitstream_len;
149 ctx->bitstream_len += size + marker_size;
150 ctx->nb_slices++;
151
152 return 0;
153}
154
156 AVBufferRef *hw_frames_ctx,
157 enum AVPixelFormat hw_format)
158{
159 // Each frame can at most have one P and one B reference
160 return ff_nvdec_frame_params(avctx, hw_frames_ctx, hw_format, 2, 0);
161}
162
163#if CONFIG_VC1_NVDEC_HWACCEL || CONFIG_WMV3_NVDEC_HWACCEL
164static int nvdec_vc1_cuda_frame_params(AVCodecContext *avctx,
165 AVBufferRef *hw_frames_ctx)
166{
167 return nvdec_vc1_frame_params(avctx, hw_frames_ctx, AV_PIX_FMT_CUDA);
168}
169#endif
170
171#if CONFIG_VC1_NVDEC_HWACCEL
173 .p.name = "vc1_nvdec",
174 .p.type = AVMEDIA_TYPE_VIDEO,
175 .p.id = AV_CODEC_ID_VC1,
176 .p.pix_fmt = AV_PIX_FMT_CUDA,
177 .start_frame = nvdec_vc1_start_frame,
178 .end_frame = ff_nvdec_simple_end_frame,
179 .decode_slice = nvdec_vc1_decode_slice,
180 .frame_params = nvdec_vc1_cuda_frame_params,
181 .init = ff_nvdec_decode_init,
182 .uninit = ff_nvdec_decode_uninit,
183 .priv_data_size = sizeof(NVDECContext),
184};
185#endif
186
187#if CONFIG_VC1_NVDEC_CUARRAY_HWACCEL || CONFIG_WMV3_NVDEC_CUARRAY_HWACCEL
188static int nvdec_vc1_cuarray_frame_params(AVCodecContext *avctx,
189 AVBufferRef *hw_frames_ctx)
190{
191 return nvdec_vc1_frame_params(avctx, hw_frames_ctx, AV_PIX_FMT_CUARRAY);
192}
193#endif
194
195#if CONFIG_VC1_NVDEC_CUARRAY_HWACCEL
197 .p.name = "vc1_nvdec_cuarray",
198 .p.type = AVMEDIA_TYPE_VIDEO,
199 .p.id = AV_CODEC_ID_VC1,
200 .p.pix_fmt = AV_PIX_FMT_CUARRAY,
201 .start_frame = nvdec_vc1_start_frame,
202 .end_frame = ff_nvdec_simple_end_frame,
203 .decode_slice = nvdec_vc1_decode_slice,
204 .frame_params = nvdec_vc1_cuarray_frame_params,
205 .init = ff_nvdec_decode_init,
206 .uninit = ff_nvdec_decode_uninit,
207 .priv_data_size = sizeof(NVDECContext),
208};
209#endif
210
211#if CONFIG_WMV3_NVDEC_HWACCEL
213 .p.name = "wmv3_nvdec",
214 .p.type = AVMEDIA_TYPE_VIDEO,
215 .p.id = AV_CODEC_ID_WMV3,
216 .p.pix_fmt = AV_PIX_FMT_CUDA,
217 .start_frame = nvdec_vc1_start_frame,
218 .end_frame = ff_nvdec_simple_end_frame,
219 .decode_slice = ff_nvdec_simple_decode_slice,
220 .frame_params = nvdec_vc1_cuda_frame_params,
221 .init = ff_nvdec_decode_init,
222 .uninit = ff_nvdec_decode_uninit,
223 .priv_data_size = sizeof(NVDECContext),
224};
225#endif
226
227#if CONFIG_WMV3_NVDEC_CUARRAY_HWACCEL
229 .p.name = "wmv3_nvdec_cuarray",
230 .p.type = AVMEDIA_TYPE_VIDEO,
231 .p.id = AV_CODEC_ID_WMV3,
232 .p.pix_fmt = AV_PIX_FMT_CUARRAY,
233 .start_frame = nvdec_vc1_start_frame,
234 .end_frame = ff_nvdec_simple_end_frame,
235 .decode_slice = ff_nvdec_simple_decode_slice,
236 .frame_params = nvdec_vc1_cuarray_frame_params,
237 .init = ff_nvdec_decode_init,
238 .uninit = ff_nvdec_decode_uninit,
239 .priv_data_size = sizeof(NVDECContext),
240};
241#endif
Libavcodec external API header.
#define s(width, name)
Definition cbs_vp9.c:198
#define NULL
Definition coverity.c:32
@ AV_CODEC_ID_VC1
Definition codec_id.h:120
@ AV_CODEC_ID_WMV3
Definition codec_id.h:121
#define AVERROR(e)
Definition error.h:45
void * av_fast_realloc(void *ptr, unsigned int *size, size_t min_size)
Reallocate the given buffer if it is not large enough, otherwise do nothing.
Definition mem.c:495
@ AVMEDIA_TYPE_VIDEO
Definition avutil.h:200
@ AV_PICTURE_TYPE_I
Intra.
Definition avutil.h:278
@ AV_PICTURE_TYPE_BI
BI type.
Definition avutil.h:284
@ AV_PICTURE_TYPE_P
Predicted.
Definition avutil.h:279
const struct FFHWAccel ff_vc1_nvdec_cuarray_hwaccel
const struct FFHWAccel ff_vc1_nvdec_hwaccel
const struct FFHWAccel ff_wmv3_nvdec_cuarray_hwaccel
const struct FFHWAccel ff_wmv3_nvdec_hwaccel
#define AV_WB32(p, v)
#define AV_RB32(p)
common internal api header.
Memory handling functions.
int ff_nvdec_simple_end_frame(AVCodecContext *avctx)
Definition nvdec.c:1051
int ff_nvdec_simple_decode_slice(AVCodecContext *avctx, const uint8_t *buffer, uint32_t size)
Definition nvdec.c:1061
int ff_nvdec_decode_init(AVCodecContext *avctx)
Definition nvdec.c:404
int ff_nvdec_get_ref_idx(AVFrame *frame)
Definition nvdec.c:1180
int ff_nvdec_start_frame(AVCodecContext *avctx, AVFrame *frame)
Definition nvdec.c:946
int ff_nvdec_decode_uninit(AVCodecContext *avctx)
Definition nvdec.c:297
int ff_nvdec_frame_params(AVCodecContext *avctx, AVBufferRef *hw_frames_ctx, enum AVPixelFormat hw_format, int dpb_size, int supports_444)
Definition nvdec.c:1083
static int nvdec_vc1_frame_params(AVCodecContext *avctx, AVBufferRef *hw_frames_ctx, enum AVPixelFormat hw_format)
Definition nvdec_vc1.c:155
static int nvdec_vc1_start_frame(AVCodecContext *avctx, const AVBufferRef *buffer_ref, const uint8_t *buffer, uint32_t size)
Definition nvdec_vc1.c:33
static int nvdec_vc1_decode_slice(AVCodecContext *avctx, const uint8_t *buffer, uint32_t size)
Definition nvdec_vc1.c:113
AVPixelFormat
Pixel format.
Definition pixfmt.h:71
@ AV_PIX_FMT_CUDA
HW acceleration through CUDA.
Definition pixfmt.h:260
@ AV_PIX_FMT_CUARRAY
hardware decoding through openharmony
Definition pixfmt.h:506
A reference to a data buffer.
Definition buffer.h:82
main external API structure.
Definition avcodec.h:443
struct AVCodecInternal * internal
Private context used for internal data.
Definition avcodec.h:478
void * priv_data
Definition avcodec.h:470
void * hwaccel_priv_data
hwaccel-specific private data
Definition internal.h:130
This structure describes decoded (raw) audio or video data.
Definition frame.h:472
int width
Definition frame.h:544
int height
Definition frame.h:544
void * private_ref
RefStruct reference for internal use by a single libav* library.
Definition frame.h:810
This struct stores per-frame lavc-internal data and is attached to it via private_ref.
Definition decode.h:33
void * hwaccel_priv
Definition decode.h:54
MpegEncContext.
Definition mpegvideo.h:67
unsigned int idx
Definition nvdec.h:55
The VC1 Context.
Definition vc1.h:176
int loop_filter
Definition vc1.h:223
int tfcntrflag
TFCNTR present.
Definition vc1.h:204
int profile
Sequence header data for all Profiles TODO: choose between ints, uint8_ts and monobit flags.
Definition vc1.h:220
int dquant
How qscale varies with MBs, 2 bits (not in Simple)
Definition vc1.h:227
int multires
frame-level RESPIC syntax element present
Definition vc1.h:188
int finterpflag
INTERPFRM present.
Definition vc1.h:232
uint8_t range_mapuv_flag
Definition vc1.h:333
int extended_mv
Ext MV in P/B (not in Simple)
Definition vc1.h:226
uint8_t range_mapy_flag
Definition vc1.h:332
int second_field
Definition vc1.h:358
uint8_t range_mapy
Definition vc1.h:334
int extended_dmv
Additional extended dmv range at P/B-frame-level.
Definition vc1.h:207
int panscanflag
NUMPANSCANWIN, TOPLEFT{X,Y}, BOTRIGHT{X,Y} present.
Definition vc1.h:205
int psf
Progressive Segmented Frame.
Definition vc1.h:213
int field_mode
1 for interlaced field pictures
Definition vc1.h:356
uint8_t rangeredfrm
Frame decoding info for S/M profiles only.
Definition vc1.h:312
int quantizer_mode
2 bits, quantizer mode used for sequence, see QUANT_*
Definition vc1.h:231
int broadcast
TFF/RFF present.
Definition vc1.h:202
int refdist_flag
REFDIST syntax element present in II, IP, PI or PP field picture headers.
Definition vc1.h:206
int max_b_frames
max number of B-frames
Definition vc1.h:230
MpegEncContext s
Definition vc1.h:177
int overlap
overlapped transforms in use
Definition vc1.h:229
uint8_t range_mapuv
Definition vc1.h:335
int cur_field_type
0: top, 1: bottom
Definition vc1.h:366
int postprocflag
Per-frame processing suggestion flag present.
Definition vc1.h:201
enum FrameCodingMode fcm
Frame decoding info for Advanced profile.
Definition vc1.h:318
int interlace
Progressive/interlaced (RPTFTM syntax element)
Definition vc1.h:203
int resync_marker
could this stream contain resync markers
Definition vc1.h:404
int fastuvmc
Rounding of qpel vector to hpel ? (not in Simple)
Definition vc1.h:225
int rangered
RANGEREDFRM (range reduction) syntax element present at frame level.
Definition vc1.h:191
int vstransform
variable-size [48]x[48] transform type + info
Definition vc1.h:228
static uint8_t tmp[40]
Definition aes_ctr.c:52
static AVFormatContext * ctx
Definition movenc.c:49
static char buffer[20]
Definition seek.c:32
int size
@ ILACE_FIELD
in the bitstream is reported as 11b
Definition vc1.h:154
@ PROFILE_ADVANCED
Definition vc1_common.h:52
@ VC1_CODE_FIELD
Definition vc1_common.h:37
@ VC1_CODE_FRAME
Definition vc1_common.h:38
@ VC1_CODE_SLICE
Definition vc1_common.h:36