mirror of
https://github.com/nyanmisaka/ffmpeg-rockchip.git
synced 2025-10-16 05:41:08 +08:00
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>
This commit is contained in:
@@ -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;
|
||||
|
Reference in New Issue
Block a user