summaryrefslogtreecommitdiff
path: root/libavcodec/encode.c
diff options
context:
space:
mode:
authorJames Almer <jamrial@gmail.com>2021-02-20 16:01:52 -0300
committerJames Almer <jamrial@gmail.com>2021-03-12 19:49:08 -0300
commit6e7e3a3820f0888ff92d6be44f40ff733bcce874 (patch)
treef057b934848eeb52d019213018b4fedaeafd61f6 /libavcodec/encode.c
parent2c96e6cb955af3062e78c5b0f9fb907cfb2e59e3 (diff)
avcodec: add a get_encode_buffer() callback to AVCodecContext
This callback is functionally the same as get_buffer2() is for decoders, and implements for the new encode API the functionality of the old encode API had where the user could provide their own buffers. Reviewed-by: Lynne <dev@lynne.ee> Reviewed-by: Michael Niedermayer <michael@niedermayer.cc> Reviewed-by: Mark Thompson <sw@jkqxz.net> Signed-off-by: James Almer <jamrial@gmail.com>
Diffstat (limited to 'libavcodec/encode.c')
-rw-r--r--libavcodec/encode.c59
1 files changed, 59 insertions, 0 deletions
diff --git a/libavcodec/encode.c b/libavcodec/encode.c
index 282337e453..abec818eb9 100644
--- a/libavcodec/encode.c
+++ b/libavcodec/encode.c
@@ -56,6 +56,59 @@ int ff_alloc_packet2(AVCodecContext *avctx, AVPacket *avpkt, int64_t size, int64
return 0;
}
+int avcodec_default_get_encode_buffer(AVCodecContext *avctx, AVPacket *avpkt, int flags)
+{
+ int ret;
+
+ if (avpkt->size < 0 || avpkt->size > INT_MAX - AV_INPUT_BUFFER_PADDING_SIZE)
+ return AVERROR(EINVAL);
+
+ if (avpkt->data || avpkt->buf) {
+ av_log(avctx, AV_LOG_ERROR, "avpkt->{data,buf} != NULL in avcodec_default_get_encode_buffer()\n");
+ return AVERROR(EINVAL);
+ }
+
+ ret = av_buffer_realloc(&avpkt->buf, avpkt->size + AV_INPUT_BUFFER_PADDING_SIZE);
+ if (ret < 0) {
+ av_log(avctx, AV_LOG_ERROR, "Failed to allocate packet of size %d\n", avpkt->size);
+ return ret;
+ }
+ avpkt->data = avpkt->buf->data;
+ memset(avpkt->data + avpkt->size, 0, AV_INPUT_BUFFER_PADDING_SIZE);
+
+ return 0;
+}
+
+int ff_get_encode_buffer(AVCodecContext *avctx, AVPacket *avpkt, int64_t size, int flags)
+{
+ int ret;
+
+ if (size < 0 || size > INT_MAX - AV_INPUT_BUFFER_PADDING_SIZE)
+ return AVERROR(EINVAL);
+
+ av_assert0(!avpkt->data && !avpkt->buf);
+
+ avpkt->size = size;
+ ret = avctx->get_encode_buffer(avctx, avpkt, flags);
+ if (ret < 0)
+ goto fail;
+
+ if (!avpkt->data || !avpkt->buf) {
+ av_log(avctx, AV_LOG_ERROR, "No buffer returned by get_encode_buffer()\n");
+ ret = AVERROR(EINVAL);
+ goto fail;
+ }
+
+ ret = 0;
+fail:
+ if (ret < 0) {
+ av_log(avctx, AV_LOG_ERROR, "get_encode_buffer() failed\n");
+ av_packet_unref(avpkt);
+ }
+
+ return ret;
+}
+
/**
* Pad last frame with silence.
*/
@@ -377,6 +430,12 @@ static int compat_encode(AVCodecContext *avctx, AVPacket *avpkt,
av_log(avctx, AV_LOG_WARNING, "AVFrame.width or height is not set\n");
}
+ if (avctx->codec->capabilities & AV_CODEC_CAP_DR1) {
+ av_log(avctx, AV_LOG_WARNING, "The deprecated avcodec_encode_* API does not support "
+ "AV_CODEC_CAP_DR1 encoders\n");
+ return AVERROR(ENOSYS);
+ }
+
ret = avcodec_send_frame(avctx, frame);
if (ret == AVERROR_EOF)
ret = 0;