[vlc-commits] vt_utils: add cvpx_pool helpers

Thomas Guillem git at videolan.org
Fri Jun 2 18:44:12 CEST 2017


vlc | branch: master | Thomas Guillem <thomas at gllm.fr> | Thu Apr  6 13:45:01 2017 +0200| [efeb55685f90bcad9c765ec7dde93858c0550529] | committer: Thomas Guillem

vt_utils: add cvpx_pool helpers

> http://git.videolan.org/gitweb.cgi/vlc.git/?a=commit;h=efeb55685f90bcad9c765ec7dde93858c0550529
---

 modules/codec/vt_utils.c | 195 +++++++++++++++++++++++++++++++++++++++++++++++
 modules/codec/vt_utils.h |  34 +++++++++
 2 files changed, 229 insertions(+)

diff --git a/modules/codec/vt_utils.c b/modules/codec/vt_utils.c
index c2f8375d27..2a84618a3c 100644
--- a/modules/codec/vt_utils.c
+++ b/modules/codec/vt_utils.c
@@ -78,3 +78,198 @@ cvpxpic_get_ref(picture_t *pic)
     assert(pic->context != NULL);
     return ((struct cvpxpic_ctx *)pic->context)->cvpx;
 }
+
+static void
+cvpxpic_destroy_mapped_ro_cb(picture_t *pic)
+{
+    CVPixelBufferRef cvpx = (void *) pic->p_sys;
+    CVPixelBufferUnlockBaseAddress(cvpx, kCVPixelBufferLock_ReadOnly);
+    CFRelease(cvpx);
+}
+
+static void
+cvpxpic_destroy_mapped_rw_cb(picture_t *pic)
+{
+    CVPixelBufferRef cvpx = (void *) pic->p_sys;
+    CVPixelBufferUnlockBaseAddress(cvpx, 0);
+    CFRelease(cvpx);
+}
+
+picture_t *
+cvpxpic_create_mapped(const video_format_t *fmt, CVPixelBufferRef cvpx,
+                      bool readonly)
+{
+    unsigned planes_count;
+    switch (fmt->i_chroma)
+    {
+        case VLC_CODEC_BGRA:
+        case VLC_CODEC_UYVY: planes_count = 0; break;
+        case VLC_CODEC_NV12: planes_count = 2; break;
+        case VLC_CODEC_I420: planes_count = 3; break;
+        default: return NULL;
+    }
+
+    CVPixelBufferLockFlags lock = readonly ? kCVPixelBufferLock_ReadOnly : 0;
+    CVPixelBufferLockBaseAddress(cvpx, lock);
+    picture_resource_t rsc = {
+        .p_sys = (void *)cvpx,
+        .pf_destroy = readonly ? cvpxpic_destroy_mapped_ro_cb
+                               : cvpxpic_destroy_mapped_rw_cb,
+    };
+
+#ifndef NDEBUG
+    assert(CVPixelBufferGetPlaneCount(cvpx) == planes_count);
+#endif
+
+    if (planes_count == 0)
+    {
+        rsc.p[0].p_pixels = CVPixelBufferGetBaseAddress(cvpx);
+        rsc.p[0].i_lines = CVPixelBufferGetHeight(cvpx);
+        rsc.p[0].i_pitch = CVPixelBufferGetBytesPerRow(cvpx);
+    }
+    else
+    {
+        for (unsigned i = 0; i < planes_count; ++i)
+        {
+            rsc.p[i].p_pixels = CVPixelBufferGetBaseAddressOfPlane(cvpx, i);
+            rsc.p[i].i_lines = CVPixelBufferGetHeightOfPlane(cvpx, i);
+            rsc.p[i].i_pitch = CVPixelBufferGetBytesPerRowOfPlane(cvpx, i);
+        }
+    }
+
+    picture_t *pic = picture_NewFromResource(fmt, &rsc);
+    if (pic == NULL)
+    {
+        CVPixelBufferUnlockBaseAddress(cvpx, lock);
+        CFRelease(cvpx);
+        return NULL;
+    }
+    CVPixelBufferRetain(cvpx);
+    return pic;
+}
+
+picture_t *
+cvpxpic_unmap(picture_t *mapped_pic)
+{
+    video_format_t fmt = mapped_pic->format;
+    switch (fmt.i_chroma)
+    {
+        case VLC_CODEC_UYVY: fmt.i_chroma = VLC_CODEC_CVPX_UYVY; break;
+        case VLC_CODEC_NV12: fmt.i_chroma = VLC_CODEC_CVPX_NV12; break;
+        case VLC_CODEC_I420: fmt.i_chroma = VLC_CODEC_CVPX_I420; break;
+        case VLC_CODEC_BGRA: fmt.i_chroma = VLC_CODEC_CVPX_BGRA; break;
+        default:
+            assert(!"invalid mapped_pic fmt");
+            picture_Release(mapped_pic);
+            return NULL;
+    }
+    assert(mapped_pic->p_sys != NULL);
+
+    picture_t *hw_pic = picture_NewFromFormat(&fmt);
+    if (hw_pic == NULL)
+    {
+        picture_Release(mapped_pic);
+        return NULL;
+    }
+
+    cvpxpic_attach(hw_pic, CVPixelBufferRetain((void *)mapped_pic->p_sys));
+    picture_CopyProperties(hw_pic, mapped_pic);
+    picture_Release(mapped_pic);
+    return hw_pic;
+}
+
+CVPixelBufferPoolRef
+cvpxpool_create(const video_format_t *fmt, unsigned count)
+{
+    int cvpx_format;
+    switch (fmt->i_chroma)
+    {
+        case VLC_CODEC_CVPX_UYVY:
+            cvpx_format = kCVPixelFormatType_422YpCbCr8;
+            break;
+        case VLC_CODEC_CVPX_NV12:
+            cvpx_format = kCVPixelFormatType_420YpCbCr8BiPlanarVideoRange;
+            break;
+        case VLC_CODEC_CVPX_I420:
+            cvpx_format = kCVPixelFormatType_420YpCbCr8Planar;
+            break;
+        case VLC_CODEC_CVPX_BGRA:
+            cvpx_format = kCVPixelFormatType_32BGRA;
+        default:
+            return NULL;
+    }
+
+    /* destination pixel buffer attributes */
+    CFMutableDictionaryRef cvpx_attrs_dict = cfdict_create(5);
+    if (unlikely(cvpx_attrs_dict == NULL))
+        return NULL;
+    CFMutableDictionaryRef pool_dict = cfdict_create(2);
+    if (unlikely(pool_dict == NULL))
+    {
+        CFRelease(cvpx_attrs_dict);
+        return NULL;
+    }
+
+#if !TARGET_OS_IPHONE
+    CFMutableDictionaryRef io_dict = cfdict_create(0);
+    if (unlikely(io_dict == NULL))
+    {
+        CFRelease(cvpx_attrs_dict);
+        CFRelease(pool_dict);
+        return NULL;
+    }
+    CFDictionarySetValue(cvpx_attrs_dict,
+                         kCVPixelBufferIOSurfacePropertiesKey, io_dict);
+    CFRelease(io_dict);
+#else
+    CFDictionarySetValue(cvpx_attrs_dict,
+                         kCVPixelBufferOpenGLESCompatibilityKey, kCFBooleanTrue);
+#endif
+
+    cfdict_set_int32(cvpx_attrs_dict, kCVPixelBufferBytesPerRowAlignmentKey,
+                     fmt->i_width);
+    cfdict_set_int32(cvpx_attrs_dict, kCVPixelBufferPixelFormatTypeKey,
+                     cvpx_format);
+    cfdict_set_int32(cvpx_attrs_dict, kCVPixelBufferWidthKey, fmt->i_width);
+    cfdict_set_int32(cvpx_attrs_dict, kCVPixelBufferHeightKey, fmt->i_height);
+
+    cfdict_set_int32(pool_dict, kCVPixelBufferPoolMinimumBufferCountKey, count);
+    cfdict_set_int32(pool_dict, kCVPixelBufferPoolMaximumBufferAgeKey, 0);
+
+    CVPixelBufferPoolRef pool;
+    CVReturn err =
+        CVPixelBufferPoolCreate(NULL, pool_dict, cvpx_attrs_dict, &pool);
+    CFRelease(pool_dict);
+    CFRelease(cvpx_attrs_dict);
+    if (err != kCVReturnSuccess)
+        return NULL;
+
+    CVPixelBufferRef cvpxs[count];
+    for (unsigned i = 0; i < count; ++i)
+    {
+        err = CVPixelBufferPoolCreatePixelBuffer(NULL, pool, &cvpxs[i]);
+        if (err != kCVReturnSuccess)
+        {
+            CVPixelBufferPoolRelease(pool);
+            pool = NULL;
+            count = i;
+            break;
+        }
+    }
+    for (unsigned i = 0; i < count; ++i)
+        CFRelease(cvpxs[i]);
+
+    return pool;
+}
+
+CVPixelBufferRef
+cvpxpool_get_cvpx(CVPixelBufferPoolRef pool)
+{
+    CVPixelBufferRef cvpx;
+    CVReturn err = CVPixelBufferPoolCreatePixelBuffer(NULL, pool, &cvpx);
+
+    if (err != kCVReturnSuccess)
+        return NULL;
+
+    return cvpx;
+}
diff --git a/modules/codec/vt_utils.h b/modules/codec/vt_utils.h
index 0c82031b92..aaba4a5c5b 100644
--- a/modules/codec/vt_utils.h
+++ b/modules/codec/vt_utils.h
@@ -41,4 +41,38 @@ int cvpxpic_attach(picture_t *p_pic, CVPixelBufferRef cvpx);
  */
 CVPixelBufferRef cvpxpic_get_ref(picture_t *pic);
 
