• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 <shared_mutex>
19 #include "native_avcodec_base.h"
20 #include "native_avcodec_videodecoder.h"
21 #include "native_avmagic.h"
22 #include "native_window.h"
23 #include "avcodec_video_decoder.h"
24 #include "avsharedmemory.h"
25 #include "avcodec_log.h"
26 #include "avcodec_errors.h"
27 #include "avcodec_dfx.h"
28 
29 namespace {
30 constexpr OHOS::HiviewDFX::HiLogLabel LABEL = {LOG_CORE, LOG_DOMAIN, "NativeVideoDecoder"};
31 }
32 
33 using namespace OHOS::MediaAVCodec;
34 class NativeVideoDecoderCallback;
35 
36 struct VideoDecoderObject : public OH_AVCodec {
VideoDecoderObjectVideoDecoderObject37     explicit VideoDecoderObject(const std::shared_ptr<AVCodecVideoDecoder> &decoder)
38         : OH_AVCodec(AVMagic::AVCODEC_MAGIC_VIDEO_DECODER), videoDecoder_(decoder)
39     {
40     }
41     ~VideoDecoderObject() = default;
42 
43     const std::shared_ptr<AVCodecVideoDecoder> videoDecoder_;
44     std::list<OHOS::sptr<OH_AVMemory>> memoryObjList_;
45     std::shared_ptr<NativeVideoDecoderCallback> callback_ = nullptr;
46     std::atomic<bool> isFlushing_ = false;
47     std::atomic<bool> isFlushed_ = false;
48     std::atomic<bool> isStop_ = false;
49     std::atomic<bool> isEOS_ = false;
50     bool isOutputSurfaceMode_ = false;
51     std::atomic<bool> isFirstFrameIn_ = true;
52     std::atomic<bool> isFirstFrameOut_ = true;
53     std::shared_mutex memoryObjListMutex_;
54 };
55 
56 class NativeVideoDecoderCallback : public AVCodecCallback {
57 public:
NativeVideoDecoderCallback(OH_AVCodec * codec,struct OH_AVCodecAsyncCallback cb,void * userData)58     NativeVideoDecoderCallback(OH_AVCodec *codec, struct OH_AVCodecAsyncCallback cb, void *userData)
59         : codec_(codec), callback_(cb), userData_(userData)
60     {
61     }
62     virtual ~NativeVideoDecoderCallback() = default;
63 
OnError(AVCodecErrorType errorType,int32_t errorCode)64     void OnError(AVCodecErrorType errorType, int32_t errorCode) override
65     {
66         std::unique_lock<std::shared_mutex> lock(mutex_);
67         (void)errorType;
68 
69         CHECK_AND_RETURN_LOG(codec_ != nullptr, "Codec is nullptr");
70         CHECK_AND_RETURN_LOG(callback_.onError != nullptr, "Callback is nullptr");
71         int32_t extErr = AVCSErrorToOHAVErrCode(static_cast<AVCodecServiceErrCode>(errorCode));
72         callback_.onError(codec_, extErr, userData_);
73     }
74 
OnOutputFormatChanged(const Format & format)75     void OnOutputFormatChanged(const Format &format) override
76     {
77         std::unique_lock<std::shared_mutex> lock(mutex_);
78 
79         CHECK_AND_RETURN_LOG(codec_ != nullptr, "Codec is nullptr");
80         CHECK_AND_RETURN_LOG(callback_.onStreamChanged != nullptr, "Callback is nullptr");
81         OHOS::sptr<OH_AVFormat> object = new (std::nothrow) OH_AVFormat(format);
82         callback_.onStreamChanged(codec_, reinterpret_cast<OH_AVFormat *>(object.GetRefPtr()), userData_);
83     }
84 
OnInputBufferAvailable(uint32_t index,std::shared_ptr<AVSharedMemory> buffer)85     void OnInputBufferAvailable(uint32_t index, std::shared_ptr<AVSharedMemory> buffer) override
86     {
87         std::shared_lock<std::shared_mutex> lock(mutex_);
88 
89         CHECK_AND_RETURN_LOG(codec_ != nullptr, "Codec is nullptr");
90         CHECK_AND_RETURN_LOG(callback_.onNeedInputData != nullptr, "Callback is nullptr");
91 
92         struct VideoDecoderObject *videoDecObj = reinterpret_cast<VideoDecoderObject *>(codec_);
93         CHECK_AND_RETURN_LOG(videoDecObj->videoDecoder_ != nullptr, "Video decoder is nullptr!");
94 
95         if (videoDecObj->isFlushing_.load() || videoDecObj->isFlushed_.load() || videoDecObj->isStop_.load() ||
96             videoDecObj->isEOS_.load()) {
97             AVCODEC_LOGD("At flush, eos or stop, no buffer available");
98             return;
99         }
100 
101         OH_AVMemory *data = GetInputData(codec_, index, buffer);
102         callback_.onNeedInputData(codec_, index, data, userData_);
103     }
104 
OnOutputBufferAvailable(uint32_t index,AVCodecBufferInfo info,AVCodecBufferFlag flag,std::shared_ptr<AVSharedMemory> buffer)105     void OnOutputBufferAvailable(uint32_t index, AVCodecBufferInfo info, AVCodecBufferFlag flag,
106                                  std::shared_ptr<AVSharedMemory> buffer) override
107     {
108         std::shared_lock<std::shared_mutex> lock(mutex_);
109         CHECK_AND_RETURN_LOG(codec_ != nullptr, "Codec is nullptr");
110         CHECK_AND_RETURN_LOG(callback_.onNeedOutputData != nullptr, "Callback is nullptr");
111 
112         struct VideoDecoderObject *videoDecObj = reinterpret_cast<VideoDecoderObject *>(codec_);
113         CHECK_AND_RETURN_LOG(videoDecObj->videoDecoder_ != nullptr, "Video decoder is nullptr!");
114 
115         if (videoDecObj->isFlushing_.load() || videoDecObj->isFlushed_.load() || videoDecObj->isStop_.load()) {
116             AVCODEC_LOGD("At flush or stop, ignore");
117             return;
118         }
119 
120         struct OH_AVCodecBufferAttr bufferAttr { info.presentationTimeUs, info.size, info.offset, flag };
121         OH_AVMemory *data = nullptr;
122         if (!videoDecObj->isOutputSurfaceMode_) {
123             data = GetOutputData(codec_, index, buffer);
124         }
125 
126         if (flag != AVCODEC_BUFFER_FLAG_CODEC_DATA) {
127             if (videoDecObj->isFirstFrameOut_) {
128                 AVCodecTrace::TraceEnd("OH::FirstFrame", info.presentationTimeUs);
129                 videoDecObj->isFirstFrameOut_ = false;
130             } else {
131                 AVCodecTrace::TraceEnd("OH::Frame", info.presentationTimeUs);
132             }
133         }
134         if (flag == AVCODEC_BUFFER_FLAG_EOS) {
135             videoDecObj->isFirstFrameIn_ = true;
136             videoDecObj->isFirstFrameOut_ = true;
137         }
138         callback_.onNeedOutputData(codec_, index, data, &bufferAttr, userData_);
139     }
140 
StopCallback()141     void StopCallback()
142     {
143         std::unique_lock<std::shared_mutex> lock(mutex_);
144         codec_ = nullptr;
145     }
146 
147 private:
GetTransData(struct OH_AVCodec ** codec,uint32_t * index,std::shared_ptr<AVSharedMemory> memory,const bool isInput)148     OH_AVMemory *GetTransData(struct OH_AVCodec **codec, uint32_t *index, std::shared_ptr<AVSharedMemory> memory,
149                               const bool isInput)
150     {
151         CHECK_AND_RETURN_RET_LOG((*codec) != nullptr, nullptr, "Codec is nullptr!");
152         CHECK_AND_RETURN_RET_LOG((*codec)->magic_ == AVMagic::AVCODEC_MAGIC_VIDEO_DECODER, nullptr,
153                                  "Codec magic error!");
154         struct VideoDecoderObject *videoDecObj = reinterpret_cast<VideoDecoderObject *>(*codec);
155         CHECK_AND_RETURN_RET_LOG(videoDecObj->videoDecoder_ != nullptr, nullptr, "Video decoder is nullptr!");
156         if (isInput) {
157             CHECK_AND_RETURN_RET_LOG(memory != nullptr, nullptr, "Memory is nullptr, get input buffer failed!");
158         } else {
159             CHECK_AND_RETURN_RET_LOG(memory != nullptr, nullptr, "Memory is nullptr, get out buffer failed!");
160         }
161 
162         {
163             std::shared_lock<std::shared_mutex> lock(videoDecObj->memoryObjListMutex_);
164             for (auto &memoryObj : videoDecObj->memoryObjList_) {
165                 if (memoryObj->IsEqualMemory(memory)) {
166                     return reinterpret_cast<OH_AVMemory *>(memoryObj.GetRefPtr());
167                 }
168             }
169         }
170 
171         OHOS::sptr<OH_AVMemory> object = new (std::nothrow) OH_AVMemory(memory);
172         CHECK_AND_RETURN_RET_LOG(object != nullptr, nullptr, "AV memory create failed");
173 
174         std::lock_guard<std::shared_mutex> lock(videoDecObj->memoryObjListMutex_);
175         videoDecObj->memoryObjList_.push_back(object);
176         return reinterpret_cast<OH_AVMemory *>(object.GetRefPtr());
177     }
178 
GetInputData(struct OH_AVCodec * codec,uint32_t index,std::shared_ptr<AVSharedMemory> memory)179     OH_AVMemory *GetInputData(struct OH_AVCodec *codec, uint32_t index, std::shared_ptr<AVSharedMemory> memory)
180     {
181         return GetTransData(&codec, &index, memory, true);
182     }
183 
GetOutputData(struct OH_AVCodec * codec,uint32_t index,std::shared_ptr<AVSharedMemory> memory)184     OH_AVMemory *GetOutputData(struct OH_AVCodec *codec, uint32_t index, std::shared_ptr<AVSharedMemory> memory)
185     {
186         return GetTransData(&codec, &index, memory, false);
187     }
188 
189     struct OH_AVCodec *codec_;
190     struct OH_AVCodecAsyncCallback callback_;
191     void *userData_;
192     std::shared_mutex mutex_;
193 };
194 
OH_VideoDecoder_CreateByMime(const char * mime)195 struct OH_AVCodec *OH_VideoDecoder_CreateByMime(const char *mime)
196 {
197     CHECK_AND_RETURN_RET_LOG(mime != nullptr, nullptr, "Mime is nullptr!");
198 
199     std::shared_ptr<AVCodecVideoDecoder> videoDecoder = VideoDecoderFactory::CreateByMime(mime);
200     CHECK_AND_RETURN_RET_LOG(videoDecoder != nullptr, nullptr, "Video decoder create by mime failed!");
201 
202     struct VideoDecoderObject *object = new (std::nothrow) VideoDecoderObject(videoDecoder);
203     CHECK_AND_RETURN_RET_LOG(object != nullptr, nullptr, "Video decoder create by mime failed!");
204 
205     return object;
206 }
207 
OH_VideoDecoder_CreateByName(const char * name)208 struct OH_AVCodec *OH_VideoDecoder_CreateByName(const char *name)
209 {
210     CHECK_AND_RETURN_RET_LOG(name != nullptr, nullptr, "Name is nullptr!");
211 
212     std::shared_ptr<AVCodecVideoDecoder> videoDecoder = VideoDecoderFactory::CreateByName(name);
213     CHECK_AND_RETURN_RET_LOG(videoDecoder != nullptr, nullptr, "Video decoder create by name failed!");
214 
215     struct VideoDecoderObject *object = new (std::nothrow) VideoDecoderObject(videoDecoder);
216     CHECK_AND_RETURN_RET_LOG(object != nullptr, nullptr, "Video decoder create by name failed!");
217 
218     return object;
219 }
220 
OH_VideoDecoder_Destroy(struct OH_AVCodec * codec)221 OH_AVErrCode OH_VideoDecoder_Destroy(struct OH_AVCodec *codec)
222 {
223     CHECK_AND_RETURN_RET_LOG(codec != nullptr, AV_ERR_INVALID_VAL, "Codec is nullptr!");
224     CHECK_AND_RETURN_RET_LOG(codec->magic_ == AVMagic::AVCODEC_MAGIC_VIDEO_DECODER, AV_ERR_INVALID_VAL,
225                              "Codec magic error!");
226 
227     struct VideoDecoderObject *videoDecObj = reinterpret_cast<VideoDecoderObject *>(codec);
228 
229     if (videoDecObj != nullptr && videoDecObj->videoDecoder_ != nullptr) {
230         if (videoDecObj->callback_ != nullptr) {
231             videoDecObj->callback_->StopCallback();
232         }
233         {
234             std::lock_guard<std::shared_mutex> lock(videoDecObj->memoryObjListMutex_);
235             videoDecObj->memoryObjList_.clear();
236         }
237         videoDecObj->isStop_.store(false);
238         int32_t ret = videoDecObj->videoDecoder_->Release();
239         if (ret != AVCS_ERR_OK) {
240             AVCODEC_LOGE("Video decoder destroy failed!");
241             delete codec;
242             return AVCSErrorToOHAVErrCode(static_cast<AVCodecServiceErrCode>(ret));
243         }
244     } else {
245         AVCODEC_LOGD("Video decoder is nullptr!");
246     }
247 
248     delete codec;
249     return AV_ERR_OK;
250 }
251 
OH_VideoDecoder_Configure(struct OH_AVCodec * codec,struct OH_AVFormat * format)252 OH_AVErrCode OH_VideoDecoder_Configure(struct OH_AVCodec *codec, struct OH_AVFormat *format)
253 {
254     CHECK_AND_RETURN_RET_LOG(codec != nullptr, AV_ERR_INVALID_VAL, "Codec is nullptr!");
255     CHECK_AND_RETURN_RET_LOG(codec->magic_ == AVMagic::AVCODEC_MAGIC_VIDEO_DECODER, AV_ERR_INVALID_VAL,
256                              "Codec magic error!");
257     CHECK_AND_RETURN_RET_LOG(format != nullptr, AV_ERR_INVALID_VAL, "Format is nullptr!");
258     CHECK_AND_RETURN_RET_LOG(format->magic_ == AVMagic::AVCODEC_MAGIC_FORMAT, AV_ERR_INVALID_VAL,
259                              "Format magic error!");
260 
261     struct VideoDecoderObject *videoDecObj = reinterpret_cast<VideoDecoderObject *>(codec);
262     CHECK_AND_RETURN_RET_LOG(videoDecObj->videoDecoder_ != nullptr, AV_ERR_INVALID_VAL, "Video decoder is nullptr!");
263 
264     int32_t ret = videoDecObj->videoDecoder_->Configure(format->format_);
265     CHECK_AND_RETURN_RET_LOG(ret == AVCS_ERR_OK, AVCSErrorToOHAVErrCode(static_cast<AVCodecServiceErrCode>(ret)),
266                              "Video decoder configure failed!");
267 
268     return AV_ERR_OK;
269 }
270 
OH_VideoDecoder_Prepare(struct OH_AVCodec * codec)271 OH_AVErrCode OH_VideoDecoder_Prepare(struct OH_AVCodec *codec)
272 {
273     CHECK_AND_RETURN_RET_LOG(codec != nullptr, AV_ERR_INVALID_VAL, "Codec is nullptr!");
274     CHECK_AND_RETURN_RET_LOG(codec->magic_ == AVMagic::AVCODEC_MAGIC_VIDEO_DECODER, AV_ERR_INVALID_VAL,
275                              "Codec magic error!");
276 
277     struct VideoDecoderObject *videoDecObj = reinterpret_cast<VideoDecoderObject *>(codec);
278     CHECK_AND_RETURN_RET_LOG(videoDecObj->videoDecoder_ != nullptr, AV_ERR_INVALID_VAL, "Video decoder is nullptr!");
279 
280     int32_t ret = videoDecObj->videoDecoder_->Prepare();
281     CHECK_AND_RETURN_RET_LOG(ret == AVCS_ERR_OK, AVCSErrorToOHAVErrCode(static_cast<AVCodecServiceErrCode>(ret)),
282                              "Video decoder prepare failed!");
283 
284     return AV_ERR_OK;
285 }
286 
OH_VideoDecoder_Start(struct OH_AVCodec * codec)287 OH_AVErrCode OH_VideoDecoder_Start(struct OH_AVCodec *codec)
288 {
289     CHECK_AND_RETURN_RET_LOG(codec != nullptr, AV_ERR_INVALID_VAL, "Codec is nullptr!");
290     CHECK_AND_RETURN_RET_LOG(codec->magic_ == AVMagic::AVCODEC_MAGIC_VIDEO_DECODER, AV_ERR_INVALID_VAL,
291                              "Codec magic error!");
292 
293     struct VideoDecoderObject *videoDecObj = reinterpret_cast<VideoDecoderObject *>(codec);
294     CHECK_AND_RETURN_RET_LOG(videoDecObj->videoDecoder_ != nullptr, AV_ERR_INVALID_VAL, "Video decoder is nullptr!");
295 
296     videoDecObj->isStop_.store(false);
297     videoDecObj->isEOS_.store(false);
298     videoDecObj->isFlushed_.store(false);
299     int32_t ret = videoDecObj->videoDecoder_->Start();
300     CHECK_AND_RETURN_RET_LOG(ret == AVCS_ERR_OK, AVCSErrorToOHAVErrCode(static_cast<AVCodecServiceErrCode>(ret)),
301                              "Video decoder start failed!");
302 
303     return AV_ERR_OK;
304 }
305 
OH_VideoDecoder_Stop(struct OH_AVCodec * codec)306 OH_AVErrCode OH_VideoDecoder_Stop(struct OH_AVCodec *codec)
307 {
308     CHECK_AND_RETURN_RET_LOG(codec != nullptr, AV_ERR_INVALID_VAL, "Codec is nullptr!");
309     CHECK_AND_RETURN_RET_LOG(codec->magic_ == AVMagic::AVCODEC_MAGIC_VIDEO_DECODER, AV_ERR_INVALID_VAL,
310                              "Codec magic error!");
311 
312     struct VideoDecoderObject *videoDecObj = reinterpret_cast<VideoDecoderObject *>(codec);
313     CHECK_AND_RETURN_RET_LOG(videoDecObj->videoDecoder_ != nullptr, AV_ERR_INVALID_VAL, "Video decoder is nullptr!");
314 
315     videoDecObj->isStop_.store(true);
316     int32_t ret = videoDecObj->videoDecoder_->Stop();
317     if (ret != AVCS_ERR_OK) {
318         videoDecObj->isStop_.store(false);
319         AVCODEC_LOGE("Video decoder stop failed");
320         return AVCSErrorToOHAVErrCode(static_cast<AVCodecServiceErrCode>(ret));
321     }
322     std::lock_guard<std::shared_mutex> lock(videoDecObj->memoryObjListMutex_);
323     videoDecObj->memoryObjList_.clear();
324 
325     return AV_ERR_OK;
326 }
327 
OH_VideoDecoder_Flush(struct OH_AVCodec * codec)328 OH_AVErrCode OH_VideoDecoder_Flush(struct OH_AVCodec *codec)
329 {
330     CHECK_AND_RETURN_RET_LOG(codec != nullptr, AV_ERR_INVALID_VAL, "Codec is nullptr!");
331     CHECK_AND_RETURN_RET_LOG(codec->magic_ == AVMagic::AVCODEC_MAGIC_VIDEO_DECODER, AV_ERR_INVALID_VAL,
332                              "Codec magic error!");
333 
334     struct VideoDecoderObject *videoDecObj = reinterpret_cast<VideoDecoderObject *>(codec);
335     CHECK_AND_RETURN_RET_LOG(videoDecObj->videoDecoder_ != nullptr, AV_ERR_INVALID_VAL, "Video decoder is nullptr!");
336 
337     videoDecObj->isFlushing_.store(true);
338     int32_t ret = videoDecObj->videoDecoder_->Flush();
339     videoDecObj->isFlushed_.store(true);
340     videoDecObj->isFlushing_.store(false);
341     CHECK_AND_RETURN_RET_LOG(ret == AVCS_ERR_OK, AVCSErrorToOHAVErrCode(static_cast<AVCodecServiceErrCode>(ret)),
342                              "Video decoder flush failed!");
343     std::lock_guard<std::shared_mutex> lock(videoDecObj->memoryObjListMutex_);
344     videoDecObj->memoryObjList_.clear();
345 
346     return AV_ERR_OK;
347 }
348 
OH_VideoDecoder_Reset(struct OH_AVCodec * codec)349 OH_AVErrCode OH_VideoDecoder_Reset(struct OH_AVCodec *codec)
350 {
351     CHECK_AND_RETURN_RET_LOG(codec != nullptr, AV_ERR_INVALID_VAL, "Codec is nullptr!");
352     CHECK_AND_RETURN_RET_LOG(codec->magic_ == AVMagic::AVCODEC_MAGIC_VIDEO_DECODER, AV_ERR_INVALID_VAL,
353                              "Codec magic error!");
354 
355     struct VideoDecoderObject *videoDecObj = reinterpret_cast<VideoDecoderObject *>(codec);
356     CHECK_AND_RETURN_RET_LOG(videoDecObj->videoDecoder_ != nullptr, AV_ERR_INVALID_VAL, "Video decoder is nullptr!");
357 
358     videoDecObj->isStop_.store(true);
359     int32_t ret = videoDecObj->videoDecoder_->Reset();
360     if (ret != AVCS_ERR_OK) {
361         videoDecObj->isStop_.store(false);
362         AVCODEC_LOGE("Video decoder reset failed!");
363         return AVCSErrorToOHAVErrCode(static_cast<AVCodecServiceErrCode>(ret));
364     }
365     std::lock_guard<std::shared_mutex> lock(videoDecObj->memoryObjListMutex_);
366     videoDecObj->memoryObjList_.clear();
367 
368     return AV_ERR_OK;
369 }
370 
OH_VideoDecoder_SetSurface(OH_AVCodec * codec,OHNativeWindow * window)371 OH_AVErrCode OH_VideoDecoder_SetSurface(OH_AVCodec *codec, OHNativeWindow *window)
372 {
373     CHECK_AND_RETURN_RET_LOG(codec != nullptr, AV_ERR_INVALID_VAL, "Codec is nullptr!");
374     CHECK_AND_RETURN_RET_LOG(codec->magic_ == AVMagic::AVCODEC_MAGIC_VIDEO_DECODER, AV_ERR_INVALID_VAL,
375                              "Codec magic error!");
376     CHECK_AND_RETURN_RET_LOG(window != nullptr, AV_ERR_INVALID_VAL, "Window is nullptr!");
377     CHECK_AND_RETURN_RET_LOG(window->surface != nullptr, AV_ERR_INVALID_VAL, "Input window surface is nullptr!");
378 
379     struct VideoDecoderObject *videoDecObj = reinterpret_cast<VideoDecoderObject *>(codec);
380     CHECK_AND_RETURN_RET_LOG(videoDecObj->videoDecoder_ != nullptr, AV_ERR_INVALID_VAL, "Video decoder is nullptr!");
381 
382     int32_t ret = videoDecObj->videoDecoder_->SetOutputSurface(window->surface);
383     CHECK_AND_RETURN_RET_LOG(ret == AVCS_ERR_OK, AVCSErrorToOHAVErrCode(static_cast<AVCodecServiceErrCode>(ret)),
384                              "Video decoder set output surface failed!");
385     videoDecObj->isOutputSurfaceMode_ = true;
386 
387     return AV_ERR_OK;
388 }
389 
OH_VideoDecoder_PushInputData(struct OH_AVCodec * codec,uint32_t index,OH_AVCodecBufferAttr attr)390 OH_AVErrCode OH_VideoDecoder_PushInputData(struct OH_AVCodec *codec, uint32_t index, OH_AVCodecBufferAttr attr)
391 {
392     CHECK_AND_RETURN_RET_LOG(codec != nullptr, AV_ERR_INVALID_VAL, "Codec is nullptr!");
393     CHECK_AND_RETURN_RET_LOG(codec->magic_ == AVMagic::AVCODEC_MAGIC_VIDEO_DECODER, AV_ERR_INVALID_VAL,
394                              "Codec magic error!");
395     CHECK_AND_RETURN_RET_LOG(attr.size >= 0, AV_ERR_INVALID_VAL, "Invalid buffer size!");
396 
397     struct VideoDecoderObject *videoDecObj = reinterpret_cast<VideoDecoderObject *>(codec);
398     CHECK_AND_RETURN_RET_LOG(videoDecObj->videoDecoder_ != nullptr, AV_ERR_INVALID_VAL, "Video decoder is nullptr!");
399 
400     if (attr.flags != AVCODEC_BUFFER_FLAGS_CODEC_DATA) {
401         if (videoDecObj->isFirstFrameIn_) {
402             AVCodecTrace::TraceBegin("OH::FirstFrame", attr.pts);
403             videoDecObj->isFirstFrameIn_ = false;
404         } else {
405             AVCodecTrace::TraceBegin("OH::Frame", attr.pts);
406         }
407     }
408 
409     struct AVCodecBufferInfo bufferInfo;
410     bufferInfo.presentationTimeUs = attr.pts;
411     bufferInfo.size = attr.size;
412     bufferInfo.offset = attr.offset;
413     enum AVCodecBufferFlag bufferFlag = static_cast<enum AVCodecBufferFlag>(attr.flags);
414 
415     int32_t ret = videoDecObj->videoDecoder_->QueueInputBuffer(index, bufferInfo, bufferFlag);
416     CHECK_AND_RETURN_RET_LOG(ret == AVCS_ERR_OK, AVCSErrorToOHAVErrCode(static_cast<AVCodecServiceErrCode>(ret)),
417                              "Video decoder push input data failed!");
418     if (bufferFlag == AVCODEC_BUFFER_FLAG_EOS) {
419         videoDecObj->isEOS_.store(true);
420     }
421 
422     return AV_ERR_OK;
423 }
424 
OH_VideoDecoder_GetOutputDescription(struct OH_AVCodec * codec)425 OH_AVFormat *OH_VideoDecoder_GetOutputDescription(struct OH_AVCodec *codec)
426 {
427     CHECK_AND_RETURN_RET_LOG(codec != nullptr, nullptr, "Codec is nullptr!");
428     CHECK_AND_RETURN_RET_LOG(codec->magic_ == AVMagic::AVCODEC_MAGIC_VIDEO_DECODER, nullptr, "Codec magic error!");
429 
430     struct VideoDecoderObject *videoDecObj = reinterpret_cast<VideoDecoderObject *>(codec);
431     CHECK_AND_RETURN_RET_LOG(videoDecObj->videoDecoder_ != nullptr, nullptr, "Video decoder is nullptr!");
432 
433     Format format;
434     int32_t ret = videoDecObj->videoDecoder_->GetOutputFormat(format);
435     CHECK_AND_RETURN_RET_LOG(ret == AVCS_ERR_OK, nullptr, "Video decoder get output description failed!");
436 
437     OH_AVFormat *avFormat = OH_AVFormat_Create();
438     CHECK_AND_RETURN_RET_LOG(avFormat != nullptr, nullptr, "Video decoder get output description failed!");
439     avFormat->format_ = format;
440 
441     return avFormat;
442 }
443 
OH_VideoDecoder_RenderOutputData(struct OH_AVCodec * codec,uint32_t index)444 OH_AVErrCode OH_VideoDecoder_RenderOutputData(struct OH_AVCodec *codec, uint32_t index)
445 {
446     CHECK_AND_RETURN_RET_LOG(codec != nullptr, AV_ERR_INVALID_VAL, "Codec is nullptr!");
447     CHECK_AND_RETURN_RET_LOG(codec->magic_ == AVMagic::AVCODEC_MAGIC_VIDEO_DECODER, AV_ERR_INVALID_VAL,
448                              "Codec magic error!");
449 
450     struct VideoDecoderObject *videoDecObj = reinterpret_cast<VideoDecoderObject *>(codec);
451     CHECK_AND_RETURN_RET_LOG(videoDecObj->videoDecoder_ != nullptr, AV_ERR_INVALID_VAL, "Video decoder is nullptr!");
452 
453     int32_t ret = videoDecObj->videoDecoder_->ReleaseOutputBuffer(index, true);
454     CHECK_AND_RETURN_RET_LOG(ret == AVCS_ERR_OK, AVCSErrorToOHAVErrCode(static_cast<AVCodecServiceErrCode>(ret)),
455                              "Video decoder render output data failed!");
456 
457     return AV_ERR_OK;
458 }
459 
OH_VideoDecoder_FreeOutputData(struct OH_AVCodec * codec,uint32_t index)460 OH_AVErrCode OH_VideoDecoder_FreeOutputData(struct OH_AVCodec *codec, uint32_t index)
461 {
462     AVCODEC_LOGD("In OH_VideoDecoder_FreeOutputData");
463     CHECK_AND_RETURN_RET_LOG(codec != nullptr, AV_ERR_INVALID_VAL, "Codec is nullptr!");
464     CHECK_AND_RETURN_RET_LOG(codec->magic_ == AVMagic::AVCODEC_MAGIC_VIDEO_DECODER, AV_ERR_INVALID_VAL,
465                              "Codec magic error!");
466 
467     struct VideoDecoderObject *videoDecObj = reinterpret_cast<VideoDecoderObject *>(codec);
468     CHECK_AND_RETURN_RET_LOG(videoDecObj->videoDecoder_ != nullptr, AV_ERR_INVALID_VAL, "Video decoder is nullptr!");
469 
470     int32_t ret = videoDecObj->videoDecoder_->ReleaseOutputBuffer(index, false);
471     CHECK_AND_RETURN_RET_LOG(ret == AVCS_ERR_OK, AVCSErrorToOHAVErrCode(static_cast<AVCodecServiceErrCode>(ret)),
472                              "Video decoder free output data failed!");
473 
474     return AV_ERR_OK;
475 }
476 
OH_VideoDecoder_SetParameter(struct OH_AVCodec * codec,struct OH_AVFormat * format)477 OH_AVErrCode OH_VideoDecoder_SetParameter(struct OH_AVCodec *codec, struct OH_AVFormat *format)
478 {
479     CHECK_AND_RETURN_RET_LOG(codec != nullptr, AV_ERR_INVALID_VAL, "Codec is nullptr!");
480     CHECK_AND_RETURN_RET_LOG(codec->magic_ == AVMagic::AVCODEC_MAGIC_VIDEO_DECODER, AV_ERR_INVALID_VAL,
481                              "Codec magic error!");
482     CHECK_AND_RETURN_RET_LOG(format != nullptr, AV_ERR_INVALID_VAL, "Format is nullptr!");
483     CHECK_AND_RETURN_RET_LOG(format->magic_ == AVMagic::AVCODEC_MAGIC_FORMAT, AV_ERR_INVALID_VAL,
484                              "Format magic error!");
485 
486     struct VideoDecoderObject *videoDecObj = reinterpret_cast<VideoDecoderObject *>(codec);
487     CHECK_AND_RETURN_RET_LOG(videoDecObj->videoDecoder_ != nullptr, AV_ERR_INVALID_VAL, "Video decoder is nullptr!");
488 
489     int32_t ret = videoDecObj->videoDecoder_->SetParameter(format->format_);
490     CHECK_AND_RETURN_RET_LOG(ret == AVCS_ERR_OK, AVCSErrorToOHAVErrCode(static_cast<AVCodecServiceErrCode>(ret)),
491                              "Video decoder set parameter failed!");
492 
493     return AV_ERR_OK;
494 }
495 
OH_VideoDecoder_SetCallback(struct OH_AVCodec * codec,struct OH_AVCodecAsyncCallback callback,void * userData)496 OH_AVErrCode OH_VideoDecoder_SetCallback(struct OH_AVCodec *codec, struct OH_AVCodecAsyncCallback callback,
497                                          void *userData)
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 
503     struct VideoDecoderObject *videoDecObj = reinterpret_cast<VideoDecoderObject *>(codec);
504     CHECK_AND_RETURN_RET_LOG(videoDecObj->videoDecoder_ != nullptr, AV_ERR_INVALID_VAL, "Video decoder is nullptr!");
505 
506     videoDecObj->callback_ = std::make_shared<NativeVideoDecoderCallback>(codec, callback, userData);
507 
508     int32_t ret = videoDecObj->videoDecoder_->SetCallback(videoDecObj->callback_);
509     CHECK_AND_RETURN_RET_LOG(ret == AVCS_ERR_OK, AVCSErrorToOHAVErrCode(static_cast<AVCodecServiceErrCode>(ret)),
510                              "Video decoder set callback failed!");
511 
512     return AV_ERR_OK;
513 }
514 
OH_VideoDecoder_IsValid(OH_AVCodec * codec,bool * isValid)515 OH_AVErrCode OH_VideoDecoder_IsValid(OH_AVCodec *codec, bool *isValid)
516 {
517     CHECK_AND_RETURN_RET_LOG(codec != nullptr, AV_ERR_INVALID_VAL, "Codec is nullptr!");
518     CHECK_AND_RETURN_RET_LOG(codec->magic_ == AVMagic::AVCODEC_MAGIC_VIDEO_DECODER, AV_ERR_INVALID_VAL,
519                              "Codec magic error!");
520     CHECK_AND_RETURN_RET_LOG(isValid != nullptr, AV_ERR_INVALID_VAL, "Input isValid is nullptr!");
521     *isValid = true;
522     return AV_ERR_OK;
523 }