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 }