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 "surface_encoder_filter.h"
17 
18 #include <iostream>
19 #include <string>
20 #include "common/log.h"
21 #include "common/media_core.h"
22 #include "filter/filter_factory.h"
23 #include "surface_encoder_adapter.h"
24 #include "muxer_filter.h"
25 
26 namespace {
27 constexpr OHOS::HiviewDFX::HiLogLabel LABEL = { LOG_CORE, LOG_DOMAIN_SYSTEM_PLAYER, "SurfaceEncoderFilter" };
28 }
29 
30 namespace OHOS {
31 namespace Media {
32 namespace Pipeline {
33 static AutoRegisterFilter<SurfaceEncoderFilter> g_registerSurfaceEncoderFilter("builtin.recorder.videoencoder",
34     FilterType::FILTERTYPE_VENC,
__anon341e43410202(const std::string& name, const FilterType type) 35     [](const std::string& name, const FilterType type) {
36         return std::make_shared<SurfaceEncoderFilter>(name, FilterType::FILTERTYPE_VENC);
37     });
38 
39 class SurfaceEncoderFilterLinkCallback : public FilterLinkCallback {
40 public:
SurfaceEncoderFilterLinkCallback(std::shared_ptr<SurfaceEncoderFilter> surfaceEncoderFilter)41     explicit SurfaceEncoderFilterLinkCallback(std::shared_ptr<SurfaceEncoderFilter> surfaceEncoderFilter)
42         : surfaceEncoderFilter_(std::move(surfaceEncoderFilter))
43     {
44     }
45 
OnLinkedResult(const sptr<AVBufferQueueProducer> & queue,std::shared_ptr<Meta> & meta)46     void OnLinkedResult(const sptr<AVBufferQueueProducer> &queue, std::shared_ptr<Meta> &meta) override
47     {
48         if (auto surfaceEncoderFilter = surfaceEncoderFilter_.lock()) {
49             surfaceEncoderFilter->OnLinkedResult(queue, meta);
50         } else {
51             MEDIA_LOG_I("invalid surfaceEncoderFilter");
52         }
53     }
54 
OnUnlinkedResult(std::shared_ptr<Meta> & meta)55     void OnUnlinkedResult(std::shared_ptr<Meta> &meta) override
56     {
57         if (auto surfaceEncoderFilter = surfaceEncoderFilter_.lock()) {
58             surfaceEncoderFilter->OnUnlinkedResult(meta);
59         } else {
60             MEDIA_LOG_I("invalid surfaceEncoderFilter");
61         }
62     }
63 
OnUpdatedResult(std::shared_ptr<Meta> & meta)64     void OnUpdatedResult(std::shared_ptr<Meta> &meta) override
65     {
66         if (auto surfaceEncoderFilter = surfaceEncoderFilter_.lock()) {
67             surfaceEncoderFilter->OnUpdatedResult(meta);
68         } else {
69             MEDIA_LOG_I("invalid surfaceEncoderFilter");
70         }
71     }
72 
73 private:
74     std::weak_ptr<SurfaceEncoderFilter> surfaceEncoderFilter_;
75 };
76 
77 class SurfaceEncoderAdapterCallback : public EncoderAdapterCallback {
78 public:
SurfaceEncoderAdapterCallback(std::shared_ptr<SurfaceEncoderFilter> surfaceEncoderFilter)79     explicit SurfaceEncoderAdapterCallback(std::shared_ptr<SurfaceEncoderFilter> surfaceEncoderFilter)
80         : surfaceEncoderFilter_(std::move(surfaceEncoderFilter))
81     {
82     }
83 
OnError(MediaAVCodec::AVCodecErrorType type,int32_t errorCode)84     void OnError(MediaAVCodec::AVCodecErrorType type, int32_t errorCode)
85     {
86         if (auto surfaceEncoderFilter = surfaceEncoderFilter_.lock()) {
87             surfaceEncoderFilter->OnError(type, errorCode);
88         } else {
89             MEDIA_LOG_D("invalid surfaceEncoderFilter");
90         }
91     }
92 
OnOutputFormatChanged(const std::shared_ptr<Meta> & format)93     void OnOutputFormatChanged(const std::shared_ptr<Meta> &format)
94     {
95     }
96 
97 private:
98     std::weak_ptr<SurfaceEncoderFilter> surfaceEncoderFilter_;
99 };
100 
101 class SurfaceEncoderAdapterKeyFramePtsCallback : public EncoderAdapterKeyFramePtsCallback {
102 public:
SurfaceEncoderAdapterKeyFramePtsCallback(std::shared_ptr<SurfaceEncoderFilter> surfaceEncoderFilter)103     explicit SurfaceEncoderAdapterKeyFramePtsCallback(std::shared_ptr<SurfaceEncoderFilter> surfaceEncoderFilter)
104         : surfaceEncoderFilter_(std::move(surfaceEncoderFilter))
105     {
106     }
107 
OnReportKeyFramePts(std::string KeyFramePts)108     void OnReportKeyFramePts(std::string KeyFramePts) override
109     {
110         if (auto surfaceEncoderFilter = surfaceEncoderFilter_.lock()) {
111             MEDIA_LOG_D("SurfaceEncoderAdapterKeyFramePtsCallback OnReportKeyFramePts start");
112             surfaceEncoderFilter->OnReportKeyFramePts(KeyFramePts);
113             MEDIA_LOG_D("SurfaceEncoderAdapterKeyFramePtsCallback OnReportKeyFramePts end");
114         } else {
115             MEDIA_LOG_I("invalid surfaceEncoderFilter");
116         }
117     }
118 
119 private:
120     std::weak_ptr<SurfaceEncoderFilter> surfaceEncoderFilter_;
121 };
122 
SurfaceEncoderFilter(std::string name,FilterType type)123 SurfaceEncoderFilter::SurfaceEncoderFilter(std::string name, FilterType type): Filter(name, type)
124 {
125     MEDIA_LOG_I("encoder filter create");
126 }
127 
~SurfaceEncoderFilter()128 SurfaceEncoderFilter::~SurfaceEncoderFilter()
129 {
130     MEDIA_LOG_I("encoder filter destroy");
131 }
132 
OnError(MediaAVCodec::AVCodecErrorType errorType,int32_t errorCode)133 void SurfaceEncoderFilter::OnError(MediaAVCodec::AVCodecErrorType errorType, int32_t errorCode)
134 {
135     MEDIA_LOG_E("AVCodec error happened. ErrorType: %{public}d, errorCode: %{public}d",
136         static_cast<int32_t>(errorType), errorCode);
137     if (eventReceiver_ != nullptr) {
138         eventReceiver_->OnEvent({"surface_encoder_filter", EventType::EVENT_ERROR, MSERR_VID_ENC_FAILED});
139     }
140 }
141 
SetCodecFormat(const std::shared_ptr<Meta> & format)142 Status SurfaceEncoderFilter::SetCodecFormat(const std::shared_ptr<Meta> &format)
143 {
144     MEDIA_LOG_I("SetCodecFormat");
145     std::string codecMimeType;
146     FALSE_RETURN_V(format->Get<Tag::MIME_TYPE>(codecMimeType), Status::ERROR_INVALID_PARAMETER);
147     if (strcmp(codecMimeType.c_str(), codecMimeType_.c_str()) != 0) {
148         isUpdateCodecNeeded_ = true;
149     }
150     FALSE_RETURN_V(format->Get<Tag::MIME_TYPE>(codecMimeType_), Status::ERROR_INVALID_PARAMETER);
151     return Status::OK;
152 }
153 
Init(const std::shared_ptr<EventReceiver> & receiver,const std::shared_ptr<FilterCallback> & callback)154 void SurfaceEncoderFilter::Init(const std::shared_ptr<EventReceiver> &receiver,
155     const std::shared_ptr<FilterCallback> &callback)
156 {
157     MEDIA_LOG_I("Init");
158     eventReceiver_ = receiver;
159     filterCallback_ = callback;
160     if (!mediaCodec_ || isUpdateCodecNeeded_.load()) {
161         if (mediaCodec_) {
162             mediaCodec_->Release();
163         }
164         mediaCodec_ = std::make_shared<SurfaceEncoderAdapter>();
165         mediaCodec_->SetCallingInfo(appUid_, appPid_, bundleName_, instanceId_);
166         Status ret = mediaCodec_->Init(codecMimeType_, true);
167         if (ret == Status::OK) {
168             std::shared_ptr<EncoderAdapterCallback> encoderAdapterCallback =
169                 std::make_shared<SurfaceEncoderAdapterCallback>(shared_from_this());
170             mediaCodec_->SetEncoderAdapterCallback(encoderAdapterCallback);
171             std::shared_ptr<EncoderAdapterKeyFramePtsCallback> encoderAdapterKeyFramePtsCallback =
172                 std::make_shared<SurfaceEncoderAdapterKeyFramePtsCallback>(shared_from_this());
173             mediaCodec_->SetEncoderAdapterKeyFramePtsCallback(encoderAdapterKeyFramePtsCallback);
174         } else {
175             MEDIA_LOG_I("Init mediaCodec fail");
176             eventReceiver_->OnEvent({"surface_encoder_filter", EventType::EVENT_ERROR, MSERR_UNKNOWN});
177         }
178         surface_ = nullptr;
179         isUpdateCodecNeeded_ = false;
180     }
181 }
182 
Configure(const std::shared_ptr<Meta> & parameter)183 Status SurfaceEncoderFilter::Configure(const std::shared_ptr<Meta> &parameter)
184 {
185     MEDIA_LOG_I("Configure");
186     if (mediaCodec_ == nullptr) {
187         return Status::ERROR_UNKNOWN;
188     }
189     configureParameter_ = parameter;
190     return mediaCodec_->Configure(parameter);
191 }
192 
SetWatermark(std::shared_ptr<AVBuffer> & waterMarkBuffer)193 Status SurfaceEncoderFilter::SetWatermark(std::shared_ptr<AVBuffer> &waterMarkBuffer)
194 {
195     MEDIA_LOG_I("SetWatermark");
196     if (mediaCodec_ == nullptr) {
197         MEDIA_LOG_E("mediaCodec_ is nullptr");
198         return Status::ERROR_UNKNOWN;
199     }
200     return mediaCodec_->SetWatermark(waterMarkBuffer);
201 }
202 
SetInputSurface(sptr<Surface> surface)203 Status SurfaceEncoderFilter::SetInputSurface(sptr<Surface> surface)
204 {
205     MEDIA_LOG_I("SetInputSurface");
206     mediaCodec_->SetInputSurface(surface);
207     return Status::OK;
208 }
209 
SetTransCoderMode()210 Status SurfaceEncoderFilter::SetTransCoderMode()
211 {
212     MEDIA_LOG_I("SetTransCoderMode");
213     mediaCodec_->SetTransCoderMode();
214     return Status::OK;
215 }
216 
GetInputSurface()217 sptr<Surface> SurfaceEncoderFilter::GetInputSurface()
218 {
219     MEDIA_LOG_I("GetInputSurface");
220     if (surface_) {
221         return surface_;
222     }
223     if (mediaCodec_ != nullptr) {
224         surface_ = mediaCodec_->GetInputSurface();
225     }
226     return surface_;
227 }
228 
DoPrepare()229 Status SurfaceEncoderFilter::DoPrepare()
230 {
231     MEDIA_LOG_I("Prepare");
232     filterCallback_->OnCallback(shared_from_this(), FilterCallBackCommand::NEXT_FILTER_NEEDED,
233         StreamType::STREAMTYPE_ENCODED_VIDEO);
234     return Status::OK;
235 }
236 
DoStart()237 Status SurfaceEncoderFilter::DoStart()
238 {
239     MEDIA_LOG_I("Start");
240     if (mediaCodec_ == nullptr) {
241         return Status::ERROR_UNKNOWN;
242     }
243     return mediaCodec_->Start();
244 }
245 
DoPause()246 Status SurfaceEncoderFilter::DoPause()
247 {
248     MEDIA_LOG_I("Pause");
249     if (mediaCodec_ == nullptr) {
250         return Status::ERROR_UNKNOWN;
251     }
252     return mediaCodec_->Pause();
253 }
254 
DoResume()255 Status SurfaceEncoderFilter::DoResume()
256 {
257     MEDIA_LOG_I("Resume");
258     if (mediaCodec_ == nullptr) {
259         return Status::ERROR_UNKNOWN;
260     }
261     return mediaCodec_->Resume();
262 }
263 
DoStop()264 Status SurfaceEncoderFilter::DoStop()
265 {
266     MEDIA_LOG_I("Stop enter");
267     if (mediaCodec_ == nullptr) {
268         return Status::OK;
269     }
270     mediaCodec_->Stop();
271     return Status::OK;
272 }
273 
Reset()274 Status SurfaceEncoderFilter::Reset()
275 {
276     MEDIA_LOG_I("Reset");
277     if (mediaCodec_ == nullptr) {
278         return Status::OK;
279     }
280     mediaCodec_->Reset();
281     return Status::OK;
282 }
283 
DoFlush()284 Status SurfaceEncoderFilter::DoFlush()
285 {
286     MEDIA_LOG_I("Flush");
287     return mediaCodec_->Flush();
288 }
289 
DoRelease()290 Status SurfaceEncoderFilter::DoRelease()
291 {
292     MEDIA_LOG_I("Release");
293     if (mediaCodec_ == nullptr) {
294         return Status::OK;
295     }
296     return mediaCodec_->Reset();
297 }
298 
NotifyEos(int64_t pts)299 Status SurfaceEncoderFilter::NotifyEos(int64_t pts)
300 {
301     MEDIA_LOG_I("NotifyEos");
302     if (mediaCodec_ == nullptr) {
303         return Status::ERROR_UNKNOWN;
304     }
305     return mediaCodec_->NotifyEos(pts);
306 }
307 
SetParameter(const std::shared_ptr<Meta> & parameter)308 void SurfaceEncoderFilter::SetParameter(const std::shared_ptr<Meta> &parameter)
309 {
310     MEDIA_LOG_I("SetParameter");
311     if (mediaCodec_ == nullptr) {
312         return;
313     }
314     bool isEos = false;
315     int64_t eosPts = UINT32_MAX;
316     if (parameter->Find(Tag::MEDIA_END_OF_STREAM) != parameter->end() &&
317         parameter->Get<Tag::MEDIA_END_OF_STREAM>(isEos) &&
318         parameter->Get<Tag::USER_FRAME_PTS>(eosPts)) {
319         if (isEos) {
320             MEDIA_LOG_I("lastBuffer PTS: " PUBLIC_LOG_D64, eosPts);
321             NotifyEos(eosPts);
322             return;
323         }
324     }
325     mediaCodec_->SetParameter(parameter);
326 }
327 
GetParameter(std::shared_ptr<Meta> & parameter)328 void SurfaceEncoderFilter::GetParameter(std::shared_ptr<Meta> &parameter)
329 {
330     MEDIA_LOG_I("GetParameter");
331 }
332 
LinkNext(const std::shared_ptr<Filter> & nextFilter,StreamType outType)333 Status SurfaceEncoderFilter::LinkNext(const std::shared_ptr<Filter> &nextFilter, StreamType outType)
334 {
335     MEDIA_LOG_I("LinkNext");
336     nextFilter_ = nextFilter;
337     nextFiltersMap_[outType].push_back(nextFilter_);
338     std::shared_ptr<FilterLinkCallback> filterLinkCallback =
339         std::make_shared<SurfaceEncoderFilterLinkCallback>(shared_from_this());
340     nextFilter->OnLinked(outType, configureParameter_, filterLinkCallback);
341     return Status::OK;
342 }
343 
UpdateNext(const std::shared_ptr<Filter> & nextFilter,StreamType outType)344 Status SurfaceEncoderFilter::UpdateNext(const std::shared_ptr<Filter> &nextFilter, StreamType outType)
345 {
346     MEDIA_LOG_I("UpdateNext");
347     return Status::OK;
348 }
349 
UnLinkNext(const std::shared_ptr<Filter> & nextFilter,StreamType outType)350 Status SurfaceEncoderFilter::UnLinkNext(const std::shared_ptr<Filter> &nextFilter, StreamType outType)
351 {
352     MEDIA_LOG_I("UnLinkNext");
353     return Status::OK;
354 }
355 
GetFilterType()356 FilterType SurfaceEncoderFilter::GetFilterType()
357 {
358     return filterType_;
359 }
360 
OnLinked(StreamType inType,const std::shared_ptr<Meta> & meta,const std::shared_ptr<FilterLinkCallback> & callback)361 Status SurfaceEncoderFilter::OnLinked(StreamType inType, const std::shared_ptr<Meta> &meta,
362     const std::shared_ptr<FilterLinkCallback> &callback)
363 {
364     MEDIA_LOG_I("OnLinked");
365     onLinkedResultCallback_ = callback;
366     return Status::OK;
367 }
368 
OnUpdated(StreamType inType,const std::shared_ptr<Meta> & meta,const std::shared_ptr<FilterLinkCallback> & callback)369 Status SurfaceEncoderFilter::OnUpdated(StreamType inType, const std::shared_ptr<Meta> &meta,
370     const std::shared_ptr<FilterLinkCallback> &callback)
371 {
372     MEDIA_LOG_I("OnUpdated");
373     return Status::OK;
374 }
375 
OnUnLinked(StreamType inType,const std::shared_ptr<FilterLinkCallback> & callback)376 Status SurfaceEncoderFilter::OnUnLinked(StreamType inType, const std::shared_ptr<FilterLinkCallback>& callback)
377 {
378     MEDIA_LOG_I("OnUnLinked");
379     return Status::OK;
380 }
381 
OnLinkedResult(const sptr<AVBufferQueueProducer> & outputBufferQueue,std::shared_ptr<Meta> & meta)382 void SurfaceEncoderFilter::OnLinkedResult(const sptr<AVBufferQueueProducer> &outputBufferQueue,
383     std::shared_ptr<Meta> &meta)
384 {
385     MEDIA_LOG_I("OnLinkedResult");
386     if (mediaCodec_ == nullptr) {
387         return;
388     }
389     mediaCodec_->SetOutputBufferQueue(outputBufferQueue);
390     if (onLinkedResultCallback_) {
391         onLinkedResultCallback_->OnLinkedResult(nullptr, meta);
392     }
393 }
394 
OnUpdatedResult(std::shared_ptr<Meta> & meta)395 void SurfaceEncoderFilter::OnUpdatedResult(std::shared_ptr<Meta> &meta)
396 {
397     MEDIA_LOG_I("OnUpdatedResult");
398 }
399 
OnUnlinkedResult(std::shared_ptr<Meta> & meta)400 void SurfaceEncoderFilter::OnUnlinkedResult(std::shared_ptr<Meta> &meta)
401 {
402     MEDIA_LOG_I("OnUnlinkedResult");
403 }
404 
SetCallingInfo(int32_t appUid,int32_t appPid,const std::string & bundleName,uint64_t instanceId)405 void SurfaceEncoderFilter::SetCallingInfo(int32_t appUid, int32_t appPid,
406     const std::string &bundleName, uint64_t instanceId)
407 {
408     appUid_ = appUid;
409     appPid_ = appPid;
410     bundleName_ = bundleName;
411     instanceId_ = instanceId;
412     if (mediaCodec_) {
413         mediaCodec_->SetCallingInfo(appUid, appPid, bundleName, instanceId);
414     }
415 }
416 
OnReportKeyFramePts(std::string KeyFramePts)417 void SurfaceEncoderFilter::OnReportKeyFramePts(std::string KeyFramePts)
418 {
419     MEDIA_LOG_I("OnReportKeyFramePts %{public}s enter", KeyFramePts.c_str());
420     const std::shared_ptr<Meta> userMeta = std::make_shared<Meta>();
421     userMeta->SetData("com.openharmony.recorder.timestamp", KeyFramePts);
422     std::shared_ptr<MuxerFilter> muxerFilter = std::static_pointer_cast<MuxerFilter>(nextFilter_);
423     if (muxerFilter != nullptr) {
424         muxerFilter->SetUserMeta(userMeta);
425         MEDIA_LOG_I("SetUserMeta %{public}s", KeyFramePts.c_str());
426     } else {
427         MEDIA_LOG_E("muxerFilter is null");
428     }
429 }
430 } // namespace Pipeline
431 } // namespace MEDIA
432 } // namespace OHOS
433