1 /* 2 * Copyright (C) 2019 The Android Open Source Project 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16 17 #ifndef __BENCHMARK_COMMON_H__ 18 #define __BENCHMARK_COMMON_H__ 19 20 #include <sys/stat.h> 21 #include <inttypes.h> 22 #include <mutex> 23 #include <queue> 24 #include <thread> 25 #include <iostream> 26 27 #include <media/NdkMediaCodec.h> 28 #include <media/NdkMediaError.h> 29 30 #include "Stats.h" 31 #define UNUSED(x) (void)(x) 32 33 using namespace std; 34 35 constexpr uint32_t kQueueDequeueTimeoutUs = 1000; 36 constexpr uint32_t kMaxCSDStrlen = 16; 37 constexpr uint32_t kMaxBufferSize = 1024 * 1024 * 16; 38 // Change in kDefaultAudioEncodeFrameSize should also be taken to 39 // AUDIO_ENCODE_DEFAULT_MAX_INPUT_SIZE present in Encoder.java 40 constexpr uint32_t kDefaultAudioEncodeFrameSize = 4096; 41 42 template <typename T> 43 class CallBackQueue { 44 public: CallBackQueue()45 CallBackQueue() {} ~CallBackQueue()46 ~CallBackQueue() {} 47 push(T elem)48 void push(T elem) { 49 bool needsNotify = false; 50 { 51 lock_guard<mutex> lock(mMutex); 52 needsNotify = mQueue.empty(); 53 mQueue.push(move(elem)); 54 } 55 if (needsNotify) mQueueNotEmptyCondition.notify_one(); 56 } 57 pop()58 T pop() { 59 unique_lock<mutex> lock(mMutex); 60 if (mQueue.empty()) { 61 mQueueNotEmptyCondition.wait(lock, [this]() { return !mQueue.empty(); }); 62 } 63 auto result = mQueue.front(); 64 mQueue.pop(); 65 return result; 66 } 67 68 private: 69 mutex mMutex; 70 queue<T> mQueue; 71 condition_variable mQueueNotEmptyCondition; 72 }; 73 74 class CallBackHandle { 75 public: CallBackHandle()76 CallBackHandle() : mSawError(false), mIsDone(false), mStats(nullptr) { 77 mStats = new Stats(); 78 } 79 ~CallBackHandle()80 virtual ~CallBackHandle() { 81 if (mIOThread.joinable()) mIOThread.join(); 82 if (mStats) delete mStats; 83 } 84 85 void ioThread(); 86 87 // Implementation in child class (Decoder/Encoder) onInputAvailable(AMediaCodec * codec,int32_t index)88 virtual void onInputAvailable(AMediaCodec *codec, int32_t index) { 89 (void)codec; 90 (void)index; 91 } onFormatChanged(AMediaCodec * codec,AMediaFormat * format)92 virtual void onFormatChanged(AMediaCodec *codec, AMediaFormat *format) { 93 (void)codec; 94 (void)format; 95 } onError(AMediaCodec * codec,media_status_t err)96 virtual void onError(AMediaCodec *codec, media_status_t err) { 97 (void)codec; 98 (void)err; 99 } onOutputAvailable(AMediaCodec * codec,int32_t index,AMediaCodecBufferInfo * bufferInfo)100 virtual void onOutputAvailable(AMediaCodec *codec, int32_t index, 101 AMediaCodecBufferInfo *bufferInfo) { 102 (void)codec; 103 (void)index; 104 (void)bufferInfo; 105 } 106 getStats()107 Stats *getStats() { return mStats; } 108 109 // Keep a queue of all function callbacks. 110 typedef function<void()> IOTask; 111 CallBackQueue<IOTask> mIOQueue; 112 thread mIOThread; 113 bool mSawError; 114 bool mIsDone; 115 116 protected: 117 Stats *mStats; 118 }; 119 120 // Async API's callback 121 void OnInputAvailableCB(AMediaCodec *codec, void *userdata, int32_t index); 122 123 void OnOutputAvailableCB(AMediaCodec *codec, void *userdata, int32_t index, 124 AMediaCodecBufferInfo *bufferInfo); 125 126 void OnFormatChangedCB(AMediaCodec *codec, void *userdata, AMediaFormat *format); 127 128 void OnErrorCB(AMediaCodec *codec, void * /* userdata */, media_status_t err, int32_t actionCode, 129 const char *detail); 130 131 // Utility to create and configure AMediaCodec 132 AMediaCodec *createMediaCodec(AMediaFormat *format, const char *mime, string codecName, 133 bool isEncoder); 134 135 #endif // __BENCHMARK_COMMON_H__ 136