1 /*
2 * Copyright (c) 2024 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_decoder_filter.h"
17 #include "surface_encoder_filter.h"
18 #include "filter/filter_factory.h"
19 #include "surface_decoder_adapter.h"
20 #include "meta/format.h"
21 #include "common/media_core.h"
22 #include "surface/native_buffer.h"
23 #include "media_description.h"
24 #include "av_common.h"
25
26 namespace {
27 constexpr OHOS::HiviewDFX::HiLogLabel LABEL = { LOG_ONLY_PRERELEASE, LOG_DOMAIN_SYSTEM_PLAYER, "SurfaceDecoderFilter" };
28 }
29
30 namespace OHOS {
31 namespace Media {
32 namespace Pipeline {
33 static AutoRegisterFilter<SurfaceDecoderFilter> g_registerSurfaceDecoderFilter("builtin.player.surfacedecoder",
__anon1c5f2f170202(const std::string& name, const FilterType type) 34 FilterType::FILTERTYPE_VIDEODEC, [](const std::string& name, const FilterType type) {
35 return std::make_shared<SurfaceDecoderFilter>(name, FilterType::FILTERTYPE_VIDEODEC);
36 });
37
38 class SurfaceDecoderFilterLinkCallback : public FilterLinkCallback {
39 public:
SurfaceDecoderFilterLinkCallback(std::shared_ptr<SurfaceDecoderFilter> surfaceDecoderFilter)40 explicit SurfaceDecoderFilterLinkCallback(std::shared_ptr<SurfaceDecoderFilter> surfaceDecoderFilter)
41 : surfaceDecoderFilter_(std::move(surfaceDecoderFilter))
42 {
43 }
44
45 ~SurfaceDecoderFilterLinkCallback() = 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 surfaceDecoderFilter = surfaceDecoderFilter_.lock()) {
50 surfaceDecoderFilter->OnLinkedResult(queue, meta);
51 } else {
52 MEDIA_LOG_I("invalid surfaceDecoderFilter");
53 }
54 }
55
OnUnlinkedResult(std::shared_ptr<Meta> & meta)56 void OnUnlinkedResult(std::shared_ptr<Meta> &meta) override
57 {
58 if (auto surfaceDecoderFilter = surfaceDecoderFilter_.lock()) {
59 surfaceDecoderFilter->OnUnlinkedResult(meta);
60 } else {
61 MEDIA_LOG_I("invalid surfaceDecoderFilter");
62 }
63 }
64
OnUpdatedResult(std::shared_ptr<Meta> & meta)65 void OnUpdatedResult(std::shared_ptr<Meta> &meta) override
66 {
67 if (auto surfaceDecoderFilter = surfaceDecoderFilter_.lock()) {
68 surfaceDecoderFilter->OnUpdatedResult(meta);
69 } else {
70 MEDIA_LOG_I("invalid surfaceDecoderFilter");
71 }
72 }
73 private:
74 std::weak_ptr<SurfaceDecoderFilter> surfaceDecoderFilter_;
75 };
76
77 class SurfaceDecoderAdapterCallback : public DecoderAdapterCallback {
78 public:
SurfaceDecoderAdapterCallback(std::shared_ptr<SurfaceDecoderFilter> surfaceDecoderFilter)79 explicit SurfaceDecoderAdapterCallback(std::shared_ptr<SurfaceDecoderFilter> surfaceDecoderFilter)
80 : surfaceDecoderFilter_(std::move(surfaceDecoderFilter))
81 {
82 }
83
OnError(MediaAVCodec::AVCodecErrorType type,int32_t errorCode)84 void OnError(MediaAVCodec::AVCodecErrorType type, int32_t errorCode) override
85 {
86 }
87
OnOutputFormatChanged(const std::shared_ptr<Meta> & format)88 void OnOutputFormatChanged(const std::shared_ptr<Meta> &format) override
89 {
90 }
91
OnBufferEos(int64_t pts,int64_t frameNum)92 void OnBufferEos(int64_t pts, int64_t frameNum) override
93 {
94 if (auto surfaceDecoderFilter = surfaceDecoderFilter_.lock()) {
95 surfaceDecoderFilter->NotifyNextFilterEos(pts, frameNum);
96 } else {
97 MEDIA_LOG_I("invalid surfaceDecoderFilter");
98 }
99 }
100 private:
101 std::weak_ptr<SurfaceDecoderFilter> surfaceDecoderFilter_;
102 };
103
SurfaceDecoderFilter(const std::string & name,FilterType type)104 SurfaceDecoderFilter::SurfaceDecoderFilter(const std::string& name, FilterType type): Filter(name, type)
105 {
106 MEDIA_LOG_I("surface decoder filter create");
107 }
108
~SurfaceDecoderFilter()109 SurfaceDecoderFilter::~SurfaceDecoderFilter()
110 {
111 MEDIA_LOG_I("surface decoder filter destroy");
112 }
113
Init(const std::shared_ptr<EventReceiver> & receiver,const std::shared_ptr<FilterCallback> & callback)114 void SurfaceDecoderFilter::Init(const std::shared_ptr<EventReceiver> &receiver,
115 const std::shared_ptr<FilterCallback> &callback)
116 {
117 MEDIA_LOG_I("Init");
118 eventReceiver_ = receiver;
119 filterCallback_ = callback;
120 }
121
Configure(const std::shared_ptr<Meta> & parameter)122 Status SurfaceDecoderFilter::Configure(const std::shared_ptr<Meta> ¶meter)
123 {
124 MEDIA_LOG_I("Configure");
125 if (mediaCodec_ == nullptr) {
126 MEDIA_LOG_E("mediaCodec is null");
127 return Status::ERROR_UNKNOWN;
128 }
129 configureParameter_ = parameter;
130 configFormat_.SetMeta(configureParameter_);
131 bool isHdr = false;
132 configureParameter_->GetData(Tag::VIDEO_IS_HDR_VIVID, isHdr);
133 if (isHdr) {
134 MEDIA_LOG_D("isHdr true,set video_decoder_output_colorspace, pixel_format");
135 configFormat_.PutIntValue(MediaAVCodec::MediaDescriptionKey::MD_KEY_VIDEO_DECODER_OUTPUT_COLOR_SPACE,
136 static_cast<int8_t>(OH_NativeBuffer_ColorSpace::OH_COLORSPACE_BT709_LIMIT));
137 configFormat_.PutIntValue(MediaAVCodec::MediaDescriptionKey::MD_KEY_PIXEL_FORMAT,
138 static_cast<int8_t>(MediaAVCodec::VideoPixelFormat::NV12));
139 } else {
140 MEDIA_LOG_D("isHdr false");
141 }
142 configFormat_.PutIntValue(Tag::VIDEO_FRAME_RATE_ADAPTIVE_MODE, true);
143 Status ret = mediaCodec_->Configure(configFormat_);
144 if (ret != Status::OK) {
145 MEDIA_LOG_E("mediaCodec Configure fail");
146 if (eventReceiver_ != nullptr) {
147 eventReceiver_->OnEvent({"surface_decoder_filter", EventType::EVENT_ERROR, MSERR_UNKNOWN});
148 }
149 }
150 return ret;
151 }
152
SetOutputSurface(sptr<Surface> surface)153 Status SurfaceDecoderFilter::SetOutputSurface(sptr<Surface> surface)
154 {
155 MEDIA_LOG_I("SetOutputSurface");
156 if (mediaCodec_ == nullptr) {
157 MEDIA_LOG_E("mediaCodec is null");
158 return Status::ERROR_UNKNOWN;
159 }
160 outputSurface_ = surface;
161 Status ret = mediaCodec_->SetOutputSurface(outputSurface_);
162 if (ret != Status::OK) {
163 MEDIA_LOG_E("mediaCodec SetOutputSurface fail");
164 if (eventReceiver_ != nullptr) {
165 eventReceiver_->OnEvent({"surface_decoder_filter", EventType::EVENT_ERROR, MSERR_UNKNOWN});
166 }
167 }
168 return ret;
169 }
170
NotifyNextFilterEos(int64_t pts,int64_t frameNum)171 Status SurfaceDecoderFilter::NotifyNextFilterEos(int64_t pts, int64_t frameNum)
172 {
173 MEDIA_LOG_I("NotifyNextFilterEos");
174 for (auto iter : nextFiltersMap_) {
175 for (auto filter : iter.second) {
176 std::shared_ptr<Meta> eosMeta = std::make_shared<Meta>();
177 eosMeta->Set<Tag::MEDIA_END_OF_STREAM>(true);
178 MEDIA_LOG_I("lastBuffer PTS: " PUBLIC_LOG_D64 " frameNum: " PUBLIC_LOG_D64, pts, frameNum);
179 eosMeta->Set<Tag::USER_FRAME_PTS>(pts);
180 eosMeta->Set<Tag::USER_PUSH_DATA_TIME>(frameNum);
181 filter->SetParameter(eosMeta);
182 }
183 }
184 return Status::OK;
185 }
186
DoPrepare()187 Status SurfaceDecoderFilter::DoPrepare()
188 {
189 MEDIA_LOG_I("Prepare");
190 if (filterCallback_ == nullptr) {
191 MEDIA_LOG_E("filterCallback is null");
192 return Status::ERROR_UNKNOWN;
193 }
194 filterCallback_->OnCallback(shared_from_this(), FilterCallBackCommand::NEXT_FILTER_NEEDED,
195 StreamType::STREAMTYPE_RAW_VIDEO);
196 return Status::OK;
197 }
198
DoStart()199 Status SurfaceDecoderFilter::DoStart()
200 {
201 MEDIA_LOG_I("Start");
202 if (mediaCodec_ == nullptr) {
203 MEDIA_LOG_E("mediaCodec is null");
204 return Status::ERROR_UNKNOWN;
205 }
206 Status ret = mediaCodec_->Start();
207 if (ret != Status::OK) {
208 MEDIA_LOG_E("mediaCodec Start fail");
209 if (eventReceiver_ != nullptr) {
210 eventReceiver_->OnEvent({"surface_decoder_filter", EventType::EVENT_ERROR, MSERR_UNKNOWN});
211 }
212 }
213 return ret;
214 }
215
DoPause()216 Status SurfaceDecoderFilter::DoPause()
217 {
218 MEDIA_LOG_I("Pause");
219 if (mediaCodec_ == nullptr) {
220 MEDIA_LOG_E("mediaCodec is null");
221 return Status::ERROR_UNKNOWN;
222 }
223 Status ret = mediaCodec_->Pause();
224 if (ret != Status::OK) {
225 MEDIA_LOG_E("mediaCodec Pause fail");
226 if (eventReceiver_ != nullptr) {
227 eventReceiver_->OnEvent({"surface_decoder_filter", EventType::EVENT_ERROR, MSERR_UNKNOWN});
228 }
229 }
230 return ret;
231 }
232
DoResume()233 Status SurfaceDecoderFilter::DoResume()
234 {
235 MEDIA_LOG_I("Resume");
236 if (mediaCodec_ == nullptr) {
237 MEDIA_LOG_E("mediaCodec is null");
238 return Status::ERROR_UNKNOWN;
239 }
240 Status ret = mediaCodec_->Resume();
241 if (ret != Status::OK) {
242 MEDIA_LOG_E("mediaCodec Resume fail");
243 if (eventReceiver_ != nullptr) {
244 eventReceiver_->OnEvent({"surface_decoder_filter", EventType::EVENT_ERROR, MSERR_UNKNOWN});
245 }
246 }
247 return ret;
248 }
249
DoStop()250 Status SurfaceDecoderFilter::DoStop()
251 {
252 MEDIA_LOG_I("Stop enter");
253 if (mediaCodec_ == nullptr) {
254 return Status::OK;
255 }
256 Status ret = mediaCodec_->Stop();
257 if (ret != Status::OK) {
258 MEDIA_LOG_E("mediaCodec Stop fail");
259 if (eventReceiver_ != nullptr) {
260 eventReceiver_->OnEvent({"surface_decoder_filter", EventType::EVENT_ERROR, MSERR_UNKNOWN});
261 }
262 return ret;
263 }
264 MEDIA_LOG_I("Stop done");
265 return Status::OK;
266 }
267
DoFlush()268 Status SurfaceDecoderFilter::DoFlush()
269 {
270 MEDIA_LOG_I("Flush");
271 return Status::OK;
272 }
273
DoRelease()274 Status SurfaceDecoderFilter::DoRelease()
275 {
276 MEDIA_LOG_I("Release");
277 return Status::OK;
278 }
279
SetParameter(const std::shared_ptr<Meta> & parameter)280 void SurfaceDecoderFilter::SetParameter(const std::shared_ptr<Meta> ¶meter)
281 {
282 MEDIA_LOG_I("SetParameter");
283 if (mediaCodec_ == nullptr) {
284 return;
285 }
286 Format format;
287 format.SetMeta(parameter);
288 auto ret = mediaCodec_->SetParameter(format);
289 if (ret != Status::OK) {
290 MEDIA_LOG_E("mediaCodec SetParameter fail");
291 if (eventReceiver_ != nullptr) {
292 eventReceiver_->OnEvent({"surface_decoder_filter", EventType::EVENT_ERROR, MSERR_UNKNOWN});
293 }
294 }
295 }
296
GetParameter(std::shared_ptr<Meta> & parameter)297 void SurfaceDecoderFilter::GetParameter(std::shared_ptr<Meta> ¶meter)
298 {
299 MEDIA_LOG_I("GetParameter");
300 }
301
LinkNext(const std::shared_ptr<Filter> & nextFilter,StreamType outType)302 Status SurfaceDecoderFilter::LinkNext(const std::shared_ptr<Filter> &nextFilter, StreamType outType)
303 {
304 MEDIA_LOG_I("LinkNext");
305 nextFilter_ = nextFilter;
306 nextFiltersMap_[outType].push_back(nextFilter_);
307 std::shared_ptr<FilterLinkCallback> filterLinkCallback =
308 std::make_shared<SurfaceDecoderFilterLinkCallback>(shared_from_this());
309 nextFilter->OnLinked(outType, configureParameter_, filterLinkCallback);
310 return Status::OK;
311 }
312
UpdateNext(const std::shared_ptr<Filter> & nextFilter,StreamType outType)313 Status SurfaceDecoderFilter::UpdateNext(const std::shared_ptr<Filter> &nextFilter, StreamType outType)
314 {
315 MEDIA_LOG_I("UpdateNext");
316 return Status::OK;
317 }
318
UnLinkNext(const std::shared_ptr<Filter> & nextFilter,StreamType outType)319 Status SurfaceDecoderFilter::UnLinkNext(const std::shared_ptr<Filter> &nextFilter, StreamType outType)
320 {
321 MEDIA_LOG_I("UnLinkNext");
322 return Status::OK;
323 }
324
GetFilterType()325 FilterType SurfaceDecoderFilter::GetFilterType()
326 {
327 return filterType_;
328 }
329
OnLinked(StreamType inType,const std::shared_ptr<Meta> & meta,const std::shared_ptr<FilterLinkCallback> & callback)330 Status SurfaceDecoderFilter::OnLinked(StreamType inType, const std::shared_ptr<Meta> &meta,
331 const std::shared_ptr<FilterLinkCallback> &callback)
332 {
333 MEDIA_LOG_I("OnLinked");
334 FALSE_RETURN_V_MSG(meta->GetData(Tag::MIME_TYPE, codecMimeType_),
335 Status::ERROR_INVALID_PARAMETER, "get mime failed.");
336 MEDIA_LOG_I("OnLinked enter the codecMimeType_ is %{public}s", codecMimeType_.c_str());
337 mediaCodec_ = std::make_shared<SurfaceDecoderAdapter>();
338 Status ret = mediaCodec_->Init(codecMimeType_);
339 if (ret == Status::OK) {
340 std::shared_ptr<DecoderAdapterCallback> decoderSurfaceCallback =
341 std::make_shared<SurfaceDecoderAdapterCallback>(shared_from_this());
342 mediaCodec_->SetDecoderAdapterCallback(decoderSurfaceCallback);
343 } else {
344 MEDIA_LOG_E("Init mediaCodec fail");
345 if (eventReceiver_ != nullptr) {
346 eventReceiver_->OnEvent({"surface_encoder_filter", EventType::EVENT_ERROR, MSERR_UNKNOWN});
347 }
348 }
349 meta_ = meta;
350 ret = Configure(meta);
351 if (ret != Status::OK) {
352 MEDIA_LOG_E("mediaCodec Configure fail");
353 }
354 onLinkedResultCallback_ = callback;
355 return Status::OK;
356 }
357
OnUpdated(StreamType inType,const std::shared_ptr<Meta> & meta,const std::shared_ptr<FilterLinkCallback> & callback)358 Status SurfaceDecoderFilter::OnUpdated(StreamType inType, const std::shared_ptr<Meta> &meta,
359 const std::shared_ptr<FilterLinkCallback> &callback)
360 {
361 MEDIA_LOG_I("OnUpdated");
362 return Status::OK;
363 }
364
OnUnLinked(StreamType inType,const std::shared_ptr<FilterLinkCallback> & callback)365 Status SurfaceDecoderFilter::OnUnLinked(StreamType inType, const std::shared_ptr<FilterLinkCallback>& callback)
366 {
367 MEDIA_LOG_I("OnUnLinked");
368 return Status::OK;
369 }
370
OnLinkedResult(const sptr<AVBufferQueueProducer> & outputBufferQueue,std::shared_ptr<Meta> & meta)371 void SurfaceDecoderFilter::OnLinkedResult(const sptr<AVBufferQueueProducer> &outputBufferQueue,
372 std::shared_ptr<Meta> &meta)
373 {
374 MEDIA_LOG_I("OnLinkedResult");
375 (void) meta;
376 if (onLinkedResultCallback_) {
377 onLinkedResultCallback_->OnLinkedResult(mediaCodec_->GetInputBufferQueue(), meta_);
378 }
379 }
380
OnUpdatedResult(std::shared_ptr<Meta> & meta)381 void SurfaceDecoderFilter::OnUpdatedResult(std::shared_ptr<Meta> &meta)
382 {
383 MEDIA_LOG_I("OnUpdatedResult");
384 }
385
OnUnlinkedResult(std::shared_ptr<Meta> & meta)386 void SurfaceDecoderFilter::OnUnlinkedResult(std::shared_ptr<Meta> &meta)
387 {
388 MEDIA_LOG_I("OnUnlinkedResult");
389 (void) meta;
390 }
391 } // namespace Pipeline
392 } // namespace MEDIA
393 } // namespace OHOS
394