+/*
+ * Create a picture mapped to a cvpx buffer
+ *
+ * @param fmt i_chroma must be VLC_CODEC_UYVY, VLC_CODEC_NV12 or VLC_CODEC_I420
+ * @param cvpx buffer to map
+ * @param readonly true to map read-only, false otherwise
+ * @return a valid picture, call picture_Release() or cvpxpic_unmap() to free
+ * the picture and unmap the cvpx buffer.
+ */
+picture_t *cvpxpic_create_mapped(const video_format_t *fmt,
+                                 CVPixelBufferRef cvpx, bool readonly);
+
+/*
+ * Create a picture attached to an unmapped cvpx buffer
+ *
+ * @param mapped_pic must be a picture created with cvpxpic_create_mapped()
+ * @return a valid picture, the pic chroma will one of VLC_CODEC_CVPX_* chromas
+ */
+picture_t *cvpxpic_unmap(picture_t *mapped_pic);
+
+/*
+ * Create a cvpx pool
+ *
+ * @param fmt i_chroma must be one of VLC_CODEC_CVPX_* chromas
+ * @param count number of pictures to alloc
+ * @return a valid cvpx pool or NULL, release it with CVPixelBufferPoolRelease()
+ */
+CVPixelBufferPoolRef cvpxpool_create(const video_format_t *fmt, unsigned count);
+
+/*
+ * Get a cvpx buffer from a pool
+ */
+CVPixelBufferRef cvpxpool_get_cvpx(CVPixelBufferPoolRef pool);
+
 #endif



More information about the vlc-commits mailing list