/* * 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 #include #include #include #include #include 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 { virtual const uint8_t* data() const override; virtual size_t size() const override; inline uint8_t *data() { return const_cast(const_cast(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); virtual ~MemoryBlock(); private: std::shared_ptr 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 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 &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 wrap() const; bool setBackBuffer(const sp &backBuffer); /** * Copy C2GraphicView to MediaImage2. */ status_t copyToMediaImage(); const sp &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 mWrapped; ///< wrapped buffer (if we can map C2Buffer to an ABuffer) uint32_t mAllocatedDepth; uint32_t mBackBufferSize; sp mMediaImage; sp mBackBuffer; ///< backing buffer if we have to copy C2Buffer <=> ABuffer MediaImage2 *getMediaImage(); }; } // namespace android #endif // CODEC2_BUFFER_UTILS_H_