1 /* 2 * Copyright (c) 2025 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 HPAE_OFFLOAD_SINK_OUTPUT_NODE_H 17 #define HPAE_OFFLOAD_SINK_OUTPUT_NODE_H 18 #include <memory> 19 #include "hpae_node.h" 20 #include "hpae_pcm_buffer.h" 21 #include "audio_info.h" 22 #include "sink/i_audio_render_sink.h" 23 #include "common/hdi_adapter_info.h" 24 #include "manager/hdi_adapter_manager.h" 25 #ifdef ENABLE_HOOK_PCM 26 #include "high_resolution_timer.h" 27 #include "hpae_pcm_dumper.h" 28 #endif 29 namespace OHOS { 30 namespace AudioStandard { 31 namespace HPAE { 32 typedef void(*AppCallbackFunc)(void* pHndl); 33 class HpaeOffloadSinkOutputNode : public InputNode<HpaePcmBuffer*> { 34 public: 35 HpaeOffloadSinkOutputNode(HpaeNodeInfo& nodeInfo); 36 virtual ~HpaeOffloadSinkOutputNode(); 37 virtual void DoProcess() override; 38 virtual bool Reset() override; 39 virtual bool ResetAll() override; 40 void Connect(const std::shared_ptr<OutputNode<HpaePcmBuffer*>>& preNode) override; 41 void DisConnect(const std::shared_ptr<OutputNode<HpaePcmBuffer*>>& preNode) override; 42 int32_t GetRenderSinkInstance(const std::string &deviceClass, const std::string &deviceNetworkId); 43 int32_t RenderSinkInit(IAudioSinkAttr& attr); 44 int32_t RenderSinkDeInit(); 45 int32_t RenderSinkFlush(); 46 int32_t RenderSinkStart(); 47 int32_t RenderSinkStop(); 48 size_t GetPreOutNum(); 49 StreamManagerState GetSinkState(void); 50 int32_t SetSinkState(StreamManagerState sinkState); 51 const char* GetRenderFrameData(void); 52 // need flush hdi cache and rewind 53 void StopStream(); 54 // flush need clear sinkoutputjnode cache 55 void FlushStream(); 56 // set offload policy state 57 void SetPolicyState(int32_t policyState); 58 // get offload latency for sinkinputnode, maybe extend to all node 59 uint64_t GetLatency(); 60 // set timeout to suspend render and stop hdi 61 int32_t SetTimeoutStopThd(uint32_t timeoutThdMs); 62 // set offload render callback type in hdi 63 int32_t SetOffloadRenderCallbackType(int32_t type); 64 void SetSpeed(float speed); 65 66 int32_t UpdateAppsUid(const std::vector<int32_t> &appsUid); 67 private: 68 // lock/unlock running lock 69 void RunningLock(bool isLock); 70 // Set hdi buffer size, change after render frame success 71 void SetBufferSizeWhileRenderFrame(); 72 void SetBufferSize(); 73 int32_t ProcessRenderFrame(); 74 // get presentation position from hdi, only trigger in offloadcallback 75 int32_t UpdatePresentationPosition(); 76 // return hdi cache len in us, cal by hdiPos_ 77 uint64_t CalcOffloadCacheLenInHdi(); 78 // set hdi volume when first write 79 void OffloadSetHdiVolume(); 80 // reset hdipos and firstWriteHdi 81 void OffloadReset(); 82 // register callback to hdi 83 void RegOffloadCallback(); 84 // offload callback reg to hdi 85 void OffloadCallback(const RenderCallbackType type); 86 // check when stop hdi, if need suspend 87 bool CheckIfSuspend(); 88 89 InputPort<HpaePcmBuffer*> inputStream_; 90 std::vector<char> renderFrameData_; 91 std::vector<char> renderFrameDataTemp_; 92 std::shared_ptr<IAudioRenderSink> audioRendererSink_ = nullptr; 93 uint32_t renderId_ = HDI_INVALID_ID; 94 IAudioSinkAttr sinkOutAttr_; 95 StreamManagerState state_ = STREAM_MANAGER_NEW; 96 #ifdef ENABLE_HOOK_PCM 97 HighResolutionTimer intervalTimer_; 98 std::unique_ptr<HpaePcmDumper> outputPcmDumper_ = nullptr; 99 #endif 100 101 AudioOffloadType hdiPolicyState_ = OFFLOAD_ACTIVE_FOREGROUND; 102 struct OffloadPolicyTask { 103 bool flag = false; // indicate if task exsit 104 AudioOffloadType state = OFFLOAD_DEFAULT; 105 TimePoint time; 106 } setPolicyStateTask_; 107 108 bool firstWriteHdi_ = true; 109 uint64_t writePos_ = 0; 110 int32_t setHdiBufferSizeNum_ = 0; 111 112 std::atomic<bool> isHdiFull_ = false; 113 114 uint32_t frameLenMs_ = 0; 115 uint32_t timeoutThdFrames_ = 0; 116 // first stand for pos(in us), second stand for time 117 std::pair<uint64_t, TimePoint> hdiPos_; 118 uint32_t suspendCount_ = 0; 119 float speed_ = 1.0f; 120 uint64_t hdiRealPos_ = 0; 121 // renderframe failed count 122 uint32_t retryCount_ = 0; 123 }; 124 125 } // namespace HPAE 126 } // namespace AudioStandard 127 } // namespace OHOS 128 129 #endif