|
|
|
@@ -28,6 +28,9 @@ |
|
|
|
#include "libavutil/avutil.h" |
|
|
|
#include "h264.h" |
|
|
|
|
|
|
|
struct vda_buffer { |
|
|
|
CVPixelBufferRef cv_buffer; |
|
|
|
}; |
|
|
|
|
|
|
|
/* Decoder callback that adds the vda frame to the queue in display order. */ |
|
|
|
static void vda_decoder_callback (void *vda_hw_ctx, |
|
|
|
@@ -108,11 +111,20 @@ static int vda_h264_decode_slice(AVCodecContext *avctx, |
|
|
|
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) |
|
|
|
{ |
|
|
|
H264Context *h = avctx->priv_data; |
|
|
|
struct vda_context *vda_ctx = avctx->hwaccel_context; |
|
|
|
AVFrame *frame = &h->cur_pic_ptr->f; |
|
|
|
struct vda_buffer *context; |
|
|
|
AVBufferRef *buffer; |
|
|
|
int status; |
|
|
|
|
|
|
|
if (!vda_ctx->decoder || !vda_ctx->priv_bitstream) |
|
|
|
@@ -124,6 +136,20 @@ static int vda_h264_end_frame(AVCodecContext *avctx) |
|
|
|
if (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; |
|
|
|
} |
|
|
|
|
|
|
|
|