1 /* 2 * Copyright (c) 2025 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 AVCODEC_SAMPLE_INFO_H 17 #define AVCODEC_SAMPLE_INFO_H 18 #include <bits/alltypes.h> 19 #include <cstdint> 20 #include <map> 21 #include <multimedia/player_framework/native_avcodec_videoencoder.h> 22 #include <string> 23 #include <condition_variable> 24 #include <queue> 25 #include <fstream> 26 #include <native_buffer/native_buffer.h> 27 #include "multimedia/player_framework/native_avcodec_base.h" 28 #include "multimedia/player_framework/native_avbuffer.h" 29 30 using namespace std; 31 32 constexpr int32_t BITRATE_10M = 10 * 1024 * 1024; // 10Mbps 33 constexpr int32_t BITRATE_20M = 20 * 1024 * 1024; // 20Mbps 34 constexpr int32_t BITRATE_30M = 30 * 1024 * 1024; // 30Mbps 35 36 const unordered_map<OH_AVPixelFormat, string> PIXEL_FORMAT_TO_STRING = { 37 {AV_PIXEL_FORMAT_YUVI420, "YUVI420"}, 38 {AV_PIXEL_FORMAT_NV12, "NV12"}, 39 {AV_PIXEL_FORMAT_NV21, "NV21"}, 40 {AV_PIXEL_FORMAT_SURFACE_FORMAT, "SURFACE_FORMAT"}, 41 {AV_PIXEL_FORMAT_RGBA, "RGBA"}, 42 }; 43 44 struct SampleInfo { 45 int32_t inputFd = -1; 46 int32_t outputFd = -1; 47 int64_t inputFileOffset = 0; 48 int64_t inputFileSize = 0; 49 string inputFilePath; 50 string videoCodecMime = ""; 51 string audioCodecMime = ""; 52 int32_t videoWidth = 0; 53 int32_t videoHeight = 0; 54 double frameRate = 0.0; 55 int64_t bitrate = 10 * 1024 * 1024; // 10Mbps; 56 int64_t frameInterval = 0; 57 OH_AVPixelFormat pixelFormat = AV_PIXEL_FORMAT_NV12; 58 uint32_t bitrateMode = CBR; 59 int32_t iFrameInterval = 100; 60 int32_t rangFlag = 1; 61 int32_t codecType = 0; 62 int32_t codecRunMode = 0; 63 string outputFilePath; 64 65 int32_t audioSampleForamt = 0; 66 int32_t audioSampleRate = 0; 67 int32_t audioChannelCount = 0; 68 int64_t audioChannelLayout = 0; 69 int32_t audioBitRate = 0; 70 uint8_t audioCodecConfig[100] = { 0 }; 71 size_t audioCodecSize = 0; 72 int32_t audioMaxInputSize = 0; 73 OH_AVFormat *audioFormat; 74 75 int32_t isHDRVivid = 0; 76 int32_t hevcProfile = HEVC_PROFILE_MAIN; 77 OH_ColorPrimary primary = COLOR_PRIMARY_BT2020; 78 OH_TransferCharacteristic transfer = TRANSFER_CHARACTERISTIC_HLG; 79 OH_MatrixCoefficient matrix = MATRIX_COEFFICIENT_BT2020_CL; 80 81 int32_t rotation = 0; 82 OHNativeWindow *window = nullptr; 83 84 void (*playDoneCallback)(void *context) = nullptr; 85 void *playDoneCallbackData = nullptr; 86 uint8_t codecConfig[1024]; 87 size_t codecConfigLen = 0; 88 int32_t aacAdts = -1; 89 }; 90 91 struct CodecBufferInfo { 92 uint32_t bufferIndex = 0; 93 uintptr_t *buffer = nullptr; 94 uint8_t *bufferAddr = nullptr; 95 OH_AVCodecBufferAttr attr = {0, 0, 0, AVCODEC_BUFFER_FLAGS_NONE}; 96 CodecBufferInfoCodecBufferInfo97 explicit CodecBufferInfo(uint8_t *addr) : bufferAddr(addr){}; CodecBufferInfoCodecBufferInfo98 CodecBufferInfo(uint8_t *addr, int32_t bufferSize) 99 : bufferAddr(addr), attr({0, bufferSize, 0, AVCODEC_BUFFER_FLAGS_NONE}){}; CodecBufferInfoCodecBufferInfo100 CodecBufferInfo(uint32_t argBufferIndex, OH_AVBuffer *argBuffer) 101 : bufferIndex(argBufferIndex), buffer(reinterpret_cast<uintptr_t *>(argBuffer)) 102 { 103 OH_AVBuffer_GetBufferAttr(argBuffer, &attr); 104 }; 105 }; 106 107 enum CodecType { 108 AUTO = 0, 109 VIDEO_HW_DECODER = 1, 110 VIDEO_SW_DECODER = 2, 111 VIDEO_HW_ENCODER = 3, 112 VIDEO_SW_ENCODER = 4, 113 }; 114 115 enum CodecRunMode { 116 SURFACE = 0, 117 BUFFER = 1 118 }; 119 120 struct CodecUserData { 121 public: 122 SampleInfo *sampleInfo = nullptr; 123 bool isDecFirstFrame = false; 124 bool isEncFirstFrame = false; 125 126 int32_t width = 0; 127 int32_t height = 0; 128 int32_t widthStride = 0; 129 int32_t heightStride = 0; 130 131 uint32_t inputFrameCount = 0; 132 mutex inputMutex; 133 condition_variable inputCond; 134 queue<CodecBufferInfo> inputBufferInfoQueue; 135 136 uint32_t outputFrameCount = 0; 137 mutex outputMutex; 138 condition_variable outputCond; 139 mutex renderMutex; 140 condition_variable renderCond; 141 queue<CodecBufferInfo> outputBufferInfoQueue; 142 143 queue<unsigned char> renderQueue; 144 145 int64_t speed = 1.0f; 146 int64_t frameWrittenForSpeed = 0; 147 int64_t endPosAudioBufferPts = 0; 148 int64_t currentPosAudioBufferPts = 0; 149 ClearQueueCodecUserData150 void ClearQueue() 151 { 152 { 153 unique_lock<mutex> lock(inputMutex); 154 auto emptyQueue = queue<CodecBufferInfo>(); 155 inputBufferInfoQueue.swap(emptyQueue); 156 } 157 { 158 unique_lock<mutex> lock(outputMutex); 159 auto emptyQueue = queue<CodecBufferInfo>(); 160 outputBufferInfoQueue.swap(emptyQueue); 161 } 162 } 163 164 // Create cache 165 std::vector<char> cache; 166 int32_t remainlen = 0; 167 ClearCacheCodecUserData168 void ClearCache() 169 { 170 cache.clear(); 171 remainlen = 0; 172 } 173 WriteCacheCodecUserData174 void WriteCache(void *buffer, int32_t bufferLen) 175 { 176 if (bufferLen + remainlen > cache.size()) { 177 cache.resize(remainlen + bufferLen); 178 } 179 std::memcpy(cache.data() + remainlen, buffer, bufferLen); 180 remainlen += bufferLen; 181 } 182 ReadCacheCodecUserData183 bool ReadCache(void *buffer, int32_t bufferLen) 184 { 185 if (remainlen < bufferLen) { 186 return false; 187 } 188 std::memcpy(buffer, cache.data(), bufferLen); 189 remainlen = remainlen - bufferLen; 190 if (remainlen > 0) { 191 std::memmove(cache.data(), cache.data() + bufferLen, remainlen); 192 } 193 return true; 194 } 195 }; 196 197 #endif // AVCODEC_SAMPLE_INFO_H