avutil/imgutils: Add wrapper for av_image_copy() to avoid casts

av_image_copy() accepts const uint8_t* const * as source;
lots of user have uint8_t* const * and therefore either
cast (the majority) or copy the array of pointers.

This commit changes this by adding a static inline wrapper
for av_image_copy() that casts between the two types
so that we do not need to add casts everywhere else.

Signed-off-by: Andreas Rheinhardt <andreas.rheinhardt@outlook.com>
This commit is contained in:
Andreas Rheinhardt 2023-09-07 00:09:10 +02:00
parent 5094d1f429
commit 423b6a7e49
22 changed files with 79 additions and 68 deletions

View File

@ -2,6 +2,10 @@ The last version increases of all libraries were on 2023-02-09
API changes, most recent first: API changes, most recent first:
2023-09-07 - xxxxxxxxxx - lavu 58.24.100 - imgutils.h
Add av_image_copy2(), a wrapper around the av_image_copy()
to overcome limitations of automatic conversions.
2023-09-07 - xxxxxxxxxx - lavu 58.23.100 - fifo.h 2023-09-07 - xxxxxxxxxx - lavu 58.23.100 - fifo.h
Constify the AVFifo pointees in av_fifo_peek() and av_fifo_peek_to_cb(). Constify the AVFifo pointees in av_fifo_peek() and av_fifo_peek_to_cb().

View File

@ -78,9 +78,9 @@ static int output_video_frame(AVFrame *frame)
/* copy decoded frame to destination buffer: /* copy decoded frame to destination buffer:
* this is required since rawvideo expects non aligned data */ * this is required since rawvideo expects non aligned data */
av_image_copy(video_dst_data, video_dst_linesize, av_image_copy2(video_dst_data, video_dst_linesize,
(const uint8_t **)(frame->data), frame->linesize, frame->data, frame->linesize,
pix_fmt, width, height); pix_fmt, width, height);
/* write to rawvideo file */ /* write to rawvideo file */
fwrite(video_dst_data[0], 1, video_dst_bufsize, video_dst_file); fwrite(video_dst_data[0], 1, video_dst_bufsize, video_dst_file);

View File

@ -430,9 +430,9 @@ static int amf_copy_surface(AVCodecContext *avctx, const AVFrame *frame,
dst_data[i] = plane->pVtbl->GetNative(plane); dst_data[i] = plane->pVtbl->GetNative(plane);
dst_linesize[i] = plane->pVtbl->GetHPitch(plane); dst_linesize[i] = plane->pVtbl->GetHPitch(plane);
} }
av_image_copy(dst_data, dst_linesize, av_image_copy2(dst_data, dst_linesize,
(const uint8_t**)frame->data, frame->linesize, frame->format, frame->data, frame->linesize, frame->format,
avctx->width, avctx->height); avctx->width, avctx->height);
return 0; return 0;
} }

View File

@ -221,9 +221,9 @@ static int libkvazaar_encode(AVCodecContext *avctx,
frame->width / 2, frame->width / 2,
0 0
}; };
av_image_copy(dst, dst_linesizes, av_image_copy2(dst, dst_linesizes,
(const uint8_t **)frame->data, frame->linesize, frame->data, frame->linesize,
frame->format, frame->width, frame->height); frame->format, frame->width, frame->height);
} }
input_pic->pts = frame->pts; input_pic->pts = frame->pts;

View File

@ -141,7 +141,8 @@ static int svc_decode_frame(AVCodecContext *avctx, AVFrame *avframe,
linesize[0] = info.UsrData.sSystemBuffer.iStride[0]; linesize[0] = info.UsrData.sSystemBuffer.iStride[0];
linesize[1] = linesize[2] = info.UsrData.sSystemBuffer.iStride[1]; linesize[1] = linesize[2] = info.UsrData.sSystemBuffer.iStride[1];
linesize[3] = 0; linesize[3] = 0;
av_image_copy(avframe->data, avframe->linesize, (const uint8_t **) ptrs, linesize, avctx->pix_fmt, avctx->width, avctx->height); av_image_copy2(avframe->data, avframe->linesize, ptrs, linesize,
avctx->pix_fmt, avctx->width, avctx->height);
avframe->pts = info.uiOutYuvTimeStamp; avframe->pts = info.uiOutYuvTimeStamp;
avframe->pkt_dts = AV_NOPTS_VALUE; avframe->pkt_dts = AV_NOPTS_VALUE;

View File

@ -329,8 +329,8 @@ static int vpx_decode(AVCodecContext *avctx, AVFrame *picture,
} else { } else {
if ((ret = ff_get_buffer(avctx, picture, 0)) < 0) if ((ret = ff_get_buffer(avctx, picture, 0)) < 0)
return ret; return ret;
av_image_copy(picture->data, picture->linesize, (const uint8_t**)planes, av_image_copy2(picture->data, picture->linesize, planes,
linesizes, avctx->pix_fmt, img->d_w, img->d_h); linesizes, avctx->pix_fmt, img->d_w, img->d_h);
} }
*got_frame = 1; *got_frame = 1;
} }

