diff options
Diffstat (limited to 'libavcodec/vda_h264.c')
-rw-r--r-- | libavcodec/vda_h264.c | 63 |
1 files changed, 48 insertions, 15 deletions
diff --git a/libavcodec/vda_h264.c b/libavcodec/vda_h264.c index 6c1845a676..1eff671f7f 100644 --- a/libavcodec/vda_h264.c +++ b/libavcodec/vda_h264.c @@ -1,34 +1,38 @@ /* - * VDA H.264 hardware acceleration + * VDA H264 HW acceleration. * * copyright (c) 2011 Sebastien Zwickert * - * This file is part of Libav. + * This file is part of FFmpeg. * - * Libav is free software; you can redistribute it and/or + * FFmpeg is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; either * version 2.1 of the License, or (at your option) any later version. * - * Libav is distributed in the hope that it will be useful, + * FFmpeg is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public - * License along with Libav; if not, write to the Free Software + * License along with FFmpeg; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ +#include <CoreFoundation/CFDictionary.h> #include <CoreFoundation/CFNumber.h> #include <CoreFoundation/CFData.h> -#include <CoreFoundation/CFString.h> +#include "vda.h" #include "libavutil/avutil.h" #include "h264.h" -#include "vda.h" -/* Decoder callback that adds the VDA frame to the queue in display order. */ +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, CFDictionaryRef user_info, OSStatus status, @@ -37,6 +41,9 @@ static void vda_decoder_callback(void *vda_hw_ctx, { struct vda_context *vda_ctx = vda_hw_ctx; + if (infoFlags & kVDADecodeInfo_FrameDropped) + vda_ctx->cv_buffer = NULL; + if (!image_buffer) return; @@ -71,7 +78,7 @@ static int vda_h264_start_frame(AVCodecContext *avctx, av_unused const uint8_t *buffer, av_unused uint32_t size) { - struct vda_context *vda_ctx = avctx->hwaccel_context; + struct vda_context *vda_ctx = avctx->hwaccel_context; if (!vda_ctx->decoder) return -1; @@ -85,7 +92,7 @@ static int vda_h264_decode_slice(AVCodecContext *avctx, const uint8_t *buffer, uint32_t size) { - struct vda_context *vda_ctx = avctx->hwaccel_context; + struct vda_context *vda_ctx = avctx->hwaccel_context; void *tmp; if (!vda_ctx->decoder) @@ -107,11 +114,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) @@ -123,6 +139,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; } @@ -130,7 +160,7 @@ int ff_vda_create_decoder(struct vda_context *vda_ctx, uint8_t *extradata, int extradata_size) { - OSStatus status = kVDADecoderNoErr; + OSStatus status; CFNumberRef height; CFNumberRef width; CFNumberRef format; @@ -140,7 +170,10 @@ int ff_vda_create_decoder(struct vda_context *vda_ctx, CFMutableDictionaryRef io_surface_properties; CFNumberRef cv_pix_fmt; - /* Each VCL NAL in the bistream sent to the decoder + vda_ctx->priv_bitstream = NULL; + vda_ctx->priv_allocated_size = 0; + + /* Each VCL NAL in the bitstream sent to the decoder * is preceded by a 4 bytes length header. * Change the avcC atom header if needed, to signal headers of 4 bytes. */ if (extradata_size >= 4 && (extradata[4] & 0x03) != 0x03) { @@ -182,9 +215,9 @@ int ff_vda_create_decoder(struct vda_context *vda_ctx, 0, &kCFTypeDictionaryKeyCallBacks, &kCFTypeDictionaryValueCallBacks); - cv_pix_fmt = CFNumberCreate(kCFAllocatorDefault, - kCFNumberSInt32Type, - &vda_ctx->cv_pix_fmt_type); + cv_pix_fmt = CFNumberCreate(kCFAllocatorDefault, + kCFNumberSInt32Type, + &vda_ctx->cv_pix_fmt_type); CFDictionarySetValue(buffer_attributes, kCVPixelBufferPixelFormatTypeKey, cv_pix_fmt); |