1 /*
2 * Copyright (c) 2025-2025 Shenzhen Kaihong Digital Industry Development 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 "audio_avcodec_decoder.h"
17 #include "avcodec_codec_name.h"
18 #include "avcodec_errors.h"
19 #include "common/common_macro.h"
20 #include "common/media_log.h"
21 #include "const_def.h"
22 #include "sharing_sink_hisysevent.h"
23
24 namespace OHOS {
25 namespace Sharing {
AudioAvCodecDecoder()26 AudioAvCodecDecoder::AudioAvCodecDecoder()
27 {
28 SHARING_LOGD("trace");
29 }
30
~AudioAvCodecDecoder()31 AudioAvCodecDecoder::~AudioAvCodecDecoder()
32 {
33 Release();
34 }
35
Init(const AudioTrack & audioTrack)36 int32_t AudioAvCodecDecoder::Init(const AudioTrack &audioTrack)
37 {
38 SHARING_LOGD("trace.");
39 if (!InitDecoder() || !SetAudioCallback() || !SetDecoderFormat(audioTrack)) {
40 return ERROR_DECODER_INIT;
41 }
42 return 0;
43 }
44
InitDecoder()45 bool AudioAvCodecDecoder::InitDecoder()
46 {
47 SHARING_LOGD("trace.");
48 if (audioDecoder_ != nullptr) {
49 SHARING_LOGE("audio decoder already init.");
50 return true;
51 }
52 audioDecoder_ = MediaAVCodec::AudioDecoderFactory::CreateByName(
53 (MediaAVCodec::AVCodecCodecName::AUDIO_DECODER_AAC_NAME).data());
54 if (audioDecoder_ == nullptr) {
55 SHARING_LOGE("create audio decoder failed.");
56 WfdSinkHiSysEvent::GetInstance().ReportError(__func__, "", SinkStage::AUDIO_DECODE,
57 SinkErrorCode::WIFI_DISPLAY_AUDIO_DECODE_FAILED);
58 return false;
59 }
60 SHARING_LOGI("init audio decoder success.");
61 return true;
62 }
63
SetAudioCallback()64 bool AudioAvCodecDecoder::SetAudioCallback()
65 {
66 SHARING_LOGD("trace.");
67 RETURN_FALSE_IF_NULL(audioDecoder_);
68 auto ret = audioDecoder_->SetCallback(std::static_pointer_cast<AudioAvCodecDecoder>(shared_from_this()));
69 if (ret != MediaAVCodec::AVCS_ERR_OK) {
70 SHARING_LOGE("set audio decoder callback failed!");
71 return false;
72 }
73 SHARING_LOGD("set audio decoder callback success");
74 return true;
75 }
76
Start()77 bool AudioAvCodecDecoder::Start()
78 {
79 SHARING_LOGD("trace.");
80 if (isRunning_) {
81 SHARING_LOGW(" decoder is running.");
82 return true;
83 }
84
85 auto audioDecoder = GetDecoder();
86 RETURN_FALSE_IF_NULL(audioDecoder);
87 auto ret = audioDecoder->Start();
88 if (ret != MediaAVCodec::AVCS_ERR_OK) {
89 SHARING_LOGE("start decoder failed");
90 WfdSinkHiSysEvent::GetInstance().ReportError(__func__, "", SinkStage::AUDIO_DECODE,
91 SinkErrorCode::WIFI_DISPLAY_AUDIO_DECODE_FAILED);
92 return false;
93 }
94 isRunning_ = true;
95 StartRender();
96 return true;
97 }
98
Stop()99 void AudioAvCodecDecoder::Stop()
100 {
101 SHARING_LOGD("trace.");
102 if (!isRunning_) {
103 SHARING_LOGE("decoder is not running");
104 return;
105 }
106 if (StopDecoder()) {
107 isRunning_ = false;
108 }
109 }
110
Release()111 void AudioAvCodecDecoder::Release()
112 {
113 SHARING_LOGD("trace.");
114 if (audioDecoder_ != nullptr) {
115 audioDecoder_->Release();
116 audioDecoder_->Reset();
117 }
118 }
119
StopDecoder()120 bool AudioAvCodecDecoder::StopDecoder()
121 {
122 SHARING_LOGD("trace.");
123 auto audioDecoder = GetDecoder();
124 RETURN_FALSE_IF_NULL(audioDecoder);
125
126 StopRender();
127 auto ret = audioDecoder->Flush();
128 if (ret != MediaAVCodec::AVCS_ERR_OK) {
129 SHARING_LOGE("Flush audioDecoder failed");
130 return false;
131 }
132 ret = audioDecoder->Stop();
133 if (ret != MediaAVCodec::AVCS_ERR_OK) {
134 SHARING_LOGE("Stop audioDecoder failed");
135 return false;
136 }
137 ret = audioDecoder->Reset();
138 if (ret != MediaAVCodec::AVCS_ERR_OK) {
139 SHARING_LOGE("Reset audioDecoder failed");
140 return false;
141 }
142 SHARING_LOGD("StopDecoder Success.");
143 return true;
144 }
145
SetDecoderFormat(const AudioTrack & audioTrack)146 bool AudioAvCodecDecoder::SetDecoderFormat(const AudioTrack &audioTrack)
147 {
148 SHARING_LOGI("trace.");
149 auto audioDecoder = GetDecoder();
150 RETURN_FALSE_IF_NULL(audioDecoder);
151
152 int32_t sampleRate =
153 audioTrack.sampleRate == 0 ? AUDIO_DECODE_DEFAULT_SAMPLERATE : static_cast<int32_t>(audioTrack.sampleRate);
154 int32_t channelCount =
155 audioTrack.channels == 0 ? AUDIO_DECODE_DEFAULT_CHANNEL_COUNT : static_cast<int32_t>(audioTrack.channels);
156
157 MediaAVCodec::Format format;
158 format.PutIntValue("sample_rate", sampleRate);
159 format.PutIntValue("channel_count", channelCount);
160 format.PutIntValue("audio_sample_format", static_cast<int32_t>(MediaAVCodec::AudioSampleFormat::SAMPLE_S16LE));
161 int32_t ret = audioDecoder->Configure(format);
162 if (ret != MediaAVCodec::AVCS_ERR_OK) {
163 WfdSinkHiSysEvent::GetInstance().ReportError(__func__, "", SinkStage::AUDIO_DECODE,
164 SinkErrorCode::WIFI_DISPLAY_AUDIO_DECODE_FAILED);
165 SHARING_LOGE("Configure decoder format failed, Error code %{public}d.", ret);
166 return false;
167 }
168 ret = audioDecoder->Prepare();
169 if (ret != MediaAVCodec::AVCS_ERR_OK) {
170 SHARING_LOGE("Configure decoder prepare failed, Error code %{public}d.", ret);
171 return false;
172 }
173 return true;
174 }
175
OnFrame(const Frame::Ptr & frame)176 void AudioAvCodecDecoder::OnFrame(const Frame::Ptr &frame)
177 {
178 SHARING_LOGD("trace.");
179 auto audioDecoder = GetDecoder();
180 RETURN_IF_NULL(audioDecoder);
181 int32_t bufferIndex = 0;
182 std::shared_ptr<MediaAVCodec::AVSharedMemory> inputBuffer;
183 {
184 std::unique_lock<std::mutex> lock(inputBufferMutex_);
185 if (inBufferQueue_.empty()) {
186 inCond_.wait_for(lock, std::chrono::milliseconds(AUDIO_DECODE_WAIT_MILLISECONDS),
187 [this]() { return (!inBufferQueue_.empty()); });
188 }
189 if (inBufferQueue_.empty()) {
190 SHARING_LOGW("Index queue is empty.");
191 WfdSinkHiSysEvent::GetInstance().ReportError(__func__, "", SinkStage::AUDIO_DECODE,
192 SinkErrorCode::WIFI_DISPLAY_AUDIO_DECODE_TIMEOUT);
193 return;
194 }
195 auto pair_data = inBufferQueue_.front();
196 bufferIndex = pair_data.first;
197 inputBuffer = pair_data.second;
198 inBufferQueue_.pop();
199 }
200
201 if ((inputBuffer == nullptr) || frame == nullptr || (frame->Data() == nullptr)) {
202 SHARING_LOGW("GetInputBuffer or GetFrameBuffer failed.");
203 return;
204 }
205 if (inputBuffer->GetSize() < frame->Size()) {
206 SHARING_LOGW("GetInputBuffer size invalid.");
207 return;
208 }
209 if (memcpy_s(inputBuffer->GetBase(), inputBuffer->GetSize(), frame->Data(), frame->Size()) != EOK) {
210 SHARING_LOGW("Copy data failed.");
211 return;
212 }
213 MediaAVCodec::AVCodecBufferInfo bufferInfo = {
214 .presentationTimeUs = frame->Pts(),
215 .size = static_cast<int32_t>(frame->Size()),
216 .offset = 0,
217 };
218 auto bufferFlag = MediaAVCodec::AVCODEC_BUFFER_FLAG_CODEC_DATA;
219 WfdSinkHiSysEvent::GetInstance().RecordMediaDecodeStartTime(MediaReportType::AUDIO, bufferInfo.presentationTimeUs);
220 int32_t ret = audioDecoder->QueueInputBuffer(bufferIndex, bufferInfo, bufferFlag);
221 if (ret != MediaAVCodec::AVCS_ERR_OK) {
222 SHARING_LOGE("Queue input buffer fail. Error code %{public}d.", ret);
223 }
224 }
225
OnError(MediaAVCodec::AVCodecErrorType errorType,int32_t errorCode)226 void AudioAvCodecDecoder::OnError(MediaAVCodec::AVCodecErrorType errorType, int32_t errorCode)
227 {
228 SHARING_LOGE("onError, errorCode = %{public}d", errorCode);
229 WfdSinkHiSysEvent::GetInstance().ReportError(__func__, "", SinkStage::AUDIO_DECODE,
230 SinkErrorCode::WIFI_DISPLAY_AUDIO_DECODE_FAILED);
231 }
232
OnInputBufferAvailable(uint32_t index,std::shared_ptr<MediaAVCodec::AVSharedMemory> buffer)233 void AudioAvCodecDecoder::OnInputBufferAvailable(uint32_t index, std::shared_ptr<MediaAVCodec::AVSharedMemory> buffer)
234 {
235 SHARING_LOGD("trace.");
236 {
237 std::lock_guard<std::mutex> lock(inputBufferMutex_);
238 if (buffer == nullptr) {
239 return;
240 }
241 inBufferQueue_.push({index, buffer});
242 }
243 inCond_.notify_all();
244 }
245
OnOutputBufferAvailable(uint32_t index,MediaAVCodec::AVCodecBufferInfo info,MediaAVCodec::AVCodecBufferFlag flag,std::shared_ptr<MediaAVCodec::AVSharedMemory> buffer)246 void AudioAvCodecDecoder::OnOutputBufferAvailable(uint32_t index, MediaAVCodec::AVCodecBufferInfo info,
247 MediaAVCodec::AVCodecBufferFlag flag,
248 std::shared_ptr<MediaAVCodec::AVSharedMemory> buffer)
249 {
250 SHARING_LOGD("trace.");
251 auto audioDecoder = GetDecoder();
252 RETURN_IF_NULL(audioDecoder);
253 if (flag & MediaAVCodec::AVCODEC_BUFFER_FLAG_EOS) {
254 SHARING_LOGE("flag is eos.");
255 return;
256 }
257 if (!buffer) {
258 SHARING_LOGE("buffer is null");
259 return;
260 }
261 if (info.size <= 0 || info.size > buffer->GetSize()) {
262 SHARING_LOGE("Codec output info error, AVCodec info: size %{public}d, memory size %{public}d.", info.size,
263 buffer->GetSize());
264 return;
265 }
266 WfdSinkHiSysEvent::GetInstance().MediaDecodeTimProc(MediaReportType::AUDIO, info.presentationTimeUs);
267
268 std::chrono::microseconds nowUs =
269 std::chrono::duration_cast<std::chrono::microseconds>(std::chrono::system_clock::now().time_since_epoch());
270 int64_t nowTimeUs = nowUs.count();
271 if (firstTimestampUs_ == 0) {
272 firstTimestampUs_ = info.presentationTimeUs;
273 }
274
275 auto frameBuffer = FrameImpl::Create();
276 frameBuffer->SetSize(static_cast<uint32_t>(info.size));
277 frameBuffer->codecId_ = CODEC_AAC;
278 frameBuffer->pts_ = static_cast<uint64_t>(info.presentationTimeUs);
279 frameBuffer->Assign((char *)buffer->GetBase(), info.size);
280 frameBuffer->index = index;
281 frameBuffer->isNeedDrop = IsNeedDropFrame(nowTimeUs);
282 Render(frameBuffer);
283 }
284
ReleaseOutputBuffer(uint32_t index)285 bool AudioAvCodecDecoder::ReleaseOutputBuffer(uint32_t index)
286 {
287 std::lock_guard<std::mutex> lock(decoderMutex_);
288 if (audioDecoder_ == nullptr) {
289 return false;
290 }
291 int32_t ret = audioDecoder_->ReleaseOutputBuffer(index);
292 if (ret != MediaAVCodec::AVCS_ERR_OK) {
293 SHARING_LOGE("ReleaseOutputBuffer fail. Error code %{public}d.", ret);
294 }
295 return ret == MediaAVCodec::AVCS_ERR_OK;
296 }
297
RenderOutBuffer()298 void AudioAvCodecDecoder::RenderOutBuffer()
299 {
300 while (isRenderReady_.load()) {
301 std::shared_ptr<FrameImpl> frameBuffer;
302 {
303 std::unique_lock<std::mutex> lock(renderBufferMutex_);
304 if (renderBuffer_.empty()) {
305 renderCond_.wait_for(lock, std::chrono::milliseconds(NEXT_FRAME_WAIT_TIME));
306 continue;
307 }
308 frameBuffer = renderBuffer_.front();
309 renderBuffer_.pop();
310 }
311
312 if (frameBuffer->isNeedDrop) {
313 SHARING_LOGE("Audio RenderBuffer is droped.");
314 ReleaseOutputBuffer(frameBuffer->index);
315 lastPlayPts_ = static_cast<int64_t>(frameBuffer->pts_);
316 continue;
317 }
318 DeliverFrame(frameBuffer);
319 ReleaseOutputBuffer(frameBuffer->index);
320 lastPlayPts_ = static_cast<int64_t>(frameBuffer->pts_);
321 }
322 }
323
Render(std::shared_ptr<FrameImpl> frameBuffer)324 void AudioAvCodecDecoder::Render(std::shared_ptr<FrameImpl> frameBuffer)
325 {
326 std::lock_guard<std::mutex> lock(renderBufferMutex_);
327 if (!frameBuffer) {
328 SHARING_LOGE("frameBuffer is null");
329 return;
330 }
331 if (!isRenderReady_.load()) {
332 SHARING_LOGE("Failed to send data.");
333 ReleaseOutputBuffer(frameBuffer->index);
334 return;
335 }
336 if (renderBuffer_.size() > MAX_BUFFER_SIZE) {
337 ClearRenderBufferQueue();
338 }
339
340 renderBuffer_.push(frameBuffer);
341 renderCond_.notify_all();
342 }
343
StopRender()344 bool AudioAvCodecDecoder::StopRender()
345 {
346 SHARING_LOGD("Stop Render");
347 isRenderReady_ = false;
348 renderCond_.notify_all();
349 if (renderThread_.joinable()) {
350 renderThread_.join();
351 }
352 std::lock_guard<std::mutex> lock(renderBufferMutex_);
353 ClearRenderBufferQueue();
354 return true;
355 }
356
ClearRenderBufferQueue()357 void AudioAvCodecDecoder::ClearRenderBufferQueue()
358 {
359 while (!renderBuffer_.empty()) {
360 auto frameBuffer = renderBuffer_.front();
361 ReleaseOutputBuffer(frameBuffer->index);
362 renderBuffer_.pop();
363 }
364 }
365
StartRender()366 bool AudioAvCodecDecoder::StartRender()
367 {
368 isRenderReady_ = true;
369 renderThread_ = std::thread([this] {
370 this->RenderOutBuffer();
371 });
372 std::string name = "AudioSpeakerRun";
373 pthread_setname_np(renderThread_.native_handle(), name.c_str());
374 return true;
375 }
376
GetDecoderTimestamp()377 int64_t AudioAvCodecDecoder::GetDecoderTimestamp()
378 {
379 int64_t timestamp = 0;
380 if (firstTimestampUs_ == 0) {
381 return timestamp;
382 }
383
384 timestamp = lastPlayPts_ - audioLatency_.load();
385 return timestamp;
386 }
387
IsNeedDropFrame(int64_t nowTimeUs)388 bool AudioAvCodecDecoder::IsNeedDropFrame(int64_t nowTimeUs)
389 {
390 std::lock_guard<std::mutex> lock(decoderMutex_);
391 if (isForceDrop_.load() && (nowTimeUs - lastDropTimeUs_ > AUDIO_DECODE_DROP_INTERVAL)) {
392 isForceDrop_ = false;
393 lastDropTimeUs_ = nowTimeUs;
394 return true;
395 }
396 return false;
397 }
398
DropOneFrame()399 void AudioAvCodecDecoder::DropOneFrame()
400 {
401 std::lock_guard<std::mutex> lock(decoderMutex_);
402 isForceDrop_ = true;
403 }
404
OnOutputFormatChanged(const MediaAVCodec::Format & format)405 void AudioAvCodecDecoder::OnOutputFormatChanged(const MediaAVCodec::Format &format)
406 {
407 SHARING_LOGD("trace.");
408 }
409
GetDecoder()410 std::shared_ptr<MediaAVCodec::AVCodecAudioDecoder> AudioAvCodecDecoder::GetDecoder()
411 {
412 std::lock_guard<std::mutex> lock(decoderMutex_);
413 return audioDecoder_;
414 }
415 } // namespace Sharing
416 } // namespace OHOS