1 /*
2 * Copyright (C) 2023-2025 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 #define MEDIA_PIPELINE
16
17 #include <malloc.h>
18 #include <map>
19 #include <unistd.h>
20 #include <vector>
21 #include "avcodec_video_decoder.h"
22 #include "avcodec_errors.h"
23 #include "avcodec_trace.h"
24 #include "common/log.h"
25 #include "media_description.h"
26 #include "surface_type.h"
27 #include "buffer/avbuffer_queue_consumer.h"
28 #include "meta/meta_key.h"
29 #include "meta/meta.h"
30 #include "video_decoder_adapter.h"
31 #include "avcodec_sysevent.h"
32 #include "media_core.h"
33 #include "scoped_timer.h"
34 #include "sync_fence.h"
35
36 namespace {
37 constexpr OHOS::HiviewDFX::HiLogLabel LABEL = { LOG_CORE, LOG_DOMAIN_SYSTEM_PLAYER, "VideoDecoderAdapter" };
38 }
39
40 namespace OHOS {
41 namespace Media {
42 using namespace MediaAVCodec;
43 using FileType = OHOS::Media::Plugins::FileType;
44 const std::string VIDEO_INPUT_BUFFER_QUEUE_NAME = "VideoDecoderInputBufferQueue";
45 constexpr uint64_t DECODER_USAGE =
46 BUFFER_USAGE_CPU_READ | BUFFER_USAGE_CPU_WRITE | BUFFER_USAGE_MEM_DMA | BUFFER_USAGE_VIDEO_DECODER;
47 static const int64_t CODEC_START_WARNING_MS = 50;
48
VideoDecoderCallback(std::shared_ptr<VideoDecoderAdapter> videoDecoder)49 VideoDecoderCallback::VideoDecoderCallback(std::shared_ptr<VideoDecoderAdapter> videoDecoder)
50 {
51 MEDIA_LOG_D_SHORT("VideoDecoderCallback instances create.");
52 videoDecoderAdapter_ = videoDecoder;
53 }
54
~VideoDecoderCallback()55 VideoDecoderCallback::~VideoDecoderCallback()
56 {
57 MEDIA_LOG_D_SHORT("~VideoDecoderCallback()");
58 }
59
OnError(MediaAVCodec::AVCodecErrorType errorType,int32_t errorCode)60 void VideoDecoderCallback::OnError(MediaAVCodec::AVCodecErrorType errorType, int32_t errorCode)
61 {
62 if (auto videoDecoderAdapter = videoDecoderAdapter_.lock()) {
63 videoDecoderAdapter->OnError(errorType, errorCode);
64 } else {
65 MEDIA_LOG_I_SHORT("invalid videoDecoderAdapter");
66 }
67 }
68
OnOutputFormatChanged(const MediaAVCodec::Format & format)69 void VideoDecoderCallback::OnOutputFormatChanged(const MediaAVCodec::Format &format)
70 {
71 if (auto videoDecoderAdapter = videoDecoderAdapter_.lock()) {
72 videoDecoderAdapter->OnOutputFormatChanged(format);
73 } else {
74 MEDIA_LOG_I_SHORT("invalid videoDecoderAdapter");
75 }
76 }
77
OnInputBufferAvailable(uint32_t index,std::shared_ptr<AVBuffer> buffer)78 void VideoDecoderCallback::OnInputBufferAvailable(uint32_t index, std::shared_ptr<AVBuffer> buffer)
79 {
80 if (auto videoDecoderAdapter = videoDecoderAdapter_.lock()) {
81 videoDecoderAdapter->OnInputBufferAvailable(index, buffer);
82 } else {
83 MEDIA_LOG_I_SHORT("invalid videoDecoderAdapter");
84 }
85 }
86
OnOutputBufferAvailable(uint32_t index,std::shared_ptr<AVBuffer> buffer)87 void VideoDecoderCallback::OnOutputBufferAvailable(uint32_t index, std::shared_ptr<AVBuffer> buffer)
88 {
89 if (auto videoDecoderAdapter = videoDecoderAdapter_.lock()) {
90 videoDecoderAdapter->OnOutputBufferAvailable(index, buffer);
91 } else {
92 MEDIA_LOG_I_SHORT("invalid videoDecoderAdapter");
93 }
94 }
95
96 class VideoConsumerListener : public IBufferConsumerListener {
97 public:
VideoConsumerListener(sptr<Surface> consumerSurface)98 explicit VideoConsumerListener(sptr<Surface> consumerSurface) : consumerSurface_(consumerSurface) {};
99
100 ~VideoConsumerListener() override = default;
101
OnBufferAvailable()102 void OnBufferAvailable() override
103 {
104 sptr<Surface> consumerSurface = consumerSurface_.promote();
105 FALSE_RETURN_MSG(consumerSurface != nullptr, "consumerSurface_ is nullptr");
106 sptr<SurfaceBuffer> surfaceBuffer = nullptr;
107 sptr<SyncFence> fence = nullptr;
108 int64_t timestamp = 0;
109 OHOS::Rect damage = {};
110 GSError err = consumerSurface->AcquireBuffer(surfaceBuffer, fence, timestamp, damage);
111 FALSE_RETURN_MSG(err == GSERROR_OK, "AcquireBuffer failed, err:%{public}d", err);
112 err = consumerSurface->ReleaseBuffer(surfaceBuffer, -1);
113 FALSE_RETURN_MSG(err == GSERROR_OK, "ReleaseBuffer failed, err:%{public}d", err);
114 }
115
116 private:
117 wptr<Surface> consumerSurface_{nullptr};
118 };
119
VideoDecoderAdapter()120 VideoDecoderAdapter::VideoDecoderAdapter()
121 {
122 MEDIA_LOG_D_SHORT("VideoDecoderAdapter instances create.");
123 }
124
~VideoDecoderAdapter()125 VideoDecoderAdapter::~VideoDecoderAdapter()
126 {
127 MEDIA_LOG_I_SHORT("~VideoDecoderAdapter()");
128 FALSE_RETURN_MSG(mediaCodec_ != nullptr, "mediaCodec_ is nullptr");
129 mediaCodec_->Release();
130 std::unique_lock<std::mutex> lock(dtsQueMutex_);
131 if (!inputBufferDtsQue_.empty()) {
132 MEDIA_LOG_I("Clear dtsQue_, currrent size: " PUBLIC_LOG_U64, static_cast<uint64_t>(inputBufferDtsQue_.size()));
133 inputBufferDtsQue_.clear();
134 }
135 }
136
Init(MediaAVCodec::AVCodecType type,bool isMimeType,const std::string & name)137 Status VideoDecoderAdapter::Init(MediaAVCodec::AVCodecType type, bool isMimeType, const std::string &name)
138 {
139 MEDIA_LOG_I_SHORT("mediaCodec_->Init.");
140
141 Format format;
142 int32_t ret;
143 std::shared_ptr<Media::Meta> callerInfo = std::make_shared<Media::Meta>();
144 callerInfo->SetData(Media::Tag::AV_CODEC_FORWARD_CALLER_PID, appPid_);
145 callerInfo->SetData(Media::Tag::AV_CODEC_FORWARD_CALLER_UID, appUid_);
146 callerInfo->SetData(Media::Tag::AV_CODEC_FORWARD_CALLER_PROCESS_NAME, bundleName_);
147 format.SetMeta(callerInfo);
148 mediaCodecName_ = "";
149 if (isMimeType) {
150 ret = MediaAVCodec::VideoDecoderFactory::CreateByMime(name, format, mediaCodec_);
151 MEDIA_LOG_I_SHORT("VideoDecoderAdapter::Init CreateByMime errorCode %{public}d", ret);
152 } else {
153 ret = MediaAVCodec::VideoDecoderFactory::CreateByName(name, format, mediaCodec_);
154 MEDIA_LOG_I_SHORT("VideoDecoderAdapter::Init CreateByName errorCode %{public}d", ret);
155 }
156
157 FALSE_RETURN_V_MSG(mediaCodec_ != nullptr, Status::ERROR_INVALID_STATE, "mediaCodec_ is nullptr");
158 mediaCodecName_ = name;
159 return Status::OK;
160 }
161
Configure(const Format & format)162 Status VideoDecoderAdapter::Configure(const Format &format)
163 {
164 MEDIA_LOG_I_SHORT("VideoDecoderAdapter->Configure.");
165 std::shared_ptr<Media::Meta> metaInfo = const_cast<Format &>(format).GetMeta();
166 FileType currentFileType = FileType::UNKNOW;
167 if (metaInfo != nullptr && metaInfo->GetData(Media::Tag::MEDIA_FILE_TYPE, currentFileType)) {
168 fileType_ = static_cast<int32_t>(currentFileType);
169 MEDIA_LOG_I("Media file type " PUBLIC_LOG_D32, fileType_);
170 }
171 FALSE_RETURN_V_MSG(mediaCodec_ != nullptr, Status::ERROR_INVALID_STATE, "mediaCodec_ is nullptr");
172 int32_t ret = mediaCodec_->Configure(format);
173 isConfigured_ = ret == AVCodecServiceErrCode::AVCS_ERR_OK;
174 return isConfigured_ ? Status::OK : Status::ERROR_INVALID_DATA;
175 }
176
SetParameter(const Format & format)177 int32_t VideoDecoderAdapter::SetParameter(const Format &format)
178 {
179 MEDIA_LOG_D_SHORT("SetParameter enter.");
180 FALSE_RETURN_V_MSG(mediaCodec_ != nullptr, AVCodecServiceErrCode::AVCS_ERR_INVALID_VAL, "mediaCodec_ is nullptr");
181 return mediaCodec_->SetParameter(format);
182 }
183
Start()184 Status VideoDecoderAdapter::Start()
185 {
186 MEDIA_LOG_I_SHORT("Start enter.");
187 FALSE_RETURN_V_MSG(mediaCodec_ != nullptr, Status::ERROR_INVALID_STATE, "mediaCodec_ is nullptr");
188 FALSE_RETURN_V_MSG(isConfigured_, Status::ERROR_INVALID_STATE, "mediaCodec_ is not configured");
189 int32_t ret;
190 {
191 ScopedTimer timer("mediaCodec Start", CODEC_START_WARNING_MS);
192 ret = mediaCodec_->Start();
193 }
194 if (ret != AVCodecServiceErrCode::AVCS_ERR_OK) {
195 std::string instanceId = std::to_string(instanceId_);
196 struct VideoCodecFaultInfo videoCodecFaultInfo;
197 videoCodecFaultInfo.appName = bundleName_;
198 videoCodecFaultInfo.instanceId = instanceId;
199 videoCodecFaultInfo.callerType = "player_framework";
200 videoCodecFaultInfo.videoCodec = mediaCodecName_;
201 videoCodecFaultInfo.errMsg = "mediaCodec_ start failed";
202 FaultVideoCodecEventWrite(videoCodecFaultInfo);
203 }
204 return ret == AVCodecServiceErrCode::AVCS_ERR_OK ? Status::OK : Status::ERROR_INVALID_STATE;
205 }
206
Stop()207 Status VideoDecoderAdapter::Stop()
208 {
209 MEDIA_LOG_I_SHORT("Stop enter.");
210 FALSE_RETURN_V_MSG(mediaCodec_ != nullptr, Status::ERROR_INVALID_STATE, "mediaCodec_ is nullptr");
211 FALSE_RETURN_V_MSG(isConfigured_, Status::ERROR_INVALID_STATE, "mediaCodec_ is not configured");
212 mediaCodec_->Stop();
213 return Status::OK;
214 }
215
Flush()216 Status VideoDecoderAdapter::Flush()
217 {
218 MEDIA_LOG_I_SHORT("Flush enter.");
219 FALSE_RETURN_V_MSG(mediaCodec_ != nullptr, Status::ERROR_INVALID_STATE, "mediaCodec_ is nullptr");
220 FALSE_RETURN_V_MSG(isConfigured_, Status::ERROR_INVALID_STATE, "mediaCodec_ is not configured");
221 int32_t ret = mediaCodec_->Flush();
222 {
223 std::unique_lock<std::mutex> lock(mutex_);
224 if (inputBufferQueueConsumer_ != nullptr) {
225 for (auto &buffer : bufferVector_) {
226 inputBufferQueueConsumer_->DetachBuffer(buffer);
227 }
228 bufferVector_.clear();
229 inputBufferQueueConsumer_->SetQueueSize(0);
230 }
231 }
232 {
233 std::unique_lock<std::mutex> lock(dtsQueMutex_);
234 if (!inputBufferDtsQue_.empty()) {
235 MEDIA_LOG_I("Clear dtsQue_, currrent size: " PUBLIC_LOG_U64,
236 static_cast<uint64_t>(inputBufferDtsQue_.size()));
237 inputBufferDtsQue_.clear();
238 }
239 }
240 return ret == AVCodecServiceErrCode::AVCS_ERR_OK ? Status::OK : Status::ERROR_INVALID_STATE;
241 }
242
Reset()243 Status VideoDecoderAdapter::Reset()
244 {
245 MEDIA_LOG_I_SHORT("Reset enter.");
246 FALSE_RETURN_V_MSG(mediaCodec_ != nullptr, Status::ERROR_INVALID_STATE, "mediaCodec_ is nullptr");
247 mediaCodec_->Reset();
248 isConfigured_ = false;
249 std::unique_lock<std::mutex> lock(mutex_);
250 if (inputBufferQueueConsumer_ != nullptr) {
251 for (auto &buffer : bufferVector_) {
252 inputBufferQueueConsumer_->DetachBuffer(buffer);
253 }
254 bufferVector_.clear();
255 inputBufferQueueConsumer_->SetQueueSize(0);
256 }
257 return Status::OK;
258 }
259
Release()260 Status VideoDecoderAdapter::Release()
261 {
262 MEDIA_LOG_I_SHORT("Release enter.");
263 FALSE_RETURN_V_MSG(mediaCodec_ != nullptr, Status::ERROR_INVALID_STATE, "mediaCodec_ is nullptr");
264 int32_t ret = mediaCodec_->Release();
265 return ret == AVCodecServiceErrCode::AVCS_ERR_OK ? Status::OK : Status::ERROR_INVALID_STATE;
266 }
267
ResetRenderTime()268 void VideoDecoderAdapter::ResetRenderTime()
269 {
270 currentTime_ = -1;
271 }
272
SetCallback(const std::shared_ptr<MediaAVCodec::MediaCodecCallback> & callback)273 int32_t VideoDecoderAdapter::SetCallback(const std::shared_ptr<MediaAVCodec::MediaCodecCallback> &callback)
274 {
275 MEDIA_LOG_D_SHORT("SetCallback enter.");
276 callback_ = callback;
277 FALSE_RETURN_V_MSG(mediaCodec_ != nullptr, AVCodecServiceErrCode::AVCS_ERR_INVALID_VAL, "mediaCodec_ is nullptr");
278 std::shared_ptr<MediaAVCodec::MediaCodecCallback> mediaCodecCallback
279 = std::make_shared<VideoDecoderCallback>(shared_from_this());
280 return mediaCodec_->SetCallback(mediaCodecCallback);
281 }
282
PrepareInputBufferQueue()283 void VideoDecoderAdapter::PrepareInputBufferQueue()
284 {
285 if (inputBufferQueue_ != nullptr && inputBufferQueue_-> GetQueueSize() > 0) {
286 MEDIA_LOG_W_SHORT("InputBufferQueue already create");
287 return;
288 }
289 inputBufferQueue_ = AVBufferQueue::Create(0,
290 MemoryType::UNKNOWN_MEMORY, VIDEO_INPUT_BUFFER_QUEUE_NAME, true);
291 inputBufferQueueProducer_ = inputBufferQueue_->GetProducer();
292 inputBufferQueueConsumer_ = inputBufferQueue_->GetConsumer();
293 isRenderStarted_ = false;
294 }
295
GetBufferQueueProducer()296 sptr<AVBufferQueueProducer> VideoDecoderAdapter::GetBufferQueueProducer()
297 {
298 return inputBufferQueueProducer_;
299 }
300
GetBufferQueueConsumer()301 sptr<AVBufferQueueConsumer> VideoDecoderAdapter::GetBufferQueueConsumer()
302 {
303 return inputBufferQueueConsumer_;
304 }
305
AquireAvailableInputBuffer()306 void VideoDecoderAdapter::AquireAvailableInputBuffer()
307 {
308 AVCodecTrace trace("VideoDecoderAdapter::AquireAvailableInputBuffer");
309 if (inputBufferQueueConsumer_ == nullptr) {
310 MEDIA_LOG_E_SHORT("inputBufferQueueConsumer_ is null");
311 return;
312 }
313 std::unique_lock<std::mutex> lock(mutex_);
314 std::shared_ptr<AVBuffer> tmpBuffer;
315 if (inputBufferQueueConsumer_->AcquireBuffer(tmpBuffer) == Status::OK) {
316 if (fileType_ == static_cast<int32_t>(FileType::AVI)) {
317 GetInputBufferDts(tmpBuffer);
318 }
319 FALSE_RETURN_MSG(tmpBuffer->meta_ != nullptr, "tmpBuffer is nullptr.");
320 int32_t metaIndex;
321 FALSE_RETURN_MSG(tmpBuffer->meta_->GetData(Tag::REGULAR_TRACK_ID, metaIndex), "get index failed.");
322 uint32_t index = static_cast<uint32_t>(metaIndex);
323 if (tmpBuffer->flag_ & (uint32_t)(Plugins::AVBufferFlag::EOS)) {
324 tmpBuffer->memory_->SetSize(0);
325 }
326 FALSE_RETURN_MSG(mediaCodec_ != nullptr, "mediaCodec_ is nullptr.");
327 if (!isRenderStarted_.load() && !(tmpBuffer->flag_& static_cast<uint32_t>(Plugins::AVBufferFlag::EOS))) {
328 MEDIA_LOG_I("AquireAvailableInputBuffer for first frame, index: %{public}u, bufferid: %{public}" PRIu64
329 ", pts: %{public}" PRIu64", flag: %{public}u", index, tmpBuffer->GetUniqueId(),
330 tmpBuffer->pts_, tmpBuffer->flag_);
331 isRenderStarted_ = true;
332 }
333 int32_t ret = mediaCodec_->QueueInputBuffer(index);
334 if (ret != ERR_OK) {
335 MEDIA_LOG_E_SHORT("QueueInputBuffer failed, index: %{public}u, bufferid: %{public}" PRIu64
336 ", pts: %{public}" PRIu64", flag: %{public}u, errCode: %{public}d", index, tmpBuffer->GetUniqueId(),
337 tmpBuffer->pts_, tmpBuffer->flag_, ret);
338 if (ret == AVCS_ERR_DECRYPT_FAILED) {
339 eventReceiver_->OnEvent({"video_decoder_adapter", EventType::EVENT_ERROR,
340 MSERR_DRM_VERIFICATION_FAILED});
341 }
342 } else {
343 MEDIA_LOG_D_SHORT("QueueInputBuffer success, index: %{public}u, bufferid: %{public}" PRIu64
344 ", pts: %{public}" PRIu64", flag: %{public}u", index, tmpBuffer->GetUniqueId(),
345 tmpBuffer->pts_, tmpBuffer->flag_);
346 }
347 } else {
348 MEDIA_LOG_E_SHORT("AcquireBuffer failed.");
349 }
350 }
351
GetInputBufferDts(std::shared_ptr<AVBuffer> & inputBuffer)352 void VideoDecoderAdapter::GetInputBufferDts(std::shared_ptr<AVBuffer> &inputBuffer)
353 {
354 FALSE_RETURN_MSG(inputBuffer != nullptr, "inputBuffer is nullptr.");
355 std::unique_lock<std::mutex> lock(dtsQueMutex_);
356 inputBufferDtsQue_.push_back(inputBuffer->dts_);
357 MEDIA_LOG_D("Inputbuffer DTS: " PUBLIC_LOG_D64 " dtsQue_ size: " PUBLIC_LOG_U64,
358 inputBuffer->dts_, static_cast<uint64_t>(inputBufferDtsQue_.size()));
359 }
360
SetOutputBufferPts(std::shared_ptr<AVBuffer> & outputBuffer)361 void VideoDecoderAdapter::SetOutputBufferPts(std::shared_ptr<AVBuffer> &outputBuffer)
362 {
363 FALSE_RETURN_MSG(outputBuffer != nullptr, "outputBuffer is nullptr.");
364 std::unique_lock<std::mutex> lock(dtsQueMutex_);
365 if (!inputBufferDtsQue_.empty()) {
366 outputBuffer->pts_ = inputBufferDtsQue_.front();
367 inputBufferDtsQue_.pop_front();
368 MEDIA_LOG_D("Outputbuffer PTS: " PUBLIC_LOG_D64 " dtsQue_ size: " PUBLIC_LOG_U64,
369 outputBuffer->pts_, static_cast<uint64_t>(inputBufferDtsQue_.size()));
370 } else {
371 MEDIA_LOG_W("DtsQue_ is empty.");
372 outputBuffer->pts_ = outputBuffer->dts_;
373 }
374 }
375
OnInputBufferAvailable(uint32_t index,std::shared_ptr<AVBuffer> buffer)376 void VideoDecoderAdapter::OnInputBufferAvailable(uint32_t index, std::shared_ptr<AVBuffer> buffer)
377 {
378 AVCodecTrace trace("VideoDecoderAdapter::OnInputBufferAvailable");
379 FALSE_RETURN_MSG(buffer != nullptr && buffer->meta_ != nullptr, "meta_ is nullptr.");
380 buffer->meta_->SetData(Tag::REGULAR_TRACK_ID, static_cast<int32_t>(index));
381 if (inputBufferQueueConsumer_ == nullptr) {
382 MEDIA_LOG_E_SHORT("inputBufferQueueConsumer_ is null");
383 return;
384 }
385 std::unique_lock<std::mutex> lock(mutex_);
386 if (inputBufferQueueConsumer_->IsBufferInQueue(buffer)) {
387 if (inputBufferQueueConsumer_->ReleaseBuffer(buffer) != Status::OK) {
388 MEDIA_LOG_E_SHORT("IsBufferInQueue ReleaseBuffer failed. index: %{public}u, bufferid: %{public}" PRIu64
389 ", pts: %{public}" PRIu64", flag: %{public}u", index, buffer->GetUniqueId(),
390 buffer->pts_, buffer->flag_);
391 } else {
392 MEDIA_LOG_D_SHORT("IsBufferInQueue ReleaseBuffer success. index: %{public}u, bufferid: %{public}" PRIu64
393 ", pts: %{public}" PRIu64", flag: %{public}u", index, buffer->GetUniqueId(),
394 buffer->pts_, buffer->flag_);
395 }
396 } else {
397 uint32_t size = inputBufferQueueConsumer_->GetQueueSize() + 1;
398 MEDIA_LOG_D_SHORT("AttachBuffer enter. index: %{public}u, size: %{public}u , bufferid: %{public}" PRIu64,
399 index, size, buffer->GetUniqueId());
400 inputBufferQueueConsumer_->SetQueueSizeAndAttachBuffer(size, buffer, false);
401 bufferVector_.push_back(buffer);
402 }
403 }
404
OnError(MediaAVCodec::AVCodecErrorType errorType,int32_t errorCode)405 void VideoDecoderAdapter::OnError(MediaAVCodec::AVCodecErrorType errorType, int32_t errorCode)
406 {
407 FALSE_RETURN_MSG(callback_ != nullptr, "OnError callback_ is nullptr");
408 callback_->OnError(errorType, errorCode);
409 }
410
OnOutputFormatChanged(const MediaAVCodec::Format & format)411 void VideoDecoderAdapter::OnOutputFormatChanged(const MediaAVCodec::Format &format)
412 {
413 FALSE_RETURN_MSG(callback_ != nullptr, "OnOutputFormatChanged callback_ is nullptr");
414 callback_->OnOutputFormatChanged(format);
415 }
416
OnOutputBufferAvailable(uint32_t index,std::shared_ptr<AVBuffer> buffer)417 void VideoDecoderAdapter::OnOutputBufferAvailable(uint32_t index, std::shared_ptr<AVBuffer> buffer)
418 {
419 AVCodecTrace trace("VideoDecoderAdapter::OnOutputBufferAvailable");
420 if (buffer != nullptr) {
421 MEDIA_LOG_D_SHORT("OnOutputBufferAvailable start. index: %{public}u, bufferid: %{public}" PRIu64
422 ", pts: %{public}" PRIu64 ", flag: %{public}u", index, buffer->GetUniqueId(), buffer->pts_, buffer->flag_);
423 } else {
424 MEDIA_LOG_D_SHORT("OnOutputBufferAvailable start. buffer is nullptr, index: %{public}u", index);
425 }
426 FALSE_RETURN_MSG(buffer != nullptr, "buffer is nullptr");
427 if (fileType_ == static_cast<int32_t>(FileType::AVI)) {
428 SetOutputBufferPts(buffer);
429 }
430 FALSE_RETURN_MSG(callback_ != nullptr, "callback_ is nullptr");
431 callback_->OnOutputBufferAvailable(index, buffer);
432 }
433
GetOutputFormat(Format & format)434 int32_t VideoDecoderAdapter::GetOutputFormat(Format &format)
435 {
436 FALSE_RETURN_V_MSG(mediaCodec_ != nullptr, AVCodecServiceErrCode::AVCS_ERR_INVALID_VAL,
437 "GetOutputFormat mediaCodec_ is nullptr");
438 return mediaCodec_->GetOutputFormat(format);
439 }
440
ReleaseOutputBuffer(uint32_t index,bool render,int64_t pts)441 int32_t VideoDecoderAdapter::ReleaseOutputBuffer(uint32_t index, bool render, int64_t pts)
442 {
443 AVCodecTrace trace("VideoDecoderAdapter::ReleaseOutputBuffer pts " + std::to_string(pts) + " " +
444 std::to_string(render));
445 FALSE_RETURN_V(mediaCodec_ != nullptr, 0);
446 FALSE_RETURN_V_NOLOG(!isPerfRecEnabled_, ReleaseOutputBufferWithPerfRecord(index, render));
447 mediaCodec_->ReleaseOutputBuffer(index, render);
448 return 0;
449 }
450
SetPerfRecEnabled(bool isPerfRecEnabled)451 Status VideoDecoderAdapter::SetPerfRecEnabled(bool isPerfRecEnabled)
452 {
453 isPerfRecEnabled_ = isPerfRecEnabled;
454 return Status::OK;
455 }
456
ReleaseOutputBufferWithPerfRecord(uint32_t index,bool render)457 int32_t VideoDecoderAdapter::ReleaseOutputBufferWithPerfRecord(uint32_t index, bool render)
458 {
459 int64_t renderTime = CALC_EXPR_TIME_MS(mediaCodec_->ReleaseOutputBuffer(index, render));
460 FALSE_RETURN_V_MSG(eventReceiver_ != nullptr, 0, "Report perf failed, callback is nullptr");
461 FALSE_RETURN_V_NOLOG(perfRecorder_.Record(renderTime) == PerfRecorder::FULL, 0);
462 eventReceiver_->
463 OnDfxEvent({ "VRNDR", DfxEventType::DFX_INFO_PERF_REPORT, perfRecorder_.GetMainPerfData() });
464 perfRecorder_.Reset();
465 return 0;
466 }
467
RenderOutputBufferAtTime(uint32_t index,int64_t renderTimestampNs,int64_t pts)468 int32_t VideoDecoderAdapter::RenderOutputBufferAtTime(uint32_t index, int64_t renderTimestampNs, int64_t pts)
469 {
470 AVCodecTrace trace("RenderOutputBufferAtTime pts " + std::to_string(pts) + " time " +
471 std::to_string(renderTimestampNs));
472 MEDIA_LOG_D_SHORT("VideoDecoderAdapter::RenderOutputBufferAtTime");
473 FALSE_RETURN_V_MSG(mediaCodec_ != nullptr, AVCodecServiceErrCode::AVCS_ERR_INVALID_VAL, "mediaCodec_ is nullptr");
474 mediaCodec_->RenderOutputBufferAtTime(index, renderTimestampNs);
475 return 0;
476 }
477
SetOutputSurface(sptr<Surface> videoSurface)478 int32_t VideoDecoderAdapter::SetOutputSurface(sptr<Surface> videoSurface)
479 {
480 MEDIA_LOG_I_SHORT("VideoDecoderAdapter::SetOutputSurface");
481 FALSE_RETURN_V_MSG(mediaCodec_ != nullptr, AVCodecServiceErrCode::AVCS_ERR_INVALID_VAL, "mediaCodec_ is nullptr");
482
483 if (videoSurface == nullptr) {
484 InitDefaultSurface();
485 return mediaCodec_->SetOutputSurface(producerSurface_);
486 }
487
488 auto status = mediaCodec_->SetOutputSurface(videoSurface);
489 FALSE_RETURN_V_NOLOG(status != MSERR_OK, status);
490 producerSurface_ = nullptr;
491 consumerSurface_ = nullptr;
492 return MSERR_OK;
493 }
494
InitDefaultSurface()495 void VideoDecoderAdapter::InitDefaultSurface()
496 {
497 MEDIA_LOG_D("InitDefaultSurface enter");
498 consumerSurface_ = Surface::CreateSurfaceAsConsumer("VirtualVideoSurface");
499 FALSE_RETURN_MSG(consumerSurface_ != nullptr, "InitSurface create consumer surface failed.");
500
501 GSError err = consumerSurface_->SetDefaultUsage(DECODER_USAGE);
502 FALSE_RETURN_MSG(err == GSERROR_OK, "InitSurface SetDefaultUsage failed.");
503 sptr<IBufferConsumerListener> listener = new VideoConsumerListener(consumerSurface_);
504 err = consumerSurface_->RegisterConsumerListener(listener);
505 FALSE_RETURN_MSG(err == GSERROR_OK, "InitSurface RegisterConsumerListener failed.");
506
507 sptr<IBufferProducer> producer = consumerSurface_->GetProducer();
508 producerSurface_ = Surface::CreateSurfaceAsProducer(producer);
509 FALSE_RETURN_MSG(producerSurface_ != nullptr, "InitSurface create producer surface failed.");
510 }
511
SetDecryptConfig(const sptr<DrmStandard::IMediaKeySessionService> & keySession,const bool svpFlag)512 int32_t VideoDecoderAdapter::SetDecryptConfig(const sptr<DrmStandard::IMediaKeySessionService> &keySession,
513 const bool svpFlag)
514 {
515 #ifdef SUPPORT_DRM
516 if (mediaCodec_ == nullptr) {
517 MEDIA_LOG_E_SHORT("mediaCodec_ is nullptr");
518 return AVCodecServiceErrCode::AVCS_ERR_INVALID_VAL;
519 }
520 if (keySession == nullptr) {
521 MEDIA_LOG_E_SHORT("keySession is nullptr");
522 return AVCodecServiceErrCode::AVCS_ERR_INVALID_VAL;
523 }
524 return mediaCodec_->SetDecryptConfig(keySession, svpFlag);
525 #else
526 return 0;
527 #endif
528 }
529
SetEventReceiver(const std::shared_ptr<Pipeline::EventReceiver> & receiver)530 void VideoDecoderAdapter::SetEventReceiver(const std::shared_ptr<Pipeline::EventReceiver> &receiver)
531 {
532 eventReceiver_ = receiver;
533 }
534
SetCallingInfo(int32_t appUid,int32_t appPid,std::string bundleName,uint64_t instanceId)535 void VideoDecoderAdapter::SetCallingInfo(int32_t appUid, int32_t appPid, std::string bundleName, uint64_t instanceId)
536 {
537 appUid_ = appUid;
538 appPid_ = appPid;
539 bundleName_ = bundleName;
540 instanceId_ = instanceId;
541 }
542
OnDumpInfo(int32_t fd)543 void VideoDecoderAdapter::OnDumpInfo(int32_t fd)
544 {
545 MEDIA_LOG_D_SHORT("VideoDecoderAdapter::OnDumpInfo called.");
546 std::string dumpString;
547 dumpString += "VideoDecoderAdapter media codec name is:" + mediaCodecName_ + "\n";
548 if (inputBufferQueue_ != nullptr) {
549 dumpString += "VideoDecoderAdapter buffer size is:" + std::to_string(inputBufferQueue_->GetQueueSize()) + "\n";
550 }
551 if (fd < 0) {
552 MEDIA_LOG_E_SHORT("VideoDecoderAdapter::OnDumpInfo fd is invalid.");
553 return;
554 }
555 int ret = write(fd, dumpString.c_str(), dumpString.size());
556 if (ret < 0) {
557 MEDIA_LOG_E_SHORT("VideoDecoderAdapter::OnDumpInfo write failed.");
558 return;
559 }
560 }
561
NotifyMemoryExchange(bool exchangeFlag)562 void VideoDecoderAdapter::NotifyMemoryExchange(bool exchangeFlag)
563 {
564 FALSE_RETURN_MSG(mediaCodec_ != nullptr, "mediaCodec_ is nullptr");
565 AVCodecTrace trace("VideoDecoderAdapter::NotifyMemoryExchange " + std::to_string(exchangeFlag));
566 MEDIA_LOG_I("Memory exchange %{public}d begin", exchangeFlag);
567 mediaCodec_->NotifyMemoryExchange(exchangeFlag);
568 MEDIA_LOG_I("Memory exchange %{public}d end", exchangeFlag);
569 }
570 } // namespace Media
571 } // namespace OHOS
572