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 <list>
17 #include <mutex>
18 #include <queue>
19 #include <shared_mutex>
20 #include <unordered_map>
21 #include "avcodec_errors.h"
22 #include "avcodec_log.h"
23 #include "avcodec_trace.h"
24 #include "avcodec_video_decoder.h"
25 #include "buffer/avsharedmemory.h"
26 #include "common/native_mfmagic.h"
27 #include "native_avbuffer.h"
28 #include "native_avcodec_base.h"
29 #include "native_avcodec_videodecoder.h"
30 #include "native_avmagic.h"
31 #include "native_window.h"
32 
33 #ifdef SUPPORT_DRM
34 #include "native_drm_object.h"
35 #endif
36 namespace {
37 constexpr OHOS::HiviewDFX::HiLogLabel LABEL = {LOG_CORE, LOG_DOMAIN_FRAMEWORK, "NativeVideoDecoder"};
38 constexpr size_t MAX_TEMPNUM = 64;
39 
40 using namespace OHOS::MediaAVCodec;
41 using namespace OHOS::Media;
42 using namespace OHOS::DrmStandard;
43 class NativeVideoDecoderCallback;
44 
45 struct VideoDecoderObject : public OH_AVCodec {
VideoDecoderObject__anonc56259bd0110::VideoDecoderObject46     explicit VideoDecoderObject(const std::shared_ptr<AVCodecVideoDecoder> &decoder)
47         : OH_AVCodec(AVMagic::AVCODEC_MAGIC_VIDEO_DECODER), videoDecoder_(decoder)
48     {
49     }
50     ~VideoDecoderObject() = default;
51 
52     void ClearBufferList();
53     void StopCallback();
54     void BufferToTempFunc(std::unordered_map<uint32_t, OHOS::sptr<OH_AVBuffer>> &tempMap);
55     void MemoryToTempFunc(std::unordered_map<uint32_t, OHOS::sptr<OH_AVMemory>> &tempMap);
56 
57     const std::shared_ptr<AVCodecVideoDecoder> videoDecoder_;
58     std::queue<OHOS::sptr<MFObjectMagic>> tempList_;
59     std::unordered_map<uint32_t, OHOS::sptr<OH_AVMemory>> outputMemoryMap_;
60     std::unordered_map<uint32_t, OHOS::sptr<OH_AVMemory>> inputMemoryMap_;
61     std::unordered_map<uint32_t, OHOS::sptr<OH_AVBuffer>> outputBufferMap_;
62     std::unordered_map<uint32_t, OHOS::sptr<OH_AVBuffer>> inputBufferMap_;
63     std::shared_ptr<NativeVideoDecoderCallback> callback_ = nullptr;
64     bool isSetMemoryCallback_ = false;
65     bool isSetBufferCallback_ = false;
66     std::atomic<bool> isEOS_ = false;
67     bool isOutputSurfaceMode_ = false;
68     std::shared_mutex objListMutex_;
69 };
70 
71 class NativeVideoDecoderCallback : public AVCodecCallback, public MediaCodecCallback {
72 public:
NativeVideoDecoderCallback(OH_AVCodec * codec,struct OH_AVCodecAsyncCallback cb,void * userData)73     NativeVideoDecoderCallback(OH_AVCodec *codec, struct OH_AVCodecAsyncCallback cb, void *userData)
74         : codec_(codec), asyncCallback_(cb), userData_(userData)
75     {
76     }
NativeVideoDecoderCallback(OH_AVCodec * codec,struct OH_AVCodecCallback cb,void * userData)77     NativeVideoDecoderCallback(OH_AVCodec *codec, struct OH_AVCodecCallback cb, void *userData)
78         : codec_(codec), callback_(cb), userData_(userData)
79     {
80     }
81     virtual ~NativeVideoDecoderCallback() = default;
82 
OnError(AVCodecErrorType errorType,int32_t errorCode)83     void OnError(AVCodecErrorType errorType, int32_t errorCode) override
84     {
85         std::shared_lock<std::shared_mutex> lock(mutex_);
86         (void)errorType;
87 
88         CHECK_AND_RETURN_LOG(codec_ != nullptr, "Codec is nullptr");
89         CHECK_AND_RETURN_LOG(codec_->magic_ == AVMagic::AVCODEC_MAGIC_VIDEO_DECODER, "Codec magic error!");
90         CHECK_AND_RETURN_LOG(asyncCallback_.onError != nullptr || callback_.onError != nullptr, "Callback is nullptr");
91         int32_t extErr = AVCSErrorToOHAVErrCode(static_cast<AVCodecServiceErrCode>(errorCode));
92         if (asyncCallback_.onError != nullptr) {
93             asyncCallback_.onError(codec_, extErr, userData_);
94         } else if (callback_.onError != nullptr) {
95             callback_.onError(codec_, extErr, userData_);
96         }
97     }
98 
OnOutputFormatChanged(const Format & format)99     void OnOutputFormatChanged(const Format &format) override
100     {
101         std::shared_lock<std::shared_mutex> lock(mutex_);
102 
103         CHECK_AND_RETURN_LOG(codec_ != nullptr, "Codec is nullptr");
104         CHECK_AND_RETURN_LOG(codec_->magic_ == AVMagic::AVCODEC_MAGIC_VIDEO_DECODER, "Codec magic error!");
105         CHECK_AND_RETURN_LOG(asyncCallback_.onStreamChanged != nullptr || callback_.onStreamChanged != nullptr,
106                              "Callback is nullptr");
107         OHOS::sptr<OH_AVFormat> object = new (std::nothrow) OH_AVFormat(format);
108         CHECK_AND_RETURN_LOG(object != nullptr, "OH_AVFormat create failed");
109         // The object lifecycle is controlled by the current function stack
110         if (asyncCallback_.onStreamChanged != nullptr) {
111             asyncCallback_.onStreamChanged(codec_, reinterpret_cast<OH_AVFormat *>(object.GetRefPtr()), userData_);
112         } else if (callback_.onStreamChanged != nullptr) {
113             callback_.onStreamChanged(codec_, reinterpret_cast<OH_AVFormat *>(object.GetRefPtr()), userData_);
114         }
115     }
116 
OnInputBufferAvailable(uint32_t index,std::shared_ptr<AVSharedMemory> buffer)117     void OnInputBufferAvailable(uint32_t index, std::shared_ptr<AVSharedMemory> buffer) override
118     {
119         std::shared_lock<std::shared_mutex> lock(mutex_);
120 
121         CHECK_AND_RETURN_LOG(codec_ != nullptr, "Codec is nullptr");
122         CHECK_AND_RETURN_LOG(codec_->magic_ == AVMagic::AVCODEC_MAGIC_VIDEO_DECODER, "Codec magic error!");
123         CHECK_AND_RETURN_LOG(asyncCallback_.onNeedInputData != nullptr, "Callback is nullptr");
124 
125         struct VideoDecoderObject *videoDecObj = reinterpret_cast<VideoDecoderObject *>(codec_);
126         CHECK_AND_RETURN_LOG(videoDecObj->videoDecoder_ != nullptr, "Video decoder is nullptr!");
127 
128         if (videoDecObj->isEOS_.load()) {
129             AVCODEC_LOGD("At eos state, no buffer available");
130             return;
131         }
132 
133         OH_AVMemory *data = GetTransData(codec_, index, buffer, false);
134         asyncCallback_.onNeedInputData(codec_, index, data, userData_);
135     }
136 
OnOutputBufferAvailable(uint32_t index,AVCodecBufferInfo info,AVCodecBufferFlag flag,std::shared_ptr<AVSharedMemory> buffer)137     void OnOutputBufferAvailable(uint32_t index, AVCodecBufferInfo info, AVCodecBufferFlag flag,
138                                  std::shared_ptr<AVSharedMemory> buffer) override
139     {
140         std::shared_lock<std::shared_mutex> lock(mutex_);
141 
142         CHECK_AND_RETURN_LOG(codec_ != nullptr, "Codec is nullptr");
143         CHECK_AND_RETURN_LOG(codec_->magic_ == AVMagic::AVCODEC_MAGIC_VIDEO_DECODER, "Codec magic error!");
144         CHECK_AND_RETURN_LOG(asyncCallback_.onNeedOutputData != nullptr, "Callback is nullptr");
145 
146         struct VideoDecoderObject *videoDecObj = reinterpret_cast<VideoDecoderObject *>(codec_);
147         CHECK_AND_RETURN_LOG(videoDecObj->videoDecoder_ != nullptr, "Video decoder is nullptr!");
148 
149         struct OH_AVCodecBufferAttr bufferAttr {
150             info.presentationTimeUs, info.size, info.offset, flag
151         };
152         OH_AVMemory *data = nullptr;
153         if (!videoDecObj->isOutputSurfaceMode_) {
154             data = GetTransData(codec_, index, buffer, true);
155         }
156 
157         if (!((flag == AVCODEC_BUFFER_FLAG_CODEC_DATA) || (flag == AVCODEC_BUFFER_FLAG_EOS))) {
158             AVCodecTrace::TraceEnd("OH::Frame", info.presentationTimeUs);
159         }
160         asyncCallback_.onNeedOutputData(codec_, index, data, &bufferAttr, userData_);
161     }
162 
OnInputBufferAvailable(uint32_t index,std::shared_ptr<AVBuffer> buffer)163     void OnInputBufferAvailable(uint32_t index, std::shared_ptr<AVBuffer> buffer) override
164     {
165         std::shared_lock<std::shared_mutex> lock(mutex_);
166 
167         CHECK_AND_RETURN_LOG(codec_ != nullptr, "Codec is nullptr");
168         CHECK_AND_RETURN_LOG(codec_->magic_ == AVMagic::AVCODEC_MAGIC_VIDEO_DECODER, "Codec magic error!");
169         CHECK_AND_RETURN_LOG(callback_.onNeedInputBuffer != nullptr, "Callback is nullptr");
170 
171         struct VideoDecoderObject *videoDecObj = reinterpret_cast<VideoDecoderObject *>(codec_);
172         CHECK_AND_RETURN_LOG(videoDecObj->videoDecoder_ != nullptr, "Video decoder is nullptr!");
173 
174         if (videoDecObj->isEOS_.load()) {
175             AVCODEC_LOGD("At eos state, no buffer available");
176             return;
177         }
178 
179         OH_AVBuffer *data = GetTransData(codec_, index, buffer, false);
180         callback_.onNeedInputBuffer(codec_, index, data, userData_);
181     }
182 
OnOutputBufferAvailable(uint32_t index,std::shared_ptr<AVBuffer> buffer)183     void OnOutputBufferAvailable(uint32_t index, std::shared_ptr<AVBuffer> buffer) override
184     {
185         std::shared_lock<std::shared_mutex> lock(mutex_);
186 
187         CHECK_AND_RETURN_LOG(codec_ != nullptr, "Codec is nullptr");
188         CHECK_AND_RETURN_LOG(codec_->magic_ == AVMagic::AVCODEC_MAGIC_VIDEO_DECODER, "Codec magic error!");
189         CHECK_AND_RETURN_LOG(callback_.onNewOutputBuffer != nullptr, "Callback is nullptr");
190 
191         struct VideoDecoderObject *videoDecObj = reinterpret_cast<VideoDecoderObject *>(codec_);
192         CHECK_AND_RETURN_LOG(videoDecObj->videoDecoder_ != nullptr, "Video decoder is nullptr!");
193 
194         OH_AVBuffer *data = nullptr;
195         data = GetTransData(codec_, index, buffer, true);
196 
197         if (!((buffer->flag_ == AVCODEC_BUFFER_FLAG_CODEC_DATA) || (buffer->flag_ == AVCODEC_BUFFER_FLAG_EOS))) {
198             AVCodecTrace::TraceEnd("OH::Frame", buffer->pts_);
199         }
200         callback_.onNewOutputBuffer(codec_, index, data, userData_);
201     }
202 
StopCallback()203     void StopCallback()
204     {
205         std::lock_guard<std::shared_mutex> lock(mutex_);
206         codec_ = nullptr;
207     }
208 
UpdateCallback(const struct OH_AVCodecAsyncCallback & cb,void * userData)209     void UpdateCallback(const struct OH_AVCodecAsyncCallback &cb, void *userData)
210     {
211         std::lock_guard<std::shared_mutex> lock(mutex_);
212         userData_ = userData;
213         asyncCallback_ = cb;
214     }
215 
UpdateCallback(const struct OH_AVCodecCallback & cb,void * userData)216     void UpdateCallback(const struct OH_AVCodecCallback &cb, void *userData)
217     {
218         std::lock_guard<std::shared_mutex> lock(mutex_);
219         userData_ = userData;
220         callback_ = cb;
221     }
222 
223 private:
GetTransData(struct OH_AVCodec * codec,uint32_t & index,std::shared_ptr<AVSharedMemory> & memory,bool isOutput)224     OH_AVMemory *GetTransData(struct OH_AVCodec *codec, uint32_t &index, std::shared_ptr<AVSharedMemory> &memory,
225                               bool isOutput)
226     {
227         struct VideoDecoderObject *videoDecObj = reinterpret_cast<VideoDecoderObject *>(codec);
228         auto &memoryMap = isOutput ? videoDecObj->outputMemoryMap_ : videoDecObj->inputMemoryMap_;
229         {
230             std::shared_lock<std::shared_mutex> lock(videoDecObj->objListMutex_);
231             auto iter = memoryMap.find(index);
232             if (iter != memoryMap.end() && iter->second->IsEqualMemory(memory)) {
233                 return reinterpret_cast<OH_AVMemory *>(iter->second.GetRefPtr());
234             }
235         }
236 
237         OHOS::sptr<OH_AVMemory> object = new (std::nothrow) OH_AVMemory(memory);
238         CHECK_AND_RETURN_RET_LOG(object != nullptr, nullptr, "AV memory create failed");
239 
240         std::lock_guard<std::shared_mutex> lock(videoDecObj->objListMutex_);
241         auto iterAndRet = memoryMap.emplace(index, object);
242         if (!iterAndRet.second) {
243             auto &temp = iterAndRet.first->second;
244             temp->magic_ = MFMagic::MFMAGIC_UNKNOWN;
245             temp->memory_ = nullptr;
246             videoDecObj->tempList_.push(std::move(temp));
247             iterAndRet.first->second = object;
248             if (videoDecObj->tempList_.size() > MAX_TEMPNUM) {
249                 videoDecObj->tempList_.pop();
250             }
251         }
252         return reinterpret_cast<OH_AVMemory *>(object.GetRefPtr());
253     }
254 
GetTransData(struct OH_AVCodec * codec,uint32_t index,std::shared_ptr<AVBuffer> & buffer,bool isOutput)255     OH_AVBuffer *GetTransData(struct OH_AVCodec *codec, uint32_t index, std::shared_ptr<AVBuffer> &buffer,
256                               bool isOutput)
257     {
258         struct VideoDecoderObject *videoDecObj = reinterpret_cast<VideoDecoderObject *>(codec);
259         auto &bufferMap = isOutput ? videoDecObj->outputBufferMap_ : videoDecObj->inputBufferMap_;
260         {
261             std::shared_lock<std::shared_mutex> lock(videoDecObj->objListMutex_);
262             auto iter = bufferMap.find(index);
263             if (iter != bufferMap.end() && iter->second->IsEqualBuffer(buffer)) {
264                 return reinterpret_cast<OH_AVBuffer *>(iter->second.GetRefPtr());
265             }
266         }
267 
268         OHOS::sptr<OH_AVBuffer> object = new (std::nothrow) OH_AVBuffer(buffer);
269         CHECK_AND_RETURN_RET_LOG(object != nullptr, nullptr, "failed to new OH_AVBuffer");
270 
271         std::lock_guard<std::shared_mutex> lock(videoDecObj->objListMutex_);
272         auto iterAndRet = bufferMap.emplace(index, object);
273         if (!iterAndRet.second) {
274             auto &temp = iterAndRet.first->second;
275             temp->magic_ = MFMagic::MFMAGIC_UNKNOWN;
276             temp->buffer_ = nullptr;
277             videoDecObj->tempList_.push(std::move(temp));
278             iterAndRet.first->second = object;
279             if (videoDecObj->tempList_.size() > MAX_TEMPNUM) {
280                 videoDecObj->tempList_.pop();
281             }
282         }
283         return reinterpret_cast<OH_AVBuffer *>(object.GetRefPtr());
284     }
285 
286     struct OH_AVCodec *codec_ = nullptr;
287     struct OH_AVCodecAsyncCallback asyncCallback_ = {nullptr, nullptr, nullptr, nullptr};
288     struct OH_AVCodecCallback callback_ = {nullptr, nullptr, nullptr, nullptr};
289     void *userData_ = nullptr;
290     std::shared_mutex mutex_;
291 };
292 
ClearBufferList()293 void VideoDecoderObject::ClearBufferList()
294 {
295     std::lock_guard<std::shared_mutex> lock(objListMutex_);
296     if (isSetBufferCallback_) {
297         BufferToTempFunc(inputBufferMap_);
298         BufferToTempFunc(outputBufferMap_);
299         inputBufferMap_.clear();
300         outputBufferMap_.clear();
301     } else if (isSetMemoryCallback_) {
302         MemoryToTempFunc(inputMemoryMap_);
303         MemoryToTempFunc(outputMemoryMap_);
304         inputMemoryMap_.clear();
305         outputMemoryMap_.clear();
306     }
307     while (tempList_.size() > MAX_TEMPNUM) {
308         tempList_.pop();
309     }
310 }
311 
StopCallback()312 void VideoDecoderObject::StopCallback()
313 {
314     if (callback_ == nullptr) {
315         return;
316     }
317     callback_->StopCallback();
318 }
319 
BufferToTempFunc(std::unordered_map<uint32_t,OHOS::sptr<OH_AVBuffer>> & tempMap)320 void VideoDecoderObject::BufferToTempFunc(std::unordered_map<uint32_t, OHOS::sptr<OH_AVBuffer>> &tempMap)
321 {
322     for (auto &val : tempMap) {
323         val.second->magic_ = MFMagic::MFMAGIC_UNKNOWN;
324         val.second->buffer_ = nullptr;
325         tempList_.push(std::move(val.second));
326     }
327 }
328 
MemoryToTempFunc(std::unordered_map<uint32_t,OHOS::sptr<OH_AVMemory>> & tempMap)329 void VideoDecoderObject::MemoryToTempFunc(std::unordered_map<uint32_t, OHOS::sptr<OH_AVMemory>> &tempMap)
330 {
331     for (auto &val : tempMap) {
332         val.second->magic_ = MFMagic::MFMAGIC_UNKNOWN;
333         val.second->memory_ = nullptr;
334         tempList_.push(std::move(val.second));
335     }
336 }
337 } // namespace
338 namespace OHOS {
339 namespace MediaAVCodec {
340 #ifdef __cplusplus
341 extern "C" {
342 #endif
OH_VideoDecoder_CreateByMime(const char * mime)343 struct OH_AVCodec *OH_VideoDecoder_CreateByMime(const char *mime)
344 {
345     CHECK_AND_RETURN_RET_LOG(mime != nullptr, nullptr, "Mime is nullptr!");
346 
347     std::shared_ptr<AVCodecVideoDecoder> videoDecoder = VideoDecoderFactory::CreateByMime(mime);
348     CHECK_AND_RETURN_RET_LOG(videoDecoder != nullptr, nullptr, "Video decoder create by mime failed!");
349 
350     struct VideoDecoderObject *object = new (std::nothrow) VideoDecoderObject(videoDecoder);
351     CHECK_AND_RETURN_RET_LOG(object != nullptr, nullptr, "Video decoder create by mime failed!");
352 
353     return object;
354 }
355 
OH_VideoDecoder_CreateByName(const char * name)356 struct OH_AVCodec *OH_VideoDecoder_CreateByName(const char *name)
357 {
358     CHECK_AND_RETURN_RET_LOG(name != nullptr, nullptr, "Name is nullptr!");
359 
360     std::shared_ptr<AVCodecVideoDecoder> videoDecoder = VideoDecoderFactory::CreateByName(name);
361     CHECK_AND_RETURN_RET_LOG(videoDecoder != nullptr, nullptr, "Video decoder create by name failed!");
362 
363     struct VideoDecoderObject *object = new (std::nothrow) VideoDecoderObject(videoDecoder);
364     CHECK_AND_RETURN_RET_LOG(object != nullptr, nullptr, "Video decoder create by name failed!");
365 
366     return object;
367 }
368 
OH_VideoDecoder_Destroy(struct OH_AVCodec * codec)369 OH_AVErrCode OH_VideoDecoder_Destroy(struct OH_AVCodec *codec)
370 {
371     CHECK_AND_RETURN_RET_LOG(codec != nullptr, AV_ERR_INVALID_VAL, "Codec is nullptr!");
372     CHECK_AND_RETURN_RET_LOG(codec->magic_ == AVMagic::AVCODEC_MAGIC_VIDEO_DECODER, AV_ERR_INVALID_VAL,
373                              "Codec magic error!");
374 
375     struct VideoDecoderObject *videoDecObj = reinterpret_cast<VideoDecoderObject *>(codec);
376 
377     if (videoDecObj != nullptr && videoDecObj->videoDecoder_ != nullptr) {
378         int32_t ret = videoDecObj->videoDecoder_->Release();
379         videoDecObj->StopCallback();
380         videoDecObj->ClearBufferList();
381         if (ret != AVCS_ERR_OK) {
382             AVCODEC_LOGE("Video decoder destroy failed!");
383             delete codec;
384             return AVCSErrorToOHAVErrCode(static_cast<AVCodecServiceErrCode>(ret));
385         }
386     } else {
387         AVCODEC_LOGD("Video decoder is nullptr!");
388     }
389 
390     delete codec;
391     return AV_ERR_OK;
392 }
393 
OH_VideoDecoder_Configure(struct OH_AVCodec * codec,struct OH_AVFormat * format)394 OH_AVErrCode OH_VideoDecoder_Configure(struct OH_AVCodec *codec, struct OH_AVFormat *format)
395 {
396     CHECK_AND_RETURN_RET_LOG(codec != nullptr, AV_ERR_INVALID_VAL, "Codec is nullptr!");
397     CHECK_AND_RETURN_RET_LOG(codec->magic_ == AVMagic::AVCODEC_MAGIC_VIDEO_DECODER, AV_ERR_INVALID_VAL,
398                              "Codec magic error!");
399     CHECK_AND_RETURN_RET_LOG(format != nullptr, AV_ERR_INVALID_VAL, "Format is nullptr!");
400     CHECK_AND_RETURN_RET_LOG(format->magic_ == MFMagic::MFMAGIC_FORMAT, AV_ERR_INVALID_VAL, "Format magic error!");
401 
402     struct VideoDecoderObject *videoDecObj = reinterpret_cast<VideoDecoderObject *>(codec);
403     CHECK_AND_RETURN_RET_LOG(videoDecObj->videoDecoder_ != nullptr, AV_ERR_INVALID_VAL, "Video decoder is nullptr!");
404 
405     int32_t ret = videoDecObj->videoDecoder_->Configure(format->format_);
406     CHECK_AND_RETURN_RET_LOG(ret == AVCS_ERR_OK, AVCSErrorToOHAVErrCode(static_cast<AVCodecServiceErrCode>(ret)),
407                              "Video decoder configure failed!");
408 
409     return AV_ERR_OK;
410 }
411 
OH_VideoDecoder_Prepare(struct OH_AVCodec * codec)412 OH_AVErrCode OH_VideoDecoder_Prepare(struct OH_AVCodec *codec)
413 {
414     CHECK_AND_RETURN_RET_LOG(codec != nullptr, AV_ERR_INVALID_VAL, "Codec is nullptr!");
415     CHECK_AND_RETURN_RET_LOG(codec->magic_ == AVMagic::AVCODEC_MAGIC_VIDEO_DECODER, AV_ERR_INVALID_VAL,
416                              "Codec magic error!");
417 
418     struct VideoDecoderObject *videoDecObj = reinterpret_cast<VideoDecoderObject *>(codec);
419     CHECK_AND_RETURN_RET_LOG(videoDecObj->videoDecoder_ != nullptr, AV_ERR_INVALID_VAL, "Video decoder is nullptr!");
420 
421     int32_t ret = videoDecObj->videoDecoder_->Prepare();
422     CHECK_AND_RETURN_RET_LOG(ret == AVCS_ERR_OK, AVCSErrorToOHAVErrCode(static_cast<AVCodecServiceErrCode>(ret)),
423                              "Video decoder prepare failed!");
424 
425     return AV_ERR_OK;
426 }
427 
OH_VideoDecoder_Start(struct OH_AVCodec * codec)428 OH_AVErrCode OH_VideoDecoder_Start(struct OH_AVCodec *codec)
429 {
430     CHECK_AND_RETURN_RET_LOG(codec != nullptr, AV_ERR_INVALID_VAL, "Codec is nullptr!");
431     CHECK_AND_RETURN_RET_LOG(codec->magic_ == AVMagic::AVCODEC_MAGIC_VIDEO_DECODER, AV_ERR_INVALID_VAL,
432                              "Codec magic error!");
433 
434     struct VideoDecoderObject *videoDecObj = reinterpret_cast<VideoDecoderObject *>(codec);
435     CHECK_AND_RETURN_RET_LOG(videoDecObj->videoDecoder_ != nullptr, AV_ERR_INVALID_VAL, "Video decoder is nullptr!");
436 
437     videoDecObj->isEOS_.store(false);
438     int32_t ret = videoDecObj->videoDecoder_->Start();
439     CHECK_AND_RETURN_RET_LOG(ret == AVCS_ERR_OK, AVCSErrorToOHAVErrCode(static_cast<AVCodecServiceErrCode>(ret)),
440                              "Video decoder start failed!");
441 
442     return AV_ERR_OK;
443 }
444 
OH_VideoDecoder_Stop(struct OH_AVCodec * codec)445 OH_AVErrCode OH_VideoDecoder_Stop(struct OH_AVCodec *codec)
446 {
447     CHECK_AND_RETURN_RET_LOG(codec != nullptr, AV_ERR_INVALID_VAL, "Codec is nullptr!");
448     CHECK_AND_RETURN_RET_LOG(codec->magic_ == AVMagic::AVCODEC_MAGIC_VIDEO_DECODER, AV_ERR_INVALID_VAL,
449                              "Codec magic error!");
450 
451     struct VideoDecoderObject *videoDecObj = reinterpret_cast<VideoDecoderObject *>(codec);
452     CHECK_AND_RETURN_RET_LOG(videoDecObj->videoDecoder_ != nullptr, AV_ERR_INVALID_VAL, "Video decoder is nullptr!");
453 
454     int32_t ret = videoDecObj->videoDecoder_->Stop();
455     if (ret != AVCS_ERR_OK) {
456         AVCODEC_LOGE("Video decoder stop failed");
457         return AVCSErrorToOHAVErrCode(static_cast<AVCodecServiceErrCode>(ret));
458     }
459     videoDecObj->ClearBufferList();
460     return AV_ERR_OK;
461 }
462 
OH_VideoDecoder_Flush(struct OH_AVCodec * codec)463 OH_AVErrCode OH_VideoDecoder_Flush(struct OH_AVCodec *codec)
464 {
465     CHECK_AND_RETURN_RET_LOG(codec != nullptr, AV_ERR_INVALID_VAL, "Codec is nullptr!");
466     CHECK_AND_RETURN_RET_LOG(codec->magic_ == AVMagic::AVCODEC_MAGIC_VIDEO_DECODER, AV_ERR_INVALID_VAL,
467                              "Codec magic error!");
468 
469     struct VideoDecoderObject *videoDecObj = reinterpret_cast<VideoDecoderObject *>(codec);
470     CHECK_AND_RETURN_RET_LOG(videoDecObj->videoDecoder_ != nullptr, AV_ERR_INVALID_VAL, "Video decoder is nullptr!");
471 
472     int32_t ret = videoDecObj->videoDecoder_->Flush();
473     CHECK_AND_RETURN_RET_LOG(ret == AVCS_ERR_OK, AVCSErrorToOHAVErrCode(static_cast<AVCodecServiceErrCode>(ret)),
474                              "Video decoder flush failed!");
475     videoDecObj->ClearBufferList();
476     return AV_ERR_OK;
477 }
478 
OH_VideoDecoder_Reset(struct OH_AVCodec * codec)479 OH_AVErrCode OH_VideoDecoder_Reset(struct OH_AVCodec *codec)
480 {
481     CHECK_AND_RETURN_RET_LOG(codec != nullptr, AV_ERR_INVALID_VAL, "Codec is nullptr!");
482     CHECK_AND_RETURN_RET_LOG(codec->magic_ == AVMagic::AVCODEC_MAGIC_VIDEO_DECODER, AV_ERR_INVALID_VAL,
483                              "Codec magic error!");
484 
485     struct VideoDecoderObject *videoDecObj = reinterpret_cast<VideoDecoderObject *>(codec);
486     CHECK_AND_RETURN_RET_LOG(videoDecObj->videoDecoder_ != nullptr, AV_ERR_INVALID_VAL, "Video decoder is nullptr!");
487 
488     int32_t ret = videoDecObj->videoDecoder_->Reset();
489     if (ret != AVCS_ERR_OK) {
490         AVCODEC_LOGE("Video decoder reset failed!");
491         return AVCSErrorToOHAVErrCode(static_cast<AVCodecServiceErrCode>(ret));
492     }
493     videoDecObj->ClearBufferList();
494     return AV_ERR_OK;
495 }
496 
OH_VideoDecoder_SetSurface(OH_AVCodec * codec,OHNativeWindow * window)497 OH_AVErrCode OH_VideoDecoder_SetSurface(OH_AVCodec *codec, OHNativeWindow *window)
498 {
499     CHECK_AND_RETURN_RET_LOG(codec != nullptr, AV_ERR_INVALID_VAL, "Codec is nullptr!");
500     CHECK_AND_RETURN_RET_LOG(codec->magic_ == AVMagic::AVCODEC_MAGIC_VIDEO_DECODER, AV_ERR_INVALID_VAL,
501                              "Codec magic error!");
502     CHECK_AND_RETURN_RET_LOG(window != nullptr, AV_ERR_INVALID_VAL, "Window is nullptr!");
503     CHECK_AND_RETURN_RET_LOG(window->surface != nullptr, AV_ERR_INVALID_VAL, "Input window surface is nullptr!");
504 
505     GSError gsRet = window->surface->Disconnect();
506     EXPECT_AND_LOGI(gsRet != GSERROR_OK, "Disconnect failed!, %{public}s", GSErrorStr(gsRet).c_str());
507 
508     struct VideoDecoderObject *videoDecObj = reinterpret_cast<VideoDecoderObject *>(codec);
509     CHECK_AND_RETURN_RET_LOG(videoDecObj->videoDecoder_ != nullptr, AV_ERR_INVALID_VAL, "Video decoder is nullptr!");
510 
511     int32_t ret = videoDecObj->videoDecoder_->SetOutputSurface(window->surface);
512     CHECK_AND_RETURN_RET_LOG(ret == AVCS_ERR_OK, AVCSErrorToOHAVErrCode(static_cast<AVCodecServiceErrCode>(ret)),
513                              "Video decoder set output surface failed!");
514     videoDecObj->isOutputSurfaceMode_ = true;
515 
516     return AV_ERR_OK;
517 }
518 
OH_VideoDecoder_PushInputData(struct OH_AVCodec * codec,uint32_t index,OH_AVCodecBufferAttr attr)519 OH_AVErrCode OH_VideoDecoder_PushInputData(struct OH_AVCodec *codec, uint32_t index, OH_AVCodecBufferAttr attr)
520 {
521     CHECK_AND_RETURN_RET_LOG(codec != nullptr, AV_ERR_INVALID_VAL, "Codec is nullptr!");
522     CHECK_AND_RETURN_RET_LOG(codec->magic_ == AVMagic::AVCODEC_MAGIC_VIDEO_DECODER, AV_ERR_INVALID_VAL,
523                              "Codec magic error!");
524     CHECK_AND_RETURN_RET_LOG(attr.size >= 0, AV_ERR_INVALID_VAL, "Invalid buffer size!");
525 
526     struct VideoDecoderObject *videoDecObj = reinterpret_cast<VideoDecoderObject *>(codec);
527     CHECK_AND_RETURN_RET_LOG(videoDecObj->videoDecoder_ != nullptr, AV_ERR_INVALID_VAL, "Video decoder is nullptr!");
528     CHECK_AND_RETURN_RET_LOG(videoDecObj->isSetMemoryCallback_, AV_ERR_INVALID_STATE,
529                              "The callback of OH_AVMemory is nullptr!");
530 
531     if (!((attr.flags == AVCODEC_BUFFER_FLAG_CODEC_DATA) || (attr.flags == AVCODEC_BUFFER_FLAG_EOS))) {
532         AVCodecTrace::TraceBegin("OH::Frame", attr.pts);
533     }
534 
535     struct AVCodecBufferInfo bufferInfo;
536     bufferInfo.presentationTimeUs = attr.pts;
537     bufferInfo.size = attr.size;
538     bufferInfo.offset = attr.offset;
539     enum AVCodecBufferFlag bufferFlag = static_cast<enum AVCodecBufferFlag>(attr.flags);
540 
541     int32_t ret = videoDecObj->videoDecoder_->QueueInputBuffer(index, bufferInfo, bufferFlag);
542     CHECK_AND_RETURN_RET_LOG(ret == AVCS_ERR_OK, AVCSErrorToOHAVErrCode(static_cast<AVCodecServiceErrCode>(ret)),
543                              "Video decoder push input data failed!");
544     if (bufferFlag == AVCODEC_BUFFER_FLAG_EOS) {
545         videoDecObj->isEOS_.store(true);
546     }
547 
548     return AV_ERR_OK;
549 }
550 
OH_VideoDecoder_PushInputBuffer(struct OH_AVCodec * codec,uint32_t index)551 OH_AVErrCode OH_VideoDecoder_PushInputBuffer(struct OH_AVCodec *codec, uint32_t index)
552 {
553     CHECK_AND_RETURN_RET_LOG(codec != nullptr, AV_ERR_INVALID_VAL, "Input codec is nullptr!");
554     CHECK_AND_RETURN_RET_LOG(codec->magic_ == AVMagic::AVCODEC_MAGIC_VIDEO_DECODER, AV_ERR_INVALID_VAL, "magic error!");
555 
556     struct VideoDecoderObject *videoDecObj = reinterpret_cast<VideoDecoderObject *>(codec);
557     CHECK_AND_RETURN_RET_LOG(videoDecObj->videoDecoder_ != nullptr, AV_ERR_INVALID_VAL, "video decoder is nullptr!");
558     CHECK_AND_RETURN_RET_LOG(videoDecObj->isSetBufferCallback_, AV_ERR_INVALID_STATE,
559                              "The callback of OH_AVBuffer is nullptr!");
560 
561     {
562         std::shared_lock<std::shared_mutex> lock(videoDecObj->objListMutex_);
563         auto bufferIter = videoDecObj->inputBufferMap_.find(index);
564         CHECK_AND_RETURN_RET_LOG(bufferIter != videoDecObj->inputBufferMap_.end(), AV_ERR_INVALID_VAL,
565                                  "Invalid buffer index");
566         auto buffer = bufferIter->second->buffer_;
567         if (buffer->flag_ == AVCODEC_BUFFER_FLAG_EOS) {
568             videoDecObj->isEOS_.store(true);
569             AVCODEC_LOGD("Set eos status to true");
570         }
571         if (!((buffer->flag_ == AVCODEC_BUFFER_FLAG_CODEC_DATA) || (buffer->flag_ == AVCODEC_BUFFER_FLAG_EOS))) {
572             AVCodecTrace::TraceBegin("OH::Frame", buffer->pts_);
573         }
574     }
575 
576     int32_t ret = videoDecObj->videoDecoder_->QueueInputBuffer(index);
577     CHECK_AND_RETURN_RET_LOG(ret == AVCS_ERR_OK, AVCSErrorToOHAVErrCode(static_cast<AVCodecServiceErrCode>(ret)),
578                              "videoDecoder QueueInputBuffer failed!");
579     return AV_ERR_OK;
580 }
581 
OH_VideoDecoder_GetOutputDescription(struct OH_AVCodec * codec)582 OH_AVFormat *OH_VideoDecoder_GetOutputDescription(struct OH_AVCodec *codec)
583 {
584     CHECK_AND_RETURN_RET_LOG(codec != nullptr, nullptr, "Codec is nullptr!");
585     CHECK_AND_RETURN_RET_LOG(codec->magic_ == AVMagic::AVCODEC_MAGIC_VIDEO_DECODER, nullptr, "Codec magic error!");
586 
587     struct VideoDecoderObject *videoDecObj = reinterpret_cast<VideoDecoderObject *>(codec);
588     CHECK_AND_RETURN_RET_LOG(videoDecObj->videoDecoder_ != nullptr, nullptr, "Video decoder is nullptr!");
589 
590     Format format;
591     int32_t ret = videoDecObj->videoDecoder_->GetOutputFormat(format);
592     CHECK_AND_RETURN_RET_LOG(ret == AVCS_ERR_OK, nullptr, "Video decoder get output description failed!");
593 
594     OH_AVFormat *avFormat = OH_AVFormat_Create();
595     CHECK_AND_RETURN_RET_LOG(avFormat != nullptr, nullptr, "Video decoder get output description failed!");
596     avFormat->format_ = format;
597 
598     return avFormat;
599 }
600 
OH_VideoDecoder_RenderOutputData(struct OH_AVCodec * codec,uint32_t index)601 OH_AVErrCode OH_VideoDecoder_RenderOutputData(struct OH_AVCodec *codec, uint32_t index)
602 {
603     CHECK_AND_RETURN_RET_LOG(codec != nullptr, AV_ERR_INVALID_VAL, "Codec is nullptr!");
604     CHECK_AND_RETURN_RET_LOG(codec->magic_ == AVMagic::AVCODEC_MAGIC_VIDEO_DECODER, AV_ERR_INVALID_VAL,
605                              "Codec magic error!");
606 
607     struct VideoDecoderObject *videoDecObj = reinterpret_cast<VideoDecoderObject *>(codec);
608     CHECK_AND_RETURN_RET_LOG(videoDecObj->videoDecoder_ != nullptr, AV_ERR_INVALID_VAL, "Video decoder is nullptr!");
609     CHECK_AND_RETURN_RET_LOG(videoDecObj->isSetMemoryCallback_, AV_ERR_INVALID_STATE,
610                              "The callback of OH_AVMemory is nullptr!");
611 
612     int32_t ret = videoDecObj->videoDecoder_->ReleaseOutputBuffer(index, true);
613     CHECK_AND_RETURN_RET_LOG(ret == AVCS_ERR_OK, AVCSErrorToOHAVErrCode(static_cast<AVCodecServiceErrCode>(ret)),
614                              "Video decoder render output data failed!");
615 
616     return AV_ERR_OK;
617 }
618 
OH_VideoDecoder_FreeOutputData(struct OH_AVCodec * codec,uint32_t index)619 OH_AVErrCode OH_VideoDecoder_FreeOutputData(struct OH_AVCodec *codec, uint32_t index)
620 {
621     AVCODEC_LOGD("In OH_VideoDecoder_FreeOutputData");
622     CHECK_AND_RETURN_RET_LOG(codec != nullptr, AV_ERR_INVALID_VAL, "Codec is nullptr!");
623     CHECK_AND_RETURN_RET_LOG(codec->magic_ == AVMagic::AVCODEC_MAGIC_VIDEO_DECODER, AV_ERR_INVALID_VAL,
624                              "Codec magic error!");
625 
626     struct VideoDecoderObject *videoDecObj = reinterpret_cast<VideoDecoderObject *>(codec);
627     CHECK_AND_RETURN_RET_LOG(videoDecObj->videoDecoder_ != nullptr, AV_ERR_INVALID_VAL, "Video decoder is nullptr!");
628     CHECK_AND_RETURN_RET_LOG(videoDecObj->isSetMemoryCallback_, AV_ERR_INVALID_STATE,
629                              "The callback of OH_AVMemory is nullptr!");
630 
631     int32_t ret = videoDecObj->videoDecoder_->ReleaseOutputBuffer(index, false);
632     CHECK_AND_RETURN_RET_LOG(ret == AVCS_ERR_OK, AVCSErrorToOHAVErrCode(static_cast<AVCodecServiceErrCode>(ret)),
633                              "Video decoder free output data failed!");
634 
635     return AV_ERR_OK;
636 }
637 
OH_VideoDecoder_RenderOutputBuffer(struct OH_AVCodec * codec,uint32_t index)638 OH_AVErrCode OH_VideoDecoder_RenderOutputBuffer(struct OH_AVCodec *codec, uint32_t index)
639 {
640     CHECK_AND_RETURN_RET_LOG(codec != nullptr, AV_ERR_INVALID_VAL, "Codec is nullptr!");
641     CHECK_AND_RETURN_RET_LOG(codec->magic_ == AVMagic::AVCODEC_MAGIC_VIDEO_DECODER, AV_ERR_INVALID_VAL,
642                              "Codec magic error!");
643     struct VideoDecoderObject *videoDecObj = reinterpret_cast<VideoDecoderObject *>(codec);
644     CHECK_AND_RETURN_RET_LOG(videoDecObj->videoDecoder_ != nullptr, AV_ERR_INVALID_VAL, "Video decoder is nullptr!");
645     CHECK_AND_RETURN_RET_LOG(videoDecObj->isSetBufferCallback_, AV_ERR_INVALID_STATE,
646                              "The callback of OH_AVBuffer is nullptr!");
647 
648     int32_t ret = videoDecObj->videoDecoder_->ReleaseOutputBuffer(index, true);
649     CHECK_AND_RETURN_RET_LOG(ret == AVCS_ERR_OK, AVCSErrorToOHAVErrCode(static_cast<AVCodecServiceErrCode>(ret)),
650                              "Video decoder render output data failed!");
651 
652     return AV_ERR_OK;
653 }
654 
OH_VideoDecoder_RenderOutputBufferAtTime(OH_AVCodec * codec,uint32_t index,int64_t renderTimestampNs)655 OH_AVErrCode OH_VideoDecoder_RenderOutputBufferAtTime(OH_AVCodec *codec, uint32_t index, int64_t renderTimestampNs)
656 {
657     CHECK_AND_RETURN_RET_LOG(codec != nullptr, AV_ERR_INVALID_VAL, "Codec is nullptr!");
658     CHECK_AND_RETURN_RET_LOG(codec->magic_ == AVMagic::AVCODEC_MAGIC_VIDEO_DECODER, AV_ERR_INVALID_VAL,
659                              "Codec magic error!");
660     struct VideoDecoderObject *videoDecObj = reinterpret_cast<VideoDecoderObject *>(codec);
661     CHECK_AND_RETURN_RET_LOG(videoDecObj->videoDecoder_ != nullptr, AV_ERR_INVALID_VAL, "Video decoder is nullptr!");
662     CHECK_AND_RETURN_RET_LOG(videoDecObj->isSetBufferCallback_, AV_ERR_INVALID_STATE,
663                              "The callback of OH_AVBuffer is nullptr!");
664 
665     int32_t ret = videoDecObj->videoDecoder_->RenderOutputBufferAtTime(index, renderTimestampNs);
666     CHECK_AND_RETURN_RET_LOG(ret == AVCS_ERR_OK, AVCSErrorToOHAVErrCode(static_cast<AVCodecServiceErrCode>(ret)),
667                              "Video decoder render output buffer at time failed!");
668     return AV_ERR_OK;
669 }
670 
OH_VideoDecoder_FreeOutputBuffer(struct OH_AVCodec * codec,uint32_t index)671 OH_AVErrCode OH_VideoDecoder_FreeOutputBuffer(struct OH_AVCodec *codec, uint32_t index)
672 {
673     AVCODEC_LOGD("In OH_VideoDecoder_FreeOutputData");
674     CHECK_AND_RETURN_RET_LOG(codec != nullptr, AV_ERR_INVALID_VAL, "Codec is nullptr!");
675     CHECK_AND_RETURN_RET_LOG(codec->magic_ == AVMagic::AVCODEC_MAGIC_VIDEO_DECODER, AV_ERR_INVALID_VAL,
676                              "Codec magic error!");
677 
678     struct VideoDecoderObject *videoDecObj = reinterpret_cast<VideoDecoderObject *>(codec);
679     CHECK_AND_RETURN_RET_LOG(videoDecObj->videoDecoder_ != nullptr, AV_ERR_INVALID_VAL, "Video decoder is nullptr!");
680     CHECK_AND_RETURN_RET_LOG(videoDecObj->isSetBufferCallback_, AV_ERR_INVALID_STATE,
681                              "The callback of OH_AVBuffer is nullptr!");
682 
683     int32_t ret = videoDecObj->videoDecoder_->ReleaseOutputBuffer(index, false);
684     CHECK_AND_RETURN_RET_LOG(ret == AVCS_ERR_OK, AVCSErrorToOHAVErrCode(static_cast<AVCodecServiceErrCode>(ret)),
685                              "Video decoder free output data failed!");
686 
687     return AV_ERR_OK;
688 }
689 
OH_VideoDecoder_SetParameter(struct OH_AVCodec * codec,struct OH_AVFormat * format)690 OH_AVErrCode OH_VideoDecoder_SetParameter(struct OH_AVCodec *codec, struct OH_AVFormat *format)
691 {
692     CHECK_AND_RETURN_RET_LOG(codec != nullptr, AV_ERR_INVALID_VAL, "Codec is nullptr!");
693     CHECK_AND_RETURN_RET_LOG(codec->magic_ == AVMagic::AVCODEC_MAGIC_VIDEO_DECODER, AV_ERR_INVALID_VAL,
694                              "Codec magic error!");
695     CHECK_AND_RETURN_RET_LOG(format != nullptr, AV_ERR_INVALID_VAL, "Format is nullptr!");
696     CHECK_AND_RETURN_RET_LOG(format->magic_ == MFMagic::MFMAGIC_FORMAT, AV_ERR_INVALID_VAL, "Format magic error!");
697 
698     struct VideoDecoderObject *videoDecObj = reinterpret_cast<VideoDecoderObject *>(codec);
699     CHECK_AND_RETURN_RET_LOG(videoDecObj->videoDecoder_ != nullptr, AV_ERR_INVALID_VAL, "Video decoder is nullptr!");
700 
701     int32_t ret = videoDecObj->videoDecoder_->SetParameter(format->format_);
702     CHECK_AND_RETURN_RET_LOG(ret == AVCS_ERR_OK, AVCSErrorToOHAVErrCode(static_cast<AVCodecServiceErrCode>(ret)),
703                              "Video decoder set parameter failed!");
704 
705     return AV_ERR_OK;
706 }
707 
OH_VideoDecoder_SetCallback(struct OH_AVCodec * codec,struct OH_AVCodecAsyncCallback callback,void * userData)708 OH_AVErrCode OH_VideoDecoder_SetCallback(struct OH_AVCodec *codec, struct OH_AVCodecAsyncCallback callback,
709                                          void *userData)
710 {
711     CHECK_AND_RETURN_RET_LOG(codec != nullptr, AV_ERR_INVALID_VAL, "Codec is nullptr!");
712     CHECK_AND_RETURN_RET_LOG(codec->magic_ == AVMagic::AVCODEC_MAGIC_VIDEO_DECODER, AV_ERR_INVALID_VAL,
713                              "Codec magic error!");
714 
715     struct VideoDecoderObject *videoDecObj = reinterpret_cast<VideoDecoderObject *>(codec);
716     CHECK_AND_RETURN_RET_LOG(videoDecObj->videoDecoder_ != nullptr, AV_ERR_INVALID_VAL, "Video decoder is nullptr!");
717 
718     if (videoDecObj->callback_ == nullptr) {
719         videoDecObj->callback_ = std::make_shared<NativeVideoDecoderCallback>(codec, callback, userData);
720     } else {
721         std::static_pointer_cast<NativeVideoDecoderCallback>(videoDecObj->callback_)
722             ->UpdateCallback(callback, userData);
723     }
724     int32_t ret =
725         videoDecObj->videoDecoder_->SetCallback(std::static_pointer_cast<AVCodecCallback>(videoDecObj->callback_));
726     CHECK_AND_RETURN_RET_LOG(ret == AVCS_ERR_OK, AVCSErrorToOHAVErrCode(static_cast<AVCodecServiceErrCode>(ret)),
727                              "Video decoder set callback failed!");
728     videoDecObj->isSetMemoryCallback_ = true;
729     return AV_ERR_OK;
730 }
731 
OH_VideoDecoder_RegisterCallback(struct OH_AVCodec * codec,struct OH_AVCodecCallback callback,void * userData)732 OH_AVErrCode OH_VideoDecoder_RegisterCallback(struct OH_AVCodec *codec, struct OH_AVCodecCallback callback,
733                                               void *userData)
734 {
735     CHECK_AND_RETURN_RET_LOG(codec != nullptr, AV_ERR_INVALID_VAL, "Codec is nullptr!");
736     CHECK_AND_RETURN_RET_LOG(codec->magic_ == AVMagic::AVCODEC_MAGIC_VIDEO_DECODER, AV_ERR_INVALID_VAL,
737                              "Codec magic error!");
738     CHECK_AND_RETURN_RET_LOG(callback.onNeedInputBuffer != nullptr, AV_ERR_INVALID_VAL,
739                              "Callback onNeedInputBuffer is nullptr");
740     CHECK_AND_RETURN_RET_LOG(callback.onNewOutputBuffer != nullptr, AV_ERR_INVALID_VAL,
741                              "Callback onNewOutputBuffer is nullptr");
742 
743     struct VideoDecoderObject *videoDecObj = reinterpret_cast<VideoDecoderObject *>(codec);
744     CHECK_AND_RETURN_RET_LOG(videoDecObj->videoDecoder_ != nullptr, AV_ERR_INVALID_VAL, "Video decoder is nullptr!");
745 
746     if (videoDecObj->callback_ == nullptr) {
747         videoDecObj->callback_ = std::make_shared<NativeVideoDecoderCallback>(codec, callback, userData);
748     } else {
749         std::static_pointer_cast<NativeVideoDecoderCallback>(videoDecObj->callback_)
750             ->UpdateCallback(callback, userData);
751     }
752     int32_t ret =
753         videoDecObj->videoDecoder_->SetCallback(std::static_pointer_cast<MediaCodecCallback>(videoDecObj->callback_));
754     CHECK_AND_RETURN_RET_LOG(ret == AVCS_ERR_OK, AVCSErrorToOHAVErrCode(static_cast<AVCodecServiceErrCode>(ret)),
755                              "Video decoder register callback failed!");
756     videoDecObj->isSetBufferCallback_ = true;
757     return AV_ERR_OK;
758 }
759 
OH_VideoDecoder_IsValid(OH_AVCodec * codec,bool * isValid)760 OH_AVErrCode OH_VideoDecoder_IsValid(OH_AVCodec *codec, bool *isValid)
761 {
762     CHECK_AND_RETURN_RET_LOG(codec != nullptr, AV_ERR_INVALID_VAL, "Codec is nullptr!");
763     CHECK_AND_RETURN_RET_LOG(codec->magic_ == AVMagic::AVCODEC_MAGIC_VIDEO_DECODER, AV_ERR_INVALID_VAL,
764                              "Codec magic error!");
765     CHECK_AND_RETURN_RET_LOG(isValid != nullptr, AV_ERR_INVALID_VAL, "Input isValid is nullptr!");
766     *isValid = true;
767     return AV_ERR_OK;
768 }
769 
770 #ifdef SUPPORT_DRM
OH_VideoDecoder_SetDecryptionConfig(OH_AVCodec * codec,MediaKeySession * mediaKeySession,bool secureVideoPath)771 OH_AVErrCode OH_VideoDecoder_SetDecryptionConfig(OH_AVCodec *codec, MediaKeySession *mediaKeySession,
772                                                  bool secureVideoPath)
773 {
774     AVCODEC_LOGI("OH_VideoDecoder_SetDecryptionConfig");
775     CHECK_AND_RETURN_RET_LOG(codec != nullptr, AV_ERR_INVALID_VAL, "Codec is nullptr!");
776     CHECK_AND_RETURN_RET_LOG(codec->magic_ == AVMagic::AVCODEC_MAGIC_VIDEO_DECODER, AV_ERR_INVALID_VAL,
777                              "Codec magic error!");
778 
779     struct VideoDecoderObject *videoDecObj = reinterpret_cast<VideoDecoderObject *>(codec);
780     CHECK_AND_RETURN_RET_LOG(videoDecObj->videoDecoder_ != nullptr, AV_ERR_INVALID_VAL, "Video decoder is nullptr!");
781 
782     struct MediaKeySessionObject *sessionObject = reinterpret_cast<MediaKeySessionObject *>(mediaKeySession);
783     CHECK_AND_RETURN_RET_LOG(sessionObject != nullptr, AV_ERR_INVALID_VAL, "sessionObject is nullptr!");
784     AVCODEC_LOGD("DRM sessionObject impl :0x%{public}06" PRIXPTR " Instances create", FAKE_POINTER(sessionObject));
785 
786     CHECK_AND_RETURN_RET_LOG(sessionObject->sessionImpl_ != nullptr, AV_ERR_INVALID_VAL,
787                              "sessionObject->impl is nullptr!");
788     AVCODEC_LOGD("DRM impl :0x%{public}06" PRIXPTR " Instances create",
789                  FAKE_POINTER(sessionObject->sessionImpl_.GetRefPtr()));
790 
791     int32_t ret = videoDecObj->videoDecoder_->SetDecryptConfig(
792         sessionObject->sessionImpl_->GetMediaKeySessionServiceProxy(), secureVideoPath);
793     CHECK_AND_RETURN_RET_LOG(ret == AVCS_ERR_OK, AVCSErrorToOHAVErrCode(static_cast<AVCodecServiceErrCode>(ret)),
794                              "Video decoder SetDecryptConfig failed!");
795 
796     return AV_ERR_OK;
797 }
798 #else
OH_VideoDecoder_SetDecryptionConfig(OH_AVCodec * codec,MediaKeySession * mediaKeySession,bool secureVideoPath)799 OH_AVErrCode OH_VideoDecoder_SetDecryptionConfig(OH_AVCodec *codec, MediaKeySession *mediaKeySession,
800                                                  bool secureVideoPath)
801 {
802     AVCODEC_LOGI("OH_VideoDecoder_SetDecryptionConfig");
803     (void)codec;
804     (void)mediaKeySession;
805     (void)secureVideoPath;
806     return AV_ERR_OK;
807 }
808 #endif
809 }
810 } // namespace MediaAVCodec
811 } // namespace OHOS