Merge remote-tracking branch 'qatar/master'
[ffmpeg.git] / libavcodec / vda.c
index 3c03dcd..e910ce1 100644 (file)
@@ -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
  */
 
 #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,8 +144,19 @@ 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);
 
+<<<<<<< HEAD
+    if (extradata[4]==0xFE) {
+        // convert 3 byte NAL sizes to 4 byte
+        extradata[4] = 0xFF;
+    }
+
+||||||| merged common ancestors
+=======
     /* Each VCL NAL in the bistream sent to the decoder
      * is preceeded by a 4 bytes length header.
      * Change the avcC atom header if needed, to signal headers of 4 bytes. */
@@ -162,14 +177,27 @@ int ff_vda_create_decoder(struct vda_context *vda_ctx,
         avc_data = CFDataCreate(kCFAllocatorDefault, extradata, extradata_size);
     }
 
+>>>>>>> qatar/master
     config_info = CFDictionaryCreateMutable(kCFAllocatorDefault,
                                             4,
                                             &kCFTypeDictionaryKeyCallBacks,
                                             &kCFTypeDictionaryValueCallBacks);
 
+<<<<<<< HEAD
+    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);
+||||||| merged common ancestors
+    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);
+=======
     height   = CFNumberCreate(kCFAllocatorDefault, kCFNumberSInt32Type, &vda_ctx->height);
     width    = CFNumberCreate(kCFAllocatorDefault, kCFNumberSInt32Type, &vda_ctx->width);
     format   = CFNumberCreate(kCFAllocatorDefault, kCFNumberSInt32Type, &vda_ctx->format);
+>>>>>>> qatar/master
 
     CFDictionarySetValue(config_info, kVDADecoderConfiguration_Height, height);
     CFDictionarySetValue(config_info, kVDADecoderConfiguration_Width, width);
@@ -184,9 +212,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);
@@ -196,7 +224,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);
 
@@ -226,6 +254,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;
 
@@ -240,7 +271,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);
 
@@ -265,8 +296,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);