diff options
author | wm4 <wm4@nowhere> | 2017-02-17 13:32:27 +0100 |
---|---|---|
committer | wm4 <wm4@nowhere> | 2017-02-17 13:32:27 +0100 |
commit | 1e4fd996bb249a773bad5d57ac5b724be52a09af (patch) | |
tree | b8d866473894b8087b941b4fee21bbfd317a8d92 /video/vt.c | |
parent | e8137ee88154b496b2370bbdd93cd3cb3564dc86 (diff) | |
download | mpv-1e4fd996bb249a773bad5d57ac5b724be52a09af.tar.bz2 mpv-1e4fd996bb249a773bad5d57ac5b724be52a09af.tar.xz |
videotoolbox: factor some duplicated code
The code for copying a videotoolbox surface to mp_image was duplicated
(with some minor differences - I picked the hw_videotoolbox.c version,
because it was "better"). mp_imgfmt_from_cvpixelformat() is somewhat
duplicated with the vt_formats[] table, but this will be fixed in a
later commit, and moving the function to shared code is preparation.
Diffstat (limited to 'video/vt.c')
-rw-r--r-- | video/vt.c | 60 |
1 files changed, 60 insertions, 0 deletions
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; +} |