1 /* 2 * Copyright 2022 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 ANDROID_C2_SOFT_HEVC_DEC_H_ 18 #define ANDROID_C2_SOFT_HEVC_DEC_H_ 19 20 #include <sys/time.h> 21 22 #include <media/stagefright/foundation/ColorUtils.h> 23 24 #include "MediaHevcDecoder.h" 25 #include "GoldfishHevcHelper.h" 26 #include <SimpleC2Component.h> 27 #include <atomic> 28 #include <map> 29 30 namespace android { 31 32 #define ALIGN2(x) ((((x) + 1) >> 1) << 1) 33 #define ALIGN8(x) ((((x) + 7) >> 3) << 3) 34 #define ALIGN16(x) ((((x) + 15) >> 4) << 4) 35 #define ALIGN32(x) ((((x) + 31) >> 5) << 5) 36 #define MAX_NUM_CORES 4 37 #define MIN(a, b) (((a) < (b)) ? (a) : (b)) 38 #define GETTIME(a, b) gettimeofday(a, b); 39 #define TIME_DIFF(start, end, diff) \ 40 diff = (((end).tv_sec - (start).tv_sec) * 1000000) + \ 41 ((end).tv_usec - (start).tv_usec); 42 43 class C2GoldfishHevcDec : public SimpleC2Component { 44 public: 45 class IntfImpl; 46 C2GoldfishHevcDec(const char *name, c2_node_id_t id, 47 const std::shared_ptr<IntfImpl> &intfImpl); 48 virtual ~C2GoldfishHevcDec(); 49 50 // From SimpleC2Component 51 c2_status_t onInit() override; 52 c2_status_t onStop() override; 53 void onReset() override; 54 void onRelease() override; 55 c2_status_t onFlush_sm() override; 56 void process(const std::unique_ptr<C2Work> &work, 57 const std::shared_ptr<C2BlockPool> &pool) override; 58 c2_status_t drain(uint32_t drainMode, 59 const std::shared_ptr<C2BlockPool> &pool) override; 60 61 private: 62 void checkMode(const std::shared_ptr<C2BlockPool> &pool); 63 // status_t createDecoder(); 64 status_t createDecoder(); 65 status_t setParams(size_t stride); 66 status_t initDecoder(); 67 bool setDecodeArgs(C2ReadView *inBuffer, C2GraphicView *outBuffer, 68 size_t inOffset, size_t inSize, uint32_t tsMarker, bool hasPicture); 69 c2_status_t ensureDecoderState(const std::shared_ptr<C2BlockPool> &pool); 70 void finishWork(uint64_t index, const std::unique_ptr<C2Work> &work); 71 status_t setFlushMode(); 72 c2_status_t drainInternal(uint32_t drainMode, 73 const std::shared_ptr<C2BlockPool> &pool, 74 const std::unique_ptr<C2Work> &work); 75 status_t resetDecoder(); 76 void resetPlugin(); 77 void deleteContext(); 78 79 void removePts(uint64_t pts); 80 void insertPts(uint32_t work_index, uint64_t pts); 81 uint64_t getWorkIndex(uint64_t pts); 82 83 // TODO:This is not the right place for this enum. These should 84 // be part of c2-vndk so that they can be accessed by all video plugins 85 // until then, make them feel at home 86 enum { 87 kNotSupported, 88 kPreferBitstream, 89 kPreferContainer, 90 }; 91 92 void getVuiParams(hevc_image_t &img); 93 void copyImageData(hevc_image_t &img); 94 95 96 97 98 // Color aspects. These are ISO values and are meant to detect changes in 99 // aspects to avoid converting them to C2 values for each frame 100 struct VuiColorAspects { 101 uint8_t primaries; 102 uint8_t transfer; 103 uint8_t coeffs; 104 uint8_t fullRange; 105 106 // default color aspects VuiColorAspectsVuiColorAspects107 VuiColorAspects() 108 : primaries(2), transfer(2), coeffs(2), fullRange(0) {} 109 110 bool operator==(const VuiColorAspects &o) const { 111 return primaries == o.primaries && transfer == o.transfer && 112 coeffs == o.coeffs && fullRange == o.fullRange; 113 } 114 }; 115 116 void sendMetadata(); 117 118 void decodeHeaderAfterFlush(); 119 120 std::unique_ptr<MediaHevcDecoder> mContext; 121 std::unique_ptr<GoldfishHevcHelper> mHevcHelper; 122 std::shared_ptr<IntfImpl> mIntf; 123 std::shared_ptr<C2GraphicBlock> mOutBlock; 124 125 std::vector<uint8_t> mCsd0; 126 std::vector<uint8_t> mCsd1; 127 128 std::map<uint64_t, uint64_t> mOldPts2Index; 129 std::map<uint64_t, uint64_t> mPts2Index; 130 std::map<uint64_t, uint64_t> mIndex2Pts; 131 132 uint8_t *mInPBuffer{nullptr}; 133 uint8_t *mOutBufferFlush{nullptr}; 134 135 hevc_image_t mImg{}; 136 VuiColorAspects mBitstreamColorAspects; 137 MetaDataColorAspects mSentMetadata = {1, 0, 0, 0}; 138 139 std::atomic_uint64_t mOutIndex; 140 // there are same pts matching to different work indices 141 // this happen during csd0/csd1 switching 142 uint64_t mPts {0}; 143 144 uint32_t mConsumedBytes{0}; 145 uint32_t mInPBufferSize = 0; 146 uint32_t mInTsMarker = 0; 147 148 // size_t mNumCores; 149 // uint32_t mOutputDelay; 150 uint32_t mWidth = 0; 151 uint32_t mHeight = 0; 152 uint32_t mStride = 0; 153 154 int mHostColorBufferId{-1}; 155 156 bool mEnableAndroidNativeBuffers{true}; 157 bool mSignalledOutputEos{false}; 158 bool mSignalledError{false}; 159 bool mHeaderDecoded{false}; 160 161 // profile 162 struct timeval mTimeStart; 163 struct timeval mTimeEnd; 164 #ifdef FILE_DUMP_ENABLE 165 char mInFile[200]; 166 #endif /* FILE_DUMP_ENABLE */ 167 168 C2_DO_NOT_COPY(C2GoldfishHevcDec); 169 }; 170 171 } // namespace android 172 173 #endif // ANDROID_C2_SOFT_HEVC_DEC_H_ 174