2019-08-17 03:49:25 +02:00
|
|
|
// Copyright 2019 The MediaPipe Authors.
|
|
|
|
//
|
|
|
|
// Licensed under the Apache License, Version 2.0 (the "License");
|
|
|
|
// you may not use this file except in compliance with the License.
|
|
|
|
// You may obtain a copy of the License at
|
|
|
|
//
|
|
|
|
// http://www.apache.org/licenses/LICENSE-2.0
|
|
|
|
//
|
|
|
|
// Unless required by applicable law or agreed to in writing, software
|
|
|
|
// distributed under the License is distributed on an "AS IS" BASIS,
|
|
|
|
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
|
|
// See the License for the specific language governing permissions and
|
|
|
|
// limitations under the License.
|
|
|
|
|
|
|
|
#ifndef MEDIAPIPE_OBJC_UTIL_H_
|
|
|
|
#define MEDIAPIPE_OBJC_UTIL_H_
|
|
|
|
|
|
|
|
#import <Accelerate/Accelerate.h>
|
|
|
|
#import <CoreFoundation/CoreFoundation.h>
|
2021-10-18 21:39:29 +02:00
|
|
|
#import <CoreGraphics/CoreGraphics.h>
|
2019-08-17 03:49:25 +02:00
|
|
|
#import <CoreVideo/CoreVideo.h>
|
|
|
|
|
|
|
|
#include "mediapipe/framework/formats/image_frame.h"
|
|
|
|
#include "mediapipe/framework/packet.h"
|
|
|
|
#include "mediapipe/framework/port/status.h"
|
|
|
|
#include "mediapipe/objc/CFHolder.h"
|
|
|
|
|
|
|
|
// TODO: namespace and/or prefix these. Split up the file.
|
|
|
|
|
|
|
|
/// Returns a vImage_Buffer describing the data inside the pixel_buffer.
|
|
|
|
/// NOTE: the pixel buffer's base address must have been locked before this
|
|
|
|
/// call, and it must stay locked as long as the vImage_Buffer is in use.
|
|
|
|
inline vImage_Buffer vImageForCVPixelBuffer(CVPixelBufferRef pixel_buffer) {
|
|
|
|
return {.data = CVPixelBufferGetBaseAddress(pixel_buffer),
|
|
|
|
.width = CVPixelBufferGetWidth(pixel_buffer),
|
|
|
|
.height = CVPixelBufferGetHeight(pixel_buffer),
|
|
|
|
.rowBytes = CVPixelBufferGetBytesPerRow(pixel_buffer)};
|
|
|
|
}
|
|
|
|
|
|
|
|
/// Returns a vImage_Buffer describing the data inside the ImageFrame.
|
|
|
|
inline vImage_Buffer vImageForImageFrame(const mediapipe::ImageFrame& frame) {
|
|
|
|
return {.data = (void*)frame.PixelData(),
|
|
|
|
.width = static_cast<vImagePixelCount>(frame.Width()),
|
|
|
|
.height = static_cast<vImagePixelCount>(frame.Height()),
|
|
|
|
.rowBytes = static_cast<size_t>(frame.WidthStep())};
|
|
|
|
}
|
|
|
|
|
|
|
|
/// Converts a grayscale image without alpha to BGRA format.
|
|
|
|
vImage_Error vImageGrayToBGRA(const vImage_Buffer* src, vImage_Buffer* dst);
|
|
|
|
|
|
|
|
/// Converts a BGRA image to grayscale without alpha.
|
|
|
|
vImage_Error vImageBGRAToGray(const vImage_Buffer* src, vImage_Buffer* dst);
|
|
|
|
|
|
|
|
/// Converts an RGBA image to grayscale without alpha.
|
|
|
|
vImage_Error vImageRGBAToGray(const vImage_Buffer* src, vImage_Buffer* dst);
|
|
|
|
|
|
|
|
/// Copy from a pixel buffer to another, converting pixel format.
|
|
|
|
/// Both pixel buffers should be locked before calling this.
|
|
|
|
vImage_Error vImageConvertCVPixelBuffers(CVPixelBufferRef src,
|
|
|
|
CVPixelBufferRef dst);
|
|
|
|
|
2021-10-06 22:44:33 +02:00
|
|
|
// Create a CVPixelBuffer without using a pool. See pixel_buffer_pool_util.h
|
|
|
|
// for creation functions that use pools.
|
|
|
|
CVReturn CreateCVPixelBufferWithoutPool(int width, int height, OSType cv_format,
|
|
|
|
CVPixelBufferRef* out_buffer);
|
|
|
|
absl::StatusOr<CFHolder<CVPixelBufferRef>> CreateCVPixelBufferWithoutPool(
|
|
|
|
int width, int height, OSType cv_format);
|
|
|
|
|
2019-08-17 03:49:25 +02:00
|
|
|
/// Returns a CVPixelBuffer that references the data inside the packet. The
|
|
|
|
/// packet must contain an ImageFrame. The CVPixelBuffer manages a copy of
|
|
|
|
/// the packet, so that the packet's data is kept alive as long as the
|
|
|
|
/// CVPixelBuffer is in use.
|
|
|
|
///
|
|
|
|
/// For formats which are not supported by both image types, it may be
|
|
|
|
/// necessary to convert the data. This is done by creating a new buffer.
|
|
|
|
/// If the optional can_overwrite parameter is true, the old buffer may be
|
|
|
|
/// modified instead.
|
2021-02-27 09:21:16 +01:00
|
|
|
absl::Status CreateCVPixelBufferForImageFramePacket(
|
2019-08-17 03:49:25 +02:00
|
|
|
const mediapipe::Packet& image_frame_packet,
|
|
|
|
CFHolder<CVPixelBufferRef>* out_buffer);
|
2021-02-27 09:21:16 +01:00
|
|
|
absl::Status CreateCVPixelBufferForImageFramePacket(
|
2019-08-17 03:49:25 +02:00
|
|
|
const mediapipe::Packet& image_frame_packet, bool can_overwrite,
|
|
|
|
CFHolder<CVPixelBufferRef>* out_buffer);
|
2021-10-06 22:44:33 +02:00
|
|
|
absl::StatusOr<CFHolder<CVPixelBufferRef>> CreateCVPixelBufferCopyingImageFrame(
|
|
|
|
const mediapipe::ImageFrame& image_frame);
|
2022-03-21 20:07:37 +01:00
|
|
|
absl::StatusOr<CFHolder<CVPixelBufferRef>> CreateCVPixelBufferForImageFrame(
|
|
|
|
std::shared_ptr<mediapipe::ImageFrame> image_frame,
|
|
|
|
bool can_overwrite = false);
|
2019-08-17 03:49:25 +02:00
|
|
|
|
|
|
|
/// Creates a CVPixelBuffer with a copy of the contents of the CGImage.
|
2021-02-27 09:21:16 +01:00
|
|
|
absl::Status CreateCVPixelBufferFromCGImage(
|
2019-08-17 03:49:25 +02:00
|
|
|
CGImageRef image, CFHolder<CVPixelBufferRef>* out_buffer);
|
|
|
|
|
|
|
|
/// Creates a CGImage with a copy of the contents of the CVPixelBuffer.
|
2021-02-27 09:21:16 +01:00
|
|
|
absl::Status CreateCGImageFromCVPixelBuffer(CVPixelBufferRef image_buffer,
|
|
|
|
CFHolder<CGImageRef>* image);
|
2019-08-17 03:49:25 +02:00
|
|
|
|
2021-02-27 09:21:16 +01:00
|
|
|
/// DEPRECATED: use the version that returns absl::Status instead.
|
2019-08-17 03:49:25 +02:00
|
|
|
CVPixelBufferRef CreateCVPixelBufferForImageFramePacket(
|
|
|
|
const mediapipe::Packet& image_frame_packet);
|
|
|
|
|
|
|
|
/// Returns an ImageFrame that references the data inside the pixel_buffer.
|
|
|
|
/// The ImageFrame retains the pixel_buffer and keeps it locked as long as it
|
|
|
|
/// is in use.
|
|
|
|
///
|
|
|
|
/// For formats which are not supported by both image types, it may be
|
|
|
|
/// necessary to convert the data. This is done by creating a new buffer.
|
|
|
|
/// If the optional can_overwrite parameter is true, the old buffer may be
|
|
|
|
/// modified instead.
|
|
|
|
///
|
|
|
|
/// ImageFrame does not have a format for BGRA data, so we normally swap the
|
|
|
|
/// channels to produce RGBA. But many graphs do not care about the order of
|
|
|
|
/// the channels; in those cases, setting the optional bgr_as_rgb parameter
|
|
|
|
/// to true skips the channel swap.
|
|
|
|
std::unique_ptr<mediapipe::ImageFrame> CreateImageFrameForCVPixelBuffer(
|
|
|
|
CVPixelBufferRef pixel_buffer);
|
|
|
|
std::unique_ptr<mediapipe::ImageFrame> CreateImageFrameForCVPixelBuffer(
|
|
|
|
CVPixelBufferRef pixel_buffer, bool can_overwrite, bool bgr_as_rgb);
|
|
|
|
|
|
|
|
/// Returns a CFDictionaryRef that can be passed to CVPixelBufferCreate to
|
|
|
|
/// ensure that the pixel buffer is compatible with OpenGL ES and with
|
|
|
|
/// CVOpenGLESTextureCacheCreateTextureFromImage.
|
|
|
|
/// The returned object is persistent and should not be released.
|
|
|
|
CFDictionaryRef GetCVPixelBufferAttributesForGlCompatibility();
|
|
|
|
|
|
|
|
/// Prints debug information about available CoreVideo pixel formats.
|
|
|
|
/// This prints to stdout.
|
|
|
|
void DumpCVPixelFormats();
|
|
|
|
|
|
|
|
#endif // MEDIAPIPE_OBJC_UTIL_H_
|