1 /*
2 * Copyright (c) 2022-2022 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 #ifdef VIDEO_SUPPORT
17
18 #define HST_LOG_TAG "VideoDecoderFilter"
19
20 #include "pipeline/filters/codec/video_decoder/video_decoder_filter.h"
21 #include "foundation/cpp_ext/memory_ext.h"
22 #include "foundation/log.h"
23 #include "foundation/osal/utils/util.h"
24 #include "foundation/utils/constants.h"
25 #include "foundation/utils/steady_clock.h"
26 #include "pipeline/factory/filter_factory.h"
27 #include "pipeline/filters/codec/codec_filter_factory.h"
28 #include "plugin/common/plugin_buffer.h"
29 #include "plugin/common/plugin_video_tags.h"
30 #include "plugin/common/surface_allocator.h"
31
32 namespace {
33 const uint32_t DEFAULT_IN_BUFFER_POOL_SIZE = 8;
34 const uint32_t DEFAULT_OUT_BUFFER_POOL_SIZE = 8;
35 const float VIDEO_PIX_DEPTH = 1.5;
36 const uint32_t VIDEO_ALIGN_SIZE = 16;
37 }
38
39 namespace OHOS {
40 namespace Media {
41 namespace Pipeline {
42 #ifdef OHOS_LITE
43 static AutoRegisterFilter<VideoDecoderFilter> g_registerVideoDecoderFilter("builtin.player.videodecoder",
__anon589c82e20202(const std::string& name) 44 [](const std::string& name) { return CreateCodecFilter(name, FilterCodecMode::VIDEO_ASYNC_DECODER); });
45 #else
46 static AutoRegisterFilter<VideoDecoderFilter> g_registerVideoDecoderFilter("builtin.player.videodecoder",
47 [](const std::string& name) { return CreateCodecFilter(name, FilterCodecMode::VIDEO_ASYNC_DECODER); });
48 #endif
VideoDecoderFilter(const std::string & name,std::shared_ptr<CodecMode> codecMode)49 VideoDecoderFilter::VideoDecoderFilter(const std::string& name, std::shared_ptr<CodecMode> codecMode)
50 : CodecFilterBase(name)
51 {
52 MEDIA_LOG_I("video decoder ctor called");
53 filterType_ = FilterType::VIDEO_DECODER;
54 bufferMetaType_ = Plugin::BufferMetaType::VIDEO;
55 pluginType_ = Plugin::PluginType::VIDEO_DECODER;
56 codecMode_ = std::move(codecMode);
57 }
58
~VideoDecoderFilter()59 VideoDecoderFilter::~VideoDecoderFilter()
60 {
61 MEDIA_LOG_D("video decoder dtor called");
62 if (plugin_) {
63 plugin_->Stop();
64 plugin_->Deinit();
65 }
66 (void)codecMode_->Release();
67 }
68
Prepare()69 ErrorCode VideoDecoderFilter::Prepare()
70 {
71 MEDIA_LOG_I("video decoder prepare called.");
72 codecMode_->SetBufferPoolSize(static_cast<uint32_t>(DEFAULT_IN_BUFFER_POOL_SIZE),
73 static_cast<uint32_t>(DEFAULT_OUT_BUFFER_POOL_SIZE));
74 (void)codecMode_->Prepare();
75 return CodecFilterBase::Prepare();
76 }
77
Start()78 ErrorCode VideoDecoderFilter::Start()
79 {
80 return CodecFilterBase::Start();
81 }
82
Stop()83 ErrorCode VideoDecoderFilter::Stop()
84 {
85 MEDIA_LOG_D("video decoder stop start.");
86 FAIL_RETURN(CodecFilterBase::Stop());
87 MEDIA_LOG_D("video decoder stop end.");
88 return ErrorCode::SUCCESS;
89 }
90
FlushStart()91 void VideoDecoderFilter::FlushStart()
92 {
93 MEDIA_LOG_I("Video decoder FlushStart entered.");
94 codecMode_->FlushStart();
95 CodecFilterBase::FlushStart();
96 }
97
FlushEnd()98 void VideoDecoderFilter::FlushEnd()
99 {
100 MEDIA_LOG_I("Video decoder FlushEnd entered.");
101 codecMode_->FlushEnd();
102 CodecFilterBase::FlushEnd();
103 }
104
Configure(const std::string & inPort,const std::shared_ptr<const Plugin::Meta> & upstreamMeta,Plugin::Meta & upstreamParams,Plugin::Meta & downstreamParams)105 bool VideoDecoderFilter::Configure(const std::string& inPort, const std::shared_ptr<const Plugin::Meta>& upstreamMeta,
106 Plugin::Meta& upstreamParams, Plugin::Meta& downstreamParams)
107 {
108 PROFILE_BEGIN("video decoder configure begin");
109 FALSE_RETURN_V(CodecFilterBase::Configure(inPort, upstreamMeta, upstreamParams, downstreamParams), false);
110 PROFILE_END("video decoder configure end");
111 return true;
112 }
113
Negotiate(const std::string & inPort,const std::shared_ptr<const Plugin::Capability> & upstreamCap,Plugin::Capability & negotiatedCap,const Plugin::Meta & upstreamParams,Plugin::Meta & downstreamParams)114 bool VideoDecoderFilter::Negotiate(const std::string& inPort,
115 const std::shared_ptr<const Plugin::Capability>& upstreamCap,
116 Plugin::Capability& negotiatedCap,
117 const Plugin::Meta& upstreamParams,
118 Plugin::Meta& downstreamParams)
119 {
120 FALSE_RETURN_V(CodecFilterBase::Negotiate(inPort, upstreamCap, negotiatedCap, upstreamParams, downstreamParams),
121 false);
122 MEDIA_LOG_D("video decoder negotiate end");
123 return true;
124 }
125
GetOutBufferPoolSize()126 uint32_t VideoDecoderFilter::GetOutBufferPoolSize()
127 {
128 return DEFAULT_OUT_BUFFER_POOL_SIZE;
129 }
130
CalculateBufferSize(const std::shared_ptr<const Plugin::Meta> & meta)131 uint32_t VideoDecoderFilter::CalculateBufferSize(const std::shared_ptr<const Plugin::Meta>& meta)
132 {
133 uint32_t bufferSize = 0;
134 uint32_t vdecWidth;
135 uint32_t vdecHeight;
136 Plugin::VideoPixelFormat vdecFormat;
137
138 FALSE_RETURN_V(meta->Get<Plugin::Tag::VIDEO_WIDTH>(vdecWidth), 0);
139 FALSE_RETURN_V(meta->Get<Plugin::Tag::VIDEO_HEIGHT>(vdecHeight), 0);
140 FALSE_RETURN_V(meta->Get<Plugin::Tag::VIDEO_PIXEL_FORMAT>(vdecFormat), 0);
141
142 // YUV420: size = stride * height * 1.5
143 uint32_t stride = Plugin::AlignUp(vdecWidth, VIDEO_ALIGN_SIZE);
144 if (vdecFormat == Plugin::VideoPixelFormat::YUV420P ||
145 vdecFormat == Plugin::VideoPixelFormat::NV21 ||
146 vdecFormat == Plugin::VideoPixelFormat::NV12) {
147 bufferSize = static_cast<uint32_t>(Plugin::AlignUp(stride, VIDEO_ALIGN_SIZE) *
148 Plugin::AlignUp(vdecHeight, VIDEO_ALIGN_SIZE) * VIDEO_PIX_DEPTH);
149 MEDIA_LOG_D("YUV output buffer size: " PUBLIC_LOG_U32, bufferSize);
150 } else if (vdecFormat == Plugin::VideoPixelFormat::RGBA ||
151 vdecFormat == Plugin::VideoPixelFormat::ARGB ||
152 vdecFormat == Plugin::VideoPixelFormat::ABGR ||
153 vdecFormat == Plugin::VideoPixelFormat::BGRA) {
154 bufferSize = static_cast<uint32_t>(Plugin::AlignUp(stride, VIDEO_ALIGN_SIZE) *
155 Plugin::AlignUp(vdecHeight, VIDEO_ALIGN_SIZE) * 4); // 4: 32bit
156 MEDIA_LOG_D("RGBA output buffer size: " PUBLIC_LOG_U32, bufferSize);
157 } else {
158 // need to check video sink support and calc buffer size
159 MEDIA_LOG_E("Unsupported video pixel format: " PUBLIC_LOG_U32, vdecFormat);
160 }
161 return bufferSize;
162 }
163
GetNegotiateParams(const Plugin::Meta & upstreamParams)164 Plugin::Meta VideoDecoderFilter::GetNegotiateParams(const Plugin::Meta& upstreamParams)
165 {
166 // video, need to get the max buffer num from plugin capability when use hdi as codec plugin interfaces
167 Plugin::Meta proposeParams = upstreamParams;
168 proposeParams.Set<Plugin::Tag::VIDEO_MAX_SURFACE_NUM>(DEFAULT_OUT_BUFFER_POOL_SIZE);
169 return proposeParams;
170 }
171
GetAllocator()172 std::shared_ptr<Allocator> VideoDecoderFilter::GetAllocator()
173 {
174 #ifndef OHOS_LITE
175 // Use sink allocator first, zero copy while passing data
176 Plugin::Tag tag = Plugin::Tag::BUFFER_ALLOCATOR;
177 auto ite = sinkParams_.Find(tag);
178 if (ite != std::end(sinkParams_)) {
179 if (Plugin::Any::IsSameTypeWith<std::shared_ptr<Plugin::SurfaceAllocator>>(ite->second)) {
180 MEDIA_LOG_D("Get SurfaceAllocator from sink");
181 return Plugin::AnyCast<std::shared_ptr<Plugin::SurfaceAllocator>>(ite->second);
182 }
183 }
184 #endif
185 return plugin_->GetAllocator();
186 }
187
UpdateParams(const std::shared_ptr<const Plugin::Meta> & upMeta,std::shared_ptr<Plugin::Meta> & meta)188 void VideoDecoderFilter::UpdateParams(const std::shared_ptr<const Plugin::Meta>& upMeta,
189 std::shared_ptr<Plugin::Meta>& meta)
190 {
191 MEDIA_LOG_D("UpdateParams begin");
192 }
193
OnInputBufferDone(const std::shared_ptr<Plugin::Buffer> & input)194 void VideoDecoderFilter::OnInputBufferDone(const std::shared_ptr<Plugin::Buffer>& input)
195 {
196 MEDIA_LOG_DD("VideoDecoderFilter::OnInputBufferDone");
197 }
198
OnOutputBufferDone(const std::shared_ptr<Plugin::Buffer> & output)199 void VideoDecoderFilter::OnOutputBufferDone(const std::shared_ptr<Plugin::Buffer>& output)
200 {
201 codecMode_->OnOutputBufferDone(output);
202 }
203 } // namespace Pipeline
204 } // namespace Media
205 } // namespace OHOS
206 #endif
207