xref: /aosp_15_r20/external/v4l2_codec2/common/include/v4l2_codec2/common/FormatConverter.h (revision 0ec5a0ec62797f775085659156625e7f1bdb369f)
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