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 &timestamp)
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_, &timestamp)) {
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