diff --git a/doc/APIchanges b/doc/APIchanges index bf4fe9419e..be2c8c65e1 100644 --- a/doc/APIchanges +++ b/doc/APIchanges @@ -2,6 +2,10 @@ The last version increases of all libraries were on 2023-02-09 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 Constify the AVFifo pointees in av_fifo_peek() and av_fifo_peek_to_cb(). diff --git a/doc/examples/demux_decode.c b/doc/examples/demux_decode.c index 298a369f43..f26611d8f4 100644 --- a/doc/examples/demux_decode.c +++ b/doc/examples/demux_decode.c @@ -78,9 +78,9 @@ static int output_video_frame(AVFrame *frame) /* copy decoded frame to destination buffer: * this is required since rawvideo expects non aligned data */ - av_image_copy(video_dst_data, video_dst_linesize, - (const uint8_t **)(frame->data), frame->linesize, - pix_fmt, width, height); + av_image_copy2(video_dst_data, video_dst_linesize, + frame->data, frame->linesize, + pix_fmt, width, height); /* write to rawvideo file */ fwrite(video_dst_data[0], 1, video_dst_bufsize, video_dst_file); diff --git a/libavcodec/amfenc.c b/libavcodec/amfenc.c index 518b8396e7..061859f85c 100644 --- a/libavcodec/amfenc.c +++ b/libavcodec/amfenc.c @@ -430,9 +430,9 @@ static int amf_copy_surface(AVCodecContext *avctx, const AVFrame *frame, dst_data[i] = plane->pVtbl->GetNative(plane); dst_linesize[i] = plane->pVtbl->GetHPitch(plane); } - av_image_copy(dst_data, dst_linesize, - (const uint8_t**)frame->data, frame->linesize, frame->format, - avctx->width, avctx->height); + av_image_copy2(dst_data, dst_linesize, + frame->data, frame->linesize, frame->format, + avctx->width, avctx->height); return 0; } diff --git a/libavcodec/libkvazaar.c b/libavcodec/libkvazaar.c index 2ef34dd82e..0ebf37607a 100644 --- a/libavcodec/libkvazaar.c +++ b/libavcodec/libkvazaar.c @@ -221,9 +221,9 @@ static int libkvazaar_encode(AVCodecContext *avctx, frame->width / 2, 0 }; - av_image_copy(dst, dst_linesizes, - (const uint8_t **)frame->data, frame->linesize, - frame->format, frame->width, frame->height); + av_image_copy2(dst, dst_linesizes, + frame->data, frame->linesize, + frame->format, frame->width, frame->height); } input_pic->pts = frame->pts; diff --git a/libavcodec/libopenh264dec.c b/libavcodec/libopenh264dec.c index af53219b41..7d650ae03e 100644 --- a/libavcodec/libopenh264dec.c +++ b/libavcodec/libopenh264dec.c @@ -141,7 +141,8 @@ static int svc_decode_frame(AVCodecContext *avctx, AVFrame *avframe, linesize[0] = info.UsrData.sSystemBuffer.iStride[0]; linesize[1] = linesize[2] = info.UsrData.sSystemBuffer.iStride[1]; 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->pkt_dts = AV_NOPTS_VALUE; diff --git a/libavcodec/libvpxdec.c b/libavcodec/libvpxdec.c index 40c8caf887..72ef5fa9a7 100644 --- a/libavcodec/libvpxdec.c +++ b/libavcodec/libvpxdec.c @@ -329,8 +329,8 @@ static int vpx_decode(AVCodecContext *avctx, AVFrame *picture, } else { if ((ret = ff_get_buffer(avctx, picture, 0)) < 0) return ret; - av_image_copy(picture->data, picture->linesize, (const uint8_t**)planes, - linesizes, avctx->pix_fmt, img->d_w, img->d_h); + av_image_copy2(picture->data, picture->linesize, planes, + linesizes, avctx->pix_fmt, img->d_w, img->d_h); } *got_frame = 1; } diff --git a/libavcodec/mediacodecenc.c b/libavcodec/mediacodecenc.c index 485ab7b4ed..a1ae5d5ec5 100644 --- a/libavcodec/mediacodecenc.c +++ b/libavcodec/mediacodecenc.c @@ -428,9 +428,6 @@ static void copy_frame_to_buffer(AVCodecContext *avctx, const AVFrame *frame, ui MediaCodecEncContext *s = avctx->priv_data; uint8_t *dst_data[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) { dst_data[0] = dst; @@ -449,8 +446,8 @@ static void copy_frame_to_buffer(AVCodecContext *avctx, const AVFrame *frame, ui av_assert0(0); } - av_image_copy(dst_data, dst_linesize, src_data, frame->linesize, - avctx->pix_fmt, avctx->width, avctx->height); + av_image_copy2(dst_data, dst_linesize, frame->data, frame->linesize, + avctx->pix_fmt, avctx->width, avctx->height); } static int mediacodec_send(AVCodecContext *avctx, diff --git a/libavcodec/mmaldec.c b/libavcodec/mmaldec.c index 8d67d10cd9..4bb3eb22ef 100644 --- a/libavcodec/mmaldec.c +++ b/libavcodec/mmaldec.c @@ -648,8 +648,8 @@ static int ffmal_copy_frame(AVCodecContext *avctx, AVFrame *frame, av_image_fill_arrays(src, linesize, buffer->data + buffer->type->video.offset[0], avctx->pix_fmt, w, h, 1); - av_image_copy(frame->data, frame->linesize, (const uint8_t **)src, linesize, - avctx->pix_fmt, avctx->width, avctx->height); + av_image_copy2(frame->data, frame->linesize, src, linesize, + avctx->pix_fmt, avctx->width, avctx->height); } frame->sample_aspect_ratio = avctx->sample_aspect_ratio; diff --git a/libavcodec/nuv.c b/libavcodec/nuv.c index 82048e9326..1dda770c97 100644 --- a/libavcodec/nuv.c +++ b/libavcodec/nuv.c @@ -56,8 +56,8 @@ static void copy_frame(AVFrame *f, const uint8_t *src, int width, int height) int src_linesize[4]; av_image_fill_arrays(src_data, src_linesize, src, f->format, width, height, 1); - av_image_copy(f->data, f->linesize, (const uint8_t **)src_data, src_linesize, - f->format, width, height); + av_image_copy2(f->data, f->linesize, src_data, src_linesize, + f->format, width, height); } /** diff --git a/libavcodec/nvenc.c b/libavcodec/nvenc.c index 9875f02dc8..65b96d6cf6 100644 --- a/libavcodec/nvenc.c +++ b/libavcodec/nvenc.c @@ -2008,9 +2008,9 @@ static int nvenc_copy_frame(AVCodecContext *avctx, NvencSurface *nv_surface, if (frame->format == AV_PIX_FMT_YUV420P) FFSWAP(uint8_t*, dst_data[1], dst_data[2]); - av_image_copy(dst_data, dst_linesize, - (const uint8_t**)frame->data, frame->linesize, frame->format, - avctx->width, avctx->height); + av_image_copy2(dst_data, dst_linesize, + frame->data, frame->linesize, frame->format, + avctx->width, avctx->height); return 0; } diff --git a/libavcodec/omx.c b/libavcodec/omx.c index 8d6519d141..82fd492071 100644 --- a/libavcodec/omx.c +++ b/libavcodec/omx.c @@ -793,7 +793,8 @@ static int omx_encode_frame(AVCodecContext *avctx, AVPacket *pkt, need_copy = 1; } 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->nOffset = 0; // Convert the timestamps to microseconds; some encoders can ignore diff --git a/libavcodec/v210dec.c b/libavcodec/v210dec.c index 04bcc612b7..d80fb4e7c6 100644 --- a/libavcodec/v210dec.c +++ b/libavcodec/v210dec.c @@ -201,7 +201,8 @@ static int decode_frame(AVCodecContext *avctx, AVFrame *pic, if (ret < 0) 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); - 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]); } diff --git a/libavdevice/xv.c b/libavdevice/xv.c index b3d79d57a8..cba933ef17 100644 --- a/libavdevice/xv.c +++ b/libavdevice/xv.c @@ -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, - xv->image_format, img->width, img->height); + av_image_copy2(data, img->pitches, input_data, linesize, + xv->image_format, img->width, img->height); return xv_repaint(s); } diff --git a/libavfilter/lavfutils.c b/libavfilter/lavfutils.c index 9aa781ef7b..6130f21e7f 100644 --- a/libavfilter/lavfutils.c +++ b/libavfilter/lavfutils.c @@ -117,7 +117,8 @@ int ff_load_image(uint8_t *data[4], int linesize[4], goto end; 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: avcodec_free_context(&codec_ctx); diff --git a/libavfilter/vf_framepack.c b/libavfilter/vf_framepack.c index 8693ad6488..cbfcf1e036 100644 --- a/libavfilter/vf_framepack.c +++ b/libavfilter/vf_framepack.c @@ -234,22 +234,18 @@ static void horizontal_frame_pack(AVFilterLink *outlink, } else { for (i = 0; i < 2; i++) { const int psize = 1 + (s->depth > 8); - const uint8_t *src[4]; uint8_t *dst[4]; 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[1] = out->data[1] + i * sub_w; dst[2] = out->data[2] + i * sub_w; - av_image_copy(dst, out->linesize, src, s->input_views[i]->linesize, - s->input_views[i]->format, - s->input_views[i]->width, - s->input_views[i]->height); + av_image_copy2(dst, out->linesize, + s->input_views[i]->data, s->input_views[i]->linesize, + s->input_views[i]->format, + s->input_views[i]->width, + s->input_views[i]->height); } } } @@ -263,15 +259,10 @@ static void vertical_frame_pack(AVFilterLink *outlink, int i; for (i = 0; i < 2; i++) { - const uint8_t *src[4]; uint8_t *dst[4]; int linesizes[4]; 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] * (interleaved + s->input_views[i]->height * (1 - interleaved)); 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] + interleaved * out->linesize[2]; - av_image_copy(dst, linesizes, src, s->input_views[i]->linesize, - s->input_views[i]->format, - s->input_views[i]->width, - s->input_views[i]->height); + av_image_copy2(dst, linesizes, + s->input_views[i]->data, s->input_views[i]->linesize, + s->input_views[i]->format, + s->input_views[i]->width, + s->input_views[i]->height); } } diff --git a/libavfilter/vf_pullup.c b/libavfilter/vf_pullup.c index 7245684085..14beb972c5 100644 --- a/libavfilter/vf_pullup.c +++ b/libavfilter/vf_pullup.c @@ -666,9 +666,9 @@ static int filter_frame(AVFilterLink *inlink, AVFrame *in) goto end; } - av_image_copy(b->planes, s->planewidth, - (const uint8_t**)in->data, in->linesize, - inlink->format, inlink->w, inlink->h); + av_image_copy2(b->planes, s->planewidth, + in->data, in->linesize, + inlink->format, inlink->w, inlink->h); p = (in->flags & AV_FRAME_FLAG_INTERLACED) ? !(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_image_copy(out->data, out->linesize, - (const uint8_t**)f->buffer->planes, s->planewidth, - inlink->format, inlink->w, inlink->h); + av_image_copy2(out->data, out->linesize, + f->buffer->planes, s->planewidth, + inlink->format, inlink->w, inlink->h); ret = ff_filter_frame(outlink, out); pullup_release_frame(f); diff --git a/libavfilter/yadif_common.c b/libavfilter/yadif_common.c index 561659e346..b26989f574 100644 --- a/libavfilter/yadif_common.c +++ b/libavfilter/yadif_common.c @@ -89,9 +89,9 @@ static void fixstride(AVFilterLink *link, AVFrame *f) if(!dst) return; av_frame_copy_props(dst, f); - av_image_copy(dst->data, dst->linesize, - (const uint8_t **)f->data, f->linesize, - dst->format, dst->width, dst->height); + av_image_copy2(dst->data, dst->linesize, + f->data, f->linesize, + dst->format, dst->width, dst->height); av_frame_unref(f); av_frame_move_ref(f, dst); av_frame_free(&dst); diff --git a/libavutil/frame.c b/libavutil/frame.c index b6cee2d886..a3f07ca089 100644 --- a/libavutil/frame.c +++ b/libavutil/frame.c @@ -833,7 +833,6 @@ AVFrameSideData *av_frame_get_side_data(const AVFrame *frame, static int frame_copy_video(AVFrame *dst, const AVFrame *src) { - const uint8_t *src_data[4]; int planes; 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]) return AVERROR(EINVAL); - memcpy(src_data, src->data, sizeof(src_data)); - av_image_copy(dst->data, dst->linesize, - src_data, src->linesize, - dst->format, src->width, src->height); + av_image_copy2(dst->data, dst->linesize, + src->data, src->linesize, + dst->format, src->width, src->height); return 0; } diff --git a/libavutil/hwcontext_d3d11va.c b/libavutil/hwcontext_d3d11va.c index aa50538d64..cc8c97d2b6 100644 --- a/libavutil/hwcontext_d3d11va.c +++ b/libavutil/hwcontext_d3d11va.c @@ -452,8 +452,8 @@ static int d3d11va_transfer_data(AVHWFramesContext *ctx, AVFrame *dst, fill_texture_ptrs(map_data, map_linesize, ctx, &desc, &map); - av_image_copy(dst->data, dst->linesize, (const uint8_t **)map_data, map_linesize, - ctx->sw_format, w, h); + av_image_copy2(dst->data, dst->linesize, map_data, map_linesize, + ctx->sw_format, w, h); ID3D11DeviceContext_Unmap(device_hwctx->device_context, staging, 0); } else { @@ -464,8 +464,8 @@ static int d3d11va_transfer_data(AVHWFramesContext *ctx, AVFrame *dst, fill_texture_ptrs(map_data, map_linesize, ctx, &desc, &map); - av_image_copy(map_data, map_linesize, (const uint8_t **)src->data, src->linesize, - ctx->sw_format, w, h); + av_image_copy2(map_data, map_linesize, src->data, src->linesize, + ctx->sw_format, w, h); ID3D11DeviceContext_Unmap(device_hwctx->device_context, staging, 0); diff --git a/libavutil/hwcontext_dxva2.c b/libavutil/hwcontext_dxva2.c index ea378df720..2c11f151ff 100644 --- a/libavutil/hwcontext_dxva2.c +++ b/libavutil/hwcontext_dxva2.c @@ -356,8 +356,8 @@ static int dxva2_transfer_data_to(AVHWFramesContext *ctx, AVFrame *dst, if (ret < 0) goto fail; - av_image_copy(map->data, map->linesize, (const uint8_t **)src->data, src->linesize, - ctx->sw_format, src->width, src->height); + av_image_copy2(map->data, map->linesize, src->data, src->linesize, + ctx->sw_format, src->width, src->height); fail: av_frame_free(&map); diff --git a/libavutil/imgutils.h b/libavutil/imgutils.h index 91312a72d3..fa3bb101b1 100644 --- a/libavutil/imgutils.h +++ b/libavutil/imgutils.h @@ -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], 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 * available, this function will use special functionality for reading from such diff --git a/libavutil/version.h b/libavutil/version.h index b9a86e50a1..132e5ffc84 100644 --- a/libavutil/version.h +++ b/libavutil/version.h @@ -79,7 +79,7 @@ */ #define LIBAVUTIL_VERSION_MAJOR 58 -#define LIBAVUTIL_VERSION_MINOR 23 +#define LIBAVUTIL_VERSION_MINOR 24 #define LIBAVUTIL_VERSION_MICRO 100 #define LIBAVUTIL_VERSION_INT AV_VERSION_INT(LIBAVUTIL_VERSION_MAJOR, \