summaryrefslogtreecommitdiffstats
path: root/libavcodec/vda.c
diff options
context:
space:
mode:
Diffstat (limited to 'libavcodec/vda.c')
-rw-r--r--libavcodec/vda.c88
1 files changed, 52 insertions, 36 deletions
diff --git a/libavcodec/vda.c b/libavcodec/vda.c
index 34739f8..a2814d7 100644
--- a/libavcodec/vda.c
+++ b/libavcodec/vda.c
@@ -1,22 +1,22 @@
/*
- * VDA hardware acceleration
+ * VDA 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
*/
@@ -29,12 +29,11 @@
#include "libavutil/avutil.h"
#include "vda_internal.h"
-/* helper to create a dictionary according to the given pts */
+/* Helper to create a dictionary according to the given pts. */
static CFDictionaryRef vda_dictionary_with_pts(int64_t i_pts)
{
- CFStringRef key = CFSTR("FF_VDA_DECODER_PTS_KEY");
- CFNumberRef value = CFNumberCreate(kCFAllocatorDefault,
- kCFNumberSInt64Type, &i_pts);
+ CFStringRef key = CFSTR("FF_VDA_DECODER_PTS_KEY");
+ CFNumberRef value = CFNumberCreate(kCFAllocatorDefault, kCFNumberSInt64Type, &i_pts);
CFDictionaryRef user_info = CFDictionaryCreate(kCFAllocatorDefault,
(const void **)&key,
(const void **)&value,
@@ -45,7 +44,7 @@ static CFDictionaryRef vda_dictionary_with_pts(int64_t i_pts)
return user_info;
}
-/* helper to retrieve the pts from the given dictionary */
+/* Helper to retrieve the pts from the given dictionary. */
static int64_t vda_pts_from_dictionary(CFDictionaryRef user_info)
{
CFNumberRef pts;
@@ -62,7 +61,7 @@ static int64_t vda_pts_from_dictionary(CFDictionaryRef user_info)
return outValue;
}
-/* Remove and release all frames from the queue. */
+/* Removes and releases all frames from the queue. */
static void vda_clear_queue(struct vda_context *vda_ctx)
{
vda_frame *top_frame;
@@ -70,7 +69,7 @@ static void vda_clear_queue(struct vda_context *vda_ctx)
pthread_mutex_lock(&vda_ctx->queue_mutex);
while (vda_ctx->queue) {
- top_frame = vda_ctx->queue;
+ top_frame = vda_ctx->queue;
vda_ctx->queue = top_frame->next_frame;
ff_vda_release_vda_frame(top_frame);
}
@@ -78,14 +77,15 @@ static void vda_clear_queue(struct vda_context *vda_ctx)
pthread_mutex_unlock(&vda_ctx->queue_mutex);
}
-/* 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,
- uint32_t infoFlags,
- CVImageBufferRef image_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,
+ uint32_t infoFlags,
+ CVImageBufferRef image_buffer)
{
- struct vda_context *vda_ctx = vda_hw_ctx;
+ struct vda_context *vda_ctx = (struct vda_context*)vda_hw_ctx;
vda_frame *new_frame;
vda_frame *queue_walker;
@@ -95,27 +95,31 @@ static void vda_decoder_callback(void *vda_hw_ctx,
if (vda_ctx->cv_pix_fmt_type != CVPixelBufferGetPixelFormatType(image_buffer))
return;
- if (!(new_frame = av_mallocz(sizeof(vda_frame))))
+ new_frame = av_mallocz(sizeof(vda_frame));
+ if (!new_frame)
return;
+
new_frame->next_frame = NULL;
- new_frame->cv_buffer = CVPixelBufferRetain(image_buffer);
- new_frame->pts = vda_pts_from_dictionary(user_info);
+ new_frame->cv_buffer = CVPixelBufferRetain(image_buffer);
+ new_frame->pts = vda_pts_from_dictionary(user_info);
pthread_mutex_lock(&vda_ctx->queue_mutex);
queue_walker = vda_ctx->queue;
- if (!queue_walker || new_frame->pts < queue_walker->pts) {
+ if (!queue_walker || (new_frame->pts < queue_walker->pts)) {
/* we have an empty queue, or this frame earlier than the current queue head */
new_frame->next_frame = queue_walker;
- vda_ctx->queue = new_frame;
+ vda_ctx->queue = new_frame;
} else {
/* walk the queue and insert this frame where it belongs in display order */
vda_frame *next_frame;
+
while (1) {
next_frame = queue_walker->next_frame;
- if (!next_frame || new_frame->pts < next_frame->pts) {
- new_frame->next_frame = next_frame;
+
+ if (!next_frame || (new_frame->pts < next_frame->pts)) {
+ new_frame->next_frame = next_frame;
queue_walker->next_frame = new_frame;
break;
}
@@ -140,16 +144,24 @@ int ff_vda_create_decoder(struct vda_context *vda_ctx,
CFMutableDictionaryRef io_surface_properties;
CFNumberRef cv_pix_fmt;
+ vda_ctx->bitstream = NULL;
+ vda_ctx->ref_size = 0;
+
pthread_mutex_init(&vda_ctx->queue_mutex, NULL);
+ if (extradata[4]==0xFE) {
+ // convert 3 byte NAL sizes to 4 byte
+ extradata[4] = 0xFF;
+ }
+
config_info = CFDictionaryCreateMutable(kCFAllocatorDefault,
4,
&kCFTypeDictionaryKeyCallBacks,
&kCFTypeDictionaryValueCallBacks);
- height = CFNumberCreate(kCFAllocatorDefault, kCFNumberSInt32Type, &vda_ctx->height);
- width = CFNumberCreate(kCFAllocatorDefault, kCFNumberSInt32Type, &vda_ctx->width);
- format = CFNumberCreate(kCFAllocatorDefault, kCFNumberSInt32Type, &vda_ctx->format);
+ height = CFNumberCreate(kCFAllocatorDefault, kCFNumberSInt32Type, &vda_ctx->height);
+ width = CFNumberCreate(kCFAllocatorDefault, kCFNumberSInt32Type, &vda_ctx->width);
+ format = CFNumberCreate(kCFAllocatorDefault, kCFNumberSInt32Type, &vda_ctx->format);
avc_data = CFDataCreate(kCFAllocatorDefault, extradata, extradata_size);
CFDictionarySetValue(config_info, kVDADecoderConfiguration_Height, height);
@@ -165,9 +177,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);
@@ -177,7 +189,7 @@ int ff_vda_create_decoder(struct vda_context *vda_ctx,
status = VDADecoderCreate(config_info,
buffer_attributes,
- vda_decoder_callback,
+ (VDADecoderOutputCallback *)vda_decoder_callback,
vda_ctx,
&vda_ctx->decoder);
@@ -207,6 +219,9 @@ int ff_vda_destroy_decoder(struct vda_context *vda_ctx)
pthread_mutex_destroy(&vda_ctx->queue_mutex);
+ if (vda_ctx->bitstream)
+ av_freep(&vda_ctx->bitstream);
+
if (kVDADecoderNoErr != status)
return status;
@@ -221,7 +236,7 @@ vda_frame *ff_vda_queue_pop(struct vda_context *vda_ctx)
return NULL;
pthread_mutex_lock(&vda_ctx->queue_mutex);
- top_frame = vda_ctx->queue;
+ top_frame = vda_ctx->queue;
vda_ctx->queue = top_frame->next_frame;
pthread_mutex_unlock(&vda_ctx->queue_mutex);
@@ -246,8 +261,9 @@ int ff_vda_decoder_decode(struct vda_context *vda_ctx,
CFDataRef coded_frame;
coded_frame = CFDataCreate(kCFAllocatorDefault, bitstream, bitstream_size);
- user_info = vda_dictionary_with_pts(frame_pts);
- status = VDADecoderDecode(vda_ctx->decoder, 0, coded_frame, user_info);
+ user_info = vda_dictionary_with_pts(frame_pts);
+
+ status = VDADecoderDecode(vda_ctx->decoder, 0, coded_frame, user_info);
CFRelease(user_info);
CFRelease(coded_frame);
OpenPOWER on IntegriCloud