1 // Copyright 2019 The Chromium Authors. All rights reserved. 2 // Use of this source code is governed by a BSD-style license that can be 3 // found in the LICENSE file. 4 5 #ifndef ANDROID_V4L2_CODEC2_COMMON_FORMAT_CONVERTER_H 6 #define ANDROID_V4L2_CODEC2_COMMON_FORMAT_CONVERTER_H 7 8 #include <limits> 9 #include <queue> 10 #include <vector> 11 12 #include <C2Buffer.h> 13 #include <ui/Size.h> 14 #include <utils/StrongPointer.h> 15 16 #include <v4l2_codec2/common/VideoPixelFormat.h> 17 18 namespace android { 19 20 class GraphicBuffer; 21 22 // ImplDefinedToRGBXMap can provide the layout for RGB-backed IMPLEMENTATION_DEFINED format case, 23 // which will be failed to map by C2AllocationGralloc::map(). When the instance is created, it will 24 // own the GraphicBuffer wrapped from input block and lock it, to provide the address, offset, and 25 // rowInc information. The GraphicBuffer will be unlocked and released under destruction. 26 class ImplDefinedToRGBXMap { 27 public: 28 ~ImplDefinedToRGBXMap(); 29 ImplDefinedToRGBXMap() = delete; 30 31 static std::unique_ptr<ImplDefinedToRGBXMap> Create(const C2ConstGraphicBlock& block); 32 addr()33 const uint8_t* addr() const { return mAddr; } offset()34 int offset() const { return 0; } rowInc()35 int rowInc() const { return mRowInc; } 36 37 private: 38 ImplDefinedToRGBXMap(sp<GraphicBuffer> buf, uint8_t* addr, int rowInc); 39 40 const sp<GraphicBuffer> mBuffer; 41 const uint8_t* mAddr; 42 const int mRowInc; 43 }; 44 45 class FormatConverter { 46 public: 47 ~FormatConverter() = default; 48 49 FormatConverter(const FormatConverter&) = delete; 50 FormatConverter& operator=(const FormatConverter&) = delete; 51 52 // Create FormatConverter instance and initialize it, nullptr will be returned on 53 // initialization error. 54 static std::unique_ptr<FormatConverter> Create(VideoPixelFormat outFormat, 55 const ui::Size& visibleSize, uint32_t inputCount, 56 const ui::Size& codedSize); 57 58 // Convert the input block into the alternative block with required pixel format and return it, 59 // or return the original block if zero-copy is applied. 60 C2ConstGraphicBlock convertBlock(uint64_t frameIndex, const C2ConstGraphicBlock& inputBlock, 61 c2_status_t* status /* non-null */); 62 // Return the block ownership when VEA no longer needs it, or erase the zero-copy BlockEntry. 63 c2_status_t returnBlock(uint64_t frameIndex); 64 // Check if there is available block for conversion. isReady()65 bool isReady() const { return !mAvailableQueue.empty(); } 66 67 private: 68 // The minimal number requirement of allocated buffers for conversion. This value is the same as 69 // kMinInputBufferArraySize from CCodecBufferChannel. 70 static constexpr uint32_t kMinInputBufferCount = 8; 71 // The constant used by BlockEntry to indicate no frame is associated with the BlockEntry. 72 static constexpr uint64_t kNoFrameAssociated = ~static_cast<uint64_t>(0); 73 74 // There are 2 types of BlockEntry: 75 // 1. If |mBlock| is an allocated graphic block (not nullptr). This BlockEntry is for 76 // conversion, and |mAssociatedFrameIndex| records the frame index of the input frame which 77 // is currently converted from. This is created on initialize() and released while 78 // FormatConverter is destroyed. 79 // 2. If |mBlock| is nullptr. This BlockEntry is only used to record zero-copied frame index to 80 // |mAssociatedFrameIndex|. This is created on zero-copy is applied during convertBlock(), 81 // and released on returnBlock() in associated with returned frame index. 82 struct BlockEntry { 83 // Constructor of convertible entry. BlockEntryBlockEntry84 BlockEntry(std::shared_ptr<C2GraphicBlock> block) : mBlock(std::move(block)) {} 85 // Constructir of zero-copy entry. BlockEntryBlockEntry86 BlockEntry(uint64_t frameIndex) : mAssociatedFrameIndex(frameIndex) {} 87 88 std::shared_ptr<C2GraphicBlock> mBlock; 89 uint64_t mAssociatedFrameIndex = kNoFrameAssociated; 90 }; 91 92 FormatConverter() = default; 93 94 // Initialize foramt converter. It will pre-allocate a set of graphic blocks as |codedSize| and 95 // |outFormat|. This function should be called prior to other functions. 96 c2_status_t initialize(VideoPixelFormat outFormat, const ui::Size& visibleSize, 97 uint32_t inputCount, const ui::Size& codedSize); 98 99 // The array of block entries. 100 std::vector<std::unique_ptr<BlockEntry>> mGraphicBlocks; 101 // The queue of recording the raw pointers of available graphic blocks. The consumed block will 102 // be popped on convertBlock(), and returned block will be pushed on returnBlock(). 103 std::queue<BlockEntry*> mAvailableQueue; 104 // The temporary U/V plane memory allocation for ABGR to NV12 conversion. They should be 105 // allocated on initialize(). 106 std::unique_ptr<uint8_t[]> mTempPlaneU; 107 std::unique_ptr<uint8_t[]> mTempPlaneV; 108 109 VideoPixelFormat mOutFormat = VideoPixelFormat::UNKNOWN; 110 ui::Size mVisibleSize; 111 }; 112 113 } // namespace android 114 115 #endif // ANDROID_V4L2_CODEC2_COMMON_FORMAT_CONVERTER_H 116