Merge remote-tracking branch 'dilaroga/master'
* dilaroga/master: avcodec/vda_h264_dec: fix a memory leak avcodec/vda_h264: use av_buffer to manage buffers Merged-by: Michael Niedermayer <michaelni@gmx.at>
This commit is contained in:
commit
1c711b6ecd
@ -134,6 +134,17 @@ struct vda_context {
|
|||||||
* - decoding: Set/Unset by libavcodec.
|
* - decoding: Set/Unset by libavcodec.
|
||||||
*/
|
*/
|
||||||
int priv_allocated_size;
|
int priv_allocated_size;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Use av_buffer to manage buffer.
|
||||||
|
* When the flag is set, the CVPixelBuffers returned by the decoder will
|
||||||
|
* be released automatically, so you have to retain them if necessary.
|
||||||
|
* Not setting this flag may cause memory leak.
|
||||||
|
*
|
||||||
|
* encoding: unused
|
||||||
|
* decoding: Set by user.
|
||||||
|
*/
|
||||||
|
int use_ref_buffer;
|
||||||
};
|
};
|
||||||
|
|
||||||
/** Create the video decoder. */
|
/** Create the video decoder. */
|
||||||
|
@ -28,6 +28,9 @@
|
|||||||
#include "libavutil/avutil.h"
|
#include "libavutil/avutil.h"
|
||||||
#include "h264.h"
|
#include "h264.h"
|
||||||
|
|
||||||
|
struct vda_buffer {
|
||||||
|
CVPixelBufferRef cv_buffer;
|
||||||
|
};
|
||||||
|
|
||||||
/* Decoder callback that adds the vda frame to the queue in display order. */
|
/* Decoder callback that adds the vda frame to the queue in display order. */
|
||||||
static void vda_decoder_callback (void *vda_hw_ctx,
|
static void vda_decoder_callback (void *vda_hw_ctx,
|
||||||
@ -108,11 +111,20 @@ static int vda_h264_decode_slice(AVCodecContext *avctx,
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void vda_h264_release_buffer(void *opaque, uint8_t *data)
|
||||||
|
{
|
||||||
|
struct vda_buffer *context = opaque;
|
||||||
|
CVPixelBufferRelease(context->cv_buffer);
|
||||||
|
av_free(context);
|
||||||
|
}
|
||||||
|
|
||||||
static int vda_h264_end_frame(AVCodecContext *avctx)
|
static int vda_h264_end_frame(AVCodecContext *avctx)
|
||||||
{
|
{
|
||||||
H264Context *h = avctx->priv_data;
|
H264Context *h = avctx->priv_data;
|
||||||
struct vda_context *vda_ctx = avctx->hwaccel_context;
|
struct vda_context *vda_ctx = avctx->hwaccel_context;
|
||||||
AVFrame *frame = &h->cur_pic_ptr->f;
|
AVFrame *frame = &h->cur_pic_ptr->f;
|
||||||
|
struct vda_buffer *context;
|
||||||
|
AVBufferRef *buffer;
|
||||||
int status;
|
int status;
|
||||||
|
|
||||||
if (!vda_ctx->decoder || !vda_ctx->priv_bitstream)
|
if (!vda_ctx->decoder || !vda_ctx->priv_bitstream)
|
||||||
@ -124,6 +136,20 @@ static int vda_h264_end_frame(AVCodecContext *avctx)
|
|||||||
if (status)
|
if (status)
|
||||||
av_log(avctx, AV_LOG_ERROR, "Failed to decode frame (%d)\n", status);
|
av_log(avctx, AV_LOG_ERROR, "Failed to decode frame (%d)\n", status);
|
||||||
|
|
||||||
|
if (!vda_ctx->use_ref_buffer || status)
|
||||||
|
return status;
|
||||||
|
|
||||||
|
context = av_mallocz(sizeof(*context));
|
||||||
|
buffer = av_buffer_create(NULL, 0, vda_h264_release_buffer, context, 0);
|
||||||
|
if (!context || !buffer) {
|
||||||
|
CVPixelBufferRelease(vda_ctx->cv_buffer);
|
||||||
|
av_free(context);
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
context->cv_buffer = vda_ctx->cv_buffer;
|
||||||
|
frame->buf[3] = buffer;
|
||||||
|
|
||||||
return status;
|
return status;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -102,6 +102,8 @@ static int vdadec_decode(AVCodecContext *avctx,
|
|||||||
AVBufferRef *buffer = pic->buf[0];
|
AVBufferRef *buffer = pic->buf[0];
|
||||||
VDABufferContext *context = av_buffer_get_opaque(buffer);
|
VDABufferContext *context = av_buffer_get_opaque(buffer);
|
||||||
CVPixelBufferRef cv_buffer = (CVPixelBufferRef)pic->data[3];
|
CVPixelBufferRef cv_buffer = (CVPixelBufferRef)pic->data[3];
|
||||||
|
|
||||||
|
CVPixelBufferRetain(cv_buffer);
|
||||||
CVPixelBufferLockBaseAddress(cv_buffer, 0);
|
CVPixelBufferLockBaseAddress(cv_buffer, 0);
|
||||||
context->cv_buffer = cv_buffer;
|
context->cv_buffer = cv_buffer;
|
||||||
pic->format = ctx->pix_fmt;
|
pic->format = ctx->pix_fmt;
|
||||||
@ -202,6 +204,7 @@ static av_cold int vdadec_init(AVCodecContext *avctx)
|
|||||||
vda_ctx->height = avctx->height;
|
vda_ctx->height = avctx->height;
|
||||||
vda_ctx->format = 'avc1';
|
vda_ctx->format = 'avc1';
|
||||||
vda_ctx->use_sync_decoding = 1;
|
vda_ctx->use_sync_decoding = 1;
|
||||||
|
vda_ctx->use_ref_buffer = 1;
|
||||||
ctx->pix_fmt = avctx->get_format(avctx, avctx->codec->pix_fmts);
|
ctx->pix_fmt = avctx->get_format(avctx, avctx->codec->pix_fmts);
|
||||||
switch (ctx->pix_fmt) {
|
switch (ctx->pix_fmt) {
|
||||||
case AV_PIX_FMT_UYVY422:
|
case AV_PIX_FMT_UYVY422:
|
||||||
|
Loading…
x
Reference in New Issue
Block a user