1 /*
2  * Copyright (C) 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 "avcodec_video_decoder_impl.h"
17 #include "avcodec_trace.h"
18 #include "avcodec_errors.h"
19 #include "avcodec_log.h"
20 #include "i_avcodec_service.h"
21 
22 namespace {
23 constexpr OHOS::HiviewDFX::HiLogLabel LABEL = {LOG_CORE, LOG_DOMAIN_FRAMEWORK, "AVCodecVideoDecoderImpl"};
24 }
25 
26 namespace OHOS {
27 namespace MediaAVCodec {
CreateByMime(const std::string & mime)28 std::shared_ptr<AVCodecVideoDecoder> VideoDecoderFactory::CreateByMime(const std::string &mime)
29 {
30     std::shared_ptr<AVCodecVideoDecoder> impl = nullptr;
31     Format format;
32 
33     int32_t ret = CreateByMime(mime, format, impl);
34     CHECK_AND_RETURN_RET_LOG(ret == AVCS_ERR_OK || impl != nullptr, nullptr,
35         "AVCodec video decoder impl init failed, %{public}s",
36         AVCSErrorToString(static_cast<AVCodecServiceErrCode>(ret)).c_str());
37     return impl;
38 }
39 
CreateByName(const std::string & name)40 std::shared_ptr<AVCodecVideoDecoder> VideoDecoderFactory::CreateByName(const std::string &name)
41 {
42     std::shared_ptr<AVCodecVideoDecoder> impl = nullptr;
43     Format format;
44 
45     int32_t ret = CreateByName(name, format, impl);
46     CHECK_AND_RETURN_RET_LOG(ret == AVCS_ERR_OK || impl != nullptr, nullptr,
47         "AVCodec video decoder impl init failed, %{public}s",
48         AVCSErrorToString(static_cast<AVCodecServiceErrCode>(ret)).c_str());
49 
50     return impl;
51 }
52 
CreateByMime(const std::string & mime,Format & format,std::shared_ptr<AVCodecVideoDecoder> & decoder)53 int32_t VideoDecoderFactory::CreateByMime(const std::string &mime,
54                                           Format &format, std::shared_ptr<AVCodecVideoDecoder> &decoder)
55 {
56     auto impl = std::make_shared<AVCodecVideoDecoderImpl>();
57 
58     int32_t ret = impl->Init(AVCODEC_TYPE_VIDEO_DECODER, true, mime, format);
59     CHECK_AND_RETURN_RET_LOG(ret == AVCS_ERR_OK, ret, "AVCodec video decoder impl init failed, %{public}s",
60                              AVCSErrorToString(static_cast<AVCodecServiceErrCode>(ret)).c_str());
61 
62     decoder = impl;
63     return AVCS_ERR_OK;
64 }
65 
CreateByName(const std::string & name,Format & format,std::shared_ptr<AVCodecVideoDecoder> & decoder)66 int32_t VideoDecoderFactory::CreateByName(const std::string &name,
67                                           Format &format, std::shared_ptr<AVCodecVideoDecoder> &decoder)
68 {
69     auto impl = std::make_shared<AVCodecVideoDecoderImpl>();
70 
71     int32_t ret = impl->Init(AVCODEC_TYPE_VIDEO_DECODER, false, name, format);
72     CHECK_AND_RETURN_RET_LOG(ret == AVCS_ERR_OK, ret, "AVCodec video decoder impl init failed, %{public}s",
73                              AVCSErrorToString(static_cast<AVCodecServiceErrCode>(ret)).c_str());
74 
75     decoder = impl;
76     return AVCS_ERR_OK;
77 }
78 
Init(AVCodecType type,bool isMimeType,const std::string & name,Format & format)79 int32_t AVCodecVideoDecoderImpl::Init(AVCodecType type, bool isMimeType, const std::string &name, Format &format)
80 {
81     AVCODEC_SYNC_TRACE;
82 
83     int32_t ret = AVCodecServiceFactory::GetInstance().CreateCodecService(codecClient_);
84     CHECK_AND_RETURN_RET_LOG(codecClient_ != nullptr, ret, "Codec client create failed");
85 
86     return codecClient_->Init(type, isMimeType, name, *format.GetMeta());
87 }
88 
AVCodecVideoDecoderImpl()89 AVCodecVideoDecoderImpl::AVCodecVideoDecoderImpl()
90 {
91     AVCODEC_LOGD("AVCodecVideoDecoderImpl:0x%{public}06" PRIXPTR " Instances create", FAKE_POINTER(this));
92 }
93 
~AVCodecVideoDecoderImpl()94 AVCodecVideoDecoderImpl::~AVCodecVideoDecoderImpl()
95 {
96     if (codecClient_ != nullptr) {
97         (void)AVCodecServiceFactory::GetInstance().DestroyCodecService(codecClient_);
98         codecClient_ = nullptr;
99     }
100     AVCODEC_LOGD("AVCodecVideoDecoderImpl:0x%{public}06" PRIXPTR " Instances destroy", FAKE_POINTER(this));
101 }
102 
Configure(const Format & format)103 int32_t AVCodecVideoDecoderImpl::Configure(const Format &format)
104 {
105     CHECK_AND_RETURN_RET_LOG(codecClient_ != nullptr, AVCS_ERR_INVALID_OPERATION, "Codec service is nullptr");
106 
107     AVCODEC_SYNC_TRACE;
108     return codecClient_->Configure(format);
109 }
110 
Prepare()111 int32_t AVCodecVideoDecoderImpl::Prepare()
112 {
113     CHECK_AND_RETURN_RET_LOG(codecClient_ != nullptr, AVCS_ERR_INVALID_OPERATION, "Codec service is nullptr");
114     AVCODEC_SYNC_TRACE;
115 
116     return codecClient_->Prepare();
117 }
118 
Start()119 int32_t AVCodecVideoDecoderImpl::Start()
120 {
121     CHECK_AND_RETURN_RET_LOG(codecClient_ != nullptr, AVCS_ERR_INVALID_OPERATION, "Codec service is nullptr");
122 
123     AVCODEC_SYNC_TRACE;
124     return codecClient_->Start();
125 }
126 
Stop()127 int32_t AVCodecVideoDecoderImpl::Stop()
128 {
129     CHECK_AND_RETURN_RET_LOG(codecClient_ != nullptr, AVCS_ERR_INVALID_OPERATION, "Codec service is nullptr");
130 
131     AVCODEC_SYNC_TRACE;
132     return codecClient_->Stop();
133 }
134 
Flush()135 int32_t AVCodecVideoDecoderImpl::Flush()
136 {
137     CHECK_AND_RETURN_RET_LOG(codecClient_ != nullptr, AVCS_ERR_INVALID_OPERATION, "Codec service is nullptr");
138 
139     AVCODEC_SYNC_TRACE;
140     return codecClient_->Flush();
141 }
142 
Reset()143 int32_t AVCodecVideoDecoderImpl::Reset()
144 {
145     CHECK_AND_RETURN_RET_LOG(codecClient_ != nullptr, AVCS_ERR_INVALID_OPERATION, "Codec service is nullptr");
146 
147     AVCODEC_SYNC_TRACE;
148     return codecClient_->Reset();
149 }
150 
Release()151 int32_t AVCodecVideoDecoderImpl::Release()
152 {
153     CHECK_AND_RETURN_RET_LOG(codecClient_ != nullptr, AVCS_ERR_INVALID_OPERATION, "Codec service is nullptr");
154 
155     AVCODEC_SYNC_TRACE;
156     return codecClient_->Release();
157 }
158 
SetOutputSurface(sptr<Surface> surface)159 int32_t AVCodecVideoDecoderImpl::SetOutputSurface(sptr<Surface> surface)
160 {
161     CHECK_AND_RETURN_RET_LOG(codecClient_ != nullptr, AVCS_ERR_INVALID_OPERATION, "Codec service is nullptr");
162 
163     AVCODEC_SYNC_TRACE;
164     return codecClient_->SetOutputSurface(surface);
165 }
166 
QueueInputBuffer(uint32_t index,AVCodecBufferInfo info,AVCodecBufferFlag flag)167 int32_t AVCodecVideoDecoderImpl::QueueInputBuffer(uint32_t index, AVCodecBufferInfo info, AVCodecBufferFlag flag)
168 {
169     CHECK_AND_RETURN_RET_LOG(codecClient_ != nullptr, AVCS_ERR_INVALID_OPERATION, "Codec service is nullptr");
170 
171     AVCODEC_SYNC_TRACE;
172     return codecClient_->QueueInputBuffer(index, info, flag);
173 }
174 
QueueInputBuffer(uint32_t index)175 int32_t AVCodecVideoDecoderImpl::QueueInputBuffer(uint32_t index)
176 {
177     CHECK_AND_RETURN_RET_LOG(codecClient_ != nullptr, AVCS_ERR_INVALID_OPERATION, "Codec service is nullptr");
178 
179     AVCODEC_SYNC_TRACE;
180     return codecClient_->QueueInputBuffer(index);
181 }
182 
GetOutputFormat(Format & format)183 int32_t AVCodecVideoDecoderImpl::GetOutputFormat(Format &format)
184 {
185     CHECK_AND_RETURN_RET_LOG(codecClient_ != nullptr, AVCS_ERR_INVALID_OPERATION, "Codec service is nullptr");
186 
187     AVCODEC_SYNC_TRACE;
188     return codecClient_->GetOutputFormat(format);
189 }
190 
ReleaseOutputBuffer(uint32_t index,bool render)191 int32_t AVCodecVideoDecoderImpl::ReleaseOutputBuffer(uint32_t index, bool render)
192 {
193     CHECK_AND_RETURN_RET_LOG(codecClient_ != nullptr, AVCS_ERR_INVALID_OPERATION, "Codec service is nullptr");
194 
195     AVCODEC_SYNC_TRACE;
196     return codecClient_->ReleaseOutputBuffer(index, render);
197 }
198 
RenderOutputBufferAtTime(uint32_t index,int64_t renderTimestampNs)199 int32_t AVCodecVideoDecoderImpl::RenderOutputBufferAtTime(uint32_t index, int64_t renderTimestampNs)
200 {
201     CHECK_AND_RETURN_RET_LOG(codecClient_ != nullptr, AVCS_ERR_INVALID_OPERATION, "Codec service is nullptr");
202 
203     AVCODEC_SYNC_TRACE;
204     return codecClient_->RenderOutputBufferAtTime(index, renderTimestampNs);
205 }
206 
SetParameter(const Format & format)207 int32_t AVCodecVideoDecoderImpl::SetParameter(const Format &format)
208 {
209     CHECK_AND_RETURN_RET_LOG(codecClient_ != nullptr, AVCS_ERR_INVALID_OPERATION, "Codec service is nullptr");
210 
211     AVCODEC_SYNC_TRACE;
212     return codecClient_->SetParameter(format);
213 }
214 
SetCallback(const std::shared_ptr<AVCodecCallback> & callback)215 int32_t AVCodecVideoDecoderImpl::SetCallback(const std::shared_ptr<AVCodecCallback> &callback)
216 {
217     CHECK_AND_RETURN_RET_LOG(codecClient_ != nullptr, AVCS_ERR_INVALID_OPERATION, "Codec service is nullptr");
218     CHECK_AND_RETURN_RET_LOG(callback != nullptr, AVCS_ERR_INVALID_VAL, "Callback is nullptr");
219 
220     AVCODEC_SYNC_TRACE;
221     return codecClient_->SetCallback(callback);
222 }
223 
SetCallback(const std::shared_ptr<MediaCodecCallback> & callback)224 int32_t AVCodecVideoDecoderImpl::SetCallback(const std::shared_ptr<MediaCodecCallback> &callback)
225 {
226     CHECK_AND_RETURN_RET_LOG(codecClient_ != nullptr, AVCS_ERR_INVALID_OPERATION, "Codec service is nullptr");
227     CHECK_AND_RETURN_RET_LOG(callback != nullptr, AVCS_ERR_INVALID_VAL, "Callback is nullptr");
228 
229     AVCODEC_SYNC_TRACE;
230     return codecClient_->SetCallback(callback);
231 }
232 
233 #ifdef SUPPORT_DRM
SetDecryptConfig(const sptr<DrmStandard::IMediaKeySessionService> & keySessionProxy,const bool svpFlag)234 int32_t AVCodecVideoDecoderImpl::SetDecryptConfig(const sptr<DrmStandard::IMediaKeySessionService> &keySessionProxy,
235     const bool svpFlag)
236 {
237     AVCODEC_LOGI("AVCodecVideoDecoderImpl SetDecryptConfig proxy");
238     CHECK_AND_RETURN_RET_LOG(codecClient_ != nullptr,
239         AVCS_ERR_INVALID_OPERATION, "Codec service is nullptr");
240     CHECK_AND_RETURN_RET_LOG(keySessionProxy != nullptr,
241         AVCS_ERR_INVALID_OPERATION, "keySessionProxy is nullptr");
242 
243     AVCODEC_SYNC_TRACE;
244     return codecClient_->SetDecryptConfig(keySessionProxy, svpFlag);
245 }
246 #endif
247 } // namespace MediaAVCodec
248 } // namespace OHOS
249