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