• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (c) 2021-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 #ifdef RECORDER_SUPPORT
16 #define HST_LOG_TAG "HiRecorderImpl"
17 
18 #include "hirecorder_impl.h"
19 #include "hitrace_meter.h"
20 #include <regex>
21 #include "foundation/osal/filesystem/file_system.h"
22 #include "pipeline/factory/filter_factory.h"
23 #include "plugin/common/media_sink.h"
24 #include "plugin/common/plugin_time.h"
25 #include "recorder_utils.h"
26 #include "utils/steady_clock.h"
27 
28 #ifndef WIN32
29     #include <unistd.h> // include the dup function on Linux system
30 #endif
31 
32 
33 namespace OHOS {
34 namespace Media {
35 namespace Record {
36 using namespace Pipeline;
37 
HiRecorderImpl(int32_t appUid,int32_t appPid,uint32_t appTokenId)38 HiRecorderImpl::HiRecorderImpl(int32_t appUid, int32_t appPid, uint32_t appTokenId)
39     : appUid_(appUid), appPid_(appPid), appTokenId_(appTokenId), fsm_(*this), curFsmState_(StateId::INIT)
40 {
41     StartTrace(HITRACE_TAG_ZMEDIA, "Hst HiRecorderImpl ctor");
42     MEDIA_LOG_I("hiRecorderImpl ctor");
43     FilterFactory::Instance().Init();
44     muxer_ = FilterFactory::Instance().CreateFilterWithType<MuxerFilter>(
45             "builtin.recorder.muxer", "muxer");
46     outputSink_ = FilterFactory::Instance().CreateFilterWithType<OutputSinkFilter>(
47             "builtin.recorder.output_sink", "output_sink");
48     FALSE_RETURN(muxer_ != nullptr);
49     FALSE_RETURN(outputSink_ != nullptr);
50     pipeline_ = std::make_shared<PipelineCore>();
51     FinishTrace(HITRACE_TAG_ZMEDIA);
52 }
53 
~HiRecorderImpl()54 HiRecorderImpl::~HiRecorderImpl()
55 {
56     fsm_.SendEvent(Intent::RESET);
57     fsm_.Stop();
58     MEDIA_LOG_D("dtor called.");
59 }
60 
Init()61 ErrorCode HiRecorderImpl::Init()
62 {
63     if (initialized_.load()) {
64         return ErrorCode::SUCCESS;
65     }
66     mediaStatStub_.Reset();
67     pipeline_->Init(this, nullptr);
68     ErrorCode ret = pipeline_->AddFilters({muxer_.get(), outputSink_.get()});
69     if (ret == ErrorCode::SUCCESS) {
70         ret = pipeline_->LinkFilters({muxer_.get(), outputSink_.get()});
71     }
72     FALSE_LOG(ret == ErrorCode::SUCCESS);
73     if (ret == ErrorCode::SUCCESS) {
74         fsm_.SetStateCallback(this);
75         fsm_.Start();
76         initialized_ = true;
77     } else {
78         pipeline_->UnlinkPrevFilters();
79         pipeline_->RemoveFilterChain(muxer_.get());
80     }
81     return ret;
82 }
83 
SetAudioSource(AudioSourceType source,int32_t & sourceId)84 int32_t HiRecorderImpl::SetAudioSource(AudioSourceType source, int32_t& sourceId)
85 {
86     StartTrace(HITRACE_TAG_ZMEDIA, "Hst recorder SetAudioSource");
87     MEDIA_LOG_I("SetAudioSource enter");
88     PROFILE_BEGIN("SetAudioSource begin");
89     sourceId = INVALID_SOURCE_ID;
90     FALSE_RETURN_V(source != AudioSourceType::AUDIO_SOURCE_INVALID,
91                    TransErrorCode(ErrorCode::ERROR_INVALID_PARAMETER_VALUE));
92     FALSE_RETURN_V(audioCount_ < static_cast<int32_t>(AUDIO_SOURCE_MAX_COUNT),
93                    TransErrorCode(ErrorCode::ERROR_INVALID_OPERATION));
94     auto tempSourceId = SourceIdGenerator::GenerateAudioSourceId(audioCount_);
95     auto ret = SetAudioSourceInternal(source, tempSourceId);
96     if (ret == ErrorCode::SUCCESS) {
97         audioCount_++;
98         audioSourceId_ = tempSourceId;
99         sourceId = static_cast<int32_t>(audioSourceId_);
100     }
101     PROFILE_END("SetAudioSource end.");
102     FinishTrace(HITRACE_TAG_ZMEDIA);
103     return TransErrorCode(ret);
104 }
105 
SetVideoSource(VideoSourceType source,int32_t & sourceId)106 int32_t HiRecorderImpl::SetVideoSource(VideoSourceType source, int32_t& sourceId)
107 {
108 #ifdef VIDEO_SUPPORT
109     MEDIA_LOG_I("SetVideoSource enter");
110     PROFILE_BEGIN("SetVideoSource begin");
111     sourceId = INVALID_SOURCE_ID;
112     FALSE_RETURN_V(source != VideoSourceType::VIDEO_SOURCE_BUTT,
113                    TransErrorCode(ErrorCode::ERROR_INVALID_PARAMETER_VALUE));
114     FALSE_RETURN_V(videoCount_ < static_cast<int32_t>(VIDEO_SOURCE_MAX_COUNT),
115                    TransErrorCode(ErrorCode::ERROR_INVALID_OPERATION));
116     auto tempSourceId = SourceIdGenerator::GenerateVideoSourceId(videoCount_);
117     auto ret = SetVideoSourceInternal(source, tempSourceId);
118     if (ret == ErrorCode::SUCCESS) {
119         videoCount_++;
120         videoSourceId_ = tempSourceId;
121         sourceId = videoSourceId_;
122     }
123     PROFILE_END("SetVideoSource end.");
124     return TransErrorCode(ret);
125 #else
126     return TransErrorCode(ErrorCode::ERROR_UNIMPLEMENTED);
127 #endif
128 }
129 
GetSurface(int32_t sourceId)130 sptr<Surface> HiRecorderImpl::GetSurface(int32_t sourceId)
131 {
132 #ifdef VIDEO_SUPPORT
133     FALSE_RETURN_V(SourceIdGenerator::IsVideo(sourceId) && sourceId == static_cast<int32_t>(videoSourceId_) &&
134         videoCapture_ != nullptr, nullptr);
135     Plugin::Any any;
136     FALSE_RETURN_V(videoCapture_ ->GetParameter(static_cast<int32_t>(Plugin::Tag::VIDEO_SURFACE), any)
137                    != ErrorCode::SUCCESS, nullptr);
138     return any.SameTypeWith(typeid(sptr<Surface>)) ? Plugin::AnyCast<sptr<Surface>>(any) : nullptr;
139 #else
140     return nullptr;
141 #endif
142 }
143 
SetOutputFormat(OutputFormatType format)144 int32_t HiRecorderImpl::SetOutputFormat(OutputFormatType format)
145 {
146     MEDIA_LOG_I("OutputFormatType enter, format = " PUBLIC_LOG_D32, static_cast<int32_t>(format));
147     FALSE_RETURN_V(format != OutputFormatType::FORMAT_BUTT, TransErrorCode(ErrorCode::ERROR_INVALID_OPERATION));
148     FALSE_RETURN_V((audioCount_ + videoCount_) > static_cast<uint32_t>(0),
149                    TransErrorCode(ErrorCode::ERROR_INVALID_OPERATION));
150     outputFormatType_ = format;
151     auto ret = fsm_.SendEvent(Intent::SET_OUTPUT_FORMAT, outputFormatType_);
152     if (ret != ErrorCode::SUCCESS) {
153         MEDIA_LOG_E("SetOutputFormat failed with error " PUBLIC_LOG_S, GetErrorName(ret));
154     }
155     return TransErrorCode(ret);
156 }
157 
SetObs(const std::weak_ptr<IRecorderEngineObs> & obs)158 int32_t HiRecorderImpl::SetObs(const std::weak_ptr<IRecorderEngineObs>& obs)
159 {
160     MEDIA_LOG_I("SetObs enter");
161     obs_ = obs;
162     return TransErrorCode(ErrorCode::SUCCESS);
163 }
164 
Configure(int32_t sourceId,const RecorderParam & recParam)165 int32_t HiRecorderImpl::Configure(int32_t sourceId, const RecorderParam& recParam)
166 {
167     StartTrace(HITRACE_TAG_ZMEDIA, "Hst recorder Configure");
168     MEDIA_LOG_I("Configure enter");
169     FALSE_RETURN_V(outputFormatType_ != OutputFormatType::FORMAT_BUTT,
170                    TransErrorCode(ErrorCode::ERROR_INVALID_OPERATION));
171     FALSE_RETURN_V(CheckParamType(sourceId, recParam), TransErrorCode(ErrorCode::ERROR_INVALID_PARAMETER_VALUE));
172     HstRecParam hstRecParam;
173     auto castRet  = CastRecorderParam(sourceId, recParam, hstRecParam);
174     FALSE_RETURN_V(castRet, TransErrorCode(ErrorCode::ERROR_INVALID_PARAMETER_VALUE));
175     auto ret = fsm_.SendEvent(Intent::CONFIGURE, hstRecParam);
176     if (ret != ErrorCode::SUCCESS) {
177         MEDIA_LOG_E("Configure failed with error " PUBLIC_LOG_S, GetErrorName(ret));
178     }
179     FinishTrace(HITRACE_TAG_ZMEDIA);
180     return TransErrorCode(ret);
181 }
182 
Prepare()183 int32_t HiRecorderImpl::Prepare()
184 {
185     StartTrace(HITRACE_TAG_ZMEDIA, "Hst recorder Prepare");
186     MEDIA_LOG_D("Prepare entered, current fsm state: " PUBLIC_LOG_S ".", fsm_.GetCurrentState().c_str());
187     PROFILE_BEGIN();
188     auto ret = fsm_.SendEvent(Intent::PREPARE);
189     if (ret != ErrorCode::SUCCESS) {
190         PROFILE_END("Prepare failed,");
191         MEDIA_LOG_E("Prepare failed with error " PUBLIC_LOG_S, GetErrorName(ret));
192         return TransErrorCode(ret);
193     } else {
194         PROFILE_END("Prepare successfully,");
195     }
196     OSAL::ScopedLock lock(stateMutex_);
197     if (curFsmState_ == StateId::RECORDING_SETTING) { // Wait state change to ready
198         cond_.Wait(lock, [this] { return curFsmState_ != StateId::RECORDING_SETTING; });
199     }
200     MEDIA_LOG_D("Prepare finished, current fsm state: " PUBLIC_LOG "s.", fsm_.GetCurrentState().c_str());
201     PROFILE_END("Prepare finished, current fsm state: " PUBLIC_LOG "s.", fsm_.GetCurrentState().c_str());
202     if (curFsmState_ == StateId::READY) {
203         ret = ErrorCode::SUCCESS;
204     } else {
205         ret = ErrorCode::ERROR_UNKNOWN;
206     }
207     FinishTrace(HITRACE_TAG_ZMEDIA);
208     return TransErrorCode(ret);
209 }
210 
Start()211 int32_t HiRecorderImpl::Start()
212 {
213     StartTrace(HITRACE_TAG_ZMEDIA, "Hst recorder Start");
214     MEDIA_LOG_I("Start enter");
215     PROFILE_BEGIN();
216     ErrorCode ret;
217     if (curFsmState_ == StateId::PAUSE) {
218         ret = fsm_.SendEvent(Intent::RESUME);
219     } else {
220         ret = fsm_.SendEvent(Intent::START);
221     }
222     PROFILE_END("Start ret = " PUBLIC_LOG_D32, TransErrorCode(ret));
223     FinishTrace(HITRACE_TAG_ZMEDIA);
224     return TransErrorCode(ret);
225 }
226 
Pause()227 int32_t HiRecorderImpl::Pause()
228 {
229     StartTrace(HITRACE_TAG_ZMEDIA, "Hst recorder Pause");
230     MEDIA_LOG_I("Pause enter");
231     PROFILE_BEGIN();
232     auto ret = TransErrorCode(fsm_.SendEvent(Intent::PAUSE));
233     PROFILE_END("Pause ret = " PUBLIC_LOG_D32, ret);
234     FinishTrace(HITRACE_TAG_ZMEDIA);
235     return ret;
236 }
237 
Resume()238 int32_t HiRecorderImpl::Resume()
239 {
240     StartTrace(HITRACE_TAG_ZMEDIA, "Hst recorder Resume");
241     MEDIA_LOG_I("Resume enter");
242     PROFILE_BEGIN();
243     auto ret = TransErrorCode(fsm_.SendEvent(Intent::RESUME));
244     PROFILE_END("Resume ret = " PUBLIC_LOG_D32, ret);
245     FinishTrace(HITRACE_TAG_ZMEDIA);
246     return ret;
247 }
248 
Stop(bool isDrainAll)249 int32_t HiRecorderImpl::Stop(bool isDrainAll)
250 {
251     StartTrace(HITRACE_TAG_ZMEDIA, "Hst recorder Stop");
252     MEDIA_LOG_I("Stop enter");
253     PROFILE_BEGIN();
254     MEDIA_LOG_D("Stop start, isDrainAll: " PUBLIC_LOG_U32, static_cast<uint32_t>(isDrainAll));
255     outputFormatType_ = OutputFormatType::FORMAT_BUTT;
256     auto ret = TransErrorCode(fsm_.SendEvent(Intent::STOP, isDrainAll));
257     PROFILE_END("Stop ret = " PUBLIC_LOG_D32, ret);
258     FinishTrace(HITRACE_TAG_ZMEDIA);
259     FALSE_RETURN_V_MSG_E(ret == ERR_OK, ret, "send STOP event to fsm fail");
260     OSAL::ScopedLock lock(stateMutex_);
261     cond_.WaitFor(lock, 3000, [this] { // 3000: time out
262         return curFsmState_ == StateId::ERROR || curFsmState_ == StateId::INIT;
263     });
264     FALSE_RETURN_V_MSG_E(curFsmState_ == StateId::INIT, ERR_UNKNOWN_REASON, "stop fail");
265     return ERR_OK;
266 }
267 
Reset()268 int32_t HiRecorderImpl::Reset()
269 {
270     StartTrace(HITRACE_TAG_ZMEDIA, "Hst recorder Reset");
271     MEDIA_LOG_I("Reset enter");
272     PROFILE_BEGIN();
273     if (curFsmState_ == StateId::RECORDING) {
274         Stop(false); // avoid start then reset the file is not be saved
275     }
276     auto ret = TransErrorCode(fsm_.SendEvent(Intent::RESET));
277     PROFILE_END("Resume ret = " PUBLIC_LOG_D32, ret);
278     FinishTrace(HITRACE_TAG_ZMEDIA);
279     return ret;
280 }
281 
SetParameter(int32_t sourceId,const RecorderParam & recParam)282 int32_t HiRecorderImpl::SetParameter(int32_t sourceId, const RecorderParam &recParam)
283 {
284     return Configure(sourceId, recParam);
285 }
286 
OnEvent(const Event & event)287 void HiRecorderImpl::OnEvent(const Event& event)
288 {
289     MEDIA_LOG_D("[HiStreamer] OnEvent (" PUBLIC_LOG_D32 ")", event.type);
290     switch (event.type) {
291         case EventType::EVENT_ERROR: {
292             fsm_.SendEventAsync(Intent::NOTIFY_ERROR, event.param);
293             auto ptr = obs_.lock();
294             if (ptr != nullptr) {
295                 ptr->OnError(IRecorderEngineObs::ErrorType::ERROR_INTERNAL,
296                              TransErrorCode(Plugin::AnyCast<ErrorCode>(event.param)));
297             }
298             break;
299         }
300         case EventType::EVENT_READY: {
301             fsm_.SendEventAsync(Intent::NOTIFY_READY);
302             break;
303         }
304         case EventType::EVENT_COMPLETE:
305             mediaStatStub_.ReceiveEvent(event);
306             if (mediaStatStub_.IsEventCompleteAllReceived()) {
307                 fsm_.SendEventAsync(Intent::NOTIFY_COMPLETE);
308             }
309             break;
310         default:
311             MEDIA_LOG_E("Unknown event(" PUBLIC_LOG_D32 ")", event.type);
312     }
313 }
314 
OnStateChanged(StateId state)315 void HiRecorderImpl::OnStateChanged(StateId state)
316 {
317     MEDIA_LOG_I("OnStateChanged from " PUBLIC_LOG_D32 " to " PUBLIC_LOG_D32, curFsmState_.load(), state);
318     {
319         OSAL::ScopedLock lock(stateMutex_);
320         curFsmState_ = state;
321         cond_.NotifyOne();
322     }
323     auto ptr = obs_.lock();
324     if (ptr != nullptr) {
325         ptr->OnInfo(IRecorderEngineObs::InfoType::INTERNEL_WARNING, CppExt::to_underlying(state));
326     }
327 }
328 
DoSetVideoSource(const Plugin::Any & param) const329 ErrorCode HiRecorderImpl::DoSetVideoSource(const Plugin::Any& param) const
330 {
331 #ifdef VIDEO_SUPPORT
332     FALSE_RETURN_V_MSG_E(videoCapture_ != nullptr, ErrorCode::ERROR_INVALID_OPERATION,
333                          "videoCapture is NULL");
334     using SrcInputPair = std::pair<int32_t, Plugin::SrcInputType>;
335     if (param.SameTypeWith(typeid(SrcInputPair))) {
336         auto srcType = Plugin::AnyCast<SrcInputPair>(param).second;
337         return videoCapture_->SetParameter(static_cast<int32_t>(Plugin::Tag::SRC_INPUT_TYPE), srcType);
338     } else {
339         return ErrorCode::ERROR_INVALID_PARAMETER_TYPE;
340     }
341 #else
342     return ErrorCode::ERROR_UNIMPLEMENTED;
343 #endif
344 }
345 
DoSetAudioSource(const Plugin::Any & param) const346 ErrorCode HiRecorderImpl::DoSetAudioSource(const Plugin::Any& param) const
347 {
348     FALSE_RETURN_V_MSG_E(audioCapture_ != nullptr, ErrorCode::ERROR_INVALID_OPERATION,
349                          "audioCapture is NULL");
350     using SrcInputPair = std::pair<int32_t, Plugin::SrcInputType>;
351     if (param.SameTypeWith(typeid(SrcInputPair))) {
352         auto srcType = Plugin::AnyCast<SrcInputPair>(param).second;
353         return audioCapture_->SetParameter(static_cast<int32_t>(Plugin::Tag::SRC_INPUT_TYPE), srcType);
354     } else {
355         return ErrorCode::ERROR_INVALID_PARAMETER_TYPE;
356     }
357 }
358 
DoConfigure(const Plugin::Any & param) const359 ErrorCode HiRecorderImpl::DoConfigure(const Plugin::Any &param) const
360 {
361     if (!param.SameTypeWith(typeid(HstRecParam))) {
362         return ErrorCode::ERROR_INVALID_PARAMETER_TYPE;
363     }
364     ErrorCode ret  = ErrorCode::SUCCESS;
365     const auto* hstParam = Plugin::AnyCast<HstRecParam>(&param);
366     switch (hstParam->stdParamType) {
367         case RecorderPublicParamType::AUD_SAMPLERATE:
368         case RecorderPublicParamType::AUD_CHANNEL:
369         case RecorderPublicParamType::AUD_BITRATE:
370         case RecorderPublicParamType::AUD_ENC_FMT:
371             ret = DoConfigureAudio(*hstParam);
372             break;
373         case RecorderPublicParamType::VID_CAPTURERATE:
374         case RecorderPublicParamType::VID_RECTANGLE:
375         case RecorderPublicParamType::VID_BITRATE:
376         case RecorderPublicParamType::VID_FRAMERATE:
377         case RecorderPublicParamType::VID_ENC_FMT:
378             ret = DoConfigureVideo(*hstParam);
379             break;
380         case RecorderPublicParamType::OUT_PATH:
381         case RecorderPublicParamType::OUT_FD:
382         case RecorderPublicParamType::VID_ORIENTATION_HINT:
383         case RecorderPublicParamType::GEO_LOCATION:
384             ret = DoConfigureOther(*hstParam);
385             break;
386         default:
387             break;
388     }
389     return ret;
390 }
391 
DoSetOutputFormat(const Plugin::Any & param) const392 ErrorCode HiRecorderImpl::DoSetOutputFormat(const Plugin::Any& param) const
393 {
394     ErrorCode ret {ErrorCode::SUCCESS};
395     if (param.SameTypeWith(typeid(OutputFormatType))) {
396         auto outputFormatType = Plugin::AnyCast<OutputFormatType>(param);
397         if (g_outputFormatToMimeMap.find(outputFormatType) != g_outputFormatToMimeMap.end()) {
398             ret = muxer_->SetOutputFormat(g_outputFormatToMimeMap.at(outputFormatType));
399         } else {
400             ret = ErrorCode::ERROR_INVALID_PARAMETER_TYPE;
401         }
402     } else {
403         ret = ErrorCode::ERROR_INVALID_PARAMETER_TYPE;
404     }
405     if (ret != ErrorCode::SUCCESS) {
406         MEDIA_LOG_E("SetOutputFormat failed with error " PUBLIC_LOG_D32, static_cast<int>(ret));
407     }
408     return ret;
409 }
410 
DoPrepare()411 ErrorCode HiRecorderImpl::DoPrepare()
412 {
413     return pipeline_->Prepare();
414 }
415 
DoStart()416 ErrorCode HiRecorderImpl::DoStart()
417 {
418     return pipeline_->Start();
419 }
420 
DoPause()421 ErrorCode HiRecorderImpl::DoPause()
422 {
423     return curFsmState_ == StateId::READY ? ErrorCode::SUCCESS: pipeline_->Pause();
424 }
425 
DoResume()426 ErrorCode HiRecorderImpl::DoResume()
427 {
428     return pipeline_->Resume();
429 }
430 
DoStop(const Plugin::Any & param)431 ErrorCode HiRecorderImpl::DoStop(const Plugin::Any& param)
432 {
433     ErrorCode ret = ErrorCode::SUCCESS;
434     mediaStatStub_.Reset();
435     if (Plugin::AnyCast<bool>(param)) {
436         if (audioCapture_) {
437             ret = audioCapture_->SendEos();
438         }
439 #ifdef VIDEO_SUPPORT
440         if (videoCapture_) {
441             ret = videoCapture_->SendEos();
442         }
443 #endif
444     } else {
445         ret = muxer_->SendEos();
446     }
447     audioCount_ = 0;
448     videoCount_ = 0;
449     audioSourceId_ = 0;
450     videoSourceId_ = 0;
451     return ret;
452 }
453 
DoReset()454 ErrorCode HiRecorderImpl::DoReset()
455 {
456     ErrorCode ret = pipeline_->Stop();
457     mediaStatStub_.Reset();
458     audioCount_ = 0;
459     videoCount_ = 0;
460     audioSourceId_ = 0;
461     videoSourceId_ = 0;
462     return ret;
463 }
464 
DoOnComplete()465 ErrorCode HiRecorderImpl::DoOnComplete()
466 {
467     return pipeline_->Stop();
468 }
469 
SetAudioSourceInternal(AudioSourceType source,int32_t sourceId)470 ErrorCode HiRecorderImpl::SetAudioSourceInternal(AudioSourceType source, int32_t sourceId)
471 {
472     if (!audioCapture_) {
473         audioCapture_ = FilterFactory::Instance().CreateFilterWithType<AudioCaptureFilter>(
474                 "builtin.recorder.audiocapture", "audiocapture");
475         audioEncoder_ = FilterFactory::Instance().CreateFilterWithType<AudioEncoderFilter>(
476                 "builtin.recorder.audioencoder", "audioencoder");
477         auto ret = pipeline_->AddFilters({audioCapture_.get(), audioEncoder_.get()});
478         FALSE_RETURN_V_MSG_E(ret == ErrorCode::SUCCESS, ret, "AddFilters audioCapture to pipeline fail");
479         ret = pipeline_->LinkFilters({audioCapture_.get(), audioEncoder_.get()});
480         FALSE_RETURN_V_MSG_E(ret == ErrorCode::SUCCESS, ret, "LinkFilters audioCapture and audioEncoder fail");
481         std::shared_ptr<InPort> muxerInPort {nullptr};
482         ret = muxer_->AddTrack(muxerInPort);
483         FALSE_RETURN_V_MSG_E(ret == ErrorCode::SUCCESS, ret, "muxer AddTrack fail");
484         ret = pipeline_->LinkPorts(audioEncoder_->GetOutPort(PORT_NAME_DEFAULT), muxerInPort);
485         FALSE_RETURN_V_MSG_E(ret == ErrorCode::SUCCESS, ret, "LinkPorts audioEncoderOutPort and muxerInPort fail");
486     }
487     FALSE_RETURN_V_MSG_E(audioCapture_ != nullptr && audioEncoder_ != nullptr, ErrorCode::ERROR_UNKNOWN,
488                          "create audioCapture/audioEncoder filter fail");
489     audioCapture_->SetParameter(static_cast<int32_t>(Plugin::Tag::APP_TOKEN_ID), appTokenId_);
490     audioCapture_->SetParameter(static_cast<int32_t>(Plugin::Tag::APP_UID), appUid_);
491     audioCapture_->SetParameter(static_cast<int32_t>(Plugin::Tag::APP_PID), appPid_);
492     return fsm_.SendEvent(Intent::SET_AUDIO_SOURCE,
493                           std::pair<int32_t, Plugin::SrcInputType>(sourceId, TransAudioInputType(source)));
494 }
495 
SetVideoSourceInternal(VideoSourceType source,int32_t sourceId)496 ErrorCode HiRecorderImpl::SetVideoSourceInternal(VideoSourceType source, int32_t sourceId)
497 {
498 #ifdef VIDEO_SUPPORT
499     videoCapture_ = FilterFactory::Instance().CreateFilterWithType<VideoCaptureFilter>(
500             "builtin.recorder.videocapture", "videocapture");
501     videoEncoder_ = FilterFactory::Instance().CreateFilterWithType<VideoEncoderFilter>(
502             "builtin.recorder.videoencoder", "videoencoder");
503     FALSE_RETURN_V_MSG_E(videoCapture_ != nullptr && videoEncoder_ != nullptr, ErrorCode::ERROR_UNKNOWN,
504                          "create videoCapture/videoEncoder filter fail");
505     auto ret = pipeline_->AddFilters({videoCapture_.get(), videoEncoder_.get()});
506     FALSE_RETURN_V_MSG_E(ret == ErrorCode::SUCCESS, ret, "AddFilters videoCapture to pipeline fail");
507     ret = pipeline_->LinkFilters({videoCapture_.get(), videoEncoder_.get()});
508     FALSE_RETURN_V_MSG_E(ret == ErrorCode::SUCCESS, ret, "LinkFilters videoCapture and videoEncoder fail");
509     std::shared_ptr<InPort> muxerInPort {nullptr};
510     ret =muxer_->AddTrack(muxerInPort);
511     FALSE_RETURN_V_MSG_E(ret == ErrorCode::SUCCESS, ret, "muxer AddTrack fail");
512     ret = pipeline_->LinkPorts(videoEncoder_->GetOutPort(PORT_NAME_DEFAULT), muxerInPort);
513     FALSE_RETURN_V_MSG_E(ret == ErrorCode::SUCCESS, ret, "LinkPorts videoEncoderOutPort and muxerInPort fail");
514     MEDIA_LOG_E("SendEvent: SET_VIDEO_SOURCE");
515     return fsm_.SendEvent(Intent::SET_VIDEO_SOURCE,
516                           std::pair<int32_t, Plugin::SrcInputType>(sourceId, TransVideoInputType(source)));
517 #else
518     return ErrorCode::ERROR_UNIMPLEMENTED;
519 #endif
520 }
521 
DoConfigureAudio(const HstRecParam & param) const522 ErrorCode HiRecorderImpl::DoConfigureAudio(const HstRecParam& param) const
523 {
524     FALSE_RETURN_V_MSG_E(audioCapture_ != nullptr && audioEncoder_ != nullptr, ErrorCode::ERROR_INVALID_OPERATION,
525                          "audioCapture/audioEncoder is NULL");
526     switch (param.stdParamType) {
527         case RecorderPublicParamType::AUD_SAMPLERATE: {
528             auto ptr = param.GetValPtr<AudSampleRate>();
529             FALSE_RETURN_V_MSG_E(ptr != nullptr, ErrorCode::ERROR_INVALID_PARAMETER_VALUE,);
530             MEDIA_LOG_I("set sample rate : " PUBLIC_LOG_D32, ptr->sampleRate);
531             return audioCapture_->SetParameter(static_cast<int32_t>(Plugin::Tag::AUDIO_SAMPLE_RATE),
532                                                static_cast<uint32_t>(ptr->sampleRate));
533         }
534         case RecorderPublicParamType::AUD_CHANNEL: {
535             auto ptr = param.GetValPtr<AudChannel>();
536             FALSE_RETURN_V_MSG_E(ptr != nullptr, ErrorCode::ERROR_INVALID_PARAMETER_VALUE,);
537             MEDIA_LOG_I("set channel : " PUBLIC_LOG_D32, ptr->channel);
538             return audioCapture_->SetParameter(static_cast<int32_t>(Plugin::Tag::AUDIO_CHANNELS),
539                                                static_cast<uint32_t>(ptr->channel));
540         }
541         case RecorderPublicParamType::AUD_BITRATE: {
542             auto ptr = param.GetValPtr<AudBitRate>();
543             FALSE_RETURN_V_MSG_E(ptr != nullptr && static_cast<int32_t>(ptr->bitRate) > 0,
544                 ErrorCode::ERROR_INVALID_PARAMETER_VALUE,);
545             MEDIA_LOG_I("set bitRate : " PUBLIC_LOG_D32, ptr->bitRate);
546             return audioCapture_->SetParameter(static_cast<int32_t>(Plugin::Tag::MEDIA_BITRATE),
547                                                static_cast<int64_t>(ptr->bitRate));
548         }
549         case RecorderPublicParamType::AUD_ENC_FMT: {
550             auto ptr = param.GetValPtr<AudEnc>();
551             FALSE_RETURN_V_MSG_E(ptr != nullptr, ErrorCode::ERROR_INVALID_PARAMETER_VALUE,);
552             auto encoderMeta = std::make_shared<Plugin::Meta>();
553             if (!TransAudioEncoderFmt(ptr->encFmt, *encoderMeta)) {
554                 return ErrorCode::ERROR_INVALID_PARAMETER_VALUE;
555             }
556             return audioEncoder_->SetAudioEncoder(param.srcId, encoderMeta);
557         }
558         default:
559             MEDIA_LOG_W("RecorderPublicParamType " PUBLIC_LOG_U32 " not supported", param.stdParamType);
560             return ErrorCode::SUCCESS;
561     }
562 }
563 
DoConfigureVideo(const HstRecParam & param) const564 ErrorCode HiRecorderImpl::DoConfigureVideo(const HstRecParam& param) const
565 {
566 #ifdef VIDEO_SUPPORT
567     FALSE_RETURN_V_MSG_E(videoCapture_ != nullptr && videoEncoder_ != nullptr, ErrorCode::ERROR_INVALID_OPERATION,
568                          "videoCapture/videoEncoder is NULL");
569     switch (param.stdParamType) {
570         case RecorderPublicParamType::VID_RECTANGLE: {
571             auto ptr = param.GetValPtr<VidRectangle>();
572             FALSE_RETURN_V_MSG_E(ptr != nullptr, ErrorCode::ERROR_INVALID_PARAMETER_VALUE,);
573             auto ret = videoCapture_->SetParameter(static_cast<int32_t>(Plugin::Tag::VIDEO_WIDTH),
574                                                    static_cast<uint32_t>(ptr->width));
575             if (ret == ErrorCode::SUCCESS) {
576                 ret = videoCapture_->SetParameter(static_cast<int32_t>(Plugin::Tag::VIDEO_HEIGHT),
577                                                   static_cast<uint32_t>(ptr->height));
578             }
579             return ret;
580         }
581         case RecorderPublicParamType::VID_CAPTURERATE: {
582             auto ptr = param.GetValPtr<CaptureRate>();
583             FALSE_RETURN_V_MSG_E(ptr != nullptr, ErrorCode::ERROR_INVALID_PARAMETER_VALUE,);
584             return videoCapture_->SetParameter(static_cast<int32_t>(Plugin::Tag::VIDEO_CAPTURE_RATE),
585                                                static_cast<double>(ptr->capRate));
586         }
587         case RecorderPublicParamType::VID_BITRATE: {
588             auto ptr = param.GetValPtr<VidBitRate>();
589             FALSE_RETURN_V_MSG_E(ptr != nullptr, ErrorCode::ERROR_INVALID_PARAMETER_VALUE,);
590             return videoCapture_->SetParameter(static_cast<int32_t>(Plugin::Tag::MEDIA_BITRATE),
591                 static_cast<int64_t>((ptr->bitRate >= 0) ? ptr->bitRate : 0));
592         }
593         case RecorderPublicParamType::VID_FRAMERATE: {
594             auto ptr = param.GetValPtr<VidFrameRate>();
595             FALSE_RETURN_V_MSG_E(ptr != nullptr, ErrorCode::ERROR_INVALID_PARAMETER_VALUE,);
596             return videoCapture_->SetParameter(static_cast<int32_t>(Plugin::Tag::VIDEO_FRAME_RATE),
597                 static_cast<uint32_t>((ptr->frameRate >= 0) ? ptr->frameRate : 0));
598         }
599         case RecorderPublicParamType::VID_ENC_FMT: {
600             auto ptr = param.GetValPtr<VidEnc>();
601             FALSE_RETURN_V_MSG_E(ptr != nullptr, ErrorCode::ERROR_INVALID_PARAMETER_VALUE,);
602             auto encoderMeta = std::make_shared<Plugin::Meta>();
603             if (!TransVideoEncoderFmt(ptr->encFmt, *encoderMeta)) {
604                 return ErrorCode::ERROR_INVALID_PARAMETER_VALUE;
605             }
606             return videoEncoder_->SetVideoEncoder(param.srcId, encoderMeta);
607         }
608         default:
609             MEDIA_LOG_W("ignore RecorderPublicParamType " PUBLIC_LOG_U32, param.stdParamType);
610             return ErrorCode::SUCCESS;
611     }
612 #else
613     return ErrorCode::ERROR_UNIMPLEMENTED;
614 #endif
615 }
616 
DoConfigureOther(const HstRecParam & param) const617 ErrorCode HiRecorderImpl::DoConfigureOther(const HstRecParam& param) const
618 {
619     FALSE_RETURN_V_MSG_E(muxer_ != nullptr && outputSink_ != nullptr, ErrorCode::ERROR_INVALID_OPERATION,
620                          "muxer/outputSink is NULL");
621     switch (param.stdParamType) {
622         case RecorderPublicParamType::OUT_PATH: {
623             auto ptr = param.GetValPtr<OutFilePath>();
624             FALSE_RETURN_V_MSG_E(ptr != nullptr, ErrorCode::ERROR_INVALID_PARAMETER_VALUE,);
625             auto dirPath = ptr->path;
626             std::regex reg("\\\\");
627             dirPath= std::regex_replace(dirPath, reg, "/");
628             FALSE_RETURN_V_MSG_E(!OSAL::FileSystem::IsRegularFile(dirPath)
629                 && OSAL::FileSystem::MakeMultipleDir(dirPath),
630                 ErrorCode::ERROR_INVALID_PARAMETER_VALUE, "OutFilePath is not a valid directory path");
631             std::string filePath;
632             FALSE_RETURN_V_MSG_E(GenerateFilePath(dirPath, outputFormatType_, filePath),
633                                  ErrorCode::ERROR_INVALID_PARAMETER_VALUE, "generate file path error");
634             MediaSink mediaSink {Plugin::ProtocolType::FILE};
635             mediaSink.SetPath(filePath);
636             return outputSink_->SetSink(mediaSink);
637         }
638         case RecorderPublicParamType::OUT_FD: {
639             auto ptr = param.GetValPtr<OutFd>();
640             FALSE_RETURN_V_MSG_E(ptr != nullptr, ErrorCode::ERROR_INVALID_PARAMETER_VALUE,);
641             MediaSink mediaSink {Plugin::ProtocolType::FD};
642             int32_t fd = ptr->fd;
643 #ifndef WIN32
644             fd = dup(fd);
645             FALSE_RETURN_V(fd >= 0, ErrorCode::ERROR_INVALID_PARAMETER_VALUE);
646 #endif
647             mediaSink.SetFd(fd);
648             return outputSink_->SetSink(mediaSink);
649         }
650         case RecorderPublicParamType::MAX_DURATION: {
651             auto ptr = param.GetValPtr<MaxDuration>();
652             FALSE_RETURN_V_MSG_E(ptr != nullptr, ErrorCode::ERROR_INVALID_PARAMETER_VALUE,);
653             int64_t hstTime = 0;
654             Plugin::Sec2HstTime(ptr->duration, hstTime);
655             return muxer_->SetMaxDuration(hstTime > 0 ? hstTime : 0);
656         }
657         case RecorderPublicParamType::MAX_SIZE: {
658             auto ptr = param.GetValPtr<MaxFileSize>();
659             FALSE_RETURN_V_MSG_E(ptr != nullptr, ErrorCode::ERROR_INVALID_PARAMETER_VALUE,);
660             return muxer_->SetMaxSize(ptr->size > 0 ? ptr->size : 0);
661         }
662         case RecorderPublicParamType::VID_ORIENTATION_HINT:
663         case RecorderPublicParamType::GEO_LOCATION:
664         default:
665             MEDIA_LOG_W("ignore RecorderPublicParamType " PUBLIC_LOG_U32, param.stdParamType);
666             return ErrorCode::SUCCESS;
667     }
668 }
669 
CheckParamType(int32_t sourceId,const RecorderParam & recParam) const670 bool HiRecorderImpl::CheckParamType(int32_t sourceId, const RecorderParam& recParam) const
671 {
672     FALSE_RETURN_V((SourceIdGenerator::IsAudio(sourceId) && recParam.IsAudioParam() &&
673         static_cast<int32_t>(audioSourceId_) == sourceId) ||
674         (SourceIdGenerator::IsVideo(sourceId) && recParam.IsVideoParam() &&
675         static_cast<int32_t>(videoSourceId_) == sourceId) ||
676         ((sourceId == DUMMY_SOURCE_ID) && !(recParam.IsAudioParam() || recParam.IsVideoParam())), false);
677     return true;
678 }
679 } // namespace Record
680 } // namespace Media
681 } // namespace OHOS
682 #endif