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