1*b7c941bbSAndroid Build Coastguard Worker /* 2*b7c941bbSAndroid Build Coastguard Worker * Copyright (C) 2020 The Android Open Source Project 3*b7c941bbSAndroid Build Coastguard Worker * 4*b7c941bbSAndroid Build Coastguard Worker * Licensed under the Apache License, Version 2.0 (the "License"); 5*b7c941bbSAndroid Build Coastguard Worker * you may not use this file except in compliance with the License. 6*b7c941bbSAndroid Build Coastguard Worker * You may obtain a copy of the License at 7*b7c941bbSAndroid Build Coastguard Worker * 8*b7c941bbSAndroid Build Coastguard Worker * http://www.apache.org/licenses/LICENSE-2.0 9*b7c941bbSAndroid Build Coastguard Worker * 10*b7c941bbSAndroid Build Coastguard Worker * Unless required by applicable law or agreed to in writing, software 11*b7c941bbSAndroid Build Coastguard Worker * distributed under the License is distributed on an "AS IS" BASIS, 12*b7c941bbSAndroid Build Coastguard Worker * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13*b7c941bbSAndroid Build Coastguard Worker * See the License for the specific language governing permissions and 14*b7c941bbSAndroid Build Coastguard Worker * limitations under the License. 15*b7c941bbSAndroid Build Coastguard Worker */ 16*b7c941bbSAndroid Build Coastguard Worker 17*b7c941bbSAndroid Build Coastguard Worker #ifndef MEDIACTSNATIVE_NATIVE_CODEC_TEST_BASE_H 18*b7c941bbSAndroid Build Coastguard Worker #define MEDIACTSNATIVE_NATIVE_CODEC_TEST_BASE_H 19*b7c941bbSAndroid Build Coastguard Worker 20*b7c941bbSAndroid Build Coastguard Worker #include <media/NdkMediaCodec.h> 21*b7c941bbSAndroid Build Coastguard Worker #include <zlib.h> 22*b7c941bbSAndroid Build Coastguard Worker 23*b7c941bbSAndroid Build Coastguard Worker #include <cmath> 24*b7c941bbSAndroid Build Coastguard Worker #include <cstdint> 25*b7c941bbSAndroid Build Coastguard Worker #include <list> 26*b7c941bbSAndroid Build Coastguard Worker #include <mutex> 27*b7c941bbSAndroid Build Coastguard Worker #include <vector> 28*b7c941bbSAndroid Build Coastguard Worker 29*b7c941bbSAndroid Build Coastguard Worker #include "NativeMediaCommon.h" 30*b7c941bbSAndroid Build Coastguard Worker 31*b7c941bbSAndroid Build Coastguard Worker #define RETURN_IF_FAIL(status, str) \ 32*b7c941bbSAndroid Build Coastguard Worker { \ 33*b7c941bbSAndroid Build Coastguard Worker media_status_t val = (status); \ 34*b7c941bbSAndroid Build Coastguard Worker if (AMEDIA_OK != val) { \ 35*b7c941bbSAndroid Build Coastguard Worker std::string msg = StringFormat("%s with error %d \n", str, val); \ 36*b7c941bbSAndroid Build Coastguard Worker ALOGE("%s", msg.c_str()); \ 37*b7c941bbSAndroid Build Coastguard Worker mErrorLogs.append((msg)); \ 38*b7c941bbSAndroid Build Coastguard Worker return false; \ 39*b7c941bbSAndroid Build Coastguard Worker } \ 40*b7c941bbSAndroid Build Coastguard Worker } 41*b7c941bbSAndroid Build Coastguard Worker 42*b7c941bbSAndroid Build Coastguard Worker #define RETURN_IF_TRUE(cond, msg) \ 43*b7c941bbSAndroid Build Coastguard Worker if ((cond)) { \ 44*b7c941bbSAndroid Build Coastguard Worker ALOGE("%s", (msg).c_str()); \ 45*b7c941bbSAndroid Build Coastguard Worker mErrorLogs.append((msg)).append("\n"); \ 46*b7c941bbSAndroid Build Coastguard Worker return false; \ 47*b7c941bbSAndroid Build Coastguard Worker } 48*b7c941bbSAndroid Build Coastguard Worker 49*b7c941bbSAndroid Build Coastguard Worker #define RETURN_IF_FALSE(cond, msg) \ 50*b7c941bbSAndroid Build Coastguard Worker if (!(cond)) { \ 51*b7c941bbSAndroid Build Coastguard Worker ALOGE("%s", (msg).c_str()); \ 52*b7c941bbSAndroid Build Coastguard Worker mErrorLogs.append((msg)).append("\n"); \ 53*b7c941bbSAndroid Build Coastguard Worker return false; \ 54*b7c941bbSAndroid Build Coastguard Worker } 55*b7c941bbSAndroid Build Coastguard Worker 56*b7c941bbSAndroid Build Coastguard Worker #define RETURN_IF_NULL(var, msg) \ 57*b7c941bbSAndroid Build Coastguard Worker if ((var) == nullptr) { \ 58*b7c941bbSAndroid Build Coastguard Worker ALOGE("%s", (msg).c_str()); \ 59*b7c941bbSAndroid Build Coastguard Worker mErrorLogs.append((msg)).append("\n"); \ 60*b7c941bbSAndroid Build Coastguard Worker return false; \ 61*b7c941bbSAndroid Build Coastguard Worker } 62*b7c941bbSAndroid Build Coastguard Worker 63*b7c941bbSAndroid Build Coastguard Worker struct callbackObject { 64*b7c941bbSAndroid Build Coastguard Worker AMediaCodecBufferInfo bufferInfo; 65*b7c941bbSAndroid Build Coastguard Worker int32_t bufferIndex; 66*b7c941bbSAndroid Build Coastguard Worker bool isInput; 67*b7c941bbSAndroid Build Coastguard Worker callbackObjectcallbackObject68*b7c941bbSAndroid Build Coastguard Worker callbackObject(int32_t index, AMediaCodecBufferInfo* info) 69*b7c941bbSAndroid Build Coastguard Worker : bufferInfo{*info}, bufferIndex{index}, isInput{false} {} 70*b7c941bbSAndroid Build Coastguard Worker callbackObjectcallbackObject71*b7c941bbSAndroid Build Coastguard Worker callbackObject(int32_t index) : bufferIndex{index}, isInput{true} {} 72*b7c941bbSAndroid Build Coastguard Worker callbackObjectcallbackObject73*b7c941bbSAndroid Build Coastguard Worker callbackObject() : bufferIndex{-1}, isInput{false} {} 74*b7c941bbSAndroid Build Coastguard Worker }; 75*b7c941bbSAndroid Build Coastguard Worker 76*b7c941bbSAndroid Build Coastguard Worker class CodecAsyncHandler { 77*b7c941bbSAndroid Build Coastguard Worker private: 78*b7c941bbSAndroid Build Coastguard Worker std::mutex mMutex; 79*b7c941bbSAndroid Build Coastguard Worker std::condition_variable mCondition; 80*b7c941bbSAndroid Build Coastguard Worker std::list<callbackObject> mCbInputQueue; 81*b7c941bbSAndroid Build Coastguard Worker std::list<callbackObject> mCbOutputQueue; 82*b7c941bbSAndroid Build Coastguard Worker AMediaFormat* mOutFormat; 83*b7c941bbSAndroid Build Coastguard Worker volatile bool mSignalledOutFormatChanged; 84*b7c941bbSAndroid Build Coastguard Worker volatile bool mSignalledError; 85*b7c941bbSAndroid Build Coastguard Worker std::string mErrorMsg; 86*b7c941bbSAndroid Build Coastguard Worker 87*b7c941bbSAndroid Build Coastguard Worker public: 88*b7c941bbSAndroid Build Coastguard Worker CodecAsyncHandler(); 89*b7c941bbSAndroid Build Coastguard Worker ~CodecAsyncHandler(); 90*b7c941bbSAndroid Build Coastguard Worker void pushToInputList(callbackObject element); 91*b7c941bbSAndroid Build Coastguard Worker void pushToOutputList(callbackObject element); 92*b7c941bbSAndroid Build Coastguard Worker callbackObject getInput(); 93*b7c941bbSAndroid Build Coastguard Worker callbackObject getOutput(); 94*b7c941bbSAndroid Build Coastguard Worker callbackObject getWork(); 95*b7c941bbSAndroid Build Coastguard Worker bool isInputQueueEmpty(); 96*b7c941bbSAndroid Build Coastguard Worker void clearQueues(); 97*b7c941bbSAndroid Build Coastguard Worker void setOutputFormat(AMediaFormat* format); 98*b7c941bbSAndroid Build Coastguard Worker AMediaFormat* getOutputFormat(); 99*b7c941bbSAndroid Build Coastguard Worker bool hasOutputFormatChanged(); 100*b7c941bbSAndroid Build Coastguard Worker bool waitOnFormatChange(); 101*b7c941bbSAndroid Build Coastguard Worker void setError(bool status, std::string& msg); 102*b7c941bbSAndroid Build Coastguard Worker bool getError() const; 103*b7c941bbSAndroid Build Coastguard Worker void resetContext(); 104*b7c941bbSAndroid Build Coastguard Worker std::string getErrorMsg(); 105*b7c941bbSAndroid Build Coastguard Worker media_status_t setCallBack(AMediaCodec* codec, bool isCodecInAsyncMode); 106*b7c941bbSAndroid Build Coastguard Worker }; 107*b7c941bbSAndroid Build Coastguard Worker 108*b7c941bbSAndroid Build Coastguard Worker class OutputManager { 109*b7c941bbSAndroid Build Coastguard Worker private: 110*b7c941bbSAndroid Build Coastguard Worker std::vector<int64_t> inpPtsArray; 111*b7c941bbSAndroid Build Coastguard Worker std::vector<int64_t> outPtsArray; 112*b7c941bbSAndroid Build Coastguard Worker std::vector<uint8_t> memory; 113*b7c941bbSAndroid Build Coastguard Worker uLong crc32value = 0U; 114*b7c941bbSAndroid Build Coastguard Worker std::string mErrorLogs; 115*b7c941bbSAndroid Build Coastguard Worker std::shared_ptr<std::string> mSharedErrorLogs; 116*b7c941bbSAndroid Build Coastguard Worker 117*b7c941bbSAndroid Build Coastguard Worker public: 118*b7c941bbSAndroid Build Coastguard Worker OutputManager(std::shared_ptr<std::string> log = std::make_shared<std::string>()) mSharedErrorLogs(log)119*b7c941bbSAndroid Build Coastguard Worker : mSharedErrorLogs(log) {} 120*b7c941bbSAndroid Build Coastguard Worker saveInPTS(int64_t pts)121*b7c941bbSAndroid Build Coastguard Worker void saveInPTS(int64_t pts) { 122*b7c941bbSAndroid Build Coastguard Worker // Add only Unique timeStamp, discarding any duplicate frame / non-display frame 123*b7c941bbSAndroid Build Coastguard Worker if (0 == std::count(inpPtsArray.begin(), inpPtsArray.end(), pts)) { 124*b7c941bbSAndroid Build Coastguard Worker inpPtsArray.push_back(pts); 125*b7c941bbSAndroid Build Coastguard Worker } 126*b7c941bbSAndroid Build Coastguard Worker } saveOutPTS(int64_t pts)127*b7c941bbSAndroid Build Coastguard Worker void saveOutPTS(int64_t pts) { outPtsArray.push_back(pts); } 128*b7c941bbSAndroid Build Coastguard Worker bool isPtsStrictlyIncreasing(int64_t lastPts); 129*b7c941bbSAndroid Build Coastguard Worker bool isOutPtsListIdenticalToInpPtsList(bool requireSorting); saveToMemory(uint8_t * buf,AMediaCodecBufferInfo * info)130*b7c941bbSAndroid Build Coastguard Worker void saveToMemory(uint8_t* buf, AMediaCodecBufferInfo* info) { 131*b7c941bbSAndroid Build Coastguard Worker memory.insert(memory.end(), buf, buf + info->size); 132*b7c941bbSAndroid Build Coastguard Worker } updateChecksum(uint8_t * buf,AMediaCodecBufferInfo * info)133*b7c941bbSAndroid Build Coastguard Worker void updateChecksum(uint8_t* buf, AMediaCodecBufferInfo* info) { 134*b7c941bbSAndroid Build Coastguard Worker updateChecksum(buf, info, 0, 0, 0, 0); 135*b7c941bbSAndroid Build Coastguard Worker } 136*b7c941bbSAndroid Build Coastguard Worker 137*b7c941bbSAndroid Build Coastguard Worker void updateChecksum(uint8_t* buf, AMediaCodecBufferInfo* info, int width, int height, 138*b7c941bbSAndroid Build Coastguard Worker int stride, int bytesPerSample); getChecksum()139*b7c941bbSAndroid Build Coastguard Worker uLong getChecksum() { return crc32value; } reset()140*b7c941bbSAndroid Build Coastguard Worker void reset() { 141*b7c941bbSAndroid Build Coastguard Worker inpPtsArray.clear(); 142*b7c941bbSAndroid Build Coastguard Worker outPtsArray.clear(); 143*b7c941bbSAndroid Build Coastguard Worker memory.clear(); 144*b7c941bbSAndroid Build Coastguard Worker crc32value = 0U; 145*b7c941bbSAndroid Build Coastguard Worker mErrorLogs.clear(); 146*b7c941bbSAndroid Build Coastguard Worker mSharedErrorLogs->clear(); 147*b7c941bbSAndroid Build Coastguard Worker } 148*b7c941bbSAndroid Build Coastguard Worker bool equalsPtsList(OutputManager* that); 149*b7c941bbSAndroid Build Coastguard Worker bool equalsDequeuedOutput(OutputManager* that); 150*b7c941bbSAndroid Build Coastguard Worker bool equals(OutputManager* that); 151*b7c941bbSAndroid Build Coastguard Worker float getRmsError(uint8_t* refData, int length); getErrorMsg()152*b7c941bbSAndroid Build Coastguard Worker std::string getErrorMsg() { return mErrorLogs + *mSharedErrorLogs; } getOutStreamSize()153*b7c941bbSAndroid Build Coastguard Worker int getOutStreamSize() { return memory.size(); } getSharedErrorLogs()154*b7c941bbSAndroid Build Coastguard Worker std::shared_ptr<std::string> getSharedErrorLogs() { return mSharedErrorLogs; } 155*b7c941bbSAndroid Build Coastguard Worker }; 156*b7c941bbSAndroid Build Coastguard Worker 157*b7c941bbSAndroid Build Coastguard Worker class CodecTestBase { 158*b7c941bbSAndroid Build Coastguard Worker protected: 159*b7c941bbSAndroid Build Coastguard Worker const char* mMediaType; 160*b7c941bbSAndroid Build Coastguard Worker bool mIsAudio; 161*b7c941bbSAndroid Build Coastguard Worker bool mIsVideo; 162*b7c941bbSAndroid Build Coastguard Worker CodecAsyncHandler mAsyncHandle; 163*b7c941bbSAndroid Build Coastguard Worker bool mIsCodecInAsyncMode; 164*b7c941bbSAndroid Build Coastguard Worker bool mSawInputEOS; 165*b7c941bbSAndroid Build Coastguard Worker bool mSawOutputEOS; 166*b7c941bbSAndroid Build Coastguard Worker bool mSignalEOSWithLastFrame; 167*b7c941bbSAndroid Build Coastguard Worker int mInputCount; 168*b7c941bbSAndroid Build Coastguard Worker int mOutputCount; 169*b7c941bbSAndroid Build Coastguard Worker int64_t mPrevOutputPts; 170*b7c941bbSAndroid Build Coastguard Worker bool mSignalledOutFormatChanged; 171*b7c941bbSAndroid Build Coastguard Worker AMediaFormat* mOutFormat; 172*b7c941bbSAndroid Build Coastguard Worker int mBytesPerSample; 173*b7c941bbSAndroid Build Coastguard Worker 174*b7c941bbSAndroid Build Coastguard Worker bool mSaveToMem; 175*b7c941bbSAndroid Build Coastguard Worker OutputManager* mOutputBuff; 176*b7c941bbSAndroid Build Coastguard Worker OutputManager* mRefBuff; 177*b7c941bbSAndroid Build Coastguard Worker OutputManager* mTestBuff; 178*b7c941bbSAndroid Build Coastguard Worker OutputManager* mReconfBuff; 179*b7c941bbSAndroid Build Coastguard Worker 180*b7c941bbSAndroid Build Coastguard Worker AMediaCodec* mCodec; 181*b7c941bbSAndroid Build Coastguard Worker std::string mTestEnv; 182*b7c941bbSAndroid Build Coastguard Worker std::string mErrorLogs; 183*b7c941bbSAndroid Build Coastguard Worker 184*b7c941bbSAndroid Build Coastguard Worker CodecTestBase(const char* mediaType); 185*b7c941bbSAndroid Build Coastguard Worker ~CodecTestBase(); 186*b7c941bbSAndroid Build Coastguard Worker virtual bool configureCodec(AMediaFormat* format, bool isAsync, bool signalEOSWithLastFrame, 187*b7c941bbSAndroid Build Coastguard Worker bool isEncoder); 188*b7c941bbSAndroid Build Coastguard Worker virtual bool flushCodec(); 189*b7c941bbSAndroid Build Coastguard Worker bool reConfigureCodec(AMediaFormat* format, bool isAsync, bool signalEOSWithLastFrame, 190*b7c941bbSAndroid Build Coastguard Worker bool isEncoder); 191*b7c941bbSAndroid Build Coastguard Worker virtual void resetContext(bool isAsync, bool signalEOSWithLastFrame); 192*b7c941bbSAndroid Build Coastguard Worker virtual bool enqueueInput(size_t bufferIndex) = 0; 193*b7c941bbSAndroid Build Coastguard Worker virtual bool dequeueOutput(size_t bufferIndex, AMediaCodecBufferInfo* bufferInfo) = 0; 194*b7c941bbSAndroid Build Coastguard Worker virtual bool isTestStateValid(); 195*b7c941bbSAndroid Build Coastguard Worker bool enqueueEOS(size_t bufferIndex); 196*b7c941bbSAndroid Build Coastguard Worker virtual bool doWork(int frameLimit); 197*b7c941bbSAndroid Build Coastguard Worker bool queueEOS(); 198*b7c941bbSAndroid Build Coastguard Worker bool waitForAllOutputs(); 199*b7c941bbSAndroid Build Coastguard Worker static int getWidth(AMediaFormat* format); 200*b7c941bbSAndroid Build Coastguard Worker static int getHeight(AMediaFormat* format); 201*b7c941bbSAndroid Build Coastguard Worker static bool isFormatSimilar(AMediaFormat* inpFormat, AMediaFormat* outFormat); hasSeenError()202*b7c941bbSAndroid Build Coastguard Worker bool hasSeenError() { return mAsyncHandle.getError(); } 203*b7c941bbSAndroid Build Coastguard Worker public: getErrorMsg()204*b7c941bbSAndroid Build Coastguard Worker std::string getErrorMsg() { 205*b7c941bbSAndroid Build Coastguard Worker return mTestEnv + 206*b7c941bbSAndroid Build Coastguard Worker "################### Error Details #####################\n" + 207*b7c941bbSAndroid Build Coastguard Worker mErrorLogs; 208*b7c941bbSAndroid Build Coastguard Worker } 209*b7c941bbSAndroid Build Coastguard Worker }; 210*b7c941bbSAndroid Build Coastguard Worker 211*b7c941bbSAndroid Build Coastguard Worker #endif // MEDIACTSNATIVE_NATIVE_CODEC_TEST_BASE_H 212