1 /*
2 * Copyright (c) 2023-2023 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 #include "audio_encoder_filter.h"
17
18 #include "common/log.h"
19 #include "filter/filter_factory.h"
20 #include "media_codec/media_codec.h"
21 #include "common/media_core.h"
22 #include "avcodec_sysevent.h"
23
24 namespace {
25 constexpr OHOS::HiviewDFX::HiLogLabel LABEL = { LOG_CORE, LOG_DOMAIN_RECORDER, "AudioEncoderFilter" };
26 }
27
28 namespace OHOS {
29 namespace Media {
30 namespace Pipeline {
31 using namespace OHOS::MediaAVCodec;
32 static AutoRegisterFilter<AudioEncoderFilter> g_registerAudioEncoderFilter("builtin.recorder.audioencoder",
33 FilterType::FILTERTYPE_AENC,
__anon3e8517520202(const std::string& name, const FilterType type) 34 [](const std::string& name, const FilterType type) {
35 return std::make_shared<AudioEncoderFilter>(name, FilterType::FILTERTYPE_AENC);
36 });
37
38 class AudioEncoderFilterLinkCallback : public FilterLinkCallback {
39 public:
AudioEncoderFilterLinkCallback(std::shared_ptr<AudioEncoderFilter> audioEncoderFilter)40 explicit AudioEncoderFilterLinkCallback(std::shared_ptr<AudioEncoderFilter> audioEncoderFilter)
41 : audioEncoderFilter_(std::move(audioEncoderFilter))
42 {
43 }
44
45 ~AudioEncoderFilterLinkCallback() = default;
46
OnLinkedResult(const sptr<AVBufferQueueProducer> & queue,std::shared_ptr<Meta> & meta)47 void OnLinkedResult(const sptr<AVBufferQueueProducer> &queue, std::shared_ptr<Meta> &meta) override
48 {
49 if (auto encoderFilter = audioEncoderFilter_.lock()) {
50 encoderFilter->OnLinkedResult(queue, meta);
51 } else {
52 MEDIA_LOG_I("invalid encoderFilter");
53 }
54 }
55
OnUnlinkedResult(std::shared_ptr<Meta> & meta)56 void OnUnlinkedResult(std::shared_ptr<Meta> &meta) override
57 {
58 if (auto encoderFilter = audioEncoderFilter_.lock()) {
59 encoderFilter->OnUnlinkedResult(meta);
60 } else {
61 MEDIA_LOG_I("invalid encoderFilter");
62 }
63 }
64
OnUpdatedResult(std::shared_ptr<Meta> & meta)65 void OnUpdatedResult(std::shared_ptr<Meta> &meta) override
66 {
67 if (auto encoderFilter = audioEncoderFilter_.lock()) {
68 encoderFilter->OnUpdatedResult(meta);
69 } else {
70 MEDIA_LOG_I("invalid encoderFilter");
71 }
72 }
73 private:
74 std::weak_ptr<AudioEncoderFilter> audioEncoderFilter_;
75 };
76
AudioEncoderFilter(std::string name,FilterType type)77 AudioEncoderFilter::AudioEncoderFilter(std::string name, FilterType type): Filter(name, type)
78 {
79 filterType_ = type;
80 MEDIA_LOG_I("audio encoder filter create");
81 }
82
~AudioEncoderFilter()83 AudioEncoderFilter::~AudioEncoderFilter()
84 {
85 MEDIA_LOG_I("audio encoder filter destroy");
86 }
87
SetCodecFormat(const std::shared_ptr<Meta> & format)88 Status AudioEncoderFilter::SetCodecFormat(const std::shared_ptr<Meta> &format)
89 {
90 MEDIA_LOG_I("SetCodecFormat");
91 FALSE_RETURN_V(format->Get<Tag::MIME_TYPE>(codecMimeType_), Status::ERROR_INVALID_PARAMETER);
92 return Status::OK;
93 }
94
Init(const std::shared_ptr<EventReceiver> & receiver,const std::shared_ptr<FilterCallback> & callback)95 void AudioEncoderFilter::Init(const std::shared_ptr<EventReceiver> &receiver,
96 const std::shared_ptr<FilterCallback> &callback)
97 {
98 MEDIA_LOG_I("Init");
99 eventReceiver_ = receiver;
100 filterCallback_ = callback;
101 mediaCodec_ = std::make_shared<MediaCodec>();
102 FALSE_RETURN_MSG(mediaCodec_ != nullptr, "mediaCodec is nullptr");
103 int32_t ret = mediaCodec_->Init(codecMimeType_, true);
104 if (ret != 0 && isTranscoderMode_) {
105 MEDIA_LOG_I("TranscoderMode");
106 FALSE_RETURN(eventReceiver_ != nullptr);
107 eventReceiver_->OnEvent({"audio_encoder_filter", EventType::EVENT_ERROR, MSERR_UNSUPPORT_AUD_ENC_TYPE});
108 }
109 }
110
Configure(const std::shared_ptr<Meta> & parameter)111 Status AudioEncoderFilter::Configure(const std::shared_ptr<Meta> ¶meter)
112 {
113 MEDIA_LOG_I("Configure");
114 configureParameter_ = parameter;
115 FALSE_RETURN_V(mediaCodec_ != nullptr, Status::ERROR_NULL_POINTER);
116 int32_t ret = mediaCodec_->Configure(parameter);
117 if (ret != 0) {
118 SetFaultEvent("AudioEncoderFilter::Configure error", ret);
119 return Status::ERROR_UNKNOWN;
120 }
121 return Status::OK;
122 }
123
GetInputSurface()124 sptr<Surface> AudioEncoderFilter::GetInputSurface()
125 {
126 FALSE_RETURN_V(mediaCodec_ != nullptr, nullptr);
127 MEDIA_LOG_I("GetInputSurface");
128 return mediaCodec_->GetInputSurface();
129 }
130
DoPrepare()131 Status AudioEncoderFilter::DoPrepare()
132 {
133 FALSE_RETURN_V(filterCallback_ != nullptr, Status::ERROR_NULL_POINTER);
134 MEDIA_LOG_I("Prepare");
135 switch (filterType_) {
136 case FilterType::FILTERTYPE_AENC:
137 if (isTranscoderMode_) {
138 MEDIA_LOG_I("TranscoderMode");
139 return filterCallback_->OnCallback(shared_from_this(), FilterCallBackCommand::NEXT_FILTER_NEEDED,
140 StreamType::STREAMTYPE_ENCODED_AUDIO);
141 }
142 filterCallback_->OnCallback(shared_from_this(), FilterCallBackCommand::NEXT_FILTER_NEEDED,
143 StreamType::STREAMTYPE_ENCODED_AUDIO);
144 break;
145 default:
146 break;
147 }
148 return Status::OK;
149 }
150
DoStart()151 Status AudioEncoderFilter::DoStart()
152 {
153 FALSE_RETURN_V(mediaCodec_ != nullptr, Status::ERROR_NULL_POINTER);
154 MEDIA_LOG_I("Start");
155 int32_t ret = mediaCodec_->Start();
156 if (ret != 0) {
157 SetFaultEvent("AudioEncoderFilter::DoStart error", ret);
158 return Status::ERROR_UNKNOWN;
159 }
160 return Status::OK;
161 }
162
DoPause()163 Status AudioEncoderFilter::DoPause()
164 {
165 MEDIA_LOG_I("Pause");
166 return Status::OK;
167 }
168
DoResume()169 Status AudioEncoderFilter::DoResume()
170 {
171 MEDIA_LOG_I("Resume");
172 return Status::OK;
173 }
174
DoStop()175 Status AudioEncoderFilter::DoStop()
176 {
177 FALSE_RETURN_V(mediaCodec_ != nullptr, Status::ERROR_NULL_POINTER);
178 MEDIA_LOG_I("Stop");
179 int32_t ret = mediaCodec_->Stop();
180 if (ret != 0) {
181 SetFaultEvent("AudioEncoderFilter::DoStop error", ret);
182 return Status::ERROR_UNKNOWN;
183 }
184 return Status::OK;
185 }
186
DoFlush()187 Status AudioEncoderFilter::DoFlush()
188 {
189 FALSE_RETURN_V(mediaCodec_ != nullptr, Status::ERROR_NULL_POINTER);
190 MEDIA_LOG_I("Flush");
191 int32_t ret = mediaCodec_->Flush();
192 if (ret != 0) {
193 SetFaultEvent("AudioEncoderFilter::DoFlush error", ret);
194 return Status::ERROR_UNKNOWN;
195 }
196 return Status::OK;
197 }
198
DoRelease()199 Status AudioEncoderFilter::DoRelease()
200 {
201 FALSE_RETURN_V(mediaCodec_ != nullptr, Status::ERROR_NULL_POINTER);
202 MEDIA_LOG_I("Release");
203 int32_t ret = mediaCodec_->Release();
204 if (ret != 0) {
205 SetFaultEvent("AudioEncoderFilter::DoRelease error", ret);
206 return Status::ERROR_UNKNOWN;
207 }
208 return Status::OK;
209 }
210
NotifyEos()211 Status AudioEncoderFilter::NotifyEos()
212 {
213 FALSE_RETURN_V(mediaCodec_ != nullptr, Status::ERROR_NULL_POINTER);
214 MEDIA_LOG_I("NotifyEos");
215 int32_t ret = mediaCodec_->NotifyEos();
216 if (ret != 0) {
217 SetFaultEvent("AudioEncoderFilter::NotifyEos error", ret);
218 return Status::ERROR_UNKNOWN;
219 }
220 return Status::OK;
221 }
222
SetTranscoderMode()223 Status AudioEncoderFilter::SetTranscoderMode()
224 {
225 MEDIA_LOG_I("SetTranscoderMode");
226 isTranscoderMode_ = true;
227 return Status::OK;
228 }
229
SetParameter(const std::shared_ptr<Meta> & parameter)230 void AudioEncoderFilter::SetParameter(const std::shared_ptr<Meta> ¶meter)
231 {
232 FALSE_RETURN_MSG(mediaCodec_ != nullptr, "mediaCodec is nullptr");
233 MEDIA_LOG_I("SetParameter");
234 mediaCodec_->SetParameter(parameter);
235 }
236
GetParameter(std::shared_ptr<Meta> & parameter)237 void AudioEncoderFilter::GetParameter(std::shared_ptr<Meta> ¶meter)
238 {
239 MEDIA_LOG_I("GetParameter");
240 }
241
LinkNext(const std::shared_ptr<Filter> & nextFilter,StreamType outType)242 Status AudioEncoderFilter::LinkNext(const std::shared_ptr<Filter> &nextFilter, StreamType outType)
243 {
244 MEDIA_LOG_I("LinkNext");
245 nextFilter_ = nextFilter;
246 nextFiltersMap_[outType].push_back(nextFilter_);
247 std::shared_ptr<FilterLinkCallback> filterLinkCallback =
248 std::make_shared<AudioEncoderFilterLinkCallback>(shared_from_this());
249 if (mediaCodec_) {
250 std::shared_ptr<Meta> parameter = std::make_shared<Meta>();
251 mediaCodec_->GetOutputFormat(parameter);
252 int32_t frameSize = 0;
253 if (parameter->Find(Tag::AUDIO_SAMPLE_PER_FRAME) != parameter->end() &&
254 parameter->Get<Tag::AUDIO_SAMPLE_PER_FRAME>(frameSize)) {
255 configureParameter_->Set<Tag::AUDIO_SAMPLE_PER_FRAME>(frameSize);
256 }
257 }
258 auto ret = nextFilter->OnLinked(outType, configureParameter_, filterLinkCallback);
259 if (ret != Status::OK) {
260 SetFaultEvent("AudioEncoderFilter::LinkNext error", (int32_t)ret);
261 }
262 FALSE_RETURN_V_MSG_E(ret == Status::OK, ret, "OnLinked failed");
263 return Status::OK;
264 }
265
UpdateNext(const std::shared_ptr<Filter> & nextFilter,StreamType outType)266 Status AudioEncoderFilter::UpdateNext(const std::shared_ptr<Filter> &nextFilter, StreamType outType)
267 {
268 MEDIA_LOG_I("UpdateNext");
269 return Status::OK;
270 }
271
UnLinkNext(const std::shared_ptr<Filter> & nextFilter,StreamType outType)272 Status AudioEncoderFilter::UnLinkNext(const std::shared_ptr<Filter> &nextFilter, StreamType outType)
273 {
274 MEDIA_LOG_I("UnLinkNext");
275 return Status::OK;
276 }
277
GetFilterType()278 FilterType AudioEncoderFilter::GetFilterType()
279 {
280 MEDIA_LOG_I("GetFilterType");
281 return filterType_;
282 }
283
OnLinked(StreamType inType,const std::shared_ptr<Meta> & meta,const std::shared_ptr<FilterLinkCallback> & callback)284 Status AudioEncoderFilter::OnLinked(StreamType inType, const std::shared_ptr<Meta> &meta,
285 const std::shared_ptr<FilterLinkCallback> &callback)
286 {
287 MEDIA_LOG_I("OnLinked");
288 onLinkedResultCallback_ = callback;
289 if (isTranscoderMode_) {
290 transcoderMeta_ = meta;
291 }
292 return Status::OK;
293 }
294
OnUpdated(StreamType inType,const std::shared_ptr<Meta> & meta,const std::shared_ptr<FilterLinkCallback> & callback)295 Status AudioEncoderFilter::OnUpdated(StreamType inType, const std::shared_ptr<Meta> &meta,
296 const std::shared_ptr<FilterLinkCallback> &callback)
297 {
298 MEDIA_LOG_I("OnUpdated");
299 return Status::OK;
300 }
301
OnUnLinked(StreamType inType,const std::shared_ptr<FilterLinkCallback> & callback)302 Status AudioEncoderFilter::OnUnLinked(StreamType inType, const std::shared_ptr<FilterLinkCallback>& callback)
303 {
304 MEDIA_LOG_I("OnUnLinked");
305 return Status::OK;
306 }
307
OnLinkedResult(const sptr<AVBufferQueueProducer> & outputBufferQueue,std::shared_ptr<Meta> & meta)308 void AudioEncoderFilter::OnLinkedResult(const sptr<AVBufferQueueProducer> &outputBufferQueue,
309 std::shared_ptr<Meta> &meta)
310 {
311 FALSE_RETURN_MSG(mediaCodec_ != nullptr, "mediaCodec is nullptr");
312 FALSE_RETURN_MSG(onLinkedResultCallback_ != nullptr, "onLinkedResultCallback is nullptr");
313 MEDIA_LOG_I("OnLinkedResult");
314 mediaCodec_->SetOutputBufferQueue(outputBufferQueue);
315 mediaCodec_->Prepare();
316 if (isTranscoderMode_) {
317 onLinkedResultCallback_->OnLinkedResult(mediaCodec_->GetInputBufferQueue(), transcoderMeta_);
318 return;
319 }
320 onLinkedResultCallback_->OnLinkedResult(mediaCodec_->GetInputBufferQueue(), meta);
321 }
322
OnUpdatedResult(std::shared_ptr<Meta> & meta)323 void AudioEncoderFilter::OnUpdatedResult(std::shared_ptr<Meta> &meta)
324 {
325 MEDIA_LOG_I("OnUpdatedResult");
326 (void) meta;
327 }
328
OnUnlinkedResult(std::shared_ptr<Meta> & meta)329 void AudioEncoderFilter::OnUnlinkedResult(std::shared_ptr<Meta> &meta)
330 {
331 MEDIA_LOG_I("OnUnlinkedResult");
332 (void) meta;
333 }
334
SetFaultEvent(const std::string & errMsg,int32_t ret)335 void AudioEncoderFilter::SetFaultEvent(const std::string &errMsg, int32_t ret)
336 {
337 SetFaultEvent(errMsg + ", ret = " + std::to_string(ret));
338 }
339
SetFaultEvent(const std::string & errMsg)340 void AudioEncoderFilter::SetFaultEvent(const std::string &errMsg)
341 {
342 AudioCodecFaultInfo audioCodecFaultInfo;
343 audioCodecFaultInfo.appName = bundleName_;
344 audioCodecFaultInfo.instanceId = std::to_string(instanceId_);
345 audioCodecFaultInfo.callerType ="player_framework";
346 audioCodecFaultInfo.audioCodec = codecMimeType_;
347 audioCodecFaultInfo.errMsg = errMsg;
348 FaultAudioCodecEventWrite(audioCodecFaultInfo);
349 }
350
SetCallingInfo(int32_t appUid,int32_t appPid,const std::string & bundleName,uint64_t instanceId)351 void AudioEncoderFilter::SetCallingInfo(int32_t appUid, int32_t appPid,
352 const std::string &bundleName, uint64_t instanceId)
353 {
354 appUid_ = appUid;
355 appPid_ = appPid;
356 bundleName_ = bundleName;
357 instanceId_ = instanceId;
358 }
359 } // namespace Pipeline
360 } // namespace MEDIA
361 } // namespace OHOS