• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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