1 /*
2  * Copyright (c) 2023-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 
16 #ifndef HISTREAMER_AUDIO_SINK_H
17 #define HISTREAMER_AUDIO_SINK_H
18 #include <mutex>
19 #include "common/status.h"
20 #include "meta/meta.h"
21 #include "sink/media_synchronous_sink.h"
22 #include "media_sync_manager.h"
23 #include "buffer/avbuffer_queue.h"
24 #include "buffer/avbuffer_queue_define.h"
25 #include "plugin/audio_sink_plugin.h"
26 #include "filter/filter.h"
27 #include "plugin/plugin_time.h"
28 
29 namespace OHOS {
30 namespace Media {
31 using namespace OHOS::Media::Plugins;
32 
33 class AudioSink : public std::enable_shared_from_this<AudioSink>, public Pipeline::MediaSynchronousSink {
34 public:
35     AudioSink();
36     ~AudioSink();
37     Status Init(std::shared_ptr<Meta>& meta, const std::shared_ptr<Pipeline::EventReceiver>& receiver);
38     sptr<AVBufferQueueProducer> GetBufferQueueProducer();
39     sptr<AVBufferQueueConsumer> GetBufferQueueConsumer();
40     Status SetParameter(const std::shared_ptr<Meta>& meta);
41     Status GetParameter(std::shared_ptr<Meta>& meta);
42     Status Prepare();
43     Status Start();
44     Status Stop();
45     Status Pause();
46     Status Resume();
47     Status Flush();
48     Status Release();
49     Status SetPlayRange(int64_t start, int64_t end);
50     Status SetVolume(float volume);
51     void DrainOutputBuffer();
52     void SetEventReceiver(const std::shared_ptr<Pipeline::EventReceiver>& receiver);
53     Status GetLatency(uint64_t& nanoSec);
54     void SetSyncCenter(std::shared_ptr<Pipeline::MediaSyncManager> syncCenter);
55     int64_t DoSyncWrite(const std::shared_ptr<OHOS::Media::AVBuffer>& buffer) override;
56     void ResetSyncInfo() override;
57     Status SetSpeed(float speed);
58     Status SetAudioEffectMode(int32_t effectMode);
59     Status GetAudioEffectMode(int32_t &effectMode);
60     int32_t SetVolumeWithRamp(float targetVolume, int32_t duration);
61     void SetThreadGroupId(const std::string& groupId);
62     Status SetIsTransitent(bool isTransitent);
63     Status ChangeTrack(std::shared_ptr<Meta>& meta, const std::shared_ptr<Pipeline::EventReceiver>& receiver);
64     Status SetMuted(bool isMuted);
65     float GetMaxAmplitude();
66     int32_t SetMaxAmplitudeCbStatus(bool status);
67 
68     static const int64_t kMinAudioClockUpdatePeriodUs = 20 * HST_USECOND;
69 
70     static const int64_t kMaxAllowedAudioSinkDelayUs = 1500 * HST_MSECOND;
71 
HasPlugin() const72     bool HasPlugin() const
73     {
74         return plugin_ != nullptr;
75     }
76 
IsInitialized() const77     bool IsInitialized() const
78     {
79         return state_ == Pipeline::FilterState::INITIALIZED;
80     }
81     Status SetSeekTime(int64_t seekTime);
82 
83 protected:
84     std::atomic<OHOS::Media::Pipeline::FilterState> state_;
85 private:
86     Status PrepareInputBufferQueue();
87     std::shared_ptr<Plugins::AudioSinkPlugin> CreatePlugin();
88     bool OnNewAudioMediaTime(int64_t mediaTimeUs);
89     int64_t getPendingAudioPlayoutDurationUs(int64_t nowUs);
90     int64_t getDurationUsPlayedAtSampleRate(uint32_t numFrames);
91     void UpdateAudioWriteTimeMayWait();
92     bool UpdateTimeAnchorIfNeeded(const std::shared_ptr<OHOS::Media::AVBuffer>& buffer);
93     void DrainAndReportEosEvent();
94     void HandleEosInner(bool drain);
95     void CalcMaxAmplitude(std::shared_ptr<AVBuffer> filledOutputBuffer);
96     void CheckUpdateState(char *frame, uint64_t replyBytes, int32_t format);
97     bool DropApeBuffer(std::shared_ptr<AVBuffer> filledOutputBuffer);
98 
99     class UnderrunDetector {
100     public:
101         void DetectAudioUnderrun(int64_t clkTime, int64_t latency);
102         void SetEventReceiver(std::weak_ptr<Pipeline::EventReceiver> eventReceiver);
103         void UpdateBufferTimeNoLock(int64_t clkTime, int64_t latency);
104         void SetLastAudioBufferDuration(int64_t durationUs);
105         void Reset();
106     private:
107         std::weak_ptr<Pipeline::EventReceiver> eventReceiver_;
108         Mutex mutex_ {};
109         int64_t lastClkTime_ {HST_TIME_NONE};
110         int64_t lastLatency_ {HST_TIME_NONE};
111         int64_t lastBufferDuration_ {HST_TIME_NONE};
112     };
113 
114     std::shared_ptr<Plugins::AudioSinkPlugin> plugin_ {};
115     std::shared_ptr<Pipeline::EventReceiver> playerEventReceiver_;
116     int32_t appUid_{0};
117     int32_t appPid_{0};
118     int64_t numFramesWritten_ {0};
119     int64_t firstAudioAnchorTimeMediaUs_ {HST_TIME_NONE};
120     int64_t nextAudioClockUpdateTimeUs_ {HST_TIME_NONE};
121     int64_t lastAnchorClockTime_  {HST_TIME_NONE};
122     int64_t latestBufferPts_ {HST_TIME_NONE};
123     int64_t latestBufferDuration_ {0};
124     int64_t bufferDurationSinceLastAnchor_ {0};
125     std::atomic<bool> forceUpdateTimeAnchorNextTime_ {true};
126     const std::string INPUT_BUFFER_QUEUE_NAME = "AudioSinkInputBufferQueue";
127     std::shared_ptr<AVBufferQueue> inputBufferQueue_;
128     sptr<AVBufferQueueProducer> inputBufferQueueProducer_;
129     sptr<AVBufferQueueConsumer> inputBufferQueueConsumer_;
130     int64_t firstPts_ {HST_TIME_NONE};
131     int32_t sampleRate_ {0};
132     int32_t samplePerFrame_ {0};
133     int64_t fixDelay_ {0};
134     bool isTransitent_ {false};
135     bool isEos_ {false};
136     std::mutex pluginMutex_;
137     float volume_ {-1.0f};
138     std::unique_ptr<Task> eosTask_ {nullptr};
139     enum class EosInterruptState : int {
140         NONE,
141         INITIAL,
142         PAUSE,
143         RESUME,
144         STOP,
145     };
146     Mutex eosMutex_ {};
147     std::atomic<bool> eosDraining_ {false};
148     std::atomic<EosInterruptState> eosInterruptType_ {EosInterruptState::NONE};
149     float speed_ {1.0f};
150     int32_t effectMode_ {-1};
151     bool isApe_ {false};
152     int64_t playRangeStartTime_ = -1;
153     int64_t playRangeEndTime_ = -1;
154     // vars for audio progress optimization
155     int64_t playingBufferDurationUs_ {0};
156     int64_t lastBufferWriteTime_ {0};
157     bool lastBufferWriteSuccess_ {true};
158     bool isMuted_ = false;
159     Mutex amplitudeMutex_ {};
160     float maxAmplitude_ = 0;
161 
162     bool calMaxAmplitudeCbStatus_ = false;
163     UnderrunDetector underrunDetector_;
164     std::atomic<int64_t> seekTimeUs_ {HST_TIME_NONE};
165 };
166 }
167 }
168 
169 #endif // HISTREAMER_AUDIO_SINK_H
170