View File

@ -428,9 +428,6 @@ static void copy_frame_to_buffer(AVCodecContext *avctx, const AVFrame *frame, ui
MediaCodecEncContext *s = avctx->priv_data; MediaCodecEncContext *s = avctx->priv_data;
uint8_t *dst_data[4] = {}; uint8_t *dst_data[4] = {};
int dst_linesize[4] = {}; int dst_linesize[4] = {};
const uint8_t *src_data[4] = {
frame->data[0], frame->data[1], frame->data[2], frame->data[3]
};
if (avctx->pix_fmt == AV_PIX_FMT_YUV420P) { if (avctx->pix_fmt == AV_PIX_FMT_YUV420P) {
dst_data[0] = dst; dst_data[0] = dst;
@ -449,8 +446,8 @@ static void copy_frame_to_buffer(AVCodecContext *avctx, const AVFrame *frame, ui
av_assert0(0); av_assert0(0);
} }
av_image_copy(dst_data, dst_linesize, src_data, frame->linesize, av_image_copy2(dst_data, dst_linesize, frame->data, frame->linesize,
avctx->pix_fmt, avctx->width, avctx->height); avctx->pix_fmt, avctx->width, avctx->height);
} }
static int mediacodec_send(AVCodecContext *avctx, static int mediacodec_send(AVCodecContext *avctx,

View File

@ -648,8 +648,8 @@ static int ffmal_copy_frame(AVCodecContext *avctx, AVFrame *frame,
av_image_fill_arrays(src, linesize, av_image_fill_arrays(src, linesize,
buffer->data + buffer->type->video.offset[0], buffer->data + buffer->type->video.offset[0],
avctx->pix_fmt, w, h, 1); avctx->pix_fmt, w, h, 1);
av_image_copy(frame->data, frame->linesize, (const uint8_t **)src, linesize, av_image_copy2(frame->data, frame->linesize, src, linesize,
avctx->pix_fmt, avctx->width, avctx->height); avctx->pix_fmt, avctx->width, avctx->height);
} }
frame->sample_aspect_ratio = avctx->sample_aspect_ratio; frame->sample_aspect_ratio = avctx->sample_aspect_ratio;

View File

@ -56,8 +56,8 @@ static void copy_frame(AVFrame *f, const uint8_t *src, int width, int height)
int src_linesize[4]; int src_linesize[4];
av_image_fill_arrays(src_data, src_linesize, src, av_image_fill_arrays(src_data, src_linesize, src,
f->format, width, height, 1); f->format, width, height, 1);
av_image_copy(f->data, f->linesize, (const uint8_t **)src_data, src_linesize, av_image_copy2(f->data, f->linesize, src_data, src_linesize,
f->format, width, height); f->format, width, height);
} }
/** /**

View File

@ -2008,9 +2008,9 @@ static int nvenc_copy_frame(AVCodecContext *avctx, NvencSurface *nv_surface,
if (frame->format == AV_PIX_FMT_YUV420P) if (frame->format == AV_PIX_FMT_YUV420P)
FFSWAP(uint8_t*, dst_data[1], dst_data[2]); FFSWAP(uint8_t*, dst_data[1], dst_data[2]);
av_image_copy(dst_data, dst_linesize, av_image_copy2(dst_data, dst_linesize,
(const uint8_t**)frame->data, frame->linesize, frame->format, frame->data, frame->linesize, frame->format,
avctx->width, avctx->height); avctx->width, avctx->height);
return 0; return 0;
} }

View File

@ -793,7 +793,8 @@ static int omx_encode_frame(AVCodecContext *avctx, AVPacket *pkt,
need_copy = 1; need_copy = 1;
} }
if (need_copy) if (need_copy)
av_image_copy(dst, linesize, (const uint8_t**) frame->data, frame->linesize, avctx->pix_fmt, avctx->width, avctx->height); av_image_copy2(dst, linesize, frame->data, frame->linesize,
avctx->pix_fmt, avctx->width, avctx->height);
buffer->nFlags = OMX_BUFFERFLAG_ENDOFFRAME; buffer->nFlags = OMX_BUFFERFLAG_ENDOFFRAME;
buffer->nOffset = 0; buffer->nOffset = 0;
// Convert the timestamps to microseconds; some encoders can ignore // Convert the timestamps to microseconds; some encoders can ignore

View File

@ -201,7 +201,8 @@ static int decode_frame(AVCodecContext *avctx, AVFrame *pic,
if (ret < 0) if (ret < 0)
return ret; return ret;
decode_row((const uint32_t *)psrc, (uint16_t *)pointers[0], (uint16_t *)pointers[1], (uint16_t *)pointers[2], avctx->width * avctx->height, s->unpack_frame); decode_row((const uint32_t *)psrc, (uint16_t *)pointers[0], (uint16_t *)pointers[1], (uint16_t *)pointers[2], avctx->width * avctx->height, s->unpack_frame);
av_image_copy(pic->data, pic->linesize, (const uint8_t **)pointers, linesizes, avctx->pix_fmt, avctx->width, avctx->height); av_image_copy2(pic->data, pic->linesize, pointers, linesizes,
avctx->pix_fmt, avctx->width, avctx->height);
av_freep(&pointers[0]); av_freep(&pointers[0]);
} }

View File

@ -315,8 +315,8 @@ static int write_picture(AVFormatContext *s, uint8_t *input_data[4],
} }
} }
av_image_copy(data, img->pitches, (const uint8_t **)input_data, linesize, av_image_copy2(data, img->pitches, input_data, linesize,
xv->image_format, img->width, img->height); xv->image_format, img->width, img->height);
return xv_repaint(s); return xv_repaint(s);
} }

View File

@ -117,7 +117,8 @@ int ff_load_image(uint8_t *data[4], int linesize[4],
goto end; goto end;
ret = 0; ret = 0;
av_image_copy(data, linesize, (const uint8_t **)frame->data, frame->linesize, *pix_fmt, *w, *h); av_image_copy2(data, linesize, frame->data, frame->linesize,
*pix_fmt, *w, *h);
end: end:
avcodec_free_context(&codec_ctx); avcodec_free_context(&codec_ctx);

View File

@ -234,22 +234,18 @@ static void horizontal_frame_pack(AVFilterLink *outlink,
} else { } else {
for (i = 0; i < 2; i++) { for (i = 0; i < 2; i++) {
const int psize = 1 + (s->depth > 8); const int psize = 1 + (s->depth > 8);
const uint8_t *src[4];
uint8_t *dst[4]; uint8_t *dst[4];
int sub_w = psize * s->input_views[i]->width >> s->pix_desc->log2_chroma_w; int sub_w = psize * s->input_views[i]->width >> s->pix_desc->log2_chroma_w;
src[0] = s->input_views[i]->data[0];
src[1] = s->input_views[i]->data[1];
src[2] = s->input_views[i]->data[2];
dst[0] = out->data[0] + i * s->input_views[i]->width * psize; dst[0] = out->data[0] + i * s->input_views[i]->width * psize;
dst[1] = out->data[1] + i * sub_w; dst[1] = out->data[1] + i * sub_w;
dst[2] = out->data[2] + i * sub_w; dst[2] = out->data[2] + i * sub_w;
av_image_copy(dst, out->linesize, src, s->input_views[i]->linesize, av_image_copy2(dst, out->linesize,
s->input_views[i]->format, s->input_views[i]->data, s->input_views[i]->linesize,
s->input_views[i]->width, s->input_views[i]->format,
s->input_views[i]->height); s->input_views[i]->width,
s->input_views[i]->height);
} }
} }
} }
@ -263,15 +259,10 @@ static void vertical_frame_pack(AVFilterLink *outlink,
int i; int i;
for (i = 0; i < 2; i++) { for (i = 0; i < 2; i++) {
const uint8_t *src[4];
uint8_t *dst[4]; uint8_t *dst[4];
int linesizes[4]; int linesizes[4];
int sub_h = s->input_views[i]->height >> s->pix_desc->log2_chroma_h; int sub_h = s->input_views[i]->height >> s->pix_desc->log2_chroma_h;
src[0] = s->input_views[i]->data[0];
src[1] = s->input_views[i]->data[1];
src[2] = s->input_views[i]->data[2];
dst[0] = out->data[0] + i * out->linesize[0] * dst[0] = out->data[0] + i * out->linesize[0] *
(interleaved + s->input_views[i]->height * (1 - interleaved)); (interleaved + s->input_views[i]->height * (1 - interleaved));
dst[1] = out->data[1] + i * out->linesize[1] * dst[1] = out->data[1] + i * out->linesize[1] *
@ -286,10 +277,11 @@ static void vertical_frame_pack(AVFilterLink *outlink,
linesizes[2] = out->linesize[2] + linesizes[2] = out->linesize[2] +
interleaved * out->linesize[2]; interleaved * out->linesize[2];
av_image_copy(dst, linesizes, src, s->input_views[i]->linesize, av_image_copy2(dst, linesizes,
s->input_views[i]->format, s->input_views[i]->data, s->input_views[i]->linesize,
s->input_views[i]->width, s->input_views[i]->format,
s->input_views[i]->height); s->input_views[i]->width,
s->input_views[i]->height);
} }
} }

View File

@ -666,9 +666,9 @@ static int filter_frame(AVFilterLink *inlink, AVFrame *in)
goto end; goto end;
} }
av_image_copy(b->planes, s->planewidth, av_image_copy2(b->planes, s->planewidth,
(const uint8_t**)in->data, in->linesize, in->data, in->linesize,
inlink->format, inlink->w, inlink->h); inlink->format, inlink->w, inlink->h);
p = (in->flags & AV_FRAME_FLAG_INTERLACED) ? p = (in->flags & AV_FRAME_FLAG_INTERLACED) ?
!(in->flags & AV_FRAME_FLAG_TOP_FIELD_FIRST) : 0; !(in->flags & AV_FRAME_FLAG_TOP_FIELD_FIRST) : 0;
@ -714,9 +714,9 @@ static int filter_frame(AVFilterLink *inlink, AVFrame *in)
} }
av_frame_copy_props(out, in); av_frame_copy_props(out, in);
av_image_copy(out->data, out->linesize, av_image_copy2(out->data, out->linesize,
(const uint8_t**)f->buffer->planes, s->planewidth, f->buffer->planes, s->planewidth,
inlink->format, inlink->w, inlink->h); inlink->format, inlink->w, inlink->h);
ret = ff_filter_frame(outlink, out); ret = ff_filter_frame(outlink, out);
pullup_release_frame(f); pullup_release_frame(f);

View File

@ -89,9 +89,9 @@ static void fixstride(AVFilterLink *link, AVFrame *f)
if(!dst) if(!dst)
return; return;
av_frame_copy_props(dst, f); av_frame_copy_props(dst, f);
av_image_copy(dst->data, dst->linesize, av_image_copy2(dst->data, dst->linesize,
(const uint8_t **)f->data, f->linesize, f->data, f->linesize,
dst->format, dst->width, dst->height); dst->format, dst->width, dst->height);
av_frame_unref(f); av_frame_unref(f);
av_frame_move_ref(f, dst); av_frame_move_ref(f, dst);
av_frame_free(&dst); av_frame_free(&dst);

View File

@ -833,7 +833,6 @@ AVFrameSideData *av_frame_get_side_data(const AVFrame *frame,
static int frame_copy_video(AVFrame *dst, const AVFrame *src) static int frame_copy_video(AVFrame *dst, const AVFrame *src)
{ {
const uint8_t *src_data[4];
int planes; int planes;
if (dst->width < src->width || if (dst->width < src->width ||
@ -848,10 +847,9 @@ static int frame_copy_video(AVFrame *dst, const AVFrame *src)
if (!dst->data[i] || !src->data[i]) if (!dst->data[i] || !src->data[i])
return AVERROR(EINVAL); return AVERROR(EINVAL);
memcpy(src_data, src->data, sizeof(src_data)); av_image_copy2(dst->data, dst->linesize,
av_image_copy(dst->data, dst->linesize, src->data, src->linesize,
src_data, src->linesize, dst->format, src->width, src->height);
dst->format, src->width, src->height);
return 0; return 0;
} }

View File

@ -452,8 +452,8 @@ static int d3d11va_transfer_data(AVHWFramesContext *ctx, AVFrame *dst,
fill_texture_ptrs(map_data, map_linesize, ctx, &desc, &map); fill_texture_ptrs(map_data, map_linesize, ctx, &desc, &map);
av_image_copy(dst->data, dst->linesize, (const uint8_t **)map_data, map_linesize, av_image_copy2(dst->data, dst->linesize, map_data, map_linesize,
ctx->sw_format, w, h); ctx->sw_format, w, h);
ID3D11DeviceContext_Unmap(device_hwctx->device_context, staging, 0); ID3D11DeviceContext_Unmap(device_hwctx->device_context, staging, 0);
} else { } else {
@ -464,8 +464,8 @@ static int d3d11va_transfer_data(AVHWFramesContext *ctx, AVFrame *dst,
fill_texture_ptrs(map_data, map_linesize, ctx, &desc, &map); fill_texture_ptrs(map_data, map_linesize, ctx, &desc, &map);
av_image_copy(map_data, map_linesize, (const uint8_t **)src->data, src->linesize, av_image_copy2(map_data, map_linesize, src->data, src->linesize,
ctx->sw_format, w, h); ctx->sw_format, w, h);
ID3D11DeviceContext_Unmap(device_hwctx->device_context, staging, 0); ID3D11DeviceContext_Unmap(device_hwctx->device_context, staging, 0);

View File

@ -356,8 +356,8 @@ static int dxva2_transfer_data_to(AVHWFramesContext *ctx, AVFrame *dst,
if (ret < 0) if (ret < 0)
goto fail; goto fail;
av_image_copy(map->data, map->linesize, (const uint8_t **)src->data, src->linesize, av_image_copy2(map->data, map->linesize, src->data, src->linesize,
ctx->sw_format, src->width, src->height); ctx->sw_format, src->width, src->height);
fail: fail:
av_frame_free(&map); av_frame_free(&map);

View File

@ -174,6 +174,22 @@ void av_image_copy(uint8_t * const dst_data[4], const int dst_linesizes[4],
const uint8_t * const src_data[4], const int src_linesizes[4], const uint8_t * const src_data[4], const int src_linesizes[4],
enum AVPixelFormat pix_fmt, int width, int height); enum AVPixelFormat pix_fmt, int width, int height);
/**
* Wrapper around av_image_copy() to workaround the limitation
* that the conversion from uint8_t * const * to const uint8_t * const *
* is not performed automatically in C.
* @see av_image_copy()
*/
static inline
void av_image_copy2(uint8_t * const dst_data[4], const int dst_linesizes[4],
uint8_t * const src_data[4], const int src_linesizes[4],
enum AVPixelFormat pix_fmt, int width, int height)
{
av_image_copy(dst_data, dst_linesizes,
(const uint8_t * const *)src_data, src_linesizes,
pix_fmt, width, height);
}
/** /**
* Copy image data located in uncacheable (e.g. GPU mapped) memory. Where * Copy image data located in uncacheable (e.g. GPU mapped) memory. Where
* available, this function will use special functionality for reading from such * available, this function will use special functionality for reading from such

View File

@ -79,7 +79,7 @@
*/ */
#define LIBAVUTIL_VERSION_MAJOR 58 #define LIBAVUTIL_VERSION_MAJOR 58
#define LIBAVUTIL_VERSION_MINOR 23 #define LIBAVUTIL_VERSION_MINOR 24
#define LIBAVUTIL_VERSION_MICRO 100 #define LIBAVUTIL_VERSION_MICRO 100
#define LIBAVUTIL_VERSION_INT AV_VERSION_INT(LIBAVUTIL_VERSION_MAJOR, \ #define LIBAVUTIL_VERSION_INT AV_VERSION_INT(LIBAVUTIL_VERSION_MAJOR, \