summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--video/decode/hw_videotoolbox.c47
-rw-r--r--video/out/opengl/hwdec_osx.c41
-rw-r--r--video/vt.c60
-rw-r--r--video/vt.h15
-rw-r--r--wscript_build.py1
5 files changed, 80 insertions, 84 deletions
diff --git a/video/decode/hw_videotoolbox.c b/video/decode/hw_videotoolbox.c
index c6f1a472bf..8edffb5453 100644
--- a/video/decode/hw_videotoolbox.c
+++ b/video/decode/hw_videotoolbox.c
@@ -25,6 +25,7 @@
#include "video/mp_image.h"
#include "video/decode/lavc.h"
#include "video/mp_image_pool.h"
+#include "video/vt.h"
#include "config.h"
struct priv {
@@ -138,55 +139,11 @@ static void uninit(struct lavc_ctx *ctx)
ctx->hwdec_priv = NULL;
}
-static int mp_imgfmt_from_cvpixelformat(uint32_t cvpixfmt)
-{
- switch (cvpixfmt) {
- case kCVPixelFormatType_420YpCbCr8Planar: return IMGFMT_420P;
- case kCVPixelFormatType_422YpCbCr8: return IMGFMT_UYVY;
- case kCVPixelFormatType_32BGRA: return IMGFMT_RGB0;
- case kCVPixelFormatType_420YpCbCr8BiPlanarVideoRange: return IMGFMT_NV12;
- }
- return 0;
-}
-
static struct mp_image *copy_image(struct lavc_ctx *ctx, struct mp_image *hw_image)
{
- if (hw_image->imgfmt != IMGFMT_VIDEOTOOLBOX)
- return hw_image;
-
struct priv *p = ctx->hwdec_priv;
- struct mp_image *image = NULL;
- CVPixelBufferRef pbuf = (CVPixelBufferRef)hw_image->planes[3];
- CVPixelBufferLockBaseAddress(pbuf, kCVPixelBufferLock_ReadOnly);
- size_t width = CVPixelBufferGetWidth(pbuf);
- size_t height = CVPixelBufferGetHeight(pbuf);
- uint32_t cvpixfmt = CVPixelBufferGetPixelFormatType(pbuf);
- int pixfmt = mp_imgfmt_from_cvpixelformat(cvpixfmt);
- if (!pixfmt)
- goto unlock;
-
- struct mp_image img = {0};
- mp_image_setfmt(&img, pixfmt);
- mp_image_set_size(&img, width, height);
-
- if (CVPixelBufferIsPlanar(pbuf)) {
- int planes = CVPixelBufferGetPlaneCount(pbuf);
- for (int i = 0; i < planes; i++) {
- img.planes[i] = CVPixelBufferGetBaseAddressOfPlane(pbuf, i);
- img.stride[i] = CVPixelBufferGetBytesPerRowOfPlane(pbuf, i);
- }
- } else {
- img.planes[0] = CVPixelBufferGetBaseAddress(pbuf);
- img.stride[0] = CVPixelBufferGetBytesPerRow(pbuf);
- }
-
- mp_image_copy_attributes(&img, hw_image);
-
- image = mp_image_pool_new_copy(p->sw_pool, &img);
-
-unlock:
- CVPixelBufferUnlockBaseAddress(pbuf, kCVPixelBufferLock_ReadOnly);
+ struct mp_image *image = mp_vt_download_image(NULL, hw_image, p->sw_pool);
if (image) {
talloc_free(hw_image);
return image;
diff --git a/video/out/opengl/hwdec_osx.c b/video/out/opengl/hwdec_osx.c
index e0fc5ab19b..ecceab658a 100644
--- a/video/out/opengl/hwdec_osx.c
+++ b/video/out/opengl/hwdec_osx.c
@@ -25,6 +25,7 @@
#include <OpenGL/CGLIOSurface.h>
#include "video/mp_image_pool.h"
+#include "video/vt.h"
#include "hwdec.h"
#include "common/global.h"
#include "options/options.h"
@@ -107,44 +108,6 @@ static struct vt_format *vt_get_gl_format_from_imgfmt(uint32_t imgfmt)
return NULL;
}
-static struct mp_image *download_image(struct mp_hwdec_ctx *ctx,
- struct mp_image *hw_image,
- struct mp_image_pool *swpool)
-{
- if (hw_image->imgfmt != IMGFMT_VIDEOTOOLBOX)
- return NULL;
-
- struct mp_image *image = NULL;
- CVPixelBufferRef pbuf = (CVPixelBufferRef)hw_image->planes[3];
- CVPixelBufferLockBaseAddress(pbuf, kCVPixelBufferLock_ReadOnly);
- size_t width = CVPixelBufferGetWidth(pbuf);
- size_t height = CVPixelBufferGetHeight(pbuf);
- uint32_t cvpixfmt = CVPixelBufferGetPixelFormatType(pbuf);
- struct vt_format *f = vt_get_gl_format(cvpixfmt);
- if (!f)
- goto unlock;
-
- struct mp_image img = {0};
- mp_image_setfmt(&img, f->imgfmt);
- mp_image_set_size(&img, width, height);
-
- for (int i = 0; i < f->planes; i++) {
- void *base = CVPixelBufferGetBaseAddressOfPlane(pbuf, i);
- size_t stride = CVPixelBufferGetBytesPerRowOfPlane(pbuf, i);
- img.planes[i] = base;
- img.stride[i] = stride;
- }
-
- mp_image_copy_attributes(&img, hw_image);
-
- image = mp_image_pool_new_copy(swpool, &img);
-
-unlock:
- CVPixelBufferUnlockBaseAddress(pbuf, kCVPixelBufferLock_ReadOnly);
-
- return image;
-}
-
static bool check_hwdec(struct gl_hwdec *hw)
{
if (hw->gl->version < 300) {
@@ -184,7 +147,7 @@ static int create(struct gl_hwdec *hw)
};
p->hwctx = (struct mp_hwdec_ctx){
.type = HWDEC_VIDEOTOOLBOX,
- .download_image = download_image,
+ .download_image = mp_vt_download_image,
.ctx = &p->vtctx,
};
hwdec_devices_add(hw->devs, &p->hwctx);
diff --git a/video/vt.c b/video/vt.c
new file mode 100644
index 0000000000..04f410eedb
--- /dev/null
+++ b/video/vt.c
@@ -0,0 +1,60 @@
+#include <CoreVideo/CoreVideo.h>
+
+#include "video/decode/lavc.h"
+
+#include "mp_image.h"
+#include "mp_image_pool.h"
+#include "vt.h"
+
+int mp_imgfmt_from_cvpixelformat(uint32_t cvpixfmt)
+{
+ switch (cvpixfmt) {
+ case kCVPixelFormatType_420YpCbCr8Planar: return IMGFMT_420P;
+ case kCVPixelFormatType_422YpCbCr8: return IMGFMT_UYVY;
+ case kCVPixelFormatType_32BGRA: return IMGFMT_RGB0;
+ case kCVPixelFormatType_420YpCbCr8BiPlanarVideoRange: return IMGFMT_NV12;
+ }
+ return 0;
+}
+
+// (ctx is unused - it's for compatibility with mp_hwdec_ctx.download_image())
+struct mp_image *mp_vt_download_image(struct mp_hwdec_ctx *ctx,
+ struct mp_image *hw_image,
+ struct mp_image_pool *swpool)
+{
+ if (hw_image->imgfmt != IMGFMT_VIDEOTOOLBOX)
+ return NULL;
+
+ struct mp_image *image = NULL;
+ CVPixelBufferRef pbuf = (CVPixelBufferRef)hw_image->planes[3];
+ CVPixelBufferLockBaseAddress(pbuf, kCVPixelBufferLock_ReadOnly);
+ size_t width = CVPixelBufferGetWidth(pbuf);
+ size_t height = CVPixelBufferGetHeight(pbuf);
+ uint32_t cvpixfmt = CVPixelBufferGetPixelFormatType(pbuf);
+ int imgfmt = mp_imgfmt_from_cvpixelformat(cvpixfmt);
+ if (!imgfmt)
+ goto unlock;
+
+ struct mp_image img = {0};
+ mp_image_setfmt(&img, imgfmt);
+ mp_image_set_size(&img, width, height);
+
+ if (CVPixelBufferIsPlanar(pbuf)) {
+ int planes = CVPixelBufferGetPlaneCount(pbuf);
+ for (int i = 0; i < planes; i++) {
+ img.planes[i] = CVPixelBufferGetBaseAddressOfPlane(pbuf, i);
+ img.stride[i] = CVPixelBufferGetBytesPerRowOfPlane(pbuf, i);
+ }
+ } else {
+ img.planes[0] = CVPixelBufferGetBaseAddress(pbuf);
+ img.stride[0] = CVPixelBufferGetBytesPerRow(pbuf);
+ }
+
+ mp_image_copy_attributes(&img, hw_image);
+
+ image = mp_image_pool_new_copy(swpool, &img);
+
+unlock:
+ CVPixelBufferUnlockBaseAddress(pbuf, kCVPixelBufferLock_ReadOnly);
+ return image;
+}
diff --git a/video/vt.h b/video/vt.h
new file mode 100644
index 0000000000..e4ad5f021b
--- /dev/null
+++ b/video/vt.h
@@ -0,0 +1,15 @@
+#ifndef MPV_VT_H
+#define MPV_VT_H
+
+#include <stdint.h>
+
+int mp_imgfmt_from_cvpixelformat(uint32_t cvpixfmt);
+
+struct mp_image;
+struct mp_image_pool;
+struct mp_hwdec_ctx;
+struct mp_image *mp_vt_download_image(struct mp_hwdec_ctx *ctx,
+ struct mp_image *hw_image,
+ struct mp_image_pool *swpool);
+
+#endif
diff --git a/wscript_build.py b/wscript_build.py
index 4f65f1ba0f..e357e95a43 100644
--- a/wscript_build.py
+++ b/wscript_build.py
@@ -303,6 +303,7 @@ def build(ctx):
( "video/vaapi.c", "vaapi" ),
( "video/vdpau.c", "vdpau" ),
( "video/vdpau_mixer.c", "vdpau" ),
+ ( "video/vt.c", "videotoolbox-hwaccel" ),
( "video/decode/d3d.c", "win32" ),
( "video/decode/dec_video.c"),
( "video/decode/hw_cuda.c", "cuda-hwaccel" ),