[FFmpeg-devel] [PATCH 17/39] avcodec/libxavs: Avoid overallocating, copying packet data
James Almer
jamrial at gmail.com
Fri May 21 15:55:46 EEST 2021
On 5/21/2021 6:17 AM, Andreas Rheinhardt wrote:
> When the packet size is known in advance like here, one can avoid
> an intermediate buffer for the packet data; also, there is no reason
> to add AV_INPUT_BUFFER_MIN_SIZE to the packet size any more, as the
> actually needed packet size can be easily calculated: It is three bytes
> more than the raw nal size per NALU.
>
> Signed-off-by: Andreas Rheinhardt <andreas.rheinhardt at outlook.com>
> ---
> libavcodec/libxavs.c | 20 +++++++++++++-------
> 1 file changed, 13 insertions(+), 7 deletions(-)
>
> diff --git a/libavcodec/libxavs.c b/libavcodec/libxavs.c
> index 253f4bde6a..ea53c49d38 100644
> --- a/libavcodec/libxavs.c
> +++ b/libavcodec/libxavs.c
> @@ -27,6 +27,7 @@
> #include <float.h>
> #include <xavs.h>
> #include "avcodec.h"
> +#include "encode.h"
> #include "internal.h"
> #include "packet_internal.h"
> #include "libavutil/internal.h"
> @@ -85,18 +86,20 @@ static int encode_nals(AVCodecContext *ctx, AVPacket *pkt,
> xavs_nal_t *nals, int nnal)
> {
> XavsContext *x4 = ctx->priv_data;
> - uint8_t *p;
> - int i, s, ret, size = x4->sei_size + AV_INPUT_BUFFER_MIN_SIZE;
> + int64_t size = x4->sei_size;
> + uint8_t *p, *p_end;
> + int i, s, ret;
>
> if (!nnal)
> return 0;
>
> for (i = 0; i < nnal; i++)
> - size += nals[i].i_payload;
> + size += 3U + nals[i].i_payload;
>
> - if ((ret = ff_alloc_packet2(ctx, pkt, size, 0)) < 0)
> + if ((ret = ff_get_encode_buffer(ctx, pkt, size, 0)) < 0)
> return ret;
> p = pkt->data;
> + p_end = pkt->data + size;
>
> /* Write the SEI as part of the first frame. */
> if (x4->sei_size > 0 && nnal > 0) {
> @@ -106,12 +109,14 @@ static int encode_nals(AVCodecContext *ctx, AVPacket *pkt,
> }
>
> for (i = 0; i < nnal; i++) {
> + int size = p_end - p;
> s = xavs_nal_encode(p, &size, 1, nals + i);
> if (s < 0)
> return -1;
> + if (s != 3U + nals[i].i_payload)
> + return AVERROR_BUG;
AVERROR_EXTERNAL. This is not a bug in our code or something we can fix
if it fails, so AVERROR_BUG is not correct (Neither would an assert for
the same reason).
> p += s;
> }
> - pkt->size = p - pkt->data;
>
> return 1;
> }
> @@ -150,7 +155,7 @@ static int XAVS_frame(AVCodecContext *avctx, AVPacket *pkt,
>
> if (!ret) {
> if (!frame && !(x4->end_of_stream)) {
> - if ((ret = ff_alloc_packet2(avctx, pkt, 4, 0)) < 0)
> + if ((ret = ff_get_encode_buffer(avctx, pkt, 4, 0)) < 0)
> return ret;
>
> pkt->data[0] = 0x0;
> @@ -425,7 +430,8 @@ const AVCodec ff_libxavs_encoder = {
> .init = XAVS_init,
> .encode2 = XAVS_frame,
> .close = XAVS_close,
> - .capabilities = AV_CODEC_CAP_DELAY | AV_CODEC_CAP_OTHER_THREADS,
> + .capabilities = AV_CODEC_CAP_DR1 | AV_CODEC_CAP_DELAY |
> + AV_CODEC_CAP_OTHER_THREADS,
> .caps_internal = FF_CODEC_CAP_AUTO_THREADS,
> .pix_fmts = (const enum AVPixelFormat[]) { AV_PIX_FMT_YUV420P, AV_PIX_FMT_NONE },
> .priv_class = &xavs_class,
>
More information about the ffmpeg-devel
mailing list