1 /* 2 * Copyright (C) 2021 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 RECORDER_ELEMENT_H 17 #define RECORDER_ELEMENT_H 18 19 #include <memory> 20 #include <unordered_map> 21 #include <type_traits> 22 #include <mutex> 23 #include <set> 24 #include <gst/gstelement.h> 25 #include "nocopyable.h" 26 #include "recorder_param.h" 27 #include "recorder_inner_defines.h" 28 #include "recorder_message_handler.h" 29 30 namespace OHOS { 31 namespace Media { 32 class RecorderElement : public RecorderMsgHandler { 33 public: 34 struct CreateParam { 35 // The source element's description that this element uniquely dependents to. 36 // For multiplexer, the description is invalid. 37 RecorderSourceDesc srcDesc; 38 std::string name; 39 }; 40 41 explicit RecorderElement(const CreateParam &createParam); 42 virtual ~RecorderElement(); 43 44 /** 45 * @brief Get this element's sourceId 46 * @return sourceId. 47 */ GetSourceId()48 inline int32_t GetSourceId() const 49 { 50 return desc_.handle_; 51 } 52 53 /** 54 * @brief Get this element's name 55 * @return sourceId. 56 */ GetName()57 inline std::string GetName() const 58 { 59 return name_; 60 } 61 62 /** 63 * @brief Initialize the element after it created. 64 * @return MSERR_OK if success, or failed. 65 */ 66 virtual int32_t Init() = 0; 67 68 /** 69 * @brief Configure the element. This will be called before CheckConfigReady. 70 * @param recParam: RecorderParam, this is the base type of specific type's recorder parameter. 71 * @return MSERR_OK if success, or failed. 72 */ Configure(const RecorderParam & recParam)73 virtual int32_t Configure(const RecorderParam &recParam) 74 { 75 (void)recParam; 76 return MSERR_OK; 77 } 78 79 /** 80 * @brief This interface will be called before Prepare to ensure that all static recorder parameters required 81 * by this element are configured completely. 82 * @return MSERR_OK if success, or failed. 83 */ CheckConfigReady()84 virtual int32_t CheckConfigReady() 85 { 86 return MSERR_OK; 87 } 88 89 /** 90 * @brief This interface is invoked before the corresponding gstreamer element's state changed from NULL to 91 * PAUSED, and during the process when the RecorderPipeline's Prepare invoked. 92 * @return MSERR_OK if success, or failed. 93 */ Prepare()94 virtual int32_t Prepare() 95 { 96 return MSERR_OK; 97 } 98 99 /** 100 * @brief This interface is invoked before the corresponding gstreamer element's state changed from PAUSED to 101 * PLAYING. and during the process when the RecorderPipeline's Start invoked. 102 * @return MSERR_OK if success, or failed. 103 */ Start()104 virtual int32_t Start() 105 { 106 return MSERR_OK; 107 } 108 109 /** 110 * @brief This interface is invoked before the corresponding gstreamer element's state changed from PLAYING to 111 * PAUSED. and during the process when the RecorderPipeline's Pause invoked. 112 * @return MSERR_OK if success, or failed. 113 */ Pause()114 virtual int32_t Pause() 115 { 116 return MSERR_OK; 117 } 118 119 /** 120 * @brief This interface is invoked before the corresponding gstreamer element's state changed from PAUSED to 121 * PLAYING. and during the process when the RecorderPipeline's Resume invoked. 122 * @return MSERR_OK if success, or failed. 123 */ Resume()124 virtual int32_t Resume() 125 { 126 return MSERR_OK; 127 } 128 129 /** 130 * @brief This interface is invoked before the Stop interface called. The components could send EOS event to 131 * relevant gstreamer element through this interface to only drain out all itself cached buffer before changing 132 * state to NULL. It is designed to speed up the whole pipeline's stopping process. If the user requires a fast 133 * stop, the components could firstly send FLUSH event to relevant gstreamer element. The upper layer will decide 134 * to whether need to wait the GST_MESSAGE_EOS according to this interface's return value. 135 * @return MSERR_OK if success, or failed. 136 */ 137 int32_t DrainAll(bool isDrain); 138 139 /** 140 * @brief This interface is invoked before the corresponding gstreamer element's state changed from PLAYING or 141 * PAUSED to NULL. and during the process when the RecorderPipeline's Stop invoked. 142 * @return MSERR_OK if success, or failed. 143 */ Stop()144 virtual int32_t Stop() 145 { 146 return MSERR_OK; 147 } 148 149 /** 150 * @brief This interface is invoked during the process when the RecorderPipeline's Reset invoked. 151 * @return MSERR_OK if success, or failed. 152 */ Reset()153 virtual int32_t Reset() 154 { 155 return MSERR_OK; 156 } 157 158 /** 159 * @brief Set dynamic parameter to this element, this will be called after Prepare and before Stop 160 * @param recParam: RecorderParam, this is the base type of specific type's recorder parameter. 161 * @return MSERR_OK if success, or failed. 162 */ SetParameter(const RecorderParam & recParam)163 virtual int32_t SetParameter(const RecorderParam &recParam) 164 { 165 (void)recParam; 166 return MSERR_OK; 167 } 168 169 /** 170 * @brief Get Parameter of this elements 171 * @param recParam: RecorderParam, this is the base type of specific type's recorder parameter. 172 * @return MSERR_OK if success, or failed. 173 */ GetParameter(RecorderParam & recParam)174 virtual int32_t GetParameter(RecorderParam &recParam) 175 { 176 (void)recParam; 177 return MSERR_OK; 178 } 179 180 /** 181 * @brief Process raw message from gstreamer's element to inner message format. 182 * @param msg: GstMessage, this is the raw message from gstreamer 183 * @param prettyMsg: RecorderMessage, this is the processed result 184 * @return see @RecorderMsgProcResult 185 */ 186 RecorderMsgProcResult OnMessageReceived(GstMessage &rawMsg, RecorderMessage &prettyMsg) final; 187 188 /** 189 * @brief Dump all dynamic or static configuration info. 190 */ Dump()191 virtual void Dump() {} 192 193 protected: 194 /** 195 * @brief Mark one parameter successfully configured to this element. 196 * @param paramType: the enum value of RecorderParamType 197 * @return None. 198 */ MarkParameter(int32_t paramType)199 void MarkParameter(int32_t paramType) 200 { 201 (void)configedParams_.insert(paramType); 202 } 203 204 /** 205 * @brief Check whether the specified type's parameter is configured. 206 * @param paramType: the enum value of RecorderParamType 207 * @return true if configured, false if not configured. 208 */ CheckParameter(int32_t paramType)209 bool CheckParameter(int32_t paramType) const 210 { 211 return configedParams_.find(paramType) != configedParams_.end(); 212 } 213 214 /** 215 * @brief Check whether the all specified type's parameters is configured. 216 * @param expectedParams: the enum value set of RecorderParamType 217 * @return true if all specified type's parameters configured, false if not all. 218 */ 219 bool CheckAllParamsConfiged(const std::set<int32_t> &expectedParams) const; 220 221 /** 222 * @brief Check whether the any one specified type's parameters is configured. 223 * @param expectedParams: the enum value set of RecorderParamType 224 * @return true if any one specified type's parameters configured, false if no one. 225 */ 226 bool CheckAnyParamConfiged(const std::set<int32_t> &expectedParams) const; 227 228 /** 229 * @brief Subclass implement to process the raw message from gstreamer's element 230 * @param msg: GstMessage, this is the raw message from gstreamer 231 * @param prettyMsg: RecorderMessage, this is the processed result 232 * @return see @RecorderMsgProcResult 233 */ DoProcessMessage(GstMessage & msg,RecorderMessage & prettyMsg)234 virtual RecorderMsgProcResult DoProcessMessage(GstMessage &msg, RecorderMessage &prettyMsg) 235 { 236 return RecorderMsgProcResult::REC_MSG_PROC_IGNORE; 237 } 238 239 friend class RecorderPipelineLinkHelper; 240 241 RecorderSourceDesc desc_; 242 std::string name_; 243 GstElement *gstElem_ = nullptr; 244 245 private: 246 std::set<int32_t> configedParams_; 247 }; 248 249 /** 250 * @brief Provides the factory to register the derived class iinstantiation method and 251 * create the RecorderElement instance. 252 */ 253 class RecorderElementFactory { 254 public: GetInstance()255 static RecorderElementFactory &GetInstance() 256 { 257 static RecorderElementFactory inst; 258 return inst; 259 } 260 261 using ElementCreator = std::function<std::shared_ptr<RecorderElement>(const RecorderElement::CreateParam&)>; 262 263 int32_t RegisterElement(const std::string &key, const ElementCreator creator); 264 std::shared_ptr<RecorderElement> CreateElement(const std::string key, const RecorderElement::CreateParam ¶m); 265 266 private: 267 RecorderElementFactory() = default; 268 ~RecorderElementFactory() = default; 269 270 std::unordered_map<std::string, ElementCreator> creatorTbl_; 271 std::mutex tblMutex_; 272 }; 273 274 template<typename T, 275 typename = std::enable_if_t<std::is_base_of_v<RecorderElement, std::decay_t<T>>>> 276 class RecorderElementRegister : public NoCopyable { 277 public: RecorderElementRegister(const std::string & key)278 RecorderElementRegister(const std::string &key) 279 { 280 (void)RecorderElementFactory::GetInstance().RegisterElement( 281 key, [](const RecorderElement::CreateParam ¶m) { 282 return std::make_shared<std::decay_t<T>>(param); 283 } 284 ); 285 } 286 287 ~RecorderElementRegister() = default; 288 }; 289 290 /** 291 * @brief Provides the RecorderElement register macro to simplify the registration. 292 */ 293 #define REGISTER_RECORDER_ELEMENT(__classname__) \ 294 static std::shared_ptr<RecorderElementRegister<__classname__>> g_##__classname__##register = \ 295 std::make_shared<RecorderElementRegister<__classname__>>(#__classname__) 296 } // namespace Media 297 } // namespace OHOS 298 #endif 299