1 /* 2 * Copyright (C) 2024 Huawei Device Co., Ltd. 3 * Licensed under the Apache License, Version 2.0 (the "License"); 4 * you may not use this file except in compliance with the License. 5 * You may obtain a copy of the License at 6 * 7 * http://www.apache.org/licenses/LICENSE-2.0 8 * 9 * Unless required by applicable law or agreed to in writing, software 10 * distributed under the License is distributed on an "AS IS" BASIS, 11 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 * See the License for the specific language governing permissions and 13 * limitations under the License. 14 */ 15 16 #ifndef FRAMEWORKS_INNERKITSIMPL_ACCESSOR_INCLUDE_BUFFER_METADATA_STREAM_H 17 #define FRAMEWORKS_INNERKITSIMPL_ACCESSOR_INCLUDE_BUFFER_METADATA_STREAM_H 18 19 #include <cstddef> 20 #include <cstdint> 21 #include <fstream> 22 #include <vector> 23 24 #include "metadata_stream.h" 25 26 namespace OHOS { 27 namespace Media { 28 #if defined(FRAMEWORKS_INNERKITSIMPL_ACCESSOR_INCLUDE_BUFFER_METADATA_STREAM_TESTS_PRIVATE) 29 #define FRAMEWORKS_INNERKITSIMPL_ACCESSOR_INCLUDE_BUFFER_METADATA_STREAM_PRIVATE_UNLESS_TESTED public 30 #else 31 #define FRAMEWORKS_INNERKITSIMPL_ACCESSOR_INCLUDE_BUFFER_METADATA_STREAM_PRIVATE_UNLESS_TESTED private 32 #endif 33 34 /** 35 * @class BufferMetadataStream 36 * @brief A class for handling image streams in memory. 37 * 38 * This class provides methods for reading from and seeking within an image 39 * stream in memory. 40 */ 41 class BufferMetadataStream : public MetadataStream { 42 public: 43 enum MemoryMode { 44 Fix, // Memory is fixed at construction and cannot be changed 45 Dynamic // Memory can be changed 46 }; 47 48 /* * 49 * @brief Constructs a new BufferMetadataStream object. 50 */ 51 BufferMetadataStream(); 52 53 /* * 54 * @brief Constructs a new BufferMetadataStream object with specified data, size and memory mode. 55 * @param originData The original data to be used for the BufferMetadataStream. 56 * @param size The size of the original data. 57 * @param mode The memory mode to be used for the BufferMetadataStream. 58 * @param originalFd The original file fd of buffer data. 59 * @param originalPath The original file path of buffer data. 60 */ 61 BufferMetadataStream(byte *originData, size_t size, MemoryMode mode, 62 int originalFd = METADATA_STREAM_INVALID_FD, 63 const std::string &originalPath = METADATA_STREAM_INVALID_PATH); 64 65 /* * 66 * @brief Destructs the BufferMetadataStream object. 67 */ 68 virtual ~BufferMetadataStream(); 69 70 /* * 71 * @brief Writes data to the BufferMetadataStream. 72 * @param data The data to be written. 73 * @param size The size of the data. On a 32-bit system, the maximum size 74 * that can be written at once is 2GB or 4GB. 75 * @return The number of bytes written. Returns -1 if an error occurred 76 * during writing. 77 */ 78 virtual ssize_t Write(uint8_t *data, ssize_t size) override; 79 80 /* * 81 * @brief Reads data from the BufferMetadataStream. 82 * @param buf The buffer to store the data. 83 * @param size The size of the data. 84 * @return The number of bytes read. Returns -1 if the buffer pointer is null. 85 */ 86 virtual ssize_t Read(uint8_t *buf, ssize_t size) override; 87 88 /* * 89 * @brief Reads a byte from the BufferMetadataStream. 90 * @return The byte read. 91 */ 92 virtual int ReadByte() override; 93 94 /* * 95 * @brief Seeks to a specific position in the image stream. 96 * @param offset The offset to seek to. This can be positive or negative. 97 * @param pos The position to seek from. This can be the beginning, current position, or end of the stream. 98 * @return The new position in the stream. Returns -1 if an invalid seek position is provided. 99 */ 100 virtual long Seek(long offset, SeekPos pos) override; 101 102 /* * 103 * @brief Gets the current position in the BufferMetadataStream. 104 * @return The current position. 105 */ 106 virtual long Tell() override; 107 108 /* * 109 * @brief Checks if the end of the BufferMetadataStream has been reached. 110 * @return true if the end has been reached, false otherwise. 111 */ 112 virtual bool IsEof() override; 113 114 /* * 115 * @brief Checks if the BufferMetadataStream is open. 116 * @return true if it is open, false otherwise. 117 */ 118 virtual bool IsOpen() override; 119 120 /* * 121 * For BufferMetadataStream, the Open function with a mode is not applicable, 122 * as the data for BufferMetadataStream is already in memory and there are no 123 * read-only scenarios. 124 * 125 * @param mode This parameter is ignored, as there are no read-only 126 * scenarios for BufferMetadataStream. 127 * @return Returns false, as this function is not applicable for 128 * BufferMetadataStream. 129 */ 130 virtual bool Open(OpenMode mode = OpenMode::ReadWrite) override; 131 132 /* * 133 * For BufferMetadataStream, the Flush function is not applicable, 134 * as the data for BufferMetadataStream is already in memory and there are no 135 * write operations that need to be flushed. 136 * 137 * @return Returns true, as this function is not applicable for 138 * BufferMetadataStream, but it is assumed that the data is always "flushed" in 139 * memory. 140 */ 141 virtual bool Flush() override; 142 143 /* * 144 * @param isWriteable This parameter is ignored, the data of 145 * BufferMetadataStream is always writable. 146 * @return Returns a pointer to the data of BufferMetadataStream. 147 * The read/write characteristics of the memory pointed to by the 148 * returned addr pointer depend on whether it comes from managed 149 * memory or is allocated by itself. If it is self-allocated, it 150 * can be both read and written. If it is managed, it depends on 151 * the read/write properties of the managed memory. 152 */ 153 virtual byte *GetAddr(bool isWriteable = false) override; 154 155 /* * 156 * Transfer the content of the source MetadataStream to the current 157 * BufferMetadataStream. This function first clears the current buffer and sets 158 * the current offset to 0. Then, this function reads data from the source 159 * MetadataStream and appends the read data to the current buffer. If an error 160 * occurs during the reading process, this function will return immediately 161 * and log the error information. 162 * 163 * @param src The source MetadataStream, this function will read data from this 164 * MetadataStream. 165 */ 166 virtual bool CopyFrom(MetadataStream &src) override; 167 168 /* * 169 * Get the size of the BufferMetadataStream. 170 * 171 * @return Returns the size of the BufferMetadataStream. 172 */ 173 virtual ssize_t GetSize() override; 174 175 /* * 176 * Release the managed memory to the external. 177 * 178 * @return Returns the pointer to the released memory. 179 */ 180 byte *Release(); 181 182 private: 183 /* 184 * These constants are used in conjunction with CalculateNewCapacity to quickly approximate potential image sizes. 185 * Based on the value of expandCount_, an appropriate capacity level is selected to optimize memory management and 186 * reduce memory copy operations, thereby enhancing the efficiency of image processing. 187 */ 188 static constexpr long METADATA_STREAM_INITIAL_CAPACITY = METADATA_STREAM_PAGE_SIZE; 189 static constexpr long METADATA_STREAM_CAPACITY_512KB = 512 * 1024; 190 static constexpr long METADATA_STREAM_CAPACITY_2MB = 2 * 1024 * 1024; 191 static constexpr long METADATA_STREAM_CAPACITY_5MB = 5 * 1024 * 1024; 192 static constexpr long METADATA_STREAM_CAPACITY_15MB = 15 * 1024 * 1024; 193 static constexpr long METADATA_STREAM_CAPACITY_30MB = 30 * 1024 * 1024; 194 195 static constexpr int INITIAL_EXPANSION = 0; 196 static constexpr int SECOND_EXPANSION = 1; 197 static constexpr int THIRD_EXPANSION = 2; 198 static constexpr int FOURTH_EXPANSION = 3; 199 static constexpr int FIFTH_EXPANSION = 4; 200 201 static constexpr int METADATA_STREAM_MAX_CAPACITY = 1024 * 1024 * 1024; 202 203 /* * 204 * @brief Closes the BufferImageStream. 205 */ 206 virtual void Close() override; 207 bool ReadAndWriteData(MetadataStream &src); 208 void HandleWriteFailure(); 209 210 /* * 211 * @brief To handle memory read/write operations where the image size is often unknown, a fixed incremental 212 * growth approach would result in numerous memory copy operations. Considering that the current scenario 213 * involves processing images, a leapfrogging approach is used to quickly approximate potential image sizes, 214 * thereby reducing the number of memory copies. 215 * @param currentOffset The current offset in the BufferImageStream. 216 * @param size The size to be added to the BufferImageStream. 217 * @return The new capacity of the BufferImageStream. 218 */ 219 long CalculateNewCapacity(long currentOffset, ssize_t size); 220 221 /* * 222 * @brief Tracks the number of capacity expansions to facilitate the leapfrogging approach in capacity calculation. 223 * This count helps in selecting the appropriate predefined capacity level during memory allocation for image 224 * processing, optimizing the approach to quickly approximate potential image sizes and reduce memory copy 225 * operations. 226 */ 227 int expandCount_ = 0; 228 229 /* * 230 * @brief The memory buffer of the BufferImageStream. 231 */ 232 byte *buffer_; 233 234 /* * 235 * @brief The original pointer saved when constructed with originData. 236 * It is needed when closing to determine whether to release the buffer. 237 */ 238 byte *originData_; 239 240 /* * 241 * @brief The pre-allocated memory capacity of the buffer. 242 */ 243 long capacity_; 244 245 /* * 246 * @brief The data size of the buffer. 247 * Since it is in memory, bufferSize will not exceed the maximum length of 248 * memory, so size_t is not used here. 249 */ 250 long bufferSize_; 251 252 /* * 253 * @brief The current offset in the BufferImageStream. 254 */ 255 long currentOffset_; 256 257 /* * 258 * @brief The memory mode, which can be fixed memory or dynamic memory. 259 * See MemoryMode for details. 260 */ 261 MemoryMode memoryMode_; 262 }; 263 } // namespace Media 264 } // namespace OHOS 265 #endif // FRAMEWORKS_INNERKITSIMPL_ACCESSOR_INCLUDE_BUFFER_METADATA_STREAM_H 266