blob: 8daf3d87af2b2eb4557464b49498e5335401294b [file] [log] [blame]
/*
* Copyright 2018, The Android Open Source Project
*
* 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 CODEC2_BUFFER_UTILS_H_
#define CODEC2_BUFFER_UTILS_H_
#include <C2Buffer.h>
#include <C2Config.h>
#include <C2ParamDef.h>
#include <media/hardware/VideoAPI.h>
#include <utils/StrongPointer.h>
#include <utils/Errors.h>
namespace android {
/**
* Converts an RGB view to planar YUV 420 media image.
*
* \param dstY pointer to media image buffer
* \param dstStride stride in bytes
* \param dstVStride vertical stride in pixels
* \param bufferSize media image buffer size
* \param src source image
*
* \retval NO_MEMORY media image is too small
* \retval OK on success
*/
status_t ConvertRGBToPlanarYUV(
uint8_t *dstY, size_t dstStride, size_t dstVStride, size_t bufferSize,
const C2GraphicView &src, C2Color::matrix_t colorMatrix = C2Color::MATRIX_BT601,
C2Color::range_t colorRange = C2Color::RANGE_LIMITED);
/**
* Returns a planar YUV 420 8-bit media image descriptor.
*
* \param width width of image in pixels
* \param height height of image in pixels
* \param stride stride of image in pixels
* \param vstride vertical stride of image in pixels
*/
MediaImage2 CreateYUV420PlanarMediaImage2(
uint32_t width, uint32_t height, uint32_t stride, uint32_t vstride);
/**
* Returns a semiplanar YUV 420 8-bit media image descriptor.
*
* \param width width of image in pixels
* \param height height of image in pixels
* \param stride stride of image in pixels
* \param vstride vertical stride of image in pixels
*/
MediaImage2 CreateYUV420SemiPlanarMediaImage2(
uint32_t width, uint32_t height, uint32_t stride, uint32_t vstride);
/**
* Copies a graphic view into a media image.
*
* \param imgBase base of MediaImage
* \param img MediaImage data
* \param view graphic view
*
* \return OK on success
*/
status_t ImageCopy(uint8_t *imgBase, const MediaImage2 *img, const C2GraphicView &view);
/**
* Copies a media image into a graphic view.
*
* \param view graphic view
* \param imgBase base of MediaImage
* \param img MediaImage data
*
* \return OK on success
*/
status_t ImageCopy(C2GraphicView &view, const uint8_t *imgBase, const MediaImage2 *img);
/**
* Returns true iff a view has a YUV 420 888 layout.
*/
bool IsYUV420(const C2GraphicView &view);
/**
* Returns true iff a view has a YUV 420 10-10-10 layout.
*/
bool IsYUV420_10bit(const C2GraphicView &view);
/**
* Returns true iff a view has a NV12 layout.
*/
bool IsNV12(const C2GraphicView &view);
/**
* Returns true iff a view has a P010 layout.
*/
bool IsP010(const C2GraphicView &view);
/**
* Returns true iff a view has a NV21 layout.
*/
bool IsNV21(const C2GraphicView &view);
/**
* Returns true iff a view has a I420 layout.
*/
bool IsI420(const C2GraphicView &view);
/**
* Returns true iff a MediaImage2 has a YUV 420 888 layout.
*/
bool IsYUV420(const MediaImage2 *img);
/**
* Returns true iff a MediaImage2 has a NV12 layout.
*/
bool IsNV12(const MediaImage2 *img);
/**
* Returns true iff a MediaImage2 has a NV21 layout.
*/
bool IsNV21(const MediaImage2 *img);
/**
* Returns true iff a MediaImage2 has a I420 layout.
*/
bool IsI420(const MediaImage2 *img);
enum FlexLayout {
FLEX_LAYOUT_UNKNOWN,
FLEX_LAYOUT_PLANAR,
FLEX_LAYOUT_SEMIPLANAR_UV,
FLEX_LAYOUT_SEMIPLANAR_VU,
};
/**
* Returns layout of YCBCR_420_888 pixel format.
*/
FlexLayout GetYuv420FlexibleLayout();
/**
* A raw memory block to use for internal buffers.
*
* TODO: replace this with C2LinearBlocks from a private C2BlockPool
*/
struct MemoryBlock : public C2MemoryBlock<uint8_t> {
virtual const uint8_t* data() const override;
virtual size_t size() const override;
inline uint8_t *data() {
return const_cast<uint8_t*>(const_cast<const MemoryBlock*>(this)->data());
}
// allocates an unmanaged block (not in a pool)
static MemoryBlock Allocate(size_t);
// memory block with no actual memory (size is 0, data is null)
MemoryBlock();
struct Impl;
MemoryBlock(std::shared_ptr<Impl> impl);
virtual ~MemoryBlock();
private:
std::shared_ptr<Impl> mImpl;
};
/**
* A raw memory mini-pool.
*/
struct MemoryBlockPool {
/**
* Fetches a block with a given size.
*
* \param size size in bytes
*/
MemoryBlock fetch(size_t size);
MemoryBlockPool();
~MemoryBlockPool() = default;
private:
struct Impl;
std::shared_ptr<Impl> mImpl;
};
struct ABuffer;
struct AMessage;
class GraphicView2MediaImageConverter {
public:
/**
* Creates a C2GraphicView <=> MediaImage converter
*
* \param view C2GraphicView object
* \param format buffer format
* \param copy whether the converter is used for copy or not
*/
GraphicView2MediaImageConverter(
const C2GraphicView &view, const sp<AMessage> &format, bool copy);
status_t initCheck() const;
uint32_t backBufferSize() const;
/**
* Wrap C2GraphicView using a MediaImage2. Note that if not wrapped, the content is not mapped
* in this function --- the caller should use CopyGraphicView2MediaImage() function to copy the
* data into a backing buffer explicitly.
*
* \return media buffer. This is null if wrapping failed.
*/
sp<ABuffer> wrap() const;
bool setBackBuffer(const sp<ABuffer> &backBuffer);
/**
* Copy C2GraphicView to MediaImage2.
*/
status_t copyToMediaImage();
const sp<ABuffer> &imageData() const;
private:
status_t mInitCheck;
const C2GraphicView mView;
uint32_t mWidth;
uint32_t mHeight;
int32_t mClientColorFormat; ///< SDK color format for MediaImage
int32_t mComponentColorFormat; ///< SDK color format from component
sp<ABuffer> mWrapped; ///< wrapped buffer (if we can map C2Buffer to an ABuffer)
uint32_t mAllocatedDepth;
uint32_t mBackBufferSize;
sp<ABuffer> mMediaImage;
sp<ABuffer> mBackBuffer; ///< backing buffer if we have to copy C2Buffer <=> ABuffer
MediaImage2 *getMediaImage();
};
} // namespace android
#endif // CODEC2_BUFFER_UTILS_H_