1 /*
2 * Copyright (c) 2023 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 #ifndef LOG_TAG
16 #define LOG_TAG "PaCapturerStreamImpl"
17 #endif
18
19 #include "safe_map.h"
20 #include "pa_capturer_stream_impl.h"
21 #include "pa_adapter_tools.h"
22 #include "audio_errors.h"
23 #include "audio_capturer_log.h"
24 #include "audio_utils.h"
25 #include "policy_handler.h"
26
27 namespace OHOS {
28 namespace AudioStandard {
29 static SafeMap<void *, std::weak_ptr<PaCapturerStreamImpl>> paCapturerMap_;
CheckReturnIfStreamInvalid(pa_stream * paStream,const int32_t retVal)30 static int32_t CheckReturnIfStreamInvalid(pa_stream *paStream, const int32_t retVal)
31 {
32 do {
33 if (!(paStream && PA_STREAM_IS_GOOD(pa_stream_get_state(paStream)))) {
34 return retVal;
35 }
36 } while (false);
37 return SUCCESS;
38 }
39
PaCapturerStreamImpl(pa_stream * paStream,AudioProcessConfig processConfig,pa_threaded_mainloop * mainloop)40 PaCapturerStreamImpl::PaCapturerStreamImpl(pa_stream *paStream, AudioProcessConfig processConfig,
41 pa_threaded_mainloop *mainloop)
42 {
43 mainloop_ = mainloop;
44 paStream_ = paStream;
45 processConfig_ = processConfig;
46 }
47
~PaCapturerStreamImpl()48 PaCapturerStreamImpl::~PaCapturerStreamImpl()
49 {
50 AUDIO_DEBUG_LOG("~PaCapturerStreamImpl");
51 if (capturerServerDumpFile_) {
52 fclose(capturerServerDumpFile_);
53 capturerServerDumpFile_ = nullptr;
54 }
55 paCapturerMap_.Erase(this);
56
57 PaLockGuard lock(mainloop_);
58 if (paStream_) {
59 if (!releasedFlag_) {
60 pa_stream_set_state_callback(paStream_, nullptr, nullptr);
61 pa_stream_set_read_callback(paStream_, nullptr, nullptr);
62 pa_stream_set_latency_update_callback(paStream_, nullptr, nullptr);
63 pa_stream_set_underflow_callback(paStream_, nullptr, nullptr);
64 pa_stream_set_moved_callback(paStream_, nullptr, nullptr);
65 pa_stream_set_started_callback(paStream_, nullptr, nullptr);
66 pa_stream_disconnect(paStream_);
67 }
68 pa_stream_unref(paStream_);
69 paStream_ = nullptr;
70 }
71 }
72
InitParams()73 int32_t PaCapturerStreamImpl::InitParams()
74 {
75 paCapturerMap_.Insert(this, weak_from_this());
76 PaLockGuard lock(mainloop_);
77 pa_stream_set_moved_callback(paStream_, PAStreamMovedCb,
78 reinterpret_cast<void *>(this)); // used to notify sink/source moved
79 pa_stream_set_read_callback(paStream_, PAStreamReadCb, reinterpret_cast<void *>(this));
80 pa_stream_set_underflow_callback(paStream_, PAStreamUnderFlowCb, reinterpret_cast<void *>(this));
81 pa_stream_set_started_callback(paStream_, PAStreamSetStartedCb, reinterpret_cast<void *>(this));
82
83 if (CheckReturnIfStreamInvalid(paStream_, ERROR) < 0) {
84 return ERR_ILLEGAL_STATE;
85 }
86
87 // Get byte size per frame
88 const pa_sample_spec *sampleSpec = pa_stream_get_sample_spec(paStream_);
89 CHECK_AND_RETURN_RET_LOG(sampleSpec != nullptr, ERR_OPERATION_FAILED,
90 "pa_sample_spec sampleSpec is nullptr");
91 if (sampleSpec->channels != processConfig_.streamInfo.channels) {
92 AUDIO_WARNING_LOG("Unequal channels, in server: %{public}d, in client: %{public}d", sampleSpec->channels,
93 processConfig_.streamInfo.channels);
94 }
95 if (static_cast<uint8_t>(sampleSpec->format) != processConfig_.streamInfo.format) {
96 AUDIO_WARNING_LOG("Unequal format, in server: %{public}d, in client: %{public}d", sampleSpec->format,
97 processConfig_.streamInfo.format);
98 }
99 byteSizePerFrame_ = pa_frame_size(sampleSpec);
100
101 // Get min buffer size in frame
102 const pa_buffer_attr *bufferAttr = pa_stream_get_buffer_attr(paStream_);
103 if (bufferAttr == nullptr) {
104 AUDIO_ERR_LOG("pa_stream_get_buffer_attr returned nullptr");
105 return ERR_OPERATION_FAILED;
106 }
107 minBufferSize_ = (size_t)bufferAttr->fragsize;
108 if (byteSizePerFrame_ == 0) {
109 AUDIO_ERR_LOG("byteSizePerFrame_ should not be zero.");
110 return ERR_INVALID_PARAM;
111 }
112 spanSizeInFrame_ = minBufferSize_ / byteSizePerFrame_;
113 AUDIO_INFO_LOG("byteSizePerFrame_ %{public}zu, spanSizeInFrame_ %{public}zu, minBufferSize_ %{public}zu",
114 byteSizePerFrame_, spanSizeInFrame_, minBufferSize_);
115
116 #ifdef DUMP_CAPTURER_STREAM_IMPL
117 capturerServerDumpFile_ = fopen("/data/data/.pulse_dir/capturer_impl.pcm", "wb+");
118 #endif
119 return SUCCESS;
120 }
121
Start()122 int32_t PaCapturerStreamImpl::Start()
123 {
124 AUDIO_INFO_LOG("Start");
125 PaLockGuard lock(mainloop_);
126 if (CheckReturnIfStreamInvalid(paStream_, ERROR) < 0) {
127 return ERR_ILLEGAL_STATE;
128 }
129 pa_operation *operation = nullptr;
130 pa_stream_state_t state = pa_stream_get_state(paStream_);
131 if (state != PA_STREAM_READY) {
132 return ERR_ILLEGAL_STATE;
133 }
134
135 streamCmdStatus_ = 0;
136 operation = pa_stream_cork(paStream_, 0, PAStreamStartSuccessCb, reinterpret_cast<void *>(this));
137 pa_operation_unref(operation);
138 return SUCCESS;
139 }
140
Pause(bool isStandby)141 int32_t PaCapturerStreamImpl::Pause(bool isStandby)
142 {
143 AUDIO_INFO_LOG("Pause");
144 PaLockGuard lock(mainloop_);
145 if (CheckReturnIfStreamInvalid(paStream_, ERROR) < 0) {
146 return ERR_ILLEGAL_STATE;
147 }
148
149 pa_stream_state_t state = pa_stream_get_state(paStream_);
150 if (state != PA_STREAM_READY) {
151 AUDIO_ERR_LOG("Stream Stop Failed");
152 return ERR_ILLEGAL_STATE;
153 }
154 pa_operation *operation = pa_stream_cork(paStream_, 1, PAStreamPauseSuccessCb, reinterpret_cast<void *>(this));
155 pa_operation_unref(operation);
156 return SUCCESS;
157 }
158
GetStreamFramesRead(uint64_t & framesRead)159 int32_t PaCapturerStreamImpl::GetStreamFramesRead(uint64_t &framesRead)
160 {
161 if (byteSizePerFrame_ == 0) {
162 AUDIO_ERR_LOG("Error frame size");
163 return ERR_OPERATION_FAILED;
164 }
165 framesRead = totalBytesRead_ / byteSizePerFrame_;
166 return SUCCESS;
167 }
168
GetCurrentTimeStamp(uint64_t & timestamp)169 int32_t PaCapturerStreamImpl::GetCurrentTimeStamp(uint64_t ×tamp)
170 {
171 PaLockGuard lock(mainloop_);
172 if (CheckReturnIfStreamInvalid(paStream_, ERROR) < 0) {
173 return ERR_ILLEGAL_STATE;
174 }
175
176 pa_operation *operation = pa_stream_update_timing_info(paStream_, NULL, NULL);
177 if (operation != nullptr) {
178 while (pa_operation_get_state(operation) == PA_OPERATION_RUNNING) {
179 pa_threaded_mainloop_wait(mainloop_);
180 }
181 pa_operation_unref(operation);
182 } else {
183 AUDIO_ERR_LOG("pa_stream_update_timing_info failed");
184 }
185
186 const pa_timing_info *info = pa_stream_get_timing_info(paStream_);
187 if (info == nullptr) {
188 AUDIO_ERR_LOG("pa_stream_get_timing_info failed");
189 return ERR_OPERATION_FAILED;
190 }
191
192 if (pa_stream_get_time(paStream_, ×tamp)) {
193 AUDIO_ERR_LOG("GetCurrentTimeStamp failed for AUDIO_SERVICE_CLIENT_RECORD");
194 return ERR_OPERATION_FAILED;
195 }
196 int32_t uid = static_cast<int32_t>(getuid());
197 const pa_sample_spec *sampleSpec = pa_stream_get_sample_spec(paStream_);
198 timestamp = pa_bytes_to_usec(info->write_index, sampleSpec);
199 // 1013 is media_service's uid
200 int32_t media_service = 1013;
201 if (uid == media_service) {
202 timestamp = pa_bytes_to_usec(totalBytesRead_, sampleSpec);
203 }
204 return SUCCESS;
205 }
206
GetLatency(uint64_t & latency)207 int32_t PaCapturerStreamImpl::GetLatency(uint64_t &latency)
208 {
209 PaLockGuard lock(mainloop_);
210 if (CheckReturnIfStreamInvalid(paStream_, ERROR) < 0) {
211 return ERR_ILLEGAL_STATE;
212 }
213 pa_usec_t paLatency {0};
214 pa_usec_t cacheLatency {0};
215 int32_t negative {0};
216
217 // Get PA latency
218 while (true) {
219 pa_operation *operation = pa_stream_update_timing_info(paStream_, PAStreamUpdateTimingInfoSuccessCb, NULL);
220 if (operation != nullptr) {
221 pa_operation_unref(operation);
222 } else {
223 AUDIO_ERR_LOG("pa_stream_update_timing_info failed");
224 }
225 if (pa_stream_get_latency(paStream_, &paLatency, &negative) >= 0) {
226 if (negative) {
227 latency = 0;
228 return ERR_OPERATION_FAILED;
229 }
230 break;
231 }
232 AUDIO_INFO_LOG("waiting for audio latency information");
233 pa_threaded_mainloop_wait(mainloop_);
234 }
235
236 // In plan, 怎么计算cacheLatency
237 // Get audio read cache latency
238 const pa_sample_spec *sampleSpec = pa_stream_get_sample_spec(paStream_);
239 cacheLatency = pa_bytes_to_usec(minBufferSize_, sampleSpec);
240
241 // Total latency will be sum of audio read cache latency + PA latency
242 latency = paLatency + cacheLatency;
243 AUDIO_DEBUG_LOG("total latency: %{public}" PRIu64 ", pa latency: %{public}" PRIu64, latency, paLatency);
244 return SUCCESS;
245 }
246
Flush()247 int32_t PaCapturerStreamImpl::Flush()
248 {
249 AUDIO_INFO_LOG("Flush");
250 PaLockGuard lock(mainloop_);
251 if (CheckReturnIfStreamInvalid(paStream_, ERROR) < 0) {
252 return ERR_ILLEGAL_STATE;
253 }
254
255 pa_operation *operation = nullptr;
256 pa_stream_state_t state = pa_stream_get_state(paStream_);
257 if (state != PA_STREAM_READY) {
258 AUDIO_ERR_LOG("Stream Flush Failed");
259 return ERR_ILLEGAL_STATE;
260 }
261 streamFlushStatus_ = 0;
262 operation = pa_stream_flush(paStream_, PAStreamFlushSuccessCb, reinterpret_cast<void *>(this));
263 if (operation == nullptr) {
264 AUDIO_ERR_LOG("Stream Flush Operation Failed");
265 return ERR_OPERATION_FAILED;
266 }
267 pa_operation_unref(operation);
268 return SUCCESS;
269 }
270
Stop()271 int32_t PaCapturerStreamImpl::Stop()
272 {
273 AUDIO_INFO_LOG("Stop");
274 PaLockGuard lock(mainloop_);
275 if (CheckReturnIfStreamInvalid(paStream_, ERROR) < 0) {
276 return ERR_ILLEGAL_STATE;
277 }
278
279 pa_stream_state_t state = pa_stream_get_state(paStream_);
280 if (state != PA_STREAM_READY) {
281 AUDIO_ERR_LOG("Stream Stop Failed");
282 return ERR_ILLEGAL_STATE;
283 }
284 pa_operation *operation = pa_stream_cork(paStream_, 1, PAStreamStopSuccessCb, reinterpret_cast<void *>(this));
285 pa_operation_unref(operation);
286 return SUCCESS;
287 }
288
Release()289 int32_t PaCapturerStreamImpl::Release()
290 {
291 AUDIO_INFO_LOG("Enter");
292
293 if (state_ == RUNNING) {
294 PaLockGuard lock(mainloop_);
295 if (CheckReturnIfStreamInvalid(paStream_, ERR_ILLEGAL_STATE) < 0) {
296 return ERR_ILLEGAL_STATE;
297 }
298 pa_operation *operation = pa_stream_cork(paStream_, 1, nullptr, nullptr);
299 CHECK_AND_RETURN_RET_LOG(operation != nullptr, ERR_OPERATION_FAILED, "pa_stream_cork operation is null");
300 pa_operation_unref(operation);
301 }
302
303 std::shared_ptr<IStatusCallback> statusCallback = statusCallback_.lock();
304 if (statusCallback != nullptr) {
305 statusCallback->OnStatusUpdate(OPERATION_RELEASED);
306 }
307 state_ = RELEASED;
308 if (processConfig_.capturerInfo.sourceType == SOURCE_TYPE_WAKEUP) {
309 PolicyHandler::GetInstance().NotifyWakeUpCapturerRemoved();
310 }
311
312 PaLockGuard lock(mainloop_);
313 if (paStream_) {
314 pa_stream_set_state_callback(paStream_, nullptr, nullptr);
315 pa_stream_set_read_callback(paStream_, nullptr, nullptr);
316 pa_stream_set_latency_update_callback(paStream_, nullptr, nullptr);
317 pa_stream_set_underflow_callback(paStream_, nullptr, nullptr);
318 pa_stream_set_moved_callback(paStream_, nullptr, nullptr);
319 pa_stream_set_started_callback(paStream_, nullptr, nullptr);
320 pa_stream_disconnect(paStream_);
321 releasedFlag_ = true;
322 }
323 return SUCCESS;
324 }
325
RegisterStatusCallback(const std::weak_ptr<IStatusCallback> & callback)326 void PaCapturerStreamImpl::RegisterStatusCallback(const std::weak_ptr<IStatusCallback> &callback)
327 {
328 statusCallback_ = callback;
329 }
330
RegisterReadCallback(const std::weak_ptr<IReadCallback> & callback)331 void PaCapturerStreamImpl::RegisterReadCallback(const std::weak_ptr<IReadCallback> &callback)
332 {
333 AUDIO_INFO_LOG("RegisterReadCallback start");
334 readCallback_ = callback;
335 }
336
DequeueBuffer(size_t length)337 BufferDesc PaCapturerStreamImpl::DequeueBuffer(size_t length)
338 {
339 BufferDesc bufferDesc;
340 const void *tempBuffer = nullptr;
341 pa_stream_peek(paStream_, &tempBuffer, &bufferDesc.bufLength);
342 bufferDesc.buffer = static_cast<uint8_t *>(const_cast<void* >(tempBuffer));
343 totalBytesRead_ += bufferDesc.bufLength;
344 if (capturerServerDumpFile_ != nullptr) {
345 fwrite(reinterpret_cast<void *>(bufferDesc.buffer), 1, bufferDesc.bufLength, capturerServerDumpFile_);
346 }
347 return bufferDesc;
348 }
349
EnqueueBuffer(const BufferDesc & bufferDesc)350 int32_t PaCapturerStreamImpl::EnqueueBuffer(const BufferDesc &bufferDesc)
351 {
352 pa_stream_drop(paStream_);
353 AUDIO_DEBUG_LOG("After enqueue capturere buffer, readable size is %{public}zu", pa_stream_readable_size(paStream_));
354 return SUCCESS;
355 }
356
DropBuffer()357 int32_t PaCapturerStreamImpl::DropBuffer()
358 {
359 pa_stream_drop(paStream_);
360 AUDIO_DEBUG_LOG("After capturere DropBuffer, readable size is %{public}zu", pa_stream_readable_size(paStream_));
361 return SUCCESS;
362 }
363
PAStreamReadCb(pa_stream * stream,size_t length,void * userdata)364 void PaCapturerStreamImpl::PAStreamReadCb(pa_stream *stream, size_t length, void *userdata)
365 {
366 Trace trace("PaCapturerStreamImpl::PAStreamReadCb:length " + std::to_string(length) + " readable:" +
367 std::to_string(pa_stream_readable_size(stream)));
368
369 if (!userdata) {
370 AUDIO_ERR_LOG("PAStreamReadCb: userdata is null");
371 return;
372 }
373 std::weak_ptr<PaCapturerStreamImpl> paCapturerStreamWeakPtr;
374 if (!paCapturerMap_.Find(userdata, paCapturerStreamWeakPtr)) {
375 AUDIO_ERR_LOG("streamImpl is null");
376 return;
377 }
378 auto streamImpl = paCapturerStreamWeakPtr.lock();
379 CHECK_AND_RETURN_LOG(streamImpl, "PAStreamWriteCb: userdata is null");
380 std::shared_ptr<IReadCallback> readCallback = streamImpl->readCallback_.lock();
381 if (readCallback != nullptr) {
382 readCallback->OnReadData(length);
383 } else {
384 AUDIO_ERR_LOG("Read callback is nullptr");
385 }
386 }
387
PAStreamMovedCb(pa_stream * stream,void * userdata)388 void PaCapturerStreamImpl::PAStreamMovedCb(pa_stream *stream, void *userdata)
389 {
390 CHECK_AND_RETURN_LOG(userdata, "PAStreamMovedCb: userdata is null");
391
392 // get stream informations.
393 uint32_t deviceIndex = pa_stream_get_device_index(stream); // pa_context_get_sink_info_by_index
394 uint32_t streamIndex = pa_stream_get_index(stream); // get pa_stream index
395
396 // Return 1 if the sink or source this stream is connected to has been suspended.
397 // This will return 0 if not, and a negative value on error.
398 int res = pa_stream_is_suspended(stream);
399 AUDIO_WARNING_LOG("PAstream:[%{public}d] moved to index:[%{public}d] suspended:[%{public}d]",
400 streamIndex, deviceIndex, res);
401 }
402
PAStreamUnderFlowCb(pa_stream * stream,void * userdata)403 void PaCapturerStreamImpl::PAStreamUnderFlowCb(pa_stream *stream, void *userdata)
404 {
405 if (!userdata) {
406 AUDIO_ERR_LOG("PAStreamUnderFlowCb: userdata is null");
407 return;
408 }
409
410 std::weak_ptr<PaCapturerStreamImpl> paCapturerStreamWeakPtr;
411 if (!paCapturerMap_.Find(userdata, paCapturerStreamWeakPtr)) {
412 AUDIO_ERR_LOG("streamImpl is null");
413 return;
414 }
415 auto streamImpl = paCapturerStreamWeakPtr.lock();
416 CHECK_AND_RETURN_LOG(streamImpl, "PAStreamWriteCb: userdata is null");
417 streamImpl->underFlowCount_++;
418
419 std::shared_ptr<IStatusCallback> statusCallback = streamImpl->statusCallback_.lock();
420 if (statusCallback != nullptr) {
421 statusCallback->OnStatusUpdate(OPERATION_UNDERRUN);
422 }
423 AUDIO_WARNING_LOG("PaCapturerStreamImpl underrun: %{public}d!", streamImpl->underFlowCount_);
424 }
425
426
PAStreamSetStartedCb(pa_stream * stream,void * userdata)427 void PaCapturerStreamImpl::PAStreamSetStartedCb(pa_stream *stream, void *userdata)
428 {
429 if (!userdata) {
430 AUDIO_ERR_LOG("PAStreamSetStartedCb: userdata is null");
431 return;
432 }
433
434 AUDIO_WARNING_LOG("PAStreamSetStartedCb");
435 }
436
PAStreamStartSuccessCb(pa_stream * stream,int32_t success,void * userdata)437 void PaCapturerStreamImpl::PAStreamStartSuccessCb(pa_stream *stream, int32_t success, void *userdata)
438 {
439 if (!userdata) {
440 AUDIO_ERR_LOG("PAStreamStartSuccessCb: userdata is null");
441 return;
442 }
443
444 std::weak_ptr<PaCapturerStreamImpl> paCapturerStreamWeakPtr;
445 if (!paCapturerMap_.Find(userdata, paCapturerStreamWeakPtr)) {
446 AUDIO_ERR_LOG("streamImpl is null");
447 return;
448 }
449 auto streamImpl = paCapturerStreamWeakPtr.lock();
450 CHECK_AND_RETURN_LOG(streamImpl, "PAStreamWriteCb: userdata is null");
451
452 streamImpl->state_ = RUNNING;
453 std::shared_ptr<IStatusCallback> statusCallback = streamImpl->statusCallback_.lock();
454 if (statusCallback != nullptr) {
455 statusCallback->OnStatusUpdate(OPERATION_STARTED);
456 }
457 streamImpl->streamCmdStatus_ = success;
458 }
459
PAStreamPauseSuccessCb(pa_stream * stream,int32_t success,void * userdata)460 void PaCapturerStreamImpl::PAStreamPauseSuccessCb(pa_stream *stream, int32_t success, void *userdata)
461 {
462 if (!userdata) {
463 AUDIO_ERR_LOG("PAStreamPauseSuccessCb: userdata is null");
464 return;
465 }
466
467 std::weak_ptr<PaCapturerStreamImpl> paCapturerStreamWeakPtr;
468 if (!paCapturerMap_.Find(userdata, paCapturerStreamWeakPtr)) {
469 AUDIO_ERR_LOG("streamImpl is null");
470 return;
471 }
472 auto streamImpl = paCapturerStreamWeakPtr.lock();
473 CHECK_AND_RETURN_LOG(streamImpl, "PAStreamWriteCb: userdata is null");
474 streamImpl->state_ = PAUSED;
475 std::shared_ptr<IStatusCallback> statusCallback = streamImpl->statusCallback_.lock();
476 if (statusCallback != nullptr) {
477 statusCallback->OnStatusUpdate(OPERATION_PAUSED);
478 }
479 streamImpl->streamCmdStatus_ = success;
480 }
481
PAStreamFlushSuccessCb(pa_stream * stream,int32_t success,void * userdata)482 void PaCapturerStreamImpl::PAStreamFlushSuccessCb(pa_stream *stream, int32_t success, void *userdata)
483 {
484 if (!userdata) {
485 AUDIO_ERR_LOG("PAStreamFlushSuccessCb: userdata is null");
486 return;
487 }
488 std::weak_ptr<PaCapturerStreamImpl> paCapturerStreamWeakPtr;
489 if (!paCapturerMap_.Find(userdata, paCapturerStreamWeakPtr)) {
490 AUDIO_ERR_LOG("streamImpl is null");
491 return;
492 }
493 auto streamImpl = paCapturerStreamWeakPtr.lock();
494 CHECK_AND_RETURN_LOG(streamImpl, "PAStreamWriteCb: userdata is null");
495 std::shared_ptr<IStatusCallback> statusCallback = streamImpl->statusCallback_.lock();
496 if (statusCallback != nullptr) {
497 statusCallback->OnStatusUpdate(OPERATION_FLUSHED);
498 }
499 streamImpl->streamFlushStatus_ = success;
500 }
501
PAStreamStopSuccessCb(pa_stream * stream,int32_t success,void * userdata)502 void PaCapturerStreamImpl::PAStreamStopSuccessCb(pa_stream *stream, int32_t success, void *userdata)
503 {
504 if (!userdata) {
505 AUDIO_ERR_LOG("PAStreamAsyncStopSuccessCb: userdata is null");
506 return;
507 }
508
509 std::weak_ptr<PaCapturerStreamImpl> paCapturerStreamWeakPtr;
510 if (!paCapturerMap_.Find(userdata, paCapturerStreamWeakPtr)) {
511 AUDIO_ERR_LOG("streamImpl is null");
512 return;
513 }
514 auto streamImpl = paCapturerStreamWeakPtr.lock();
515 CHECK_AND_RETURN_LOG(streamImpl, "PAStreamWriteCb: userdata is null");
516
517 std::shared_ptr<IStatusCallback> statusCallback = streamImpl->statusCallback_.lock();
518 if (statusCallback != nullptr) {
519 statusCallback->OnStatusUpdate(OPERATION_STOPPED);
520 }
521 }
522
GetMinimumBufferSize(size_t & minBufferSize) const523 int32_t PaCapturerStreamImpl::GetMinimumBufferSize(size_t &minBufferSize) const
524 {
525 minBufferSize = minBufferSize_;
526 return SUCCESS;
527 }
528
GetByteSizePerFrame(size_t & byteSizePerFrame) const529 void PaCapturerStreamImpl::GetByteSizePerFrame(size_t &byteSizePerFrame) const
530 {
531 byteSizePerFrame = byteSizePerFrame_;
532 }
533
GetSpanSizePerFrame(size_t & spanSizeInFrame) const534 void PaCapturerStreamImpl::GetSpanSizePerFrame(size_t &spanSizeInFrame) const
535 {
536 spanSizeInFrame = spanSizeInFrame_;
537 }
538
SetStreamIndex(uint32_t index)539 void PaCapturerStreamImpl::SetStreamIndex(uint32_t index)
540 {
541 AUDIO_INFO_LOG("Using index/sessionId %{public}d", index);
542 streamIndex_ = index;
543 }
544
GetStreamIndex()545 uint32_t PaCapturerStreamImpl::GetStreamIndex()
546 {
547 return streamIndex_;
548 }
549
PAStreamUpdateTimingInfoSuccessCb(pa_stream * stream,int32_t success,void * userdata)550 void PaCapturerStreamImpl::PAStreamUpdateTimingInfoSuccessCb(pa_stream *stream, int32_t success, void *userdata)
551 {
552 PaCapturerStreamImpl *capturerStreamImpl = (PaCapturerStreamImpl *)userdata;
553 pa_threaded_mainloop *mainLoop = (pa_threaded_mainloop *)capturerStreamImpl->mainloop_;
554 pa_threaded_mainloop_signal(mainLoop, 0);
555 }
556
557 } // namespace AudioStandard
558 } // namespace OHOS
559