• 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 
23 namespace OHOS {
24 namespace Sharing {
AudioAvCodecDecoder()25 AudioAvCodecDecoder::AudioAvCodecDecoder()
26 {
27     SHARING_LOGD("tracs");
28 }
29 
~AudioAvCodecDecoder()30 AudioAvCodecDecoder::~AudioAvCodecDecoder()
31 {
32     Release();
33 }
34 
Init(const AudioTrack & audioTrack)35 int32_t AudioAvCodecDecoder::Init(const AudioTrack &audioTrack)
36 {
37     SHARING_LOGD("trace.");
38     if (!InitDecoder() || !SetAudioCallback() || !SetDecoderFormat(audioTrack)) {
39         return ERROR_DECODER_INIT;
40     }
41     return 0;
42 }
43 
InitDecoder()44 bool AudioAvCodecDecoder::InitDecoder()
45 {
46     SHARING_LOGD("trace.");
47     if (audioDecoder_ != nullptr) {
48         SHARING_LOGE("audio decoder already init.");
49         return true;
50     }
51     audioDecoder_ = MediaAVCodec::AudioDecoderFactory::CreateByName(
52         (MediaAVCodec::AVCodecCodecName::AUDIO_DECODER_AAC_NAME).data());
53     if (audioDecoder_ == nullptr) {
54         SHARING_LOGE("create audio decoder failed.");
55         return false;
56     }
57     SHARING_LOGI("init audio decoder success.");
58     return true;
59 }
60 
SetAudioCallback()61 bool AudioAvCodecDecoder::SetAudioCallback()
62 {
63     SHARING_LOGD("trace.");
64     RETURN_FALSE_IF_NULL(audioDecoder_);
65     auto ret = audioDecoder_->SetCallback(std::static_pointer_cast<AudioAvCodecDecoder>(shared_from_this()));
66     if (ret != MediaAVCodec::AVCS_ERR_OK) {
67         SHARING_LOGE("set audio decoder callback failed!");
68         return false;
69     }
70     SHARING_LOGD("set audio decoder callback success");
71     return true;
72 }
73 
Start()74 bool AudioAvCodecDecoder::Start()
75 {
76     SHARING_LOGD("trace.");
77     if (isRunning_) {
78         SHARING_LOGW(" decoder is running.");
79         return true;
80     }
81 
82     auto audioDecoder = GetDecoder();
83     RETURN_FALSE_IF_NULL(audioDecoder);
84     auto ret = audioDecoder->Start();
85     if (ret != MediaAVCodec::AVCS_ERR_OK) {
86         SHARING_LOGE("start decoder failed");
87         return false;
88     }
89     isRunning_ = true;
90     return true;
91 }
92 
Stop()93 void AudioAvCodecDecoder::Stop()
94 {
95     SHARING_LOGD("trace.");
96     if (!isRunning_) {
97         SHARING_LOGE("decoder is not running");
98         return;
99     }
100     if (StopDecoder()) {
101         isRunning_ = false;
102         isFirstFrame_ = false;
103     }
104 }
105 
Release()106 void AudioAvCodecDecoder::Release()
107 {
108     SHARING_LOGD("trace.");
109     if (audioDecoder_ != nullptr) {
110         audioDecoder_->Release();
111         audioDecoder_->Reset();
112     }
113 }
114 
StopDecoder()115 bool AudioAvCodecDecoder::StopDecoder()
116 {
117     SHARING_LOGD("trace.");
118     auto audioDecoder = GetDecoder();
119     RETURN_FALSE_IF_NULL(audioDecoder);
120 
121     auto ret = audioDecoder->Flush();
122     if (ret != MediaAVCodec::AVCS_ERR_OK) {
123         SHARING_LOGE("Flush audioDecoder failed");
124         return false;
125     }
126     ret = audioDecoder->Stop();
127     if (ret != MediaAVCodec::AVCS_ERR_OK) {
128         SHARING_LOGE("Stop audioDecoder failed");
129         return false;
130     }
131     ret = audioDecoder->Reset();
132     if (ret != MediaAVCodec::AVCS_ERR_OK) {
133         SHARING_LOGE("Reset audioDecoder failed");
134         return false;
135     }
136     SHARING_LOGD("StopDecoder Success.");
137     return true;
138 }
139 
SetDecoderFormat(const AudioTrack & audioTrack)140 bool AudioAvCodecDecoder::SetDecoderFormat(const AudioTrack &audioTrack)
141 {
142     SHARING_LOGI("trace.");
143     auto audioDecoder = GetDecoder();
144     RETURN_FALSE_IF_NULL(audioDecoder);
145 
146     int32_t sampleRate =
147         audioTrack.sampleRate == 0 ? AUDIO_DECODE_DEFAULT_SAMPLERRATE : static_cast<int32_t>(audioTrack.sampleRate);
148     int32_t channelCount =
149         audioTrack.channels == 0 ? AUDIO_DECODE_DEFAULT_CHANNEL_COUNT : static_cast<int32_t>(audioTrack.channels);
150 
151     MediaAVCodec::Format format;
152     format.PutIntValue("sample_rate", sampleRate);
153     format.PutIntValue("channel_count", channelCount);
154     format.PutIntValue("audio_sample_format", static_cast<int32_t>(MediaAVCodec::AudioSampleFormat::SAMPLE_S16LE));
155     int32_t ret = audioDecoder->Configure(format);
156     if (ret != MediaAVCodec::AVCS_ERR_OK) {
157         SHARING_LOGE("Configure decoder format failed, Error code %{public}d.", ret);
158         return false;
159     }
160     ret = audioDecoder->Prepare();
161     if (ret != MediaAVCodec::AVCS_ERR_OK) {
162         SHARING_LOGE("Configure decoder prepare failed, Error code %{public}d.", ret);
163         return false;
164     }
165     return true;
166 }
167 
OnFrame(const Frame::Ptr & frame)168 void AudioAvCodecDecoder::OnFrame(const Frame::Ptr &frame)
169 {
170     SHARING_LOGD("trace.");
171     auto audioDecoder = GetDecoder();
172     RETURN_IF_NULL(audioDecoder);
173     int32_t bufferIndex = 0;
174     std::shared_ptr<MediaAVCodec::AVSharedMemory> inputBuffer;
175     {
176         std::unique_lock<std::mutex> lock(inputBufferMutex_);
177         if (inBufferQueue_.empty()) {
178             inCond_.wait_for(lock, std::chrono::milliseconds(AUDIO_DECODE_WAIT_MILLISECONDS),
179                              [this]() { return (!inBufferQueue_.empty()); });
180         }
181         if (inBufferQueue_.empty()) {
182             SHARING_LOGW("Index queue is empty.");
183             return;
184         }
185         auto pair_data = inBufferQueue_.front();
186         bufferIndex = pair_data.first;
187         inputBuffer = pair_data.second;
188         inBufferQueue_.pop();
189     }
190 
191     if ((inputBuffer == nullptr) || frame == nullptr || (frame->Data() == nullptr)) {
192         SHARING_LOGW("GetInputBuffer or GetFrameBuffer failed.");
193         return;
194     }
195     if (memcpy_s(inputBuffer->GetBase(), inputBuffer->GetSize(), frame->Data(), frame->Size()) != EOK) {
196         SHARING_LOGW("Copy data failed.");
197         return;
198     }
199     MediaAVCodec::AVCodecBufferInfo bufferInfo = {
200         .presentationTimeUs = frame->Pts(),
201         .size = static_cast<int32_t>(frame->Size()),
202         .offset = 0,
203     };
204     auto bufferFlag = MediaAVCodec::AVCODEC_BUFFER_FLAG_CODEC_DATA;
205     if (isFirstFrame_) {
206         bufferFlag = MediaAVCodec::AVCODEC_BUFFER_FLAG_CODEC_DATA;
207         isFirstFrame_ = false;
208     } else {
209         bufferFlag = MediaAVCodec::AVCODEC_BUFFER_FLAG_CODEC_DATA;
210     }
211     int32_t ret = audioDecoder->QueueInputBuffer(bufferIndex, bufferInfo, bufferFlag);
212     if (ret != MediaAVCodec::AVCS_ERR_OK) {
213         SHARING_LOGE("Queue input buffer fail. Error code %{public}d.", ret);
214     }
215 }
216 
OnError(MediaAVCodec::AVCodecErrorType errorType,int32_t errorCode)217 void AudioAvCodecDecoder::OnError(MediaAVCodec::AVCodecErrorType errorType, int32_t errorCode)
218 {
219     SHARING_LOGE("onError, errorCode = %{public}d", errorCode);
220 }
221 
OnInputBufferAvailable(uint32_t index,std::shared_ptr<MediaAVCodec::AVSharedMemory> buffer)222 void AudioAvCodecDecoder::OnInputBufferAvailable(uint32_t index, std::shared_ptr<MediaAVCodec::AVSharedMemory> buffer)
223 {
224     SHARING_LOGD("trace.");
225     {
226         std::lock_guard<std::mutex> lock(inputBufferMutex_);
227         inBufferQueue_.push({index, buffer});
228     }
229     inCond_.notify_all();
230 }
231 
OnOutputBufferAvailable(uint32_t index,MediaAVCodec::AVCodecBufferInfo info,MediaAVCodec::AVCodecBufferFlag flag,std::shared_ptr<MediaAVCodec::AVSharedMemory> buffer)232 void AudioAvCodecDecoder::OnOutputBufferAvailable(uint32_t index, MediaAVCodec::AVCodecBufferInfo info,
233                                                   MediaAVCodec::AVCodecBufferFlag flag,
234                                                   std::shared_ptr<MediaAVCodec::AVSharedMemory> buffer)
235 {
236     SHARING_LOGD("trace.");
237     auto audioDecoder = GetDecoder();
238     RETURN_IF_NULL(audioDecoder);
239     if (flag & MediaAVCodec::AVCODEC_BUFFER_FLAG_EOS) {
240         SHARING_LOGE("flag is eos.");
241         return;
242     }
243     if (!buffer) {
244         SHARING_LOGE("buffer is null");
245         return;
246     }
247     if (info.size <= 0 || info.size > buffer->GetSize()) {
248         SHARING_LOGE("Codec output info error, AVCodec info: size %{public}d, memory size %{public}d.", info.size,
249                      buffer->GetSize());
250         return;
251     }
252     auto frameBuffer = FrameImpl::Create();
253     frameBuffer->SetSize(static_cast<uint32_t>(info.size));
254     frameBuffer->codecId_ = CODEC_AAC;
255     frameBuffer->pts_ = static_cast<uint32_t>(info.presentationTimeUs);
256     frameBuffer->Assign((char *)buffer->GetBase(), info.size);
257     DeliverFrame(frameBuffer);
258     int32_t ret = audioDecoder->ReleaseOutputBuffer(index);
259     if (ret != MediaAVCodec::AVCS_ERR_OK) {
260         SHARING_LOGE("ReleaseOutputBuffer fail. Error code %{public}d.", ret);
261     }
262 }
263 
OnOutputFormatChanged(const MediaAVCodec::Format & format)264 void AudioAvCodecDecoder::OnOutputFormatChanged(const MediaAVCodec::Format &format)
265 {
266     SHARING_LOGD("trace.");
267 }
268 
GetDecoder()269 std::shared_ptr<MediaAVCodec::AVCodecAudioDecoder> AudioAvCodecDecoder::GetDecoder()
270 {
271     std::lock_guard<std::mutex> lock(decoderMutex_);
272     return audioDecoder_;
273 }
274 } // namespace Sharing
275 } // namespace OHOS