1 /*
2 * Copyright (c) 2020-2021 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
16 #include "player_audio_sink.h"
17 #include "player_sync.h"
18 #include "media_log.h"
19 #include <unistd.h>
20 #include <cmath>
21 #include <sys/time.h>
22
23 namespace OHOS {
24 namespace Media {
25 #define CHECK_FAILED_RETURN(value, target, ret, printfString) \
26 do { \
27 if ((value) != (target)) { \
28 MEDIA_ERR_LOG(" %s ", (printfString != nullptr) ? (printfString) : " "); \
29 return (ret); \
30 } \
31 } while (0)
32
33 #define CHECK_NULL_RETURN(value, ret, printfString) \
34 do { \
35 if ((value) == nullptr) { \
36 MEDIA_ERR_LOG(" %s ", (printfString != nullptr) ? (printfString) : " "); \
37 return (ret); \
38 } \
39 } while (0)
40
41 const int32_t HALF_FACTOR = 2;
42 const int32_t MAX_QUEUE_BUF_NUM = 32;
43 const int32_t MAX_AUDIO_ADAPTER_NUM = 2;
44 const int32_t AUDIO_SAMPLE_WIDTH_BYTE = 2;
45
AudioSink()46 AudioSink::AudioSink()
47 : started_(false), paused_(false), eosSended_(false), rendFrameCnt_(0), lastRendFrameCnt_(0),
48 pauseAfterPlay_(false), syncHdl_(nullptr), renderMode_(RENDER_MODE_NORMAL),
49 rendStartTime_(-1), lastRendPts_(AV_INVALID_PTS), lastRendSysTimeMs_(-1), renderDelay_(0),
50 leftVolume_(0.0f), rightVolume_(0.0f), eosPts_(AV_INVALID_PTS), receivedEos_(false), audioManager_(nullptr),
51 audioAdapter_(nullptr), audioRender_(nullptr), reportedFirstFrame(false), audioStreamType_(0)
52 {
53 ResetRendStartTime();
54 frameCacheQue_.clear();
55 frameReleaseQue_.clear();
56 callBack_.onEventCallback = nullptr;
57 callBack_.priv= nullptr;
58 attr_.sinkType = SINK_TYPE_BUT;
59 attr_.trackId = 0;
60 attr_.audAttr.format = 0;
61 attr_.audAttr.sampleFmt = 0;
62 attr_.audAttr.sampleRate = 0;
63 attr_.audAttr.channel = 0;
64 attr_.audAttr.volume = 0.0;
65 renderPort_.dir = PORT_OUT;
66 renderPort_.portId = 0;
67 renderPort_.portName = nullptr;
68 }
69
~AudioSink()70 AudioSink::~AudioSink()
71 {
72 DeInit();
73 }
74
DeInit()75 void AudioSink::DeInit()
76 {
77 started_ = false;
78 if (frameCacheQue_.size() != 0 || frameReleaseQue_.size()) {
79 MEDIA_ERR_LOG("frames should be released before DeInit!!!");
80 }
81 if (audioAdapter_ != nullptr && audioRender_ != nullptr) {
82 audioAdapter_->DestroyRender(audioAdapter_, audioRender_);
83 }
84 if (audioManager_ != nullptr) {
85 audioManager_->UnloadAdapter(audioManager_, audioAdapter_);
86 }
87 frameCacheQue_.clear();
88 frameReleaseQue_.clear();
89 }
90
Init(SinkAttr & atrr)91 int32_t AudioSink::Init(SinkAttr &atrr)
92 {
93 attr_ = atrr;
94 audioManager_ = GetAudioManagerFuncs();
95 if (audioManager_ == nullptr) {
96 return SINK_GET_DEVICE_FAILED;
97 }
98 int32_t ret = 0;
99 int32_t size = -1;
100 struct AudioAdapterDescriptor *descs = nullptr;
101 audioManager_->GetAllAdapters(audioManager_, &descs, &size);
102 if (size > MAX_AUDIO_ADAPTER_NUM) {
103 return SINK_GET_DEVICE_FAILED;
104 }
105 for (int index = 0; index < size; index++) {
106 struct AudioAdapterDescriptor *desc = &descs[index];
107 for (int port = 0; (desc != nullptr && port < static_cast<int>(desc->portNum)); port++) {
108 if (desc->ports[port].dir == PORT_OUT &&
109 (audioManager_->LoadAdapter(audioManager_, desc, &audioAdapter_)) == 0 && audioAdapter_ != nullptr) {
110 (void)audioAdapter_->InitAllPorts(audioAdapter_);
111 if (memcpy_s(&renderPort_, sizeof(struct AudioPort),
112 &desc->ports[port], sizeof(struct AudioPort)) != 0) {
113 MEDIA_ERR_LOG("memcpy_s failed");
114 }
115 break;
116 }
117 }
118 }
119 if (ret != 0 || audioAdapter_ == nullptr) {
120 MEDIA_ERR_LOG("load audiodevice failed");
121 return SINK_LAOD_DEVICE_FAILED;
122 }
123
124 struct AudioSampleAttributes param;
125 param.sampleRate = attr_.audAttr.sampleRate;
126 param.format = AUDIO_FORMAT_TYPE_PCM_16_BIT;
127 param.channelCount = attr_.audAttr.channel;
128 param.interleaved = false;
129 param.type = (audioStreamType_ == 1) ? AUDIO_IN_COMMUNICATION : AUDIO_IN_MEDIA;
130 MEDIA_INFO_LOG("sampleRate:%u, channelCount:%u", param.sampleRate, param.channelCount);
131
132 struct AudioDeviceDescriptor deviceDesc;
133 deviceDesc.portId = 0;
134 deviceDesc.pins = PIN_OUT_SPEAKER;
135 deviceDesc.desc = nullptr;
136 ret = audioAdapter_->CreateRender(audioAdapter_, &deviceDesc, ¶m, &audioRender_);
137 if (ret != 0 || audioRender_ == nullptr) {
138 MEDIA_ERR_LOG("AudioDeviceCreateRender failed");
139 return SINK_OPEN_STREAM_FAILED;
140 }
141 MEDIA_DEBUG_LOG("init success");
142 return SINK_SUCCESS;
143 }
144
ResetRendStartTime()145 void AudioSink::ResetRendStartTime()
146 {
147 lastRendFrameCnt_ = 0;
148 lastRendPts_ = AV_INVALID_PTS;
149 rendStartTime_ = AV_INVALID_PTS;
150 }
151
GetStatus(AudioSinkStatus & status)152 void AudioSink::GetStatus(AudioSinkStatus &status)
153 {
154 status.audFrameCount = rendFrameCnt_;
155 }
156
UpdateAudioPts(int64_t lastPts,int64_t & timestamp,CodecBuffer & renderFrame)157 void AudioSink::UpdateAudioPts(int64_t lastPts, int64_t ×tamp, CodecBuffer &renderFrame)
158 {
159 if (renderFrame.timeStamp == -1) {
160 float sampleCnt = (renderFrame.buffer[0].length / attr_.audAttr.channel) / AUDIO_SAMPLE_WIDTH_BYTE;
161 float duration = (static_cast<int64_t>(sampleCnt) * MS_SCALE) / attr_.audAttr.sampleRate;
162 renderFrame.timeStamp = lastPts + duration;
163 }
164 timestamp = renderFrame.timeStamp;
165 renderDelay_ = 0;
166 if (audioRender_->GetLatency(audioRender_, &renderDelay_) == HI_SUCCESS) {
167 timestamp -= renderDelay_;
168 }
169 }
170
QueueRenderFrame(const PlayerBufferInfo & frame,const bool cacheQueue)171 void AudioSink::QueueRenderFrame(const PlayerBufferInfo &frame, const bool cacheQueue)
172 {
173 std::lock_guard<std::mutex> lock(mutex_);
174 if (frame.info.bufferCnt == 0) {
175 return;
176 }
177 if (cacheQueue) {
178 frameCacheQue_.push_back(frame);
179 } else {
180 frameReleaseQue_.push_back(frame);
181 }
182 }
183
GetRenderFrame(PlayerBufferInfo & renderFrame,const PlayerBufferInfo & frame)184 int32_t AudioSink::GetRenderFrame(PlayerBufferInfo &renderFrame, const PlayerBufferInfo &frame)
185 {
186 std::lock_guard<std::mutex> lock(mutex_);
187 int32_t ret = SINK_QUE_EMPTY;
188 if (frame.info.bufferCnt != 0) {
189 frameCacheQue_.push_back(frame);
190 }
191 if (frameCacheQue_.size() != 0) {
192 renderFrame = frameCacheQue_[0];
193 ret = SINK_SUCCESS;
194 }
195 return ret;
196 }
197
ReleaseQueHeadFrame(void)198 void AudioSink::ReleaseQueHeadFrame(void)
199 {
200 std::lock_guard<std::mutex> lock(mutex_);
201 if (frameCacheQue_.size() != 0) {
202 PlayerBufferInfo frame = frameCacheQue_[0];
203 frameCacheQue_.erase(frameCacheQue_.begin());
204 frameReleaseQue_.push_back(frame);
205 }
206 }
207
ReleaseQueAllFrame(void)208 void AudioSink::ReleaseQueAllFrame(void)
209 {
210 size_t i;
211 size_t queSize;
212 std::lock_guard<std::mutex> lock(mutex_);
213 queSize = frameCacheQue_.size();
214 if (queSize > MAX_QUEUE_BUF_NUM) {
215 return;
216 }
217 for (i = 0; i < queSize; i++) {
218 frameReleaseQue_.push_back(frameCacheQue_[i]);
219 }
220 frameCacheQue_.clear();
221 }
222
DequeReleaseFrame(PlayerBufferInfo & frame)223 int32_t AudioSink::DequeReleaseFrame(PlayerBufferInfo &frame)
224 {
225 std::lock_guard<std::mutex> lock(mutex_);
226 if (frameReleaseQue_.size() == 0) {
227 return SINK_QUE_EMPTY;
228 }
229 frame = frameReleaseQue_[0];
230 frameReleaseQue_.erase(frameReleaseQue_.begin());
231 return SINK_SUCCESS;
232 }
233
RenderRptEvent(EventCbType event)234 void AudioSink::RenderRptEvent(EventCbType event)
235 {
236 if (callBack_.onEventCallback != nullptr) {
237 if (event == EVNET_AUDIO_PLAY_EOS && eosSended_) {
238 return;
239 }
240 callBack_.onEventCallback(callBack_.priv, event, 0, 0);
241 if (event == EVNET_AUDIO_PLAY_EOS) {
242 eosSended_ = true;
243 }
244 }
245 }
246
WriteToAudioDevice(CodecBuffer & renderFrame)247 int32_t AudioSink::WriteToAudioDevice(CodecBuffer &renderFrame)
248 {
249 int32_t ret;
250 uint64_t writeLen = 0;
251 if ((audioRender_ == nullptr) || (&renderFrame.buffer[0] == nullptr)) {
252 ReleaseQueHeadFrame();
253 return SINK_RENDER_ERROR;
254 }
255
256 ret = audioRender_->RenderFrame(audioRender_, (void*)(renderFrame.buffer[0].buf + renderFrame.buffer[0].offset),
257 static_cast<uint64_t>(renderFrame.buffer[0].length), &writeLen);
258 if ((unsigned long)renderFrame.buffer[0].length != writeLen) {
259 return SINK_RENDER_FULL;
260 } else if (ret != HI_SUCCESS) {
261 ReleaseQueHeadFrame();
262 MEDIA_ERR_LOG("RenderFrame failed ret: %x", ret);
263 return SINK_RENDER_ERROR;
264 }
265 ReleaseQueHeadFrame();
266 return HI_SUCCESS;
267 }
268
RenderFrame(PlayerBufferInfo & frame)269 int32_t AudioSink::RenderFrame(PlayerBufferInfo &frame)
270 {
271 SyncRet syncRet = SYNC_RET_PLAY;
272 int64_t crtPlayPts = 0;
273 uint64_t frameCnt;
274 PlayerBufferInfo renderFrame;
275 struct AudioTimeStamp timestamp;
276
277 if (!reportedFirstFrame && renderMode_ == RENDER_MODE_PAUSE_AFTER_PLAY) {
278 callBack_.onEventCallback(callBack_.priv, EVNET_FIRST_AUDIO_REND, 0, 0);
279 reportedFirstFrame = true;
280 MEDIA_INFO_LOG("report first audio frame");
281 }
282
283 if (paused_ || renderMode_ == RENDER_MODE_PAUSE_AFTER_PLAY) {
284 QueueRenderFrame(frame, true);
285 return SINK_SUCCESS;
286 }
287 if (!started_ || audioRender_ == nullptr) {
288 QueueRenderFrame(frame, false);
289 MEDIA_ERR_LOG("paused or audio dev not inited");
290 return SINK_RENDER_ERROR;
291 }
292
293 if (GetRenderFrame(renderFrame, frame) != SINK_SUCCESS) {
294 if (receivedEos_) {
295 RenderRptEvent(EVNET_AUDIO_PLAY_EOS);
296 return SINK_RENDER_EOS;
297 }
298 return SINK_QUE_EMPTY;
299 }
300 if (pauseAfterPlay_) {
301 return SINK_SUCCESS;
302 }
303
304 int32_t ret = audioRender_->GetRenderPosition(audioRender_, &frameCnt, ×tamp);
305 if (ret != HI_SUCCESS) {
306 MEDIA_ERR_LOG("GetRenderPosition failed,ret=0x%x", ret);
307 return SINK_RENDER_ERROR;
308 }
309
310 UpdateAudioPts(lastRendPts_, crtPlayPts, renderFrame.info);
311 ret = (syncHdl_ != nullptr) ? syncHdl_->ProcAudFrame(crtPlayPts, syncRet) : HI_SUCCESS;
312 if (ret != HI_SUCCESS) {
313 MEDIA_ERR_LOG("ProcAudFrame pts: %lld failed", renderFrame.info.timeStamp);
314 ReleaseQueHeadFrame();
315 return SINK_RENDER_ERROR;
316 }
317 if (syncRet == SYNC_RET_PLAY) {
318 ret = WriteToAudioDevice(renderFrame.info);
319 } else if (syncRet == SYNC_RET_DROP) {
320 ReleaseQueHeadFrame();
321 ret = SINK_SUCCESS;
322 } else if (syncRet == SYNC_RET_REPEAT) {
323 ret = SINK_RENDER_DELAY;
324 } else {
325 MEDIA_ERR_LOG("aud invalid sync ret: %d", syncRet);
326 ReleaseQueHeadFrame();
327 ret = SINK_RENDER_ERROR;
328 }
329
330 if (ret == SINK_SUCCESS || ret == SINK_RENDER_ERROR) {
331 lastRendPts_ = renderFrame.info.timeStamp;
332 rendFrameCnt_++;
333 }
334 return ret;
335 }
336
RenderEos(void)337 void AudioSink::RenderEos(void)
338 {
339 receivedEos_ = true;
340 eosPts_ = lastRendPts_;
341 }
342
Start(void)343 int32_t AudioSink::Start(void)
344 {
345 CHECK_FAILED_RETURN(started_, false, SINK_SUCCESS, "have started");
346 CHECK_NULL_RETURN(audioRender_, SINK_INVALID_OP, "audio dev not inited");
347 int32_t ret = audioRender_->control.Start((AudioHandle)audioRender_);
348 if (ret == 0) {
349 started_ = true;
350 }
351 return ret;
352 }
353
SetVolume(float left,float right)354 int32_t AudioSink::SetVolume(float left, float right)
355 {
356 float volume;
357 CHECK_FAILED_RETURN(started_, true, -1, "not started");
358 if (audioRender_ == nullptr) {
359 MEDIA_ERR_LOG("AudioSink::SetVolume failed audioRender_ null");
360 return -1;
361 }
362
363 leftVolume_ = left;
364 rightVolume_ = right;
365 if ((leftVolume_ == 0) && (rightVolume_ != 0)) {
366 volume = rightVolume_;
367 } else if ((leftVolume_ != 0) && (rightVolume_ == 0)) {
368 volume = leftVolume_;
369 } else {
370 volume = (leftVolume_ + rightVolume_) / HALF_FACTOR;
371 }
372 audioRender_->volume.SetVolume(reinterpret_cast<AudioHandle>(audioRender_), volume);
373 return SINK_SUCCESS;
374 }
375
GetVolume(float & left,float & right)376 int32_t AudioSink::GetVolume(float &left, float &right)
377 {
378 left = leftVolume_;
379 right = rightVolume_;
380 return SINK_SUCCESS;
381 }
382
Stop(void)383 int32_t AudioSink::Stop(void)
384 {
385 if (started_ && audioRender_ != nullptr) {
386 (void)audioRender_->control.Stop(reinterpret_cast<AudioHandle>(audioRender_));
387 }
388 ReleaseQueAllFrame();
389 rendFrameCnt_ = 0;
390 started_ = false;
391 paused_ = false;
392 eosSended_ = false;
393 return SINK_SUCCESS;
394 }
395
Pause(void)396 int32_t AudioSink::Pause(void)
397 {
398 if (started_ && audioRender_ != nullptr) {
399 (void)audioRender_->control.Pause(reinterpret_cast<AudioHandle>(audioRender_));
400 }
401 paused_ = true;
402 return SINK_SUCCESS;
403 }
404
Resume(void)405 int32_t AudioSink::Resume(void)
406 {
407 CHECK_FAILED_RETURN(paused_, true, -1, "not paused");
408 CHECK_NULL_RETURN(audioRender_, -1, "audioRender_ is null");
409 (void)audioRender_->control.Resume(reinterpret_cast<AudioHandle>(audioRender_));
410 paused_ = false;
411 renderMode_ = RENDER_MODE_NORMAL;
412 return SINK_SUCCESS;
413 }
414
Reset(void)415 int32_t AudioSink::Reset(void)
416 {
417 ReleaseQueAllFrame();
418 if (started_ && audioRender_ != nullptr) {
419 (void)audioRender_->control.Flush(reinterpret_cast<AudioHandle>(audioRender_));
420 }
421
422 ResetRendStartTime();
423 receivedEos_ = false;
424 renderDelay_ = 0;
425 return SINK_SUCCESS;
426 }
427
RegisterCallBack(PlayEventCallback & callback)428 int32_t AudioSink::RegisterCallBack(PlayEventCallback &callback)
429 {
430 callBack_ = callback;
431 return SINK_SUCCESS;
432 }
433
SetSync(PlayerSync * sync)434 void AudioSink::SetSync(PlayerSync *sync)
435 {
436 syncHdl_ = sync;
437 }
438
Flush(void)439 int32_t AudioSink::Flush(void)
440 {
441 if (started_ && audioRender_ != nullptr) {
442 (void)audioRender_->control.Flush(reinterpret_cast<AudioHandle>(audioRender_));
443 }
444 renderDelay_ = 0;
445 return 0;
446 }
447
GetRenderPosition(int64_t & position)448 void AudioSink::GetRenderPosition(int64_t &position)
449 {
450 position = lastRendPts_;
451 }
452
SetRenderMode(RenderMode mode)453 void AudioSink::SetRenderMode(RenderMode mode)
454 {
455 renderMode_ = mode;
456 }
457
SetAudioStreamType(int32_t & type)458 void AudioSink::SetAudioStreamType(int32_t &type)
459 {
460 audioStreamType_ = type;
461 }
462 }
463 }