Skip to content

Commit 8eac960

Browse files
committed
avutil/hwcontext_cuda: use generic size and pointer assignment functions
1 parent b7f04a8 commit 8eac960

File tree

1 file changed

+15
-66
lines changed

1 file changed

+15
-66
lines changed

libavutil/hwcontext_cuda.c

Lines changed: 15 additions & 66 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,7 @@
2424
#include "mem.h"
2525
#include "pixdesc.h"
2626
#include "pixfmt.h"
27+
#include "imgutils.h"
2728

2829
#define CUDA_FRAME_ALIGNMENT 256
2930

@@ -117,7 +118,6 @@ static AVBufferRef *cuda_pool_alloc(void *opaque, int size)
117118
static int cuda_frames_init(AVHWFramesContext *ctx)
118119
{
119120
CUDAFramesContext *priv = ctx->internal->priv;
120-
int aligned_width = FFALIGN(ctx->width, CUDA_FRAME_ALIGNMENT);
121121
int i;
122122

123123
for (i = 0; i < FF_ARRAY_ELEMS(supported_formats); i++) {
@@ -133,29 +133,10 @@ static int cuda_frames_init(AVHWFramesContext *ctx)
133133
av_pix_fmt_get_chroma_sub_sample(ctx->sw_format, &priv->shift_width, &priv->shift_height);
134134

135135
if (!ctx->pool) {
136-
int size;
136+
int size = av_image_get_buffer_size(ctx->sw_format, ctx->width, ctx->height, CUDA_FRAME_ALIGNMENT);
137137

138-
switch (ctx->sw_format) {
139-
case AV_PIX_FMT_NV12:
140-
case AV_PIX_FMT_YUV420P:
141-
size = aligned_width * ctx->height * 3 / 2;
142-
break;
143-
case AV_PIX_FMT_YUV444P:
144-
case AV_PIX_FMT_P010:
145-
case AV_PIX_FMT_P016:
146-
size = aligned_width * ctx->height * 3;
147-
break;
148-
case AV_PIX_FMT_YUV444P16:
149-
size = aligned_width * ctx->height * 6;
150-
break;
151-
case AV_PIX_FMT_0RGB32:
152-
case AV_PIX_FMT_0BGR32:
153-
size = aligned_width * ctx->height * 4;
154-
break;
155-
default:
156-
av_log(ctx, AV_LOG_ERROR, "BUG: Pixel format missing from size calculation.");
157-
return AVERROR_BUG;
158-
}
138+
if (size < 0)
139+
return size;
159140

160141
ctx->internal->pool_internal = av_buffer_pool_init2(size, ctx, cuda_pool_alloc, NULL);
161142
if (!ctx->internal->pool_internal)
@@ -167,54 +148,22 @@ static int cuda_frames_init(AVHWFramesContext *ctx)
167148

168149
static int cuda_get_buffer(AVHWFramesContext *ctx, AVFrame *frame)
169150
{
170-
int aligned_width;
171-
int width_in_bytes = ctx->width;
172-
173-
if (ctx->sw_format == AV_PIX_FMT_P010 ||
174-
ctx->sw_format == AV_PIX_FMT_P016 ||
175-
ctx->sw_format == AV_PIX_FMT_YUV444P16) {
176-
width_in_bytes *= 2;
177-
}
178-
aligned_width = FFALIGN(width_in_bytes, CUDA_FRAME_ALIGNMENT);
151+
int res;
179152

180153
frame->buf[0] = av_buffer_pool_get(ctx->pool);
181154
if (!frame->buf[0])
182155
return AVERROR(ENOMEM);
183156

184-
switch (ctx->sw_format) {
185-
case AV_PIX_FMT_NV12:
186-
case AV_PIX_FMT_P010:
187-
case AV_PIX_FMT_P016:
188-
frame->data[0] = frame->buf[0]->data;
189-
frame->data[1] = frame->data[0] + aligned_width * ctx->height;
190-
frame->linesize[0] = aligned_width;
191-
frame->linesize[1] = aligned_width;
192-
break;
193-
case AV_PIX_FMT_YUV420P:
194-
frame->data[0] = frame->buf[0]->data;
195-
frame->data[2] = frame->data[0] + aligned_width * ctx->height;
196-
frame->data[1] = frame->data[2] + aligned_width * ctx->height / 4;
197-
frame->linesize[0] = aligned_width;
198-
frame->linesize[1] = aligned_width / 2;
199-
frame->linesize[2] = aligned_width / 2;
200-
break;
201-
case AV_PIX_FMT_YUV444P:
202-
case AV_PIX_FMT_YUV444P16:
203-
frame->data[0] = frame->buf[0]->data;
204-
frame->data[1] = frame->data[0] + aligned_width * ctx->height;
205-
frame->data[2] = frame->data[1] + aligned_width * ctx->height;
206-
frame->linesize[0] = aligned_width;
207-
frame->linesize[1] = aligned_width;
208-
frame->linesize[2] = aligned_width;
209-
break;
210-
case AV_PIX_FMT_0BGR32:
211-
case AV_PIX_FMT_0RGB32:
212-
frame->data[0] = frame->buf[0]->data;
213-
frame->linesize[0] = aligned_width * 4;
214-
break;
215-
default:
216-
av_frame_unref(frame);
217-
return AVERROR_BUG;
157+
res = av_image_fill_arrays(frame->data, frame->linesize, frame->buf[0]->data,
158+
ctx->sw_format, ctx->width, ctx->height, CUDA_FRAME_ALIGNMENT);
159+
if (res < 0)
160+
return res;
161+
162+
// YUV420P is a special case.
163+
// Nvenc expects the U/V planes in swapped order from how ffmpeg expects them.
164+
if (ctx->sw_format == AV_PIX_FMT_YUV420P) {
165+
FFSWAP(uint8_t*, frame->data[1], frame->data[2]);
166+
FFSWAP(int, frame->linesize[1], frame->linesize[2]);
218167
}
219168

220169
frame->format = AV_PIX_FMT_CUDA;

0 commit comments

Comments
 (0)