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