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 auto streamImpl = static_cast<PaCapturerStreamImpl *>(userdata);
374 if (streamImpl->abortFlag_ != 0) {
375 AUDIO_ERR_LOG("PAStreamReadCb: Abort pa stream read callback");
376 streamImpl->abortFlag_--;
377 return ;
378 }
379 std::shared_ptr<IReadCallback> readCallback = streamImpl->readCallback_.lock();
380 if (readCallback != nullptr) {
381 readCallback->OnReadData(length);
382 } else {
383 AUDIO_ERR_LOG("Read callback is nullptr");
384 }
385 }
386
PAStreamMovedCb(pa_stream * stream,void * userdata)387 void PaCapturerStreamImpl::PAStreamMovedCb(pa_stream *stream, void *userdata)
388 {
389 CHECK_AND_RETURN_LOG(userdata, "PAStreamMovedCb: userdata is null");
390
391 // get stream informations.
392 uint32_t deviceIndex = pa_stream_get_device_index(stream); // pa_context_get_sink_info_by_index
393 uint32_t streamIndex = pa_stream_get_index(stream); // get pa_stream index
394
395 // Return 1 if the sink or source this stream is connected to has been suspended.
396 // This will return 0 if not, and a negative value on error.
397 int res = pa_stream_is_suspended(stream);
398 AUDIO_WARNING_LOG("PAstream:[%{public}d] moved to index:[%{public}d] suspended:[%{public}d]",
399 streamIndex, deviceIndex, res);
400 }
401
PAStreamUnderFlowCb(pa_stream * stream,void * userdata)402 void PaCapturerStreamImpl::PAStreamUnderFlowCb(pa_stream *stream, void *userdata)
403 {
404 if (!userdata) {
405 AUDIO_ERR_LOG("PAStreamUnderFlowCb: userdata is null");
406 return;
407 }
408
409 PaCapturerStreamImpl *streamImpl = static_cast<PaCapturerStreamImpl *>(userdata);
410 streamImpl->underFlowCount_++;
411
412 std::shared_ptr<IStatusCallback> statusCallback = streamImpl->statusCallback_.lock();
413 if (statusCallback != nullptr) {
414 statusCallback->OnStatusUpdate(OPERATION_UNDERRUN);
415 }
416 AUDIO_WARNING_LOG("PaCapturerStreamImpl underrun: %{public}d!", streamImpl->underFlowCount_);
417 }
418
419
PAStreamSetStartedCb(pa_stream * stream,void * userdata)420 void PaCapturerStreamImpl::PAStreamSetStartedCb(pa_stream *stream, void *userdata)
421 {
422 if (!userdata) {
423 AUDIO_ERR_LOG("PAStreamSetStartedCb: userdata is null");
424 return;
425 }
426
427 AUDIO_WARNING_LOG("PAStreamSetStartedCb");
428 }
429
PAStreamStartSuccessCb(pa_stream * stream,int32_t success,void * userdata)430 void PaCapturerStreamImpl::PAStreamStartSuccessCb(pa_stream *stream, int32_t success, void *userdata)
431 {
432 if (!userdata) {
433 AUDIO_ERR_LOG("PAStreamStartSuccessCb: userdata is null");
434 return;
435 }
436
437 std::weak_ptr<PaCapturerStreamImpl> paCapturerStreamWeakPtr;
438 if (!paCapturerMap_.Find(userdata, paCapturerStreamWeakPtr)) {
439 AUDIO_ERR_LOG("streamImpl is null");
440 return;
441 }
442 auto streamImpl = paCapturerStreamWeakPtr.lock();
443 CHECK_AND_RETURN_LOG(streamImpl, "PAStreamWriteCb: userdata is null");
444
445 streamImpl->state_ = RUNNING;
446 std::shared_ptr<IStatusCallback> statusCallback = streamImpl->statusCallback_.lock();
447 if (statusCallback != nullptr) {
448 statusCallback->OnStatusUpdate(OPERATION_STARTED);
449 }
450 streamImpl->streamCmdStatus_ = success;
451 }
452
PAStreamPauseSuccessCb(pa_stream * stream,int32_t success,void * userdata)453 void PaCapturerStreamImpl::PAStreamPauseSuccessCb(pa_stream *stream, int32_t success, void *userdata)
454 {
455 if (!userdata) {
456 AUDIO_ERR_LOG("PAStreamPauseSuccessCb: userdata is null");
457 return;
458 }
459
460 PaCapturerStreamImpl *streamImpl = static_cast<PaCapturerStreamImpl *>(userdata);
461 streamImpl->state_ = PAUSED;
462 std::shared_ptr<IStatusCallback> statusCallback = streamImpl->statusCallback_.lock();
463 if (statusCallback != nullptr) {
464 statusCallback->OnStatusUpdate(OPERATION_PAUSED);
465 }
466 streamImpl->streamCmdStatus_ = success;
467 }
468
PAStreamFlushSuccessCb(pa_stream * stream,int32_t success,void * userdata)469 void PaCapturerStreamImpl::PAStreamFlushSuccessCb(pa_stream *stream, int32_t success, void *userdata)
470 {
471 if (!userdata) {
472 AUDIO_ERR_LOG("PAStreamFlushSuccessCb: userdata is null");
473 return;
474 }
475 PaCapturerStreamImpl *streamImpl = static_cast<PaCapturerStreamImpl *>(userdata);
476 std::shared_ptr<IStatusCallback> statusCallback = streamImpl->statusCallback_.lock();
477 if (statusCallback != nullptr) {
478 statusCallback->OnStatusUpdate(OPERATION_FLUSHED);
479 }
480 streamImpl->streamFlushStatus_ = success;
481 }
482
PAStreamStopSuccessCb(pa_stream * stream,int32_t success,void * userdata)483 void PaCapturerStreamImpl::PAStreamStopSuccessCb(pa_stream *stream, int32_t success, void *userdata)
484 {
485 if (!userdata) {
486 AUDIO_ERR_LOG("PAStreamAsyncStopSuccessCb: userdata is null");
487 return;
488 }
489
490 std::weak_ptr<PaCapturerStreamImpl> paCapturerStreamWeakPtr;
491 if (!paCapturerMap_.Find(userdata, paCapturerStreamWeakPtr)) {
492 AUDIO_ERR_LOG("streamImpl is null");
493 return;
494 }
495 auto streamImpl = paCapturerStreamWeakPtr.lock();
496 CHECK_AND_RETURN_LOG(streamImpl, "PAStreamWriteCb: userdata is null");
497
498 std::shared_ptr<IStatusCallback> statusCallback = streamImpl->statusCallback_.lock();
499 if (statusCallback != nullptr) {
500 statusCallback->OnStatusUpdate(OPERATION_STOPPED);
501 }
502 }
503
GetMinimumBufferSize(size_t & minBufferSize) const504 int32_t PaCapturerStreamImpl::GetMinimumBufferSize(size_t &minBufferSize) const
505 {
506 minBufferSize = minBufferSize_;
507 return SUCCESS;
508 }
509
GetByteSizePerFrame(size_t & byteSizePerFrame) const510 void PaCapturerStreamImpl::GetByteSizePerFrame(size_t &byteSizePerFrame) const
511 {
512 byteSizePerFrame = byteSizePerFrame_;
513 }
514
GetSpanSizePerFrame(size_t & spanSizeInFrame) const515 void PaCapturerStreamImpl::GetSpanSizePerFrame(size_t &spanSizeInFrame) const
516 {
517 spanSizeInFrame = spanSizeInFrame_;
518 }
519
SetStreamIndex(uint32_t index)520 void PaCapturerStreamImpl::SetStreamIndex(uint32_t index)
521 {
522 AUDIO_INFO_LOG("Using index/sessionId %{public}d", index);
523 streamIndex_ = index;
524 }
525
GetStreamIndex()526 uint32_t PaCapturerStreamImpl::GetStreamIndex()
527 {
528 return streamIndex_;
529 }
530
AbortCallback(int32_t abortTimes)531 void PaCapturerStreamImpl::AbortCallback(int32_t abortTimes)
532 {
533 abortFlag_ += abortTimes;
534 }
535
PAStreamUpdateTimingInfoSuccessCb(pa_stream * stream,int32_t success,void * userdata)536 void PaCapturerStreamImpl::PAStreamUpdateTimingInfoSuccessCb(pa_stream *stream, int32_t success, void *userdata)
537 {
538 PaCapturerStreamImpl *capturerStreamImpl = (PaCapturerStreamImpl *)userdata;
539 pa_threaded_mainloop *mainLoop = (pa_threaded_mainloop *)capturerStreamImpl->mainloop_;
540 pa_threaded_mainloop_signal(mainLoop, 0);
541 }
542 } // namespace AudioStandard
543 } // namespace OHOS
544