1 /* 2 * Copyright (c) 2020, Intel Corporation 3 * 4 * Permission is hereby granted, free of charge, to any person obtaining a 5 * copy of this software and associated documentation files (the "Software"), 6 * to deal in the Software without restriction, including without limitation 7 * the rights to use, copy, modify, merge, publish, distribute, sublicense, 8 * and/or sell copies of the Software, and to permit persons to whom the 9 * Software is furnished to do so, subject to the following conditions: 10 * 11 * The above copyright notice and this permission notice shall be included 12 * in all copies or substantial portions of the Software. 13 * 14 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS 15 * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 16 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL 17 * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR 18 * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, 19 * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR 20 * OTHER DEALINGS IN THE SOFTWARE. 21 */ 22 //! 23 //! \file decode_internal_target.h 24 //! \brief Defines the interface for internal dest surface alloacted by driver 25 //! 26 27 #ifndef __DECODE_INTERNAL_TARGET_H__ 28 #define __DECODE_INTERNAL_TARGET_H__ 29 30 #include "decode_allocator.h" 31 #include "decode_utils.h" 32 #include "decode_basic_feature.h" 33 34 namespace decode { 35 36 class InternalTargets 37 { 38 public: 39 //! 40 //! \brief InternalTargets constructor 41 //! InternalTargets()42 InternalTargets() {}; 43 44 //! 45 //! \brief InternalTargets deconstructor 46 //! ~InternalTargets()47 virtual ~InternalTargets() 48 { 49 DECODE_FUNC_CALL(); 50 51 if (m_allocator != nullptr) 52 { 53 for (auto &surface : m_activeSurfaces) 54 { 55 m_allocator->Destroy(surface.second); 56 } 57 m_activeSurfaces.clear(); 58 59 for (auto &surface : m_aviableSurfaces) 60 { 61 m_allocator->Destroy(surface); 62 } 63 } 64 m_aviableSurfaces.clear(); 65 } 66 67 //! 68 //! \brief Initialize surfaces 69 //! \param [in] allocator 70 //! Reference to decode allocator 71 //! \return MOS_STATUS 72 //! MOS_STATUS_SUCCESS if success, else fail reason 73 //! Init(DecodeAllocator & allocator)74 MOS_STATUS Init(DecodeAllocator& allocator) 75 { 76 DECODE_FUNC_CALL(); 77 78 m_allocator = &allocator; 79 DECODE_ASSERT(m_aviableSurfaces.empty()); 80 DECODE_ASSERT(m_activeSurfaces.empty()); 81 82 return MOS_STATUS_SUCCESS; 83 } 84 85 //! 86 //! \brief Figure out surface for current picture, and add it to active surface list 87 //! \param [in] frameIdx 88 //! The frame index for current picture 89 //! \param [in] dstSurface 90 //! The requirement for the current surface 91 //! \param [in] isMmcEnabled 92 //! The MMC flag for currrent surface 93 //! \param [in] resUsageType 94 //! The resource usage for currrent surface 95 //! \param [in] accessReq 96 //! The access requirement for current surface 97 //! \return MOS_STATUS 98 //! MOS_STATUS_SUCCESS if success, else fail reason 99 //! 100 MOS_STATUS ActiveCurSurf(uint32_t curFrameIdx, PMOS_SURFACE dstSurface, bool isMmcEnabled, 101 ResourceUsage resUsageType = resourceDefault, ResourceAccessReq accessReq = lockableVideoMem) 102 { 103 DECODE_FUNC_CALL(); 104 105 for (auto iter = m_activeSurfaces.begin(); iter!= m_activeSurfaces.end(); iter++) 106 { 107 if (curFrameIdx == iter->first) 108 { 109 return MOS_STATUS_SUCCESS; 110 } 111 } 112 113 if (m_aviableSurfaces.size() == 0) 114 { 115 m_currentSurface = m_allocator->AllocateSurface( 116 dstSurface->dwWidth, 117 MOS_ALIGN_CEIL(dstSurface->dwHeight, 8), 118 "Internal target surface", 119 dstSurface->Format, 120 isMmcEnabled, 121 resUsageType, 122 accessReq, 123 dstSurface->TileModeGMM); 124 } 125 else 126 { 127 auto iter = m_aviableSurfaces.begin(); 128 m_currentSurface = *iter; 129 m_aviableSurfaces.erase(iter); 130 DECODE_CHK_STATUS(m_allocator->Resize(m_currentSurface, 131 dstSurface->dwWidth, 132 MOS_ALIGN_CEIL(dstSurface->dwHeight, 8), 133 accessReq, 134 false, 135 "Internal target surface")); 136 } 137 138 DECODE_CHK_NULL(m_currentSurface); 139 140 auto ret = m_activeSurfaces.insert(std::make_pair(curFrameIdx, m_currentSurface)); 141 DECODE_CHK_COND(ret.second == false, 142 "Failed to active surface with index %d, maybe it is already existed", 143 ret.first->first); 144 145 return MOS_STATUS_SUCCESS; 146 } 147 148 //! 149 //! \brief Update internal surfaces corresponding to reference list 150 //! \param [in] curFrameIdx 151 //! The frame index for current picture 152 //! \param [in] refFrameList 153 //! The frame indicies of reference frame list 154 //! \param [in] fixedFrameIdx 155 //! The frameIdx user wants to keep into the refFrameList 156 //! Default value is 0xff 157 //! \return MOS_STATUS 158 //! MOS_STATUS_SUCCESS if success, else fail reason 159 //! 160 MOS_STATUS UpdateRefList(uint32_t curFrameIdx, const std::vector<uint32_t> &refFrameList, uint32_t fixedFrameIdx = 0xff) 161 { 162 DECODE_FUNC_CALL(); 163 164 auto iter = m_activeSurfaces.begin(); 165 while (iter != m_activeSurfaces.end()) 166 { 167 if (iter->first == fixedFrameIdx) 168 { 169 ++iter; 170 continue; 171 } 172 173 if (!IsReference(iter->first, curFrameIdx, refFrameList)) 174 { 175 auto buffer = iter->second; 176 iter = m_activeSurfaces.erase(iter); 177 178 m_aviableSurfaces.push_back(buffer); 179 } 180 else 181 { 182 ++iter; 183 } 184 } 185 186 return MOS_STATUS_SUCCESS; 187 } 188 189 //! 190 //! \brief Return current internal surface for current frame 191 //! \return PMOS_SURFACE* 192 //! Point to surface for current frame, nullptr if fail 193 //! GetCurSurf()194 PMOS_SURFACE GetCurSurf() { return m_currentSurface; } 195 196 protected: 197 //! 198 //! \brief Check if the index of surface is persent in current reference list 199 //! \param [in] frameIndex 200 //! The frame index corresponding to surface 201 //! \param [in] frameIdx 202 //! The frame index for current picture 203 //! \param [in] refFrameList 204 //! The frame indicies of reference frame list 205 //! \return bool 206 //! True if surface is using by current frame, false if not 207 //! IsReference(uint32_t frameIdx,uint32_t curFrameIdx,const std::vector<uint32_t> & refFrameList)208 bool IsReference(uint32_t frameIdx, uint32_t curFrameIdx, const std::vector<uint32_t> &refFrameList) 209 { 210 DECODE_FUNC_CALL(); 211 212 if (frameIdx == curFrameIdx) 213 { 214 return false; 215 } 216 217 for(auto iter : refFrameList) 218 { 219 if (frameIdx == iter) 220 { 221 return true; 222 } 223 } 224 225 return false; 226 } 227 228 private: 229 std::map<uint32_t, PMOS_SURFACE> m_activeSurfaces; //!< Active surfaces corresponding to current reference frame list 230 std::vector<PMOS_SURFACE> m_aviableSurfaces; //!< Surfaces in idle 231 PMOS_SURFACE m_currentSurface = nullptr; //!< Point to surface of current picture 232 DecodeAllocator* m_allocator = nullptr; 233 234 MEDIA_CLASS_DEFINE_END(decode__InternalTargets) 235 }; 236 237 } // namespace decode 238 #endif // !__DECODE_INTERNAL_TARGET_H__ 239