1 /* 2 * Copyright (C) 2022 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 AVDECODER_DEMO_COMMON_H 17 #define AVDECODER_DEMO_COMMON_H 18 19 #include <iostream> 20 #include <atomic> 21 #include <fstream> 22 #include <queue> 23 #include <string> 24 #include <vector> 25 #include <thread> 26 #include <sys/time.h> 27 #include "securec.h" 28 #include "nocopyable.h" 29 #include "media_description.h" 30 #include "avcodec_audio_common.h" 31 #include "native_avcodec_audioencoder.h" 32 #include "avcodec_audio_channel_layout.h" 33 #include "avcodec_audio_encoder.h" 34 35 #ifdef __cplusplus 36 extern "C" { 37 #endif 38 #include "libavformat/avformat.h" 39 #include "libavutil/opt.h" 40 #ifdef __cplusplus 41 } 42 #endif 43 44 namespace OHOS { 45 namespace MediaAVCodec { 46 extern void OnError(OH_AVCodec* codec, int32_t errorCode, void* userData); 47 extern void OnOutputFormatChanged(OH_AVCodec* codec, OH_AVFormat* format, void* userData); 48 extern void OnInputBufferAvailable(OH_AVCodec* codec, uint32_t index, OH_AVMemory* data, void* userData); 49 extern void OnOutputBufferAvailable(OH_AVCodec* codec, uint32_t index, 50 OH_AVMemory* data, OH_AVCodecBufferAttr* attr, void* userData); 51 52 constexpr uint32_t FRAME_DURATION_US = 33000; 53 constexpr int32_t INPUT_FRAME_BYTES = 2 * 1024 * 4; 54 constexpr int32_t COMMON_FLAC_NUM = 576; 55 constexpr int32_t S16_BITS_PER_SAMPLE = 2; 56 constexpr int32_t S32_BITS_PER_SAMPLE = 4; 57 constexpr int32_t UNKNOWN_CHANNEL = 0; 58 59 constexpr int32_t AAC_FRAME_SIZE = 1024; 60 constexpr int32_t AAC_DEFAULT_BYTES_PER_SAMPLE = 4; 61 62 constexpr double DEFAULT_TIME_NUM = 1000000.0; 63 constexpr uint32_t ERROR_INDEX = 100; 64 65 typedef enum MyTimer { 66 TIMER_NONE = 0, 67 TIMER_INPUT = 1, 68 TIMER_FREEOUTPUT = 2, 69 TIMER_GETOUTPUTDESCRIPTION = 3 70 } MyTimer; 71 72 class AEncSignal { 73 public: 74 std::mutex inMutex_; 75 std::mutex outMutex_; 76 std::condition_variable inCond_; 77 std::condition_variable outCond_; 78 std::queue<uint32_t> inQueue_; 79 std::queue<uint32_t> outQueue_; 80 std::queue<OH_AVMemory*> inBufferQueue_; 81 std::queue<OH_AVMemory*> outBufferQueue_; 82 std::queue<OH_AVCodecBufferAttr> attrQueue_; 83 std::queue<AVCodecBufferInfo> infoQueue_; 84 std::queue<AVCodecBufferFlag> flagQueue_; 85 std::queue<std::shared_ptr<AVSharedMemory>> inInnerBufQueue_; 86 std::queue<std::shared_ptr<AVSharedMemory>> outInnerBufQueue_; 87 }; 88 class InnerAEnDemoCallback : public AVCodecCallback, public NoCopyable { 89 public: 90 explicit InnerAEnDemoCallback(std::shared_ptr<AEncSignal> signal); 91 ~InnerAEnDemoCallback() = default; 92 93 void OnError(AVCodecErrorType errorType, int32_t errorCode) override; 94 void OnOutputFormatChanged(const Format& format) override; 95 void OnInputBufferAvailable(uint32_t index, std::shared_ptr<AVSharedMemory> buffer) override; 96 void OnOutputBufferAvailable(uint32_t index, AVCodecBufferInfo info, AVCodecBufferFlag flag, 97 std::shared_ptr<AVSharedMemory> buffer) override; 98 private: 99 std::shared_ptr<AEncSignal> innersignal_; 100 }; 101 102 class AudioEncoderDemo : public NoCopyable { 103 public: 104 AudioEncoderDemo(); 105 ~AudioEncoderDemo(); 106 107 // native api 108 OH_AVCodec* NativeCreateByMime(const char* mime); 109 OH_AVCodec* NativeCreateByName(const char* name); 110 OH_AVErrCode NativeDestroy(OH_AVCodec *codec); 111 OH_AVErrCode NativeSetCallback(OH_AVCodec* codec, OH_AVCodecAsyncCallback callback); 112 OH_AVErrCode NativeConfigure(OH_AVCodec* codec, OH_AVFormat* format); 113 OH_AVErrCode NativePrepare(OH_AVCodec* codec); 114 OH_AVErrCode NativeStart(OH_AVCodec* codec); 115 OH_AVErrCode NativeStop(OH_AVCodec* codec); 116 OH_AVErrCode NativeFlush(OH_AVCodec* codec); 117 OH_AVErrCode NativeReset(OH_AVCodec* codec); 118 OH_AVFormat* NativeGetOutputDescription(OH_AVCodec* codec); 119 OH_AVErrCode NativeSetParameter(OH_AVCodec* codec, OH_AVFormat* format); 120 OH_AVErrCode NativePushInputData(OH_AVCodec* codec, uint32_t index, OH_AVCodecBufferAttr attr); 121 OH_AVErrCode NativeFreeOutputData(OH_AVCodec* codec, uint32_t index); 122 OH_AVErrCode NativeIsValid(OH_AVCodec* codec, bool* isVaild); 123 124 void stopThread(); 125 void updateInputData(); 126 void updateOutputData(); 127 128 void setTimerFlag(int32_t flag); 129 130 uint32_t NativeGetInputIndex(); 131 uint8_t* NativeGetInputBuf(); 132 uint32_t NativeGetOutputIndex(); 133 void HandleEOS(const uint32_t& index); 134 135 void NativePushInput(uint32_t index); 136 void NativeGetDescription(); 137 void NativeWriteOutput(std::ofstream& outputFile, uint32_t index, 138 OH_AVCodecBufferAttr attr, OH_AVMemory* data); 139 void NativeInputFunc(); 140 void NativeOutputFunc(); 141 void NativeCreateToStart(const char* name, OH_AVFormat* format); 142 void NativeStopAndClear(); 143 144 void NativeRunCase(std::string inputFile, std::string outputFile, 145 const char* name, OH_AVFormat* format); 146 void NativeRunCaseWithoutCreate(OH_AVCodec* handle, std::string inputFile, 147 std::string outputFile, OH_AVFormat* format, const char* name, bool needConfig); 148 void NativeRunCasePerformance(std::string inputFile, std::string outputFile, 149 const char* name, OH_AVFormat* format); 150 void NativeRunCaseFlush(std::string inputFile, std::string outputFileFirst, 151 std::string outputFileSecond, const char* name, OH_AVFormat* format); 152 void NativeRunCaseReset(std::string inputFile, std::string outputFileFirst, 153 std::string outputFileSecond, const char* name, OH_AVFormat* format); 154 OH_AVFormat* NativeRunCaseGetOutputDescription(std::string inputFile, 155 std::string outputFile, const char* name, OH_AVFormat* format); 156 157 // for test 158 void TestOutputFunc(); 159 void TestRunCase(std::string inputFile, std::string outputFile, const char* name, OH_AVFormat* format); 160 161 // Inner api 162 int32_t InnerCreateByMime(const std::string& mime); 163 int32_t InnerCreateByName(const std::string& name); 164 int32_t InnerConfigure(const Format& format); 165 int32_t InnerPrepare(); 166 int32_t InnerStart(); 167 int32_t InnerStop(); 168 int32_t InnerFlush(); 169 int32_t InnerReset(); 170 int32_t InnerRelease(); 171 int32_t InnerQueueInputBuffer(uint32_t index, AVCodecBufferInfo info, AVCodecBufferFlag flag); 172 173 int32_t InnerGetOutputFormat(Format& format); 174 int32_t InnerReleaseOutputBuffer(uint32_t index); 175 int32_t InnerSetParameter(const Format& format); 176 int32_t InnerSetCallback(const std::shared_ptr<AVCodecCallback>& callback); 177 int32_t InnerDestroy(); 178 void InnerInputFunc(); 179 void InnerOutputFunc(); 180 void InnerRunCase(std::string inputFile, std::string outputFile, 181 const std::string& name, Format& format); 182 void InnerRunCaseFlush(std::string inputFile, std::string outputFileFirst, 183 std::string outputFileSecond, const std::string& name, Format& format); 184 185 void InnerCreateToStart(const std::string& name, Format& format); 186 void InnerStopAndClear(); 187 void InnerRunCaseReset(std::string inputFile, std::string outputFileFirst, 188 std::string outputFileSecond, const std::string& name, Format& format); 189 190 std::shared_ptr<AEncSignal> getSignal(); 191 void InnerStopThread(); 192 void InnerHandleEOS(const uint32_t& index); 193 uint32_t InnerGetInputIndex(); 194 uint32_t InnerGetOutputIndex(); 195 int32_t InnerStartWithThread(); 196 void InnerUpdateInputData(); 197 void InnerUpdateOutputData(); 198 199 private: 200 std::atomic<bool> isRunning_ = false; 201 std::ifstream inputFile_; 202 std::unique_ptr<std::thread> inputLoop_; 203 std::unique_ptr<std::thread> outputLoop_; 204 OH_AVCodec* audioEnc_; 205 AEncSignal* signal_; 206 struct OH_AVCodecAsyncCallback cb_; 207 bool isFirstFrame_ = true; 208 209 std::unique_ptr<std::ifstream> testFile_; 210 std::shared_ptr<AVCodecAudioEncoder> inneraudioEnc_; 211 std::shared_ptr<AEncSignal> innersignal_; 212 std::shared_ptr<InnerAEnDemoCallback> innercb_; 213 uint32_t frameCount_ = 0; 214 int64_t timeStamp_ = 0; 215 216 std::queue<uint32_t> inIndexQueue_; 217 std::queue<uint8_t*> inBufQueue_; 218 std::queue<uint32_t> outIndexQueue_; 219 220 std::string outputFilePath; 221 std::string inputFilePath; 222 OH_AVFormat* curFormat = nullptr; 223 bool isGetOutputDescription = false; 224 225 int32_t timerFlag = 0; 226 int32_t runTimes = 0; 227 double totalTime = 0.0; 228 double otherTime = 0.0; 229 struct timeval startTime, endTime; 230 struct timeval start, end; 231 struct timeval inputStart, inputEnd; 232 struct timeval outputStart, outputEnd; 233 int32_t inputBufSize = INPUT_FRAME_BYTES; 234 }; 235 } 236 } 237 #endif // AVDECODER_DEMO_COMMON_H