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 |inputBlock| to the configured pixel format and return it as |convertedBlock|. 59 // Returns the original block if no conversion is required. 60 c2_status_t convertBlock(uint64_t frameIndex, const C2ConstGraphicBlock& inputBlock, 61 C2ConstGraphicBlock* convertedBlock); 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 constant used by BlockEntry to indicate no frame is associated with the BlockEntry. 69 static constexpr uint64_t kNoFrameAssociated = ~static_cast<uint64_t>(0); 70 71 // There are 2 types of BlockEntry: 72 // 1. If |mBlock| is an allocated graphic block (not nullptr). This BlockEntry is for 73 // conversion, and |mAssociatedFrameIndex| records the frame index of the input frame which 74 // is currently converted from. This is created on initialize() and released while 75 // FormatConverter is destroyed. 76 // 2. If |mBlock| is nullptr. This BlockEntry is only used to record zero-copied frame index to 77 // |mAssociatedFrameIndex|. This is created on zero-copy is applied during convertBlock(), 78 // and released on returnBlock() in associated with returned frame index. 79 struct BlockEntry { 80 // Constructor of convertible entry. BlockEntryBlockEntry81 BlockEntry(std::shared_ptr<C2GraphicBlock> block) : mBlock(std::move(block)) {} 82 // Constructir of zero-copy entry. BlockEntryBlockEntry83 BlockEntry(uint64_t frameIndex) : mAssociatedFrameIndex(frameIndex) {} 84 85 std::shared_ptr<C2GraphicBlock> mBlock; 86 uint64_t mAssociatedFrameIndex = kNoFrameAssociated; 87 }; 88 89 FormatConverter() = default; 90 91 // Initialize format converter. This pre-allocates a set of graphic blocks with |codedSize| and 92 // |outFormat| for format conversion. This function should be called prior to other functions. 93 c2_status_t initialize(VideoPixelFormat outFormat, const ui::Size& visibleSize, 94 uint32_t inputCount, const ui::Size& codedSize); 95 96 // Allocate a set of graphic blocks with |mCodedSize| and |mOutFormat| for format conversion. 97 c2_status_t allocateBuffers(uint32_t count); 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 // The output pixel format. 110 VideoPixelFormat mOutFormat = VideoPixelFormat::UNKNOWN; 111 // The video frame visible size. 112 ui::Size mVisibleSize; 113 // The video frame coded size. 114 ui::Size mCodedSize; 115 }; 116 117 } // namespace android 118 119 #endif // ANDROID_V4L2_CODEC2_COMMON_FORMAT_CONVERTER_H 120