1e0e9324cSopenharmony_ci/* 2e0e9324cSopenharmony_ci * Copyright (c) 2023 Shenzhen Kaihong Digital Industry Development Co., Ltd. 3e0e9324cSopenharmony_ci * Licensed under the Apache License, Version 2.0 (the "License"); 4e0e9324cSopenharmony_ci * you may not use this file except in compliance with the License. 5e0e9324cSopenharmony_ci * You may obtain a copy of the License at 6e0e9324cSopenharmony_ci * 7e0e9324cSopenharmony_ci * http://www.apache.org/licenses/LICENSE-2.0 8e0e9324cSopenharmony_ci * 9e0e9324cSopenharmony_ci * Unless required by applicable law or agreed to in writing, software 10e0e9324cSopenharmony_ci * distributed under the License is distributed on an "AS IS" BASIS, 11e0e9324cSopenharmony_ci * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12e0e9324cSopenharmony_ci * See the License for the specific language governing permissions and 13e0e9324cSopenharmony_ci * limitations under the License. 14e0e9324cSopenharmony_ci */ 15e0e9324cSopenharmony_ci 16e0e9324cSopenharmony_ci#include "buffer_dispatcher.h" 17e0e9324cSopenharmony_ci#include <cmath> 18e0e9324cSopenharmony_ci#include <cstdarg> 19e0e9324cSopenharmony_ci#include <cstdint> 20e0e9324cSopenharmony_ci#include "common/common_macro.h" 21e0e9324cSopenharmony_ci#include "media_channel_def.h" 22e0e9324cSopenharmony_ci 23e0e9324cSopenharmony_cinamespace OHOS { 24e0e9324cSopenharmony_cinamespace Sharing { 25e0e9324cSopenharmony_ci 26e0e9324cSopenharmony_ciconstexpr int32_t WRITING_TIMTOUT = 30; 27e0e9324cSopenharmony_ciconstexpr int32_t FIX_OFFSET_TWO = 2; 28e0e9324cSopenharmony_ciconstexpr int32_t FIX_OFFSET_ONE = 1; 29e0e9324cSopenharmony_ci 30e0e9324cSopenharmony_civoid BufferReceiver::SetSource(IBufferReader::Ptr dataReader) 31e0e9324cSopenharmony_ci{ 32e0e9324cSopenharmony_ci SHARING_LOGD("trace."); 33e0e9324cSopenharmony_ci bufferReader_ = dataReader; 34e0e9324cSopenharmony_ci} 35e0e9324cSopenharmony_ci 36e0e9324cSopenharmony_ciint32_t BufferReceiver::OnMediaDataNotify() 37e0e9324cSopenharmony_ci{ 38e0e9324cSopenharmony_ci SHARING_LOGD("BufferReceiver Media notified."); 39e0e9324cSopenharmony_ci dataReady_ = true; 40e0e9324cSopenharmony_ci notifyData_.notify_one(); 41e0e9324cSopenharmony_ci return 0; 42e0e9324cSopenharmony_ci} 43e0e9324cSopenharmony_ci 44e0e9324cSopenharmony_ciint32_t BufferReceiver::OnAudioDataNotify() 45e0e9324cSopenharmony_ci{ 46e0e9324cSopenharmony_ci MEDIA_LOGD("BufferReceiver Audio notified."); 47e0e9324cSopenharmony_ci nonBlockAudio_ = true; 48e0e9324cSopenharmony_ci notifyAudio_.notify_one(); 49e0e9324cSopenharmony_ci return 0; 50e0e9324cSopenharmony_ci} 51e0e9324cSopenharmony_ci 52e0e9324cSopenharmony_ciint32_t BufferReceiver::OnVideoDataNotify() 53e0e9324cSopenharmony_ci{ 54e0e9324cSopenharmony_ci MEDIA_LOGD("BufferReceiver Video notified."); 55e0e9324cSopenharmony_ci nonBlockVideo_ = true; 56e0e9324cSopenharmony_ci notifyVideo_.notify_one(); 57e0e9324cSopenharmony_ci return 0; 58e0e9324cSopenharmony_ci} 59e0e9324cSopenharmony_ci 60e0e9324cSopenharmony_cibool BufferReceiver::IsMixedReceiver() 61e0e9324cSopenharmony_ci{ 62e0e9324cSopenharmony_ci MEDIA_LOGD("trace."); 63e0e9324cSopenharmony_ci return mixed_; 64e0e9324cSopenharmony_ci} 65e0e9324cSopenharmony_ci 66e0e9324cSopenharmony_ciint32_t BufferReceiver::RequestRead(MediaType type, std::function<void(const MediaData::Ptr &data)> cb) 67e0e9324cSopenharmony_ci{ 68e0e9324cSopenharmony_ci MEDIA_LOGD("trace."); 69e0e9324cSopenharmony_ci if (bufferReader_ == nullptr) { 70e0e9324cSopenharmony_ci SHARING_LOGE("BufferReceiver read failed null dispatcher."); 71e0e9324cSopenharmony_ci return -1; 72e0e9324cSopenharmony_ci } 73e0e9324cSopenharmony_ci 74e0e9324cSopenharmony_ci if (firstMRead_ && type == MEDIA_TYPE_AV) { 75e0e9324cSopenharmony_ci bufferReader_->NotifyReadReady(GetReceiverId(), type); 76e0e9324cSopenharmony_ci mixed_ = true; 77e0e9324cSopenharmony_ci firstMRead_ = false; 78e0e9324cSopenharmony_ci } else if (firstARead_ && type == MEDIA_TYPE_AUDIO) { 79e0e9324cSopenharmony_ci bufferReader_->NotifyReadReady(GetReceiverId(), type); 80e0e9324cSopenharmony_ci firstARead_ = false; 81e0e9324cSopenharmony_ci } else if (firstVRead_ && type == MEDIA_TYPE_VIDEO) { 82e0e9324cSopenharmony_ci bufferReader_->NotifyReadReady(GetReceiverId(), type); 83e0e9324cSopenharmony_ci firstVRead_ = false; 84e0e9324cSopenharmony_ci } 85e0e9324cSopenharmony_ci std::unique_lock<std::mutex> locker(mutex_); 86e0e9324cSopenharmony_ci MEDIA_LOGD("BufferDispatcher NotifyThreadWorker before wait, receiverId: %{public}u.", GetReceiverId()); 87e0e9324cSopenharmony_ci switch (type) { 88e0e9324cSopenharmony_ci /* cv will waiting if pred is false; 89e0e9324cSopenharmony_ci so set waiting audio pred (type != MEDIA_TYPE_AUDIO) to NOT block other type.*/ 90e0e9324cSopenharmony_ci case MEDIA_TYPE_AUDIO: 91e0e9324cSopenharmony_ci MEDIA_LOGD("wait Audio, receiverId: %{public}u.", GetReceiverId()); 92e0e9324cSopenharmony_ci notifyAudio_.wait(locker, [=]() { return nonBlockAudio_ || type != MEDIA_TYPE_AUDIO; }); 93e0e9324cSopenharmony_ci nonBlockAudio_ = false; 94e0e9324cSopenharmony_ci break; 95e0e9324cSopenharmony_ci case MEDIA_TYPE_VIDEO: 96e0e9324cSopenharmony_ci MEDIA_LOGD("wait Video, receiverId: %{public}u.", GetReceiverId()); 97e0e9324cSopenharmony_ci notifyVideo_.wait(locker, [=]() { return nonBlockVideo_ || type != MEDIA_TYPE_VIDEO; }); 98e0e9324cSopenharmony_ci nonBlockVideo_ = false; 99e0e9324cSopenharmony_ci break; 100e0e9324cSopenharmony_ci case MEDIA_TYPE_AV: 101e0e9324cSopenharmony_ci MEDIA_LOGD("wait Mixed, receiverId: %{public}u.", GetReceiverId()); 102e0e9324cSopenharmony_ci notifyData_.wait(locker, [=]() { return dataReady_ || type != MEDIA_TYPE_AV; }); 103e0e9324cSopenharmony_ci dataReady_ = false; 104e0e9324cSopenharmony_ci break; 105e0e9324cSopenharmony_ci default: 106e0e9324cSopenharmony_ci return 0; 107e0e9324cSopenharmony_ci break; 108e0e9324cSopenharmony_ci } 109e0e9324cSopenharmony_ci 110e0e9324cSopenharmony_ci bufferReader_->ClearDataBit(GetReceiverId(), type); 111e0e9324cSopenharmony_ci bufferReader_->ClearReadBit(GetReceiverId(), type); 112e0e9324cSopenharmony_ci MEDIA_LOGD("BufferDispatcher NotifyThreadWorker after wait start read, receiverId: %{public}u.", GetReceiverId()); 113e0e9324cSopenharmony_ci int32_t ret = bufferReader_->ReadBufferData(GetReceiverId(), type, cb); 114e0e9324cSopenharmony_ci bufferReader_->NotifyReadReady(GetReceiverId(), type); 115e0e9324cSopenharmony_ci dataReady_ = false; 116e0e9324cSopenharmony_ci 117e0e9324cSopenharmony_ci return ret; 118e0e9324cSopenharmony_ci} 119e0e9324cSopenharmony_ci 120e0e9324cSopenharmony_civoid BufferReceiver::NotifyReadStart() 121e0e9324cSopenharmony_ci{ 122e0e9324cSopenharmony_ci SHARING_LOGD("receiverId: %{public}u notify start read.", GetReceiverId()); 123e0e9324cSopenharmony_ci firstARead_ = true; 124e0e9324cSopenharmony_ci firstVRead_ = true; 125e0e9324cSopenharmony_ci firstMRead_ = true; 126e0e9324cSopenharmony_ci} 127e0e9324cSopenharmony_ci 128e0e9324cSopenharmony_ciuint32_t BufferReceiver::GetReceiverId() 129e0e9324cSopenharmony_ci{ 130e0e9324cSopenharmony_ci MEDIA_LOGD("trace."); 131e0e9324cSopenharmony_ci return GetId(); 132e0e9324cSopenharmony_ci} 133e0e9324cSopenharmony_ci 134e0e9324cSopenharmony_ciuint32_t BufferReceiver::GetDispatcherId() 135e0e9324cSopenharmony_ci{ 136e0e9324cSopenharmony_ci SHARING_LOGD("trace."); 137e0e9324cSopenharmony_ci if (bufferReader_) { 138e0e9324cSopenharmony_ci return bufferReader_->GetDispatcherId(); 139e0e9324cSopenharmony_ci } 140e0e9324cSopenharmony_ci 141e0e9324cSopenharmony_ci return 0; 142e0e9324cSopenharmony_ci} 143e0e9324cSopenharmony_ci 144e0e9324cSopenharmony_civoid BufferReceiver::NotifyReadStop() 145e0e9324cSopenharmony_ci{ 146e0e9324cSopenharmony_ci SHARING_LOGD("receiverId: %{public}u notify stop read.", GetReceiverId()); 147e0e9324cSopenharmony_ci nonBlockAudio_ = true; 148e0e9324cSopenharmony_ci nonBlockVideo_ = true; 149e0e9324cSopenharmony_ci dataReady_ = true; 150e0e9324cSopenharmony_ci notifyAudio_.notify_all(); 151e0e9324cSopenharmony_ci notifyVideo_.notify_all(); 152e0e9324cSopenharmony_ci notifyData_.notify_all(); 153e0e9324cSopenharmony_ci} 154e0e9324cSopenharmony_ci 155e0e9324cSopenharmony_civoid BufferReceiver::EnableKeyMode(bool enable) 156e0e9324cSopenharmony_ci{ 157e0e9324cSopenharmony_ci SHARING_LOGD("bufferReceiver id %{public}u SetKeyOnlyMode %{public}d.", GetReceiverId(), enable); 158e0e9324cSopenharmony_ci if (keyOnly_ == true && enable == false) { 159e0e9324cSopenharmony_ci SHARING_LOGD("Set KeyOnlyMode false, need report fast read over."); 160e0e9324cSopenharmony_ci accelerationDone_ = true; 161e0e9324cSopenharmony_ci } 162e0e9324cSopenharmony_ci 163e0e9324cSopenharmony_ci keyOnly_ = enable; 164e0e9324cSopenharmony_ci if (bufferReader_ && enable) { 165e0e9324cSopenharmony_ci bufferReader_->ClearDataBit(GetReceiverId(), MEDIA_TYPE_VIDEO); 166e0e9324cSopenharmony_ci } 167e0e9324cSopenharmony_ci 168e0e9324cSopenharmony_ci auto listener = listener_.lock(); 169e0e9324cSopenharmony_ci if (listener) { 170e0e9324cSopenharmony_ci listener->OnKeyModeNotify(enable); 171e0e9324cSopenharmony_ci } 172e0e9324cSopenharmony_ci} 173e0e9324cSopenharmony_ci 174e0e9324cSopenharmony_cibool BufferReceiver::IsKeyMode() 175e0e9324cSopenharmony_ci{ 176e0e9324cSopenharmony_ci MEDIA_LOGD("trace."); 177e0e9324cSopenharmony_ci return keyOnly_; 178e0e9324cSopenharmony_ci} 179e0e9324cSopenharmony_ci 180e0e9324cSopenharmony_cibool BufferReceiver::IsKeyRedirect() 181e0e9324cSopenharmony_ci{ 182e0e9324cSopenharmony_ci SHARING_LOGD("trace."); 183e0e9324cSopenharmony_ci return keyRedirect_; 184e0e9324cSopenharmony_ci} 185e0e9324cSopenharmony_ci 186e0e9324cSopenharmony_ciconst MediaData::Ptr BufferReceiver::GetSPS() 187e0e9324cSopenharmony_ci{ 188e0e9324cSopenharmony_ci MEDIA_LOGD("trace."); 189e0e9324cSopenharmony_ci if (bufferReader_) { 190e0e9324cSopenharmony_ci return bufferReader_->GetSPS(); 191e0e9324cSopenharmony_ci } 192e0e9324cSopenharmony_ci 193e0e9324cSopenharmony_ci return nullptr; 194e0e9324cSopenharmony_ci} 195e0e9324cSopenharmony_ci 196e0e9324cSopenharmony_ciconst MediaData::Ptr BufferReceiver::GetPPS() 197e0e9324cSopenharmony_ci{ 198e0e9324cSopenharmony_ci MEDIA_LOGD("trace."); 199e0e9324cSopenharmony_ci if (bufferReader_) { 200e0e9324cSopenharmony_ci return bufferReader_->GetPPS(); 201e0e9324cSopenharmony_ci } 202e0e9324cSopenharmony_ci 203e0e9324cSopenharmony_ci return nullptr; 204e0e9324cSopenharmony_ci} 205e0e9324cSopenharmony_ci 206e0e9324cSopenharmony_cibool BufferReceiver::NeedAcceleration() 207e0e9324cSopenharmony_ci{ 208e0e9324cSopenharmony_ci MEDIA_LOGD("trace."); 209e0e9324cSopenharmony_ci return accelerationDone_; 210e0e9324cSopenharmony_ci} 211e0e9324cSopenharmony_ci 212e0e9324cSopenharmony_civoid BufferReceiver::DisableAcceleration() 213e0e9324cSopenharmony_ci{ 214e0e9324cSopenharmony_ci SHARING_LOGD("trace."); 215e0e9324cSopenharmony_ci accelerationDone_ = false; 216e0e9324cSopenharmony_ci} 217e0e9324cSopenharmony_ci 218e0e9324cSopenharmony_civoid BufferReceiver::SendAccelerationDone() 219e0e9324cSopenharmony_ci{ 220e0e9324cSopenharmony_ci SHARING_LOGD("trace."); 221e0e9324cSopenharmony_ci auto listener = listener_.lock(); 222e0e9324cSopenharmony_ci if (listener) { 223e0e9324cSopenharmony_ci listener->OnAccelerationDoneNotify(); 224e0e9324cSopenharmony_ci } 225e0e9324cSopenharmony_ci} 226e0e9324cSopenharmony_ci 227e0e9324cSopenharmony_civoid BufferReceiver::EnableKeyRedirect(bool enable) 228e0e9324cSopenharmony_ci{ 229e0e9324cSopenharmony_ci SHARING_LOGD("trace."); 230e0e9324cSopenharmony_ci if (bufferReader_ && enable) { 231e0e9324cSopenharmony_ci bufferReader_->EnableKeyRedirect(enable); 232e0e9324cSopenharmony_ci } 233e0e9324cSopenharmony_ci keyRedirect_ = enable; 234e0e9324cSopenharmony_ci} 235e0e9324cSopenharmony_ci 236e0e9324cSopenharmony_civoid BufferReceiver::SetBufferReceiverListener(std::weak_ptr<IBufferReceiverListener> listener) 237e0e9324cSopenharmony_ci{ 238e0e9324cSopenharmony_ci SHARING_LOGD("trace."); 239e0e9324cSopenharmony_ci listener_ = listener; 240e0e9324cSopenharmony_ci} 241e0e9324cSopenharmony_ci 242e0e9324cSopenharmony_ciusing DataNotifier = BufferDispatcher::DataNotifier; 243e0e9324cSopenharmony_ci 244e0e9324cSopenharmony_civoid DataNotifier::NotifyDataReceiver(MediaType type) 245e0e9324cSopenharmony_ci{ 246e0e9324cSopenharmony_ci MEDIA_LOGD("trace."); 247e0e9324cSopenharmony_ci if (receiver_.lock() == nullptr) { 248e0e9324cSopenharmony_ci SHARING_LOGE("target receiver NOT exist."); 249e0e9324cSopenharmony_ci return; 250e0e9324cSopenharmony_ci } 251e0e9324cSopenharmony_ci 252e0e9324cSopenharmony_ci if (block_) { 253e0e9324cSopenharmony_ci return; 254e0e9324cSopenharmony_ci } 255e0e9324cSopenharmony_ci 256e0e9324cSopenharmony_ci MEDIA_LOGD("notify target type %{public}d.", type); 257e0e9324cSopenharmony_ci switch (type) { 258e0e9324cSopenharmony_ci case MEDIA_TYPE_AUDIO: 259e0e9324cSopenharmony_ci GetBufferReceiver()->OnAudioDataNotify(); 260e0e9324cSopenharmony_ci break; 261e0e9324cSopenharmony_ci case MEDIA_TYPE_VIDEO: 262e0e9324cSopenharmony_ci GetBufferReceiver()->OnVideoDataNotify(); 263e0e9324cSopenharmony_ci break; 264e0e9324cSopenharmony_ci case MEDIA_TYPE_AV: 265e0e9324cSopenharmony_ci GetBufferReceiver()->OnMediaDataNotify(); 266e0e9324cSopenharmony_ci break; 267e0e9324cSopenharmony_ci default: 268e0e9324cSopenharmony_ci SHARING_LOGI("none process case."); 269e0e9324cSopenharmony_ci break; 270e0e9324cSopenharmony_ci } 271e0e9324cSopenharmony_ci} 272e0e9324cSopenharmony_ci 273e0e9324cSopenharmony_ciBufferReceiver::Ptr DataNotifier::GetBufferReceiver() 274e0e9324cSopenharmony_ci{ 275e0e9324cSopenharmony_ci MEDIA_LOGD("trace."); 276e0e9324cSopenharmony_ci return receiver_.lock(); 277e0e9324cSopenharmony_ci} 278e0e9324cSopenharmony_ci 279e0e9324cSopenharmony_ciuint32_t DataNotifier::GetReceiverId() 280e0e9324cSopenharmony_ci{ 281e0e9324cSopenharmony_ci MEDIA_LOGD("trace."); 282e0e9324cSopenharmony_ci auto receiver = receiver_.lock(); 283e0e9324cSopenharmony_ci if (receiver == nullptr) { 284e0e9324cSopenharmony_ci SHARING_LOGE("target receiver NOT exist."); 285e0e9324cSopenharmony_ci return INVALID_INDEX; 286e0e9324cSopenharmony_ci } 287e0e9324cSopenharmony_ci 288e0e9324cSopenharmony_ci return receiver->GetReceiverId(); 289e0e9324cSopenharmony_ci} 290e0e9324cSopenharmony_ci 291e0e9324cSopenharmony_civoid DataNotifier::SetListenDispatcher(IBufferReader::Ptr dispatcher) 292e0e9324cSopenharmony_ci{ 293e0e9324cSopenharmony_ci SHARING_LOGD("trace."); 294e0e9324cSopenharmony_ci dispatcher_ = dispatcher; 295e0e9324cSopenharmony_ci} 296e0e9324cSopenharmony_ci 297e0e9324cSopenharmony_civoid DataNotifier::SetNotifyReceiver(BufferReceiver::Ptr receiver) 298e0e9324cSopenharmony_ci{ 299e0e9324cSopenharmony_ci SHARING_LOGD("trace."); 300e0e9324cSopenharmony_ci receiver_ = receiver; 301e0e9324cSopenharmony_ci} 302e0e9324cSopenharmony_ci 303e0e9324cSopenharmony_civoid DataNotifier::SetBlock() 304e0e9324cSopenharmony_ci{ 305e0e9324cSopenharmony_ci SHARING_LOGD("trace."); 306e0e9324cSopenharmony_ci block_ = true; 307e0e9324cSopenharmony_ci} 308e0e9324cSopenharmony_ci 309e0e9324cSopenharmony_civoid DataNotifier::SetNeedUpdate(bool enable, MediaType type) 310e0e9324cSopenharmony_ci{ 311e0e9324cSopenharmony_ci MEDIA_LOGD("trace."); 312e0e9324cSopenharmony_ci if (type == MEDIA_TYPE_AUDIO) { 313e0e9324cSopenharmony_ci needUpdateAIndex = enable; 314e0e9324cSopenharmony_ci } else { 315e0e9324cSopenharmony_ci needUpdateVIndex = enable; 316e0e9324cSopenharmony_ci } 317e0e9324cSopenharmony_ci} 318e0e9324cSopenharmony_ci 319e0e9324cSopenharmony_cibool DataNotifier::DataAvailable(MediaType type) 320e0e9324cSopenharmony_ci{ 321e0e9324cSopenharmony_ci MEDIA_LOGD("trace."); 322e0e9324cSopenharmony_ci auto dispatcher = dispatcher_.lock(); 323e0e9324cSopenharmony_ci if (dispatcher == nullptr) { 324e0e9324cSopenharmony_ci SHARING_LOGE("target dispatcher NOT exist."); 325e0e9324cSopenharmony_ci return false; 326e0e9324cSopenharmony_ci } 327e0e9324cSopenharmony_ci 328e0e9324cSopenharmony_ci if (type == MEDIA_TYPE_AUDIO) { 329e0e9324cSopenharmony_ci return audioIndex != INVALID_INDEX && 330e0e9324cSopenharmony_ci (audioIndex < dispatcher->GetLatestAudioIndex() || !dispatcher->IsRead(GetReceiverId(), audioIndex + 1)); 331e0e9324cSopenharmony_ci } else if (type == MEDIA_TYPE_VIDEO) { 332e0e9324cSopenharmony_ci return videoIndex != INVALID_INDEX && 333e0e9324cSopenharmony_ci (videoIndex < dispatcher->GetLatestVideoIndex() || !dispatcher->IsRead(GetReceiverId(), videoIndex + 1)); 334e0e9324cSopenharmony_ci } else { 335e0e9324cSopenharmony_ci return videoIndex != INVALID_INDEX && 336e0e9324cSopenharmony_ci (videoIndex < dispatcher->GetBufferSize() - 1 || !dispatcher->IsRead(GetReceiverId(), videoIndex + 1)); 337e0e9324cSopenharmony_ci } 338e0e9324cSopenharmony_ci 339e0e9324cSopenharmony_ci return false; 340e0e9324cSopenharmony_ci} 341e0e9324cSopenharmony_ci 342e0e9324cSopenharmony_cibool DataNotifier::IsMixedReceiver() 343e0e9324cSopenharmony_ci{ 344e0e9324cSopenharmony_ci MEDIA_LOGD("trace."); 345e0e9324cSopenharmony_ci auto receiver = receiver_.lock(); 346e0e9324cSopenharmony_ci if (receiver == nullptr) { 347e0e9324cSopenharmony_ci SHARING_LOGE("target receiver NOT exist."); 348e0e9324cSopenharmony_ci return false; 349e0e9324cSopenharmony_ci } 350e0e9324cSopenharmony_ci 351e0e9324cSopenharmony_ci return receiver->IsMixedReceiver(); 352e0e9324cSopenharmony_ci} 353e0e9324cSopenharmony_ci 354e0e9324cSopenharmony_ciuint32_t DataNotifier::GetReceiverReadIndex(MediaType type) 355e0e9324cSopenharmony_ci{ 356e0e9324cSopenharmony_ci MEDIA_LOGD("trace."); 357e0e9324cSopenharmony_ci switch (type) { 358e0e9324cSopenharmony_ci case MEDIA_TYPE_VIDEO: 359e0e9324cSopenharmony_ci MEDIA_LOGD("Video Recvid:%{public}d index: %{public}d.", GetReceiverId(), videoIndex); 360e0e9324cSopenharmony_ci return videoIndex; 361e0e9324cSopenharmony_ci break; 362e0e9324cSopenharmony_ci case MEDIA_TYPE_AUDIO: 363e0e9324cSopenharmony_ci MEDIA_LOGD("Audio Recvid:%{public}d index: %{public}d.", GetReceiverId(), audioIndex); 364e0e9324cSopenharmony_ci return audioIndex; 365e0e9324cSopenharmony_ci break; 366e0e9324cSopenharmony_ci case MEDIA_TYPE_AV: 367e0e9324cSopenharmony_ci MEDIA_LOGD("Mixed Recvid:%{public}d vindex: %{public}d aindex: %{public}d.", GetReceiverId(), videoIndex, 368e0e9324cSopenharmony_ci audioIndex); 369e0e9324cSopenharmony_ci if (audioIndex != INVALID_INDEX && videoIndex != INVALID_INDEX) { 370e0e9324cSopenharmony_ci return audioIndex <= videoIndex ? audioIndex : videoIndex; 371e0e9324cSopenharmony_ci } else if (audioIndex == INVALID_INDEX && videoIndex == INVALID_INDEX) { 372e0e9324cSopenharmony_ci return INVALID_INDEX; 373e0e9324cSopenharmony_ci } else { 374e0e9324cSopenharmony_ci return audioIndex == INVALID_INDEX ? videoIndex : audioIndex; 375e0e9324cSopenharmony_ci } 376e0e9324cSopenharmony_ci break; 377e0e9324cSopenharmony_ci default: 378e0e9324cSopenharmony_ci return INVALID_INDEX; 379e0e9324cSopenharmony_ci break; 380e0e9324cSopenharmony_ci } 381e0e9324cSopenharmony_ci} 382e0e9324cSopenharmony_ci 383e0e9324cSopenharmony_cibool DataNotifier::IsKeyModeReceiver() 384e0e9324cSopenharmony_ci{ 385e0e9324cSopenharmony_ci MEDIA_LOGD("trace."); 386e0e9324cSopenharmony_ci auto receiver = receiver_.lock(); 387e0e9324cSopenharmony_ci if (receiver) { 388e0e9324cSopenharmony_ci return receiver->IsKeyMode(); 389e0e9324cSopenharmony_ci } 390e0e9324cSopenharmony_ci 391e0e9324cSopenharmony_ci return false; 392e0e9324cSopenharmony_ci} 393e0e9324cSopenharmony_ci 394e0e9324cSopenharmony_cibool DataNotifier::IsKeyRedirectReceiver() 395e0e9324cSopenharmony_ci{ 396e0e9324cSopenharmony_ci SHARING_LOGD("trace."); 397e0e9324cSopenharmony_ci auto receiver = receiver_.lock(); 398e0e9324cSopenharmony_ci if (receiver) { 399e0e9324cSopenharmony_ci return receiver->IsKeyRedirect(); 400e0e9324cSopenharmony_ci } 401e0e9324cSopenharmony_ci 402e0e9324cSopenharmony_ci return false; 403e0e9324cSopenharmony_ci} 404e0e9324cSopenharmony_ci 405e0e9324cSopenharmony_cibool DataNotifier::NeedAcceleration() 406e0e9324cSopenharmony_ci{ 407e0e9324cSopenharmony_ci MEDIA_LOGD("trace."); 408e0e9324cSopenharmony_ci auto receiver = receiver_.lock(); 409e0e9324cSopenharmony_ci if (receiver == nullptr) { 410e0e9324cSopenharmony_ci SHARING_LOGE("target receiver NOT exist."); 411e0e9324cSopenharmony_ci return false; 412e0e9324cSopenharmony_ci } 413e0e9324cSopenharmony_ci 414e0e9324cSopenharmony_ci return receiver->NeedAcceleration(); 415e0e9324cSopenharmony_ci} 416e0e9324cSopenharmony_ci 417e0e9324cSopenharmony_civoid DataNotifier::SendAccelerationDone() 418e0e9324cSopenharmony_ci{ 419e0e9324cSopenharmony_ci SHARING_LOGD("trace."); 420e0e9324cSopenharmony_ci auto receiver = receiver_.lock(); 421e0e9324cSopenharmony_ci if (receiver == nullptr) { 422e0e9324cSopenharmony_ci SHARING_LOGE("target receiver NOT exist."); 423e0e9324cSopenharmony_ci return; 424e0e9324cSopenharmony_ci } 425e0e9324cSopenharmony_ci 426e0e9324cSopenharmony_ci receiver->SendAccelerationDone(); 427e0e9324cSopenharmony_ci receiver->DisableAcceleration(); 428e0e9324cSopenharmony_ci} 429e0e9324cSopenharmony_ci 430e0e9324cSopenharmony_ciBufferDispatcher::BufferDispatcher(uint32_t maxCapacity, uint32_t capacityIncrement) 431e0e9324cSopenharmony_ci{ 432e0e9324cSopenharmony_ci SHARING_LOGD("BufferDispatcher ctor, set capacity: %{public}u.", maxCapacity); 433e0e9324cSopenharmony_ci maxBufferCapacity_ = maxCapacity; 434e0e9324cSopenharmony_ci bufferCapacityIncrement_ = capacityIncrement; 435e0e9324cSopenharmony_ci { 436e0e9324cSopenharmony_ci std::lock_guard<std::mutex> lock(idleMutex_); 437e0e9324cSopenharmony_ci idleAudioBuffer_.set_capacity(INITIAL_BUFFER_CAPACITY); 438e0e9324cSopenharmony_ci idleVideoBuffer_.set_capacity(INITIAL_BUFFER_CAPACITY); 439e0e9324cSopenharmony_ci for (size_t i = 0; i < INITIAL_BUFFER_CAPACITY; i++) { 440e0e9324cSopenharmony_ci MediaData::Ptr adata = std::make_shared<MediaData>(); 441e0e9324cSopenharmony_ci MediaData::Ptr vdata = std::make_shared<MediaData>(); 442e0e9324cSopenharmony_ci adata->buff = std::make_shared<DataBuffer>(); 443e0e9324cSopenharmony_ci vdata->buff = std::make_shared<DataBuffer>(); 444e0e9324cSopenharmony_ci idleAudioBuffer_.push_back(adata); 445e0e9324cSopenharmony_ci idleVideoBuffer_.push_back(vdata); 446e0e9324cSopenharmony_ci } 447e0e9324cSopenharmony_ci } 448e0e9324cSopenharmony_ci 449e0e9324cSopenharmony_ci writingTimer_ = std::make_unique<TimeoutTimer>("dispatcher-writing-timer"); 450e0e9324cSopenharmony_ci 451e0e9324cSopenharmony_ci std::unique_lock<std::shared_mutex> locker(bufferMutex_); 452e0e9324cSopenharmony_ci circularBuffer_.set_capacity(INITIAL_BUFFER_CAPACITY); 453e0e9324cSopenharmony_ci StartDispatch(); 454e0e9324cSopenharmony_ci} 455e0e9324cSopenharmony_ci 456e0e9324cSopenharmony_ciBufferDispatcher::~BufferDispatcher() 457e0e9324cSopenharmony_ci{ 458e0e9324cSopenharmony_ci SHARING_LOGI("BufferDispatcher dtor."); 459e0e9324cSopenharmony_ci running_ = false; 460e0e9324cSopenharmony_ci StopDispatch(); 461e0e9324cSopenharmony_ci FlushBuffer(); 462e0e9324cSopenharmony_ci ReleaseIdleBuffer(); 463e0e9324cSopenharmony_ci ReleaseAllReceiver(); 464e0e9324cSopenharmony_ci} 465e0e9324cSopenharmony_ci 466e0e9324cSopenharmony_civoid BufferDispatcher::StartDispatch() 467e0e9324cSopenharmony_ci{ 468e0e9324cSopenharmony_ci SHARING_LOGD("trace."); 469e0e9324cSopenharmony_ci running_ = true; 470e0e9324cSopenharmony_ci notifyThread_ = std::thread(&BufferDispatcher::NotifyThreadWorker, this); 471e0e9324cSopenharmony_ci std::string name = "notifyThread"; 472e0e9324cSopenharmony_ci pthread_setname_np(notifyThread_.native_handle(), name.c_str()); 473e0e9324cSopenharmony_ci} 474e0e9324cSopenharmony_ci 475e0e9324cSopenharmony_civoid BufferDispatcher::StopDispatch() 476e0e9324cSopenharmony_ci{ 477e0e9324cSopenharmony_ci SHARING_LOGD("trace."); 478e0e9324cSopenharmony_ci running_ = false; 479e0e9324cSopenharmony_ci continueNotify_ = true; 480e0e9324cSopenharmony_ci 481e0e9324cSopenharmony_ci if (writingTimer_) { 482e0e9324cSopenharmony_ci writingTimer_.reset(); 483e0e9324cSopenharmony_ci } 484e0e9324cSopenharmony_ci 485e0e9324cSopenharmony_ci dataCV_.notify_all(); 486e0e9324cSopenharmony_ci if (notifyThread_.joinable()) { 487e0e9324cSopenharmony_ci notifyThread_.join(); 488e0e9324cSopenharmony_ci } 489e0e9324cSopenharmony_ci} 490e0e9324cSopenharmony_ci 491e0e9324cSopenharmony_civoid BufferDispatcher::SetBufferCapacity(size_t capacity) 492e0e9324cSopenharmony_ci{ 493e0e9324cSopenharmony_ci SHARING_LOGD("trace."); 494e0e9324cSopenharmony_ci std::unique_lock<std::shared_mutex> locker(bufferMutex_); 495e0e9324cSopenharmony_ci circularBuffer_.set_capacity(capacity); 496e0e9324cSopenharmony_ci} 497e0e9324cSopenharmony_ci 498e0e9324cSopenharmony_civoid BufferDispatcher::SetDataMode(MediaDispacherMode dataMode) 499e0e9324cSopenharmony_ci{ 500e0e9324cSopenharmony_ci SHARING_LOGD("trace."); 501e0e9324cSopenharmony_ci dataMode_ = dataMode; 502e0e9324cSopenharmony_ci} 503e0e9324cSopenharmony_ci 504e0e9324cSopenharmony_civoid BufferDispatcher::ReleaseIdleBuffer() 505e0e9324cSopenharmony_ci{ 506e0e9324cSopenharmony_ci SHARING_LOGD("BufferDispatcher idle Release Start."); 507e0e9324cSopenharmony_ci std::unique_lock<std::mutex> locker(idleMutex_); 508e0e9324cSopenharmony_ci for (auto &data : idleAudioBuffer_) { 509e0e9324cSopenharmony_ci if (data != nullptr && data->buff != nullptr) { 510e0e9324cSopenharmony_ci data->buff.reset(); 511e0e9324cSopenharmony_ci } 512e0e9324cSopenharmony_ci } 513e0e9324cSopenharmony_ci 514e0e9324cSopenharmony_ci idleAudioBuffer_.clear(); 515e0e9324cSopenharmony_ci for (auto &data : idleVideoBuffer_) { 516e0e9324cSopenharmony_ci if (data != nullptr && data->buff != nullptr) { 517e0e9324cSopenharmony_ci data->buff.reset(); 518e0e9324cSopenharmony_ci } 519e0e9324cSopenharmony_ci } 520e0e9324cSopenharmony_ci 521e0e9324cSopenharmony_ci idleVideoBuffer_.clear(); 522e0e9324cSopenharmony_ci SHARING_LOGD("BufferDispatcher idle Release End."); 523e0e9324cSopenharmony_ci} 524e0e9324cSopenharmony_ci 525e0e9324cSopenharmony_civoid BufferDispatcher::FlushBuffer() 526e0e9324cSopenharmony_ci{ 527e0e9324cSopenharmony_ci SHARING_LOGI("BufferDispatcher Start flushing, dispatcherId: %{public}u.", GetDispatcherId()); 528e0e9324cSopenharmony_ci { 529e0e9324cSopenharmony_ci std::lock_guard<std::mutex> lock(idleMutex_); 530e0e9324cSopenharmony_ci idleAudioBuffer_.clear(); 531e0e9324cSopenharmony_ci idleVideoBuffer_.clear(); 532e0e9324cSopenharmony_ci for (size_t i = 0; i < INITIAL_BUFFER_CAPACITY; i++) { 533e0e9324cSopenharmony_ci MediaData::Ptr adata = std::make_shared<MediaData>(); 534e0e9324cSopenharmony_ci MediaData::Ptr vdata = std::make_shared<MediaData>(); 535e0e9324cSopenharmony_ci adata->buff = std::make_shared<DataBuffer>(); 536e0e9324cSopenharmony_ci vdata->buff = std::make_shared<DataBuffer>(); 537e0e9324cSopenharmony_ci idleAudioBuffer_.push_back(adata); 538e0e9324cSopenharmony_ci idleVideoBuffer_.push_back(vdata); 539e0e9324cSopenharmony_ci } 540e0e9324cSopenharmony_ci } 541e0e9324cSopenharmony_ci 542e0e9324cSopenharmony_ci std::unique_lock<std::shared_mutex> locker(bufferMutex_); 543e0e9324cSopenharmony_ci for (auto &data : circularBuffer_) { 544e0e9324cSopenharmony_ci if (data->mediaData != nullptr && data->mediaData->buff != nullptr) { 545e0e9324cSopenharmony_ci data->mediaData->buff.reset(); 546e0e9324cSopenharmony_ci } 547e0e9324cSopenharmony_ci } 548e0e9324cSopenharmony_ci 549e0e9324cSopenharmony_ci circularBuffer_.clear(); 550e0e9324cSopenharmony_ci waitingKey_ = true; 551e0e9324cSopenharmony_ci gop_ = 0; 552e0e9324cSopenharmony_ci audioFrameCnt_ = 0; 553e0e9324cSopenharmony_ci videoFrameCnt_ = 0; 554e0e9324cSopenharmony_ci ResetAllIndex(); 555e0e9324cSopenharmony_ci SHARING_LOGD("BufferDispatcher Dispatcher flushing end, dispatcherId: %{public}u.", GetDispatcherId()); 556e0e9324cSopenharmony_ci} 557e0e9324cSopenharmony_ci 558e0e9324cSopenharmony_ciMediaData::Ptr BufferDispatcher::RequestDataBuffer(MediaType type, uint32_t size) 559e0e9324cSopenharmony_ci{ 560e0e9324cSopenharmony_ci SHARING_LOGD("trace."); 561e0e9324cSopenharmony_ci std::lock_guard<std::mutex> lock(idleMutex_); 562e0e9324cSopenharmony_ci if (size <= 0) { 563e0e9324cSopenharmony_ci SHARING_LOGE("Size invalid."); 564e0e9324cSopenharmony_ci return nullptr; 565e0e9324cSopenharmony_ci } 566e0e9324cSopenharmony_ci 567e0e9324cSopenharmony_ci MediaData::Ptr retData; 568e0e9324cSopenharmony_ci if (type == MEDIA_TYPE_VIDEO) { 569e0e9324cSopenharmony_ci if (!idleVideoBuffer_.empty()) { 570e0e9324cSopenharmony_ci SHARING_LOGD("video From idle."); 571e0e9324cSopenharmony_ci retData = idleVideoBuffer_.front(); 572e0e9324cSopenharmony_ci idleVideoBuffer_.pop_front(); 573e0e9324cSopenharmony_ci if (retData == nullptr) { 574e0e9324cSopenharmony_ci MEDIA_LOGW("video From alloc when idle nullptr."); 575e0e9324cSopenharmony_ci retData = std::make_shared<MediaData>(); 576e0e9324cSopenharmony_ci } 577e0e9324cSopenharmony_ci return retData; 578e0e9324cSopenharmony_ci } 579e0e9324cSopenharmony_ci } else { 580e0e9324cSopenharmony_ci if (!idleAudioBuffer_.empty()) { 581e0e9324cSopenharmony_ci SHARING_LOGD("Audio From idle."); 582e0e9324cSopenharmony_ci retData = idleAudioBuffer_.front(); 583e0e9324cSopenharmony_ci idleAudioBuffer_.pop_front(); 584e0e9324cSopenharmony_ci if (retData == nullptr) { 585e0e9324cSopenharmony_ci MEDIA_LOGW("Audio From alloc when idle nullptr."); 586e0e9324cSopenharmony_ci retData = std::make_shared<MediaData>(); 587e0e9324cSopenharmony_ci } 588e0e9324cSopenharmony_ci return retData; 589e0e9324cSopenharmony_ci } 590e0e9324cSopenharmony_ci } 591e0e9324cSopenharmony_ci 592e0e9324cSopenharmony_ci SHARING_LOGD("Audio/video from alloc."); 593e0e9324cSopenharmony_ci retData = std::make_shared<MediaData>(); 594e0e9324cSopenharmony_ci return retData; 595e0e9324cSopenharmony_ci} 596e0e9324cSopenharmony_ci 597e0e9324cSopenharmony_civoid BufferDispatcher::ReturnIdleBuffer(DataSpec::Ptr &data) 598e0e9324cSopenharmony_ci{ 599e0e9324cSopenharmony_ci MEDIA_LOGD("trace."); 600e0e9324cSopenharmony_ci std::lock_guard<std::mutex> lock(idleMutex_); 601e0e9324cSopenharmony_ci if (data == nullptr || data->mediaData == nullptr) { 602e0e9324cSopenharmony_ci return; 603e0e9324cSopenharmony_ci } 604e0e9324cSopenharmony_ci if (data->mediaData->mediaType == MEDIA_TYPE_VIDEO) { 605e0e9324cSopenharmony_ci if (idleVideoBuffer_.size() < INITIAL_BUFFER_CAPACITY) { 606e0e9324cSopenharmony_ci idleVideoBuffer_.push_back(data->mediaData); 607e0e9324cSopenharmony_ci MEDIA_LOGD("data: push_back in idleVideoBuffer_, size: %{public}zu.", idleVideoBuffer_.size()); 608e0e9324cSopenharmony_ci } 609e0e9324cSopenharmony_ci } else { 610e0e9324cSopenharmony_ci if (idleAudioBuffer_.size() < INITIAL_BUFFER_CAPACITY) { 611e0e9324cSopenharmony_ci idleAudioBuffer_.push_back(data->mediaData); 612e0e9324cSopenharmony_ci MEDIA_LOGD("data: push_back in idleAudioBuffer_, size: %{public}zu.", idleAudioBuffer_.size()); 613e0e9324cSopenharmony_ci } 614e0e9324cSopenharmony_ci } 615e0e9324cSopenharmony_ci 616e0e9324cSopenharmony_ci data.reset(); 617e0e9324cSopenharmony_ci} 618e0e9324cSopenharmony_ci 619e0e9324cSopenharmony_cisize_t BufferDispatcher::GetBufferSize() 620e0e9324cSopenharmony_ci{ 621e0e9324cSopenharmony_ci SHARING_LOGD("trace."); 622e0e9324cSopenharmony_ci return circularBuffer_.size(); 623e0e9324cSopenharmony_ci} 624e0e9324cSopenharmony_ci 625e0e9324cSopenharmony_ciuint32_t BufferDispatcher::FindReceiverIndex(uint32_t receiverId) 626e0e9324cSopenharmony_ci{ 627e0e9324cSopenharmony_ci MEDIA_LOGD("trace."); 628e0e9324cSopenharmony_ci if (notifiers_.find(receiverId) != notifiers_.end()) { 629e0e9324cSopenharmony_ci return notifiers_[receiverId]->GetReadIndex(); 630e0e9324cSopenharmony_ci } 631e0e9324cSopenharmony_ci 632e0e9324cSopenharmony_ci return INVALID_INDEX; 633e0e9324cSopenharmony_ci} 634e0e9324cSopenharmony_ci 635e0e9324cSopenharmony_cibool BufferDispatcher::IsRecevierExist(uint32_t receiverId) 636e0e9324cSopenharmony_ci{ 637e0e9324cSopenharmony_ci SHARING_LOGD("trace."); 638e0e9324cSopenharmony_ci auto notifier = GetNotifierByReceiverId(receiverId); 639e0e9324cSopenharmony_ci if (notifier == nullptr) { 640e0e9324cSopenharmony_ci return false; 641e0e9324cSopenharmony_ci } 642e0e9324cSopenharmony_ci 643e0e9324cSopenharmony_ci return true; 644e0e9324cSopenharmony_ci} 645e0e9324cSopenharmony_ci 646e0e9324cSopenharmony_civoid BufferDispatcher::EnableKeyMode(bool enable) 647e0e9324cSopenharmony_ci{ 648e0e9324cSopenharmony_ci SHARING_LOGD("trace."); 649e0e9324cSopenharmony_ci keyOnly_ = enable; 650e0e9324cSopenharmony_ci} 651e0e9324cSopenharmony_ci 652e0e9324cSopenharmony_ciint32_t BufferDispatcher::AttachReceiver(BufferReceiver::Ptr receiver) 653e0e9324cSopenharmony_ci{ 654e0e9324cSopenharmony_ci SHARING_LOGD("trace."); 655e0e9324cSopenharmony_ci if (receiver == nullptr) { 656e0e9324cSopenharmony_ci return -1; 657e0e9324cSopenharmony_ci } 658e0e9324cSopenharmony_ci 659e0e9324cSopenharmony_ci if (IsRecevierExist(receiver->GetReceiverId())) { 660e0e9324cSopenharmony_ci SHARING_LOGE("Exist."); 661e0e9324cSopenharmony_ci return 0; 662e0e9324cSopenharmony_ci } 663e0e9324cSopenharmony_ci 664e0e9324cSopenharmony_ci receiver->NotifyReadStart(); 665e0e9324cSopenharmony_ci std::lock_guard<std::mutex> locker(notifyMutex_); 666e0e9324cSopenharmony_ci if (readRefFlag_ == 0xFFFF) { 667e0e9324cSopenharmony_ci SHARING_LOGE("readRefFlag limited."); 668e0e9324cSopenharmony_ci return -1; 669e0e9324cSopenharmony_ci } 670e0e9324cSopenharmony_ci 671e0e9324cSopenharmony_ci DataNotifier::Ptr notifier = std::make_shared<DataNotifier>(); 672e0e9324cSopenharmony_ci notifier->SetListenDispatcher(shared_from_this()); 673e0e9324cSopenharmony_ci notifier->SetNotifyReceiver(receiver); 674e0e9324cSopenharmony_ci 675e0e9324cSopenharmony_ci auto usableRef = ~readRefFlag_ & (-(~readRefFlag_)); 676e0e9324cSopenharmony_ci 677e0e9324cSopenharmony_ci if ((usableRef & (usableRef - 1)) != 0) { 678e0e9324cSopenharmony_ci SHARING_LOGE("usableRef: %{public}d invalid.", usableRef); 679e0e9324cSopenharmony_ci return -1; 680e0e9324cSopenharmony_ci } 681e0e9324cSopenharmony_ci 682e0e9324cSopenharmony_ci readRefFlag_ |= usableRef; 683e0e9324cSopenharmony_ci notifier->SetReadIndex(static_cast<uint32_t>(log2(usableRef))); 684e0e9324cSopenharmony_ci SHARING_LOGI("receiverId: %{public}d, readIndex: %{public}d, usableRef: %{public}d, readRefFlag_: %{public}d.", 685e0e9324cSopenharmony_ci receiver->GetReceiverId(), notifier->GetReadIndex(), usableRef, readRefFlag_); 686e0e9324cSopenharmony_ci receiver->SetSource(shared_from_this()); 687e0e9324cSopenharmony_ci notifiers_.emplace(receiver->GetReceiverId(), notifier); 688e0e9324cSopenharmony_ci 689e0e9324cSopenharmony_ci if (circularBuffer_.empty()) { 690e0e9324cSopenharmony_ci notifier->audioIndex = INVALID_INDEX; 691e0e9324cSopenharmony_ci notifier->videoIndex = INVALID_INDEX; 692e0e9324cSopenharmony_ci SetReceiverDataRef(receiver->GetReceiverId(), MEDIA_TYPE_AUDIO, false); 693e0e9324cSopenharmony_ci SetReceiverDataRef(receiver->GetReceiverId(), MEDIA_TYPE_VIDEO, false); 694e0e9324cSopenharmony_ci SHARING_LOGD("BufferDispatcher Attach when buffer empty RecvId: %{public}d.", receiver->GetReceiverId()); 695e0e9324cSopenharmony_ci videoNeedActivate_ = true; 696e0e9324cSopenharmony_ci audioNeedActivate_ = true; 697e0e9324cSopenharmony_ci return 0; 698e0e9324cSopenharmony_ci } 699e0e9324cSopenharmony_ci 700e0e9324cSopenharmony_ci if (dataMode_ == MEDIA_AUDIO_ONLY) { 701e0e9324cSopenharmony_ci notifier->audioIndex = circularBuffer_.size() - 1; 702e0e9324cSopenharmony_ci SetReceiverDataRef(receiver->GetReceiverId(), MEDIA_TYPE_AUDIO, true); 703e0e9324cSopenharmony_ci notifier->videoIndex = INVALID_INDEX; 704e0e9324cSopenharmony_ci SetReceiverDataRef(receiver->GetReceiverId(), MEDIA_TYPE_VIDEO, false); 705e0e9324cSopenharmony_ci SHARING_LOGD("BufferDispatcher Attach when Keyindex List empty RecvId: %{public}d.", 706e0e9324cSopenharmony_ci receiver->GetReceiverId()); 707e0e9324cSopenharmony_ci } else { 708e0e9324cSopenharmony_ci if (!keyIndexList_.empty()) { 709e0e9324cSopenharmony_ci SHARING_LOGD("BufferDispatcher Attach with Keyindex RecvId: %{public}d KeyIndex:%{public}d.", 710e0e9324cSopenharmony_ci receiver->GetReceiverId(), keyIndexList_.back()); 711e0e9324cSopenharmony_ci uint32_t tempIndex = FindNextIndex(keyIndexList_.back(), MEDIA_TYPE_AUDIO); 712e0e9324cSopenharmony_ci notifier->audioIndex = tempIndex == keyIndexList_.back() ? INVALID_INDEX : tempIndex; 713e0e9324cSopenharmony_ci notifier->videoIndex = keyIndexList_.back(); 714e0e9324cSopenharmony_ci bool isAudioReady = tempIndex != INVALID_INDEX ? true : false; 715e0e9324cSopenharmony_ci SetReceiverDataRef(receiver->GetReceiverId(), MEDIA_TYPE_AUDIO, isAudioReady); 716e0e9324cSopenharmony_ci SetReceiverDataRef(receiver->GetReceiverId(), MEDIA_TYPE_VIDEO, true); 717e0e9324cSopenharmony_ci if (lastAudioIndex_ == INVALID_INDEX) { 718e0e9324cSopenharmony_ci audioNeedActivate_ = true; 719e0e9324cSopenharmony_ci } 720e0e9324cSopenharmony_ci } else { 721e0e9324cSopenharmony_ci SHARING_LOGD("BufferDispatcher Attach with Non Keyindex Exist RecvId: %{public}d.", 722e0e9324cSopenharmony_ci receiver->GetReceiverId()); 723e0e9324cSopenharmony_ci uint32_t tempIndex = FindLastIndex(MEDIA_TYPE_AUDIO); 724e0e9324cSopenharmony_ci notifier->audioIndex = tempIndex; 725e0e9324cSopenharmony_ci notifier->videoIndex = INVALID_INDEX; 726e0e9324cSopenharmony_ci SetReceiverDataRef(receiver->GetReceiverId(), MEDIA_TYPE_AUDIO, true); 727e0e9324cSopenharmony_ci SetReceiverDataRef(receiver->GetReceiverId(), MEDIA_TYPE_VIDEO, false); 728e0e9324cSopenharmony_ci if (lastAudioIndex_ == INVALID_INDEX) { 729e0e9324cSopenharmony_ci audioNeedActivate_ = true; 730e0e9324cSopenharmony_ci } 731e0e9324cSopenharmony_ci } 732e0e9324cSopenharmony_ci } 733e0e9324cSopenharmony_ci 734e0e9324cSopenharmony_ci return 0; 735e0e9324cSopenharmony_ci} 736e0e9324cSopenharmony_ci 737e0e9324cSopenharmony_ciint32_t BufferDispatcher::DetachReceiver(BufferReceiver::Ptr receiver) 738e0e9324cSopenharmony_ci{ 739e0e9324cSopenharmony_ci SHARING_LOGI("buffer dispatcher: Detach receiver in."); 740e0e9324cSopenharmony_ci if (receiver == nullptr) { 741e0e9324cSopenharmony_ci SHARING_LOGE("buffer dispatcher: Detach receiver failed - null receiver."); 742e0e9324cSopenharmony_ci return -1; 743e0e9324cSopenharmony_ci } 744e0e9324cSopenharmony_ci 745e0e9324cSopenharmony_ci if (!IsRecevierExist(receiver->GetReceiverId())) { 746e0e9324cSopenharmony_ci SHARING_LOGE("BufferDispatcher AttachReceiver No Vaild Recevier Exist."); 747e0e9324cSopenharmony_ci return 0; 748e0e9324cSopenharmony_ci } 749e0e9324cSopenharmony_ci 750e0e9324cSopenharmony_ci auto notifier = GetNotifierByReceiverPtr(receiver); 751e0e9324cSopenharmony_ci if (notifier == nullptr) { 752e0e9324cSopenharmony_ci SHARING_LOGE("buffer dispatcher: Detach receiver failed - no find receiver in notifiers."); 753e0e9324cSopenharmony_ci return -1; 754e0e9324cSopenharmony_ci } 755e0e9324cSopenharmony_ci 756e0e9324cSopenharmony_ci std::lock_guard<std::mutex> locker(notifyMutex_); 757e0e9324cSopenharmony_ci notifier->SetBlock(); 758e0e9324cSopenharmony_ci SetReceiverReadRef(receiver->GetReceiverId(), MEDIA_TYPE_AUDIO, false); 759e0e9324cSopenharmony_ci SetReceiverReadRef(receiver->GetReceiverId(), MEDIA_TYPE_VIDEO, false); 760e0e9324cSopenharmony_ci 761e0e9324cSopenharmony_ci readRefFlag_ &= ~(RECV_FLAG_BASE << notifier->GetReadIndex()); 762e0e9324cSopenharmony_ci notifiers_.erase(receiver->GetReceiverId()); 763e0e9324cSopenharmony_ci SHARING_LOGI("now refFlag: %{public}d.", readRefFlag_); 764e0e9324cSopenharmony_ci return 0; 765e0e9324cSopenharmony_ci} 766e0e9324cSopenharmony_ci 767e0e9324cSopenharmony_ciint32_t BufferDispatcher::DetachReceiver(uint32_t receiverId, DataNotifier::Ptr notifier) 768e0e9324cSopenharmony_ci{ 769e0e9324cSopenharmony_ci SHARING_LOGI("buffer dispatcher: Detach notifier in."); 770e0e9324cSopenharmony_ci if (notifier == nullptr) { 771e0e9324cSopenharmony_ci SHARING_LOGE("buffer dispatcher: Detach receiver failed - null notifier."); 772e0e9324cSopenharmony_ci return -1; 773e0e9324cSopenharmony_ci } 774e0e9324cSopenharmony_ci notifier->SetBlock(); 775e0e9324cSopenharmony_ci SetReceiverReadRef(receiverId, MEDIA_TYPE_AUDIO, false); 776e0e9324cSopenharmony_ci SetReceiverReadRef(receiverId, MEDIA_TYPE_VIDEO, false); 777e0e9324cSopenharmony_ci 778e0e9324cSopenharmony_ci readRefFlag_ &= ~(RECV_FLAG_BASE << notifier->GetReadIndex()); 779e0e9324cSopenharmony_ci notifiers_.erase(receiverId); 780e0e9324cSopenharmony_ci SHARING_LOGI("now refFlag: %{public}d.", readRefFlag_); 781e0e9324cSopenharmony_ci return 0; 782e0e9324cSopenharmony_ci} 783e0e9324cSopenharmony_ci 784e0e9324cSopenharmony_civoid BufferDispatcher::ReleaseAllReceiver() 785e0e9324cSopenharmony_ci{ 786e0e9324cSopenharmony_ci SHARING_LOGD("trace."); 787e0e9324cSopenharmony_ci std::lock_guard<std::mutex> locker(notifyMutex_); 788e0e9324cSopenharmony_ci for (auto it = notifiers_.begin(); it != notifiers_.end();) { 789e0e9324cSopenharmony_ci auto notifier = it->second; 790e0e9324cSopenharmony_ci if (notifier == nullptr) { 791e0e9324cSopenharmony_ci ++it; 792e0e9324cSopenharmony_ci continue; 793e0e9324cSopenharmony_ci } 794e0e9324cSopenharmony_ci 795e0e9324cSopenharmony_ci auto receiver = notifier->GetBufferReceiver(); 796e0e9324cSopenharmony_ci if (receiver == nullptr) { 797e0e9324cSopenharmony_ci ++it; 798e0e9324cSopenharmony_ci continue; 799e0e9324cSopenharmony_ci } 800e0e9324cSopenharmony_ci 801e0e9324cSopenharmony_ci auto receiverId = receiver->GetReceiverId(); 802e0e9324cSopenharmony_ci if (notifiers_.find(receiverId) != notifiers_.end()) { 803e0e9324cSopenharmony_ci auto notifierFind = notifiers_[receiverId]; 804e0e9324cSopenharmony_ci ++it; 805e0e9324cSopenharmony_ci DetachReceiver(receiverId, notifierFind); 806e0e9324cSopenharmony_ci } else { 807e0e9324cSopenharmony_ci ++it; 808e0e9324cSopenharmony_ci SHARING_LOGE("buffer dispatcher: Detach receiver failed - no find receiver in notifiers."); 809e0e9324cSopenharmony_ci } 810e0e9324cSopenharmony_ci } 811e0e9324cSopenharmony_ci 812e0e9324cSopenharmony_ci notifiers_.clear(); 813e0e9324cSopenharmony_ci SHARING_LOGD("release all receiver out."); 814e0e9324cSopenharmony_ci} 815e0e9324cSopenharmony_ci 816e0e9324cSopenharmony_civoid BufferDispatcher::SetBufferDispatcherListener(BufferDispatcherListener::Ptr listener) 817e0e9324cSopenharmony_ci{ 818e0e9324cSopenharmony_ci SHARING_LOGD("trace."); 819e0e9324cSopenharmony_ci listener_ = listener; 820e0e9324cSopenharmony_ci RETURN_IF_NULL(writingTimer_); 821e0e9324cSopenharmony_ci writingTimer_->StartTimer( 822e0e9324cSopenharmony_ci WRITING_TIMTOUT, "waiting for continuous data inputs", 823e0e9324cSopenharmony_ci [this]() { 824e0e9324cSopenharmony_ci if (!writing_) { 825e0e9324cSopenharmony_ci SHARING_LOGI("writing timeout"); 826e0e9324cSopenharmony_ci auto listener = listener_.lock(); 827e0e9324cSopenharmony_ci if (listener) { 828e0e9324cSopenharmony_ci listener->OnWriteTimeout(); 829e0e9324cSopenharmony_ci } 830e0e9324cSopenharmony_ci } else { 831e0e9324cSopenharmony_ci SHARING_LOGI("restart timer"); 832e0e9324cSopenharmony_ci writing_ = false; 833e0e9324cSopenharmony_ci } 834e0e9324cSopenharmony_ci }, 835e0e9324cSopenharmony_ci true); 836e0e9324cSopenharmony_ci} 837e0e9324cSopenharmony_ci 838e0e9324cSopenharmony_ciDataNotifier::Ptr BufferDispatcher::GetNotifierByReceiverPtr(BufferReceiver::Ptr receiver) 839e0e9324cSopenharmony_ci{ 840e0e9324cSopenharmony_ci SHARING_LOGD("trace."); 841e0e9324cSopenharmony_ci 842e0e9324cSopenharmony_ci return GetNotifierByReceiverId(receiver->GetReceiverId()); 843e0e9324cSopenharmony_ci} 844e0e9324cSopenharmony_ci 845e0e9324cSopenharmony_ciDataNotifier::Ptr BufferDispatcher::GetNotifierByReceiverId(uint32_t receiverId) 846e0e9324cSopenharmony_ci{ 847e0e9324cSopenharmony_ci MEDIA_LOGD("trace."); 848e0e9324cSopenharmony_ci std::lock_guard<std::mutex> locker(notifyMutex_); 849e0e9324cSopenharmony_ci if (notifiers_.find(receiverId) != notifiers_.end()) { 850e0e9324cSopenharmony_ci return notifiers_[receiverId]; 851e0e9324cSopenharmony_ci } 852e0e9324cSopenharmony_ci 853e0e9324cSopenharmony_ci return nullptr; 854e0e9324cSopenharmony_ci} 855e0e9324cSopenharmony_ci 856e0e9324cSopenharmony_ciint32_t BufferDispatcher::ReadBufferData(uint32_t receiverId, MediaType type, 857e0e9324cSopenharmony_ci std::function<void(const MediaData::Ptr &data)> cb) 858e0e9324cSopenharmony_ci{ 859e0e9324cSopenharmony_ci MEDIA_LOGD("in, receiverId: %{public}u.", receiverId); 860e0e9324cSopenharmony_ci auto notifier = GetNotifierByReceiverId(receiverId); 861e0e9324cSopenharmony_ci if (notifier == nullptr) { 862e0e9324cSopenharmony_ci SHARING_LOGE("notifier is nullptr."); 863e0e9324cSopenharmony_ci return -1; 864e0e9324cSopenharmony_ci } 865e0e9324cSopenharmony_ci 866e0e9324cSopenharmony_ci std::shared_lock<std::shared_mutex> locker(bufferMutex_); 867e0e9324cSopenharmony_ci uint32_t readIndex = notifier->GetReceiverReadIndex(type); 868e0e9324cSopenharmony_ci if (readIndex >= circularBuffer_.size()) { 869e0e9324cSopenharmony_ci SHARING_LOGE("Read wrong index exceed size."); 870e0e9324cSopenharmony_ci return -1; 871e0e9324cSopenharmony_ci } 872e0e9324cSopenharmony_ci 873e0e9324cSopenharmony_ci if ((keyOnly_ || notifier->IsKeyModeReceiver()) && type == MEDIA_TYPE_VIDEO && 874e0e9324cSopenharmony_ci !IsKeyVideoFrame(circularBuffer_.at(readIndex))) { 875e0e9324cSopenharmony_ci UpdateReceiverReadIndex(receiverId, readIndex, type); 876e0e9324cSopenharmony_ci SHARING_LOGE("Read Non Key Video in KeyOnly Mode index: %{public}u.", readIndex); 877e0e9324cSopenharmony_ci return -1; 878e0e9324cSopenharmony_ci } 879e0e9324cSopenharmony_ci 880e0e9324cSopenharmony_ci if (IsDataReaded(receiverId, circularBuffer_.at(readIndex))) { 881e0e9324cSopenharmony_ci UpdateReceiverReadIndex(receiverId, readIndex, type); 882e0e9324cSopenharmony_ci return -1; 883e0e9324cSopenharmony_ci } 884e0e9324cSopenharmony_ci 885e0e9324cSopenharmony_ci readIndex = notifier->GetReceiverReadIndex(type); 886e0e9324cSopenharmony_ci if (readIndex >= circularBuffer_.size()) { 887e0e9324cSopenharmony_ci return -1; 888e0e9324cSopenharmony_ci } 889e0e9324cSopenharmony_ci 890e0e9324cSopenharmony_ci auto data = circularBuffer_.at(readIndex); 891e0e9324cSopenharmony_ci if (data == nullptr) { 892e0e9324cSopenharmony_ci SHARING_LOGE("BufferDispatcher Read data nullptr."); 893e0e9324cSopenharmony_ci return -1; 894e0e9324cSopenharmony_ci } 895e0e9324cSopenharmony_ci 896e0e9324cSopenharmony_ci if (IsKeyVideoFrame(data)) { 897e0e9324cSopenharmony_ci int32_t bufferVideoCacheCnt = 0; 898e0e9324cSopenharmony_ci for (size_t i = readIndex + 1; i < circularBuffer_.size(); i++) { 899e0e9324cSopenharmony_ci if (circularBuffer_[i]->mediaData->mediaType == MEDIA_TYPE_VIDEO) 900e0e9324cSopenharmony_ci bufferVideoCacheCnt++; 901e0e9324cSopenharmony_ci } 902e0e9324cSopenharmony_ci MEDIA_LOGD("TEST STATISTIC:interval: buffer cache %{public}d frames.", bufferVideoCacheCnt); 903e0e9324cSopenharmony_ci } 904e0e9324cSopenharmony_ci 905e0e9324cSopenharmony_ci SetReceiverReadFlag(receiverId, data); 906e0e9324cSopenharmony_ci if (cb != nullptr) { 907e0e9324cSopenharmony_ci cb(data->mediaData); 908e0e9324cSopenharmony_ci } 909e0e9324cSopenharmony_ci 910e0e9324cSopenharmony_ci MEDIA_LOGD("Current data readed, Recvid:%{public}d, remain %{public}zu data, readIndex: %{public}u, " 911e0e9324cSopenharmony_ci "readtype: %{public}d, diff: %{public}zu.", 912e0e9324cSopenharmony_ci receiverId, circularBuffer_.size(), readIndex, int32_t(type), circularBuffer_.size() - readIndex); 913e0e9324cSopenharmony_ci UpdateReceiverReadIndex(receiverId, readIndex, type); 914e0e9324cSopenharmony_ci return 0; 915e0e9324cSopenharmony_ci} 916e0e9324cSopenharmony_ci 917e0e9324cSopenharmony_ciint32_t BufferDispatcher::InputData(const MediaData::Ptr &data) 918e0e9324cSopenharmony_ci{ 919e0e9324cSopenharmony_ci if (data == nullptr || data->buff == nullptr) { 920e0e9324cSopenharmony_ci SHARING_LOGE("data nullptr."); 921e0e9324cSopenharmony_ci return -1; 922e0e9324cSopenharmony_ci } 923e0e9324cSopenharmony_ci MEDIA_LOGD("inputmediatype: %{public}d, keyFrame: %{public}d, pts: %{public}" PRIu64 ".", data->mediaType, 924e0e9324cSopenharmony_ci data->keyFrame, data->pts); 925e0e9324cSopenharmony_ci 926e0e9324cSopenharmony_ci if (!writing_) { 927e0e9324cSopenharmony_ci writing_ = true; 928e0e9324cSopenharmony_ci } 929e0e9324cSopenharmony_ci 930e0e9324cSopenharmony_ci DataSpec::Ptr dataSpec = std::make_shared<DataSpec>(); 931e0e9324cSopenharmony_ci dataSpec->mediaData = data; 932e0e9324cSopenharmony_ci if (dataMode_ == MEDIA_AUDIO_ONLY) { 933e0e9324cSopenharmony_ci WriteDataIntoBuffer(dataSpec); 934e0e9324cSopenharmony_ci } else { 935e0e9324cSopenharmony_ci PreProcessDataSpec(dataSpec); 936e0e9324cSopenharmony_ci } 937e0e9324cSopenharmony_ci 938e0e9324cSopenharmony_ci if (circularBuffer_.size() > 0) { 939e0e9324cSopenharmony_ci MEDIA_LOGD("inputmediatype: %{public}d, keyFrame: %{public}d, pts: %{public}" PRIu64 ".", 940e0e9324cSopenharmony_ci circularBuffer_[circularBuffer_.size() - 1]->mediaData->mediaType, 941e0e9324cSopenharmony_ci circularBuffer_[circularBuffer_.size() - 1]->mediaData->keyFrame, 942e0e9324cSopenharmony_ci circularBuffer_[circularBuffer_.size() - 1]->mediaData->pts); 943e0e9324cSopenharmony_ci } 944e0e9324cSopenharmony_ci 945e0e9324cSopenharmony_ci if (data->keyFrame) { 946e0e9324cSopenharmony_ci MEDIA_LOGD("dispatcherId: %{public}u, after InputData, current circularBuffer_ size: %{public}zu, " 947e0e9324cSopenharmony_ci "idleVideoBuffer_ size: %{public}zu, idle_audioBuffer_ size: %{public}zu, " 948e0e9324cSopenharmony_ci "keyFrame: %{public}s, data size: %{public}d, adataCount:%{public}d.", 949e0e9324cSopenharmony_ci GetDispatcherId(), circularBuffer_.size(), idleVideoBuffer_.size(), idleAudioBuffer_.size(), 950e0e9324cSopenharmony_ci data->keyFrame ? "true" : "false", data->buff->Size(), audioFrameCnt_); 951e0e9324cSopenharmony_ci } 952e0e9324cSopenharmony_ci 953e0e9324cSopenharmony_ci return 0; 954e0e9324cSopenharmony_ci} 955e0e9324cSopenharmony_ci 956e0e9324cSopenharmony_civoid BufferDispatcher::PreProcessDataSpec(const DataSpec::Ptr &dataSpec) 957e0e9324cSopenharmony_ci{ 958e0e9324cSopenharmony_ci MEDIA_LOGD("trace."); 959e0e9324cSopenharmony_ci if (waitingKey_) { 960e0e9324cSopenharmony_ci if (IsAudioData(dataSpec)) { 961e0e9324cSopenharmony_ci } else if (!IsKeyVideoFrame(dataSpec)) { 962e0e9324cSopenharmony_ci SHARING_LOGD("BufferDispatcher Waiting First Key Video Frame."); 963e0e9324cSopenharmony_ci return; 964e0e9324cSopenharmony_ci } else { 965e0e9324cSopenharmony_ci SHARING_LOGD("BufferDispatcher received first key video frame and restore from uncontinuous...Flushing."); 966e0e9324cSopenharmony_ci FlushBuffer(); 967e0e9324cSopenharmony_ci baseCounter_++; 968e0e9324cSopenharmony_ci capacityEvaluating_ = true; 969e0e9324cSopenharmony_ci waitingKey_ = false; 970e0e9324cSopenharmony_ci } 971e0e9324cSopenharmony_ci } else { 972e0e9324cSopenharmony_ci if (capacityEvaluating_) { 973e0e9324cSopenharmony_ci ReCalculateCapacity(IsKeyVideoFrame(dataSpec)); 974e0e9324cSopenharmony_ci } 975e0e9324cSopenharmony_ci } 976e0e9324cSopenharmony_ci 977e0e9324cSopenharmony_ci WriteDataIntoBuffer(dataSpec); 978e0e9324cSopenharmony_ci} 979e0e9324cSopenharmony_ci 980e0e9324cSopenharmony_ciint32_t BufferDispatcher::WriteDataIntoBuffer(const DataSpec::Ptr &data) 981e0e9324cSopenharmony_ci{ 982e0e9324cSopenharmony_ci MEDIA_LOGD("trace."); 983e0e9324cSopenharmony_ci if (data->mediaData == nullptr || data->mediaData->buff == nullptr) { 984e0e9324cSopenharmony_ci SHARING_LOGE("null data."); 985e0e9324cSopenharmony_ci return -1; 986e0e9324cSopenharmony_ci } 987e0e9324cSopenharmony_ci 988e0e9324cSopenharmony_ci if (NeedExtendToDBCapacity()) { 989e0e9324cSopenharmony_ci SHARING_LOGD("BufferDispatcher buffer Extended to %{public}d CRTL_SIZE.", doubleBufferCapacity_); 990e0e9324cSopenharmony_ci SetBufferCapacity(doubleBufferCapacity_); 991e0e9324cSopenharmony_ci } 992e0e9324cSopenharmony_ci 993e0e9324cSopenharmony_ci if (NeedRestoreToNormalCapacity()) { 994e0e9324cSopenharmony_ci std::unique_lock<std::shared_mutex> locker(bufferMutex_); 995e0e9324cSopenharmony_ci int32_t popSize = circularBuffer_.size() - INITIAL_BUFFER_CAPACITY; 996e0e9324cSopenharmony_ci for (int32_t i = 0; i < popSize; i++) { 997e0e9324cSopenharmony_ci if (HeadFrameNeedReserve()) { 998e0e9324cSopenharmony_ci MEDIA_LOGW("dispatcherId: %{public}u, need reserve but pop, mediaType: " 999e0e9324cSopenharmony_ci "%{public}d, keyFrame: %{public}s, pts: %{public}" PRIu64 ".", 1000e0e9324cSopenharmony_ci GetDispatcherId(), int32_t(circularBuffer_.front()->mediaData->mediaType), 1001e0e9324cSopenharmony_ci circularBuffer_.front()->mediaData->keyFrame ? "true" : "false", 1002e0e9324cSopenharmony_ci circularBuffer_.front()->mediaData->pts); 1003e0e9324cSopenharmony_ci } 1004e0e9324cSopenharmony_ci 1005e0e9324cSopenharmony_ci MEDIA_LOGW("dispatcherId: %{public}u, delete data, mediaType: %{public}d, keyFrame: " 1006e0e9324cSopenharmony_ci "%{public}s, pts: %{public}" PRIu64 ", reserveFlag: %{public}x.", 1007e0e9324cSopenharmony_ci GetDispatcherId(), int32_t(circularBuffer_.front()->mediaData->mediaType), 1008e0e9324cSopenharmony_ci circularBuffer_.front()->mediaData->keyFrame ? "true" : "false", 1009e0e9324cSopenharmony_ci circularBuffer_.front()->mediaData->pts, circularBuffer_.front()->reserveFlag.load()); 1010e0e9324cSopenharmony_ci circularBuffer_.pop_front(); 1011e0e9324cSopenharmony_ci audioFrameCnt_--; 1012e0e9324cSopenharmony_ci UpdateIndex(); 1013e0e9324cSopenharmony_ci } 1014e0e9324cSopenharmony_ci 1015e0e9324cSopenharmony_ci baseBufferCapacity_ = INITIAL_BUFFER_CAPACITY; 1016e0e9324cSopenharmony_ci doubleBufferCapacity_ = INITIAL_BUFFER_CAPACITY * 2; // 2 : increasement 1017e0e9324cSopenharmony_ci SHARING_LOGD("BufferDispatcher buffer Extended to %{public}d NORMALSIZE.", baseBufferCapacity_); 1018e0e9324cSopenharmony_ci circularBuffer_.set_capacity(baseBufferCapacity_); 1019e0e9324cSopenharmony_ci } 1020e0e9324cSopenharmony_ci 1021e0e9324cSopenharmony_ci if (IsKeyVideoFrame(data) && !keyOnly_) { 1022e0e9324cSopenharmony_ci EraseOldGopDatas(); 1023e0e9324cSopenharmony_ci } 1024e0e9324cSopenharmony_ci 1025e0e9324cSopenharmony_ci bool updateIndexFlag = false; 1026e0e9324cSopenharmony_ci std::unique_lock<std::shared_mutex> locker(bufferMutex_); 1027e0e9324cSopenharmony_ci if (circularBuffer_.size() >= circularBuffer_.capacity()) { 1028e0e9324cSopenharmony_ci updateIndexFlag = true; 1029e0e9324cSopenharmony_ci } 1030e0e9324cSopenharmony_ci 1031e0e9324cSopenharmony_ci if (updateIndexFlag) { 1032e0e9324cSopenharmony_ci uint32_t nextDeleteIndex = 1; 1033e0e9324cSopenharmony_ci if (IsVideoData(data)) { 1034e0e9324cSopenharmony_ci nextDeleteIndex = FindNextDeleteVideoIndex(); 1035e0e9324cSopenharmony_ci } 1036e0e9324cSopenharmony_ci 1037e0e9324cSopenharmony_ci for (size_t i = 0; i <= nextDeleteIndex; i++) { 1038e0e9324cSopenharmony_ci MediaType headType = circularBuffer_.front()->mediaData->mediaType; 1039e0e9324cSopenharmony_ci DataSpec::Ptr retBuff = circularBuffer_.front(); 1040e0e9324cSopenharmony_ci if (HeadFrameNeedReserve()) { 1041e0e9324cSopenharmony_ci MEDIA_LOGW("dispatcherId: %{public}u, need reserve but pop, mediaType: " 1042e0e9324cSopenharmony_ci "%{public}d, keyFrame: %{public}s, pts: %{public}" PRIu64 ".", 1043e0e9324cSopenharmony_ci GetDispatcherId(), int32_t(retBuff->mediaData->mediaType), 1044e0e9324cSopenharmony_ci retBuff->mediaData->keyFrame ? "true" : "false", retBuff->mediaData->pts); 1045e0e9324cSopenharmony_ci } 1046e0e9324cSopenharmony_ci 1047e0e9324cSopenharmony_ci MEDIA_LOGW("dispatcherId: %{public}u, delete data, mediaType: %{public}d, " 1048e0e9324cSopenharmony_ci "keyFrame: %{public}s, pts: %{public}" PRIu64 ", reserveFlag: %{public}x.", 1049e0e9324cSopenharmony_ci GetDispatcherId(), int32_t(circularBuffer_.front()->mediaData->mediaType), 1050e0e9324cSopenharmony_ci circularBuffer_.front()->mediaData->keyFrame ? "true" : "false", 1051e0e9324cSopenharmony_ci circularBuffer_.front()->mediaData->pts, circularBuffer_.front()->reserveFlag.load()); 1052e0e9324cSopenharmony_ci 1053e0e9324cSopenharmony_ci circularBuffer_.pop_front(); 1054e0e9324cSopenharmony_ci ReturnIdleBuffer(retBuff); 1055e0e9324cSopenharmony_ci headType == MEDIA_TYPE_AUDIO ? audioFrameCnt_-- : videoFrameCnt_--; 1056e0e9324cSopenharmony_ci UpdateIndex(); 1057e0e9324cSopenharmony_ci } 1058e0e9324cSopenharmony_ci } 1059e0e9324cSopenharmony_ci 1060e0e9324cSopenharmony_ci data->reserveFlag = 0; 1061e0e9324cSopenharmony_ci MEDIA_LOGD("WriteDataIntoBuffer data type: %{public}d, keyFrame: %{public}s, pts: %{public}" PRIu64 1062e0e9324cSopenharmony_ci ", cur_size: %{public}zu, capacity: %{public}zu dispatcher[%{public}u].", 1063e0e9324cSopenharmony_ci int32_t(data->mediaData->mediaType), data->mediaData->keyFrame ? "true" : "false", data->mediaData->pts, 1064e0e9324cSopenharmony_ci circularBuffer_.size(), circularBuffer_.capacity(), GetDispatcherId()); 1065e0e9324cSopenharmony_ci circularBuffer_.push_back(data); 1066e0e9324cSopenharmony_ci if (IsAudioData(data)) { 1067e0e9324cSopenharmony_ci lastAudioIndex_ = circularBuffer_.size() - 1; 1068e0e9324cSopenharmony_ci ActiveDataRef(MEDIA_TYPE_AUDIO, false); 1069e0e9324cSopenharmony_ci audioFrameCnt_++; 1070e0e9324cSopenharmony_ci } else { 1071e0e9324cSopenharmony_ci lastVideoIndex_ = circularBuffer_.size() - 1; 1072e0e9324cSopenharmony_ci if (!keyOnly_ || (keyOnly_ && IsKeyVideoFrame(data))) { 1073e0e9324cSopenharmony_ci ActiveDataRef(MEDIA_TYPE_VIDEO, IsKeyVideoFrame(data)); 1074e0e9324cSopenharmony_ci } 1075e0e9324cSopenharmony_ci videoFrameCnt_++; 1076e0e9324cSopenharmony_ci } 1077e0e9324cSopenharmony_ci 1078e0e9324cSopenharmony_ci if (audioNeedActivate_ && IsAudioData(data)) { 1079e0e9324cSopenharmony_ci MEDIA_LOGD("BufferDispatcher ActivateReceiverIndex By AudioData."); 1080e0e9324cSopenharmony_ci ActivateReceiverIndex(circularBuffer_.size() - 1, MEDIA_TYPE_AUDIO); 1081e0e9324cSopenharmony_ci } 1082e0e9324cSopenharmony_ci 1083e0e9324cSopenharmony_ci if (IsKeyVideoFrame(data)) { 1084e0e9324cSopenharmony_ci uint32_t keyIndex = circularBuffer_.size() - 1; 1085e0e9324cSopenharmony_ci { 1086e0e9324cSopenharmony_ci std::lock_guard<std::mutex> indexLocker(notifyMutex_); 1087e0e9324cSopenharmony_ci keyIndexList_.push_back(keyIndex); 1088e0e9324cSopenharmony_ci } 1089e0e9324cSopenharmony_ci if (videoNeedActivate_) { 1090e0e9324cSopenharmony_ci MEDIA_LOGD("BufferDispatcher ActivateReceiverIndex By KeyVideo Frame index: %{public}d.", keyIndex); 1091e0e9324cSopenharmony_ci ActivateReceiverIndex(keyIndex, MEDIA_TYPE_VIDEO); 1092e0e9324cSopenharmony_ci } 1093e0e9324cSopenharmony_ci if (keyRedirect_) { 1094e0e9324cSopenharmony_ci OnKeyRedirect(); 1095e0e9324cSopenharmony_ci EnableKeyRedirect(false); 1096e0e9324cSopenharmony_ci } 1097e0e9324cSopenharmony_ci } 1098e0e9324cSopenharmony_ci 1099e0e9324cSopenharmony_ci continueNotify_ = true; 1100e0e9324cSopenharmony_ci dataCV_.notify_one(); 1101e0e9324cSopenharmony_ci return 0; 1102e0e9324cSopenharmony_ci} 1103e0e9324cSopenharmony_ci 1104e0e9324cSopenharmony_civoid BufferDispatcher::EraseOldGopDatas() 1105e0e9324cSopenharmony_ci{ 1106e0e9324cSopenharmony_ci MEDIA_LOGD("BufferDispatcher Delete old datas In."); 1107e0e9324cSopenharmony_ci if (dataMode_ == MEDIA_AUDIO_ONLY) { 1108e0e9324cSopenharmony_ci FlushBuffer(); 1109e0e9324cSopenharmony_ci return; 1110e0e9324cSopenharmony_ci } 1111e0e9324cSopenharmony_ci 1112e0e9324cSopenharmony_ci std::unique_lock<std::shared_mutex> locker(bufferMutex_); 1113e0e9324cSopenharmony_ci uint32_t nextKey = 0; 1114e0e9324cSopenharmony_ci { 1115e0e9324cSopenharmony_ci std::lock_guard<std::mutex> lock(notifyMutex_); 1116e0e9324cSopenharmony_ci if (!keyIndexList_.empty() && keyIndexList_.back() > 0) { 1117e0e9324cSopenharmony_ci MEDIA_LOGD("find next key listsize %{public}zu, back:%{public}d.", keyIndexList_.size(), 1118e0e9324cSopenharmony_ci keyIndexList_.back()); 1119e0e9324cSopenharmony_ci nextKey = keyIndexList_.back(); 1120e0e9324cSopenharmony_ci keyIndexList_.clear(); 1121e0e9324cSopenharmony_ci keyIndexList_.push_back(nextKey); 1122e0e9324cSopenharmony_ci } 1123e0e9324cSopenharmony_ci } 1124e0e9324cSopenharmony_ci 1125e0e9324cSopenharmony_ci MEDIA_LOGD("erase between 0 to next Video Frame %{public}d.", nextKey); 1126e0e9324cSopenharmony_ci DeleteHeadDatas(nextKey, false); 1127e0e9324cSopenharmony_ci nextKey = FindNextDeleteVideoIndex(); 1128e0e9324cSopenharmony_ci DeleteHeadDatas(nextKey, true); 1129e0e9324cSopenharmony_ci std::string indexs; 1130e0e9324cSopenharmony_ci 1131e0e9324cSopenharmony_ci MEDIA_LOGD("circularBuffer_ size: %{public}zu.", circularBuffer_.size()); 1132e0e9324cSopenharmony_ci for (auto &keyIndex : keyIndexList_) { 1133e0e9324cSopenharmony_ci indexs += std::to_string(keyIndex) + ", "; 1134e0e9324cSopenharmony_ci MEDIA_LOGD("keyIndex update to %{public}d.", keyIndex); 1135e0e9324cSopenharmony_ci } 1136e0e9324cSopenharmony_ci 1137e0e9324cSopenharmony_ci MEDIA_LOGD("current keyIndex: %{public}s.", indexs.c_str()); 1138e0e9324cSopenharmony_ci} 1139e0e9324cSopenharmony_ci 1140e0e9324cSopenharmony_civoid BufferDispatcher::DeleteHeadDatas(uint32_t size, bool forceDelete) 1141e0e9324cSopenharmony_ci{ 1142e0e9324cSopenharmony_ci SHARING_LOGI("%{public}s, size %{public}d.", __FUNCTION__, size); 1143e0e9324cSopenharmony_ci if (size <= 0) { 1144e0e9324cSopenharmony_ci MEDIA_LOGW("invalid Size, dispatcherId: %{public}u!", GetDispatcherId()); 1145e0e9324cSopenharmony_ci return; 1146e0e9324cSopenharmony_ci } 1147e0e9324cSopenharmony_ci 1148e0e9324cSopenharmony_ci for (size_t i = 0; i < size; i++) { 1149e0e9324cSopenharmony_ci if (HeadFrameNeedReserve() && !forceDelete) { 1150e0e9324cSopenharmony_ci MEDIA_LOGD("index %{public}zu need reserve.", i); 1151e0e9324cSopenharmony_ci break; 1152e0e9324cSopenharmony_ci } 1153e0e9324cSopenharmony_ci if (circularBuffer_.empty()) { 1154e0e9324cSopenharmony_ci return; 1155e0e9324cSopenharmony_ci } 1156e0e9324cSopenharmony_ci DataSpec::Ptr retBuff = circularBuffer_.front(); 1157e0e9324cSopenharmony_ci MEDIA_LOGD("BufferDispatcher pop out headtype %{public}d.", retBuff->mediaData->mediaType); 1158e0e9324cSopenharmony_ci retBuff->mediaData->mediaType == MEDIA_TYPE_AUDIO ? audioFrameCnt_-- : videoFrameCnt_--; 1159e0e9324cSopenharmony_ci if (HeadFrameNeedReserve()) { 1160e0e9324cSopenharmony_ci MEDIA_LOGW("dispatcherId: %{public}u, need reserve but pop, mediaType: " 1161e0e9324cSopenharmony_ci "%{public}d, keyFrame: %{public}s, pts: %{public}" PRIu64 ".", 1162e0e9324cSopenharmony_ci GetDispatcherId(), int32_t(retBuff->mediaData->mediaType), 1163e0e9324cSopenharmony_ci retBuff->mediaData->keyFrame ? "true" : "false", retBuff->mediaData->pts); 1164e0e9324cSopenharmony_ci } 1165e0e9324cSopenharmony_ci 1166e0e9324cSopenharmony_ci MEDIA_LOGD( 1167e0e9324cSopenharmony_ci "dispatcherId: %{public}u, delete data, mediaType: %{public}d, keyFrame: %{public}s, pts: %{public}" PRIu64 1168e0e9324cSopenharmony_ci ", reserveFlag: %{public}x.", 1169e0e9324cSopenharmony_ci GetDispatcherId(), int32_t(circularBuffer_.front()->mediaData->mediaType), 1170e0e9324cSopenharmony_ci circularBuffer_.front()->mediaData->keyFrame ? "true" : "false", circularBuffer_.front()->mediaData->pts, 1171e0e9324cSopenharmony_ci circularBuffer_.front()->reserveFlag.load()); 1172e0e9324cSopenharmony_ci circularBuffer_.pop_front(); 1173e0e9324cSopenharmony_ci ReturnIdleBuffer(retBuff); 1174e0e9324cSopenharmony_ci UpdateIndex(); 1175e0e9324cSopenharmony_ci } 1176e0e9324cSopenharmony_ci 1177e0e9324cSopenharmony_ci if (circularBuffer_.size() < baseBufferCapacity_ && circularBuffer_.capacity() > baseBufferCapacity_) { 1178e0e9324cSopenharmony_ci MEDIA_LOGE("capacity return to base %{public}d.", baseBufferCapacity_); 1179e0e9324cSopenharmony_ci circularBuffer_.set_capacity(baseBufferCapacity_); 1180e0e9324cSopenharmony_ci } 1181e0e9324cSopenharmony_ci} 1182e0e9324cSopenharmony_ci 1183e0e9324cSopenharmony_civoid BufferDispatcher::UpdateIndex() 1184e0e9324cSopenharmony_ci{ 1185e0e9324cSopenharmony_ci MEDIA_LOGD("trace."); 1186e0e9324cSopenharmony_ci std::lock_guard<std::mutex> locker(notifyMutex_); 1187e0e9324cSopenharmony_ci if (!keyIndexList_.empty() && keyIndexList_.front() == 0) { 1188e0e9324cSopenharmony_ci keyIndexList_.pop_front(); 1189e0e9324cSopenharmony_ci MEDIA_LOGD("BufferDispatcher pop out first 0 keyIndex after listsize %{public}zu.", keyIndexList_.size()); 1190e0e9324cSopenharmony_ci } 1191e0e9324cSopenharmony_ci 1192e0e9324cSopenharmony_ci for (auto &keyIndex : keyIndexList_) { 1193e0e9324cSopenharmony_ci if (keyIndex > 0) { 1194e0e9324cSopenharmony_ci keyIndex--; 1195e0e9324cSopenharmony_ci } 1196e0e9324cSopenharmony_ci } 1197e0e9324cSopenharmony_ci 1198e0e9324cSopenharmony_ci for (auto &[recvId, notifier] : notifiers_) { 1199e0e9324cSopenharmony_ci if (notifier->videoIndex > 0 && notifier->videoIndex != INVALID_INDEX) { 1200e0e9324cSopenharmony_ci notifier->videoIndex--; 1201e0e9324cSopenharmony_ci } 1202e0e9324cSopenharmony_ci if (notifier->audioIndex > 0 && notifier->audioIndex != INVALID_INDEX) { 1203e0e9324cSopenharmony_ci notifier->audioIndex--; 1204e0e9324cSopenharmony_ci } 1205e0e9324cSopenharmony_ci } 1206e0e9324cSopenharmony_ci 1207e0e9324cSopenharmony_ci if (lastVideoIndex_ > 0 && lastVideoIndex_ != INVALID_INDEX) { 1208e0e9324cSopenharmony_ci lastVideoIndex_--; 1209e0e9324cSopenharmony_ci } 1210e0e9324cSopenharmony_ci 1211e0e9324cSopenharmony_ci if (lastAudioIndex_ > 0 && lastAudioIndex_ != INVALID_INDEX) { 1212e0e9324cSopenharmony_ci lastAudioIndex_--; 1213e0e9324cSopenharmony_ci } 1214e0e9324cSopenharmony_ci} 1215e0e9324cSopenharmony_ci 1216e0e9324cSopenharmony_ciuint32_t BufferDispatcher::FindNextDeleteVideoIndex() 1217e0e9324cSopenharmony_ci{ 1218e0e9324cSopenharmony_ci MEDIA_LOGD("trace."); 1219e0e9324cSopenharmony_ci for (size_t i = 0; i < circularBuffer_.size(); i++) { 1220e0e9324cSopenharmony_ci if (circularBuffer_[i]->mediaData != nullptr && circularBuffer_[i]->mediaData->mediaType == MEDIA_TYPE_VIDEO) { 1221e0e9324cSopenharmony_ci return i; 1222e0e9324cSopenharmony_ci } 1223e0e9324cSopenharmony_ci } 1224e0e9324cSopenharmony_ci 1225e0e9324cSopenharmony_ci return 0; 1226e0e9324cSopenharmony_ci} 1227e0e9324cSopenharmony_ci 1228e0e9324cSopenharmony_ciuint32_t BufferDispatcher::FindLastIndex(MediaType type) 1229e0e9324cSopenharmony_ci{ 1230e0e9324cSopenharmony_ci SHARING_LOGD("trace."); 1231e0e9324cSopenharmony_ci if (circularBuffer_.empty()) { 1232e0e9324cSopenharmony_ci return INVALID_INDEX; 1233e0e9324cSopenharmony_ci } 1234e0e9324cSopenharmony_ci 1235e0e9324cSopenharmony_ci return type == MEDIA_TYPE_AUDIO ? lastAudioIndex_ : lastVideoIndex_; 1236e0e9324cSopenharmony_ci} 1237e0e9324cSopenharmony_ci 1238e0e9324cSopenharmony_civoid BufferDispatcher::UpdateReceiverReadIndex(uint32_t receiverId, const uint32_t readIndex, MediaType type) 1239e0e9324cSopenharmony_ci{ 1240e0e9324cSopenharmony_ci MEDIA_LOGD("trace."); 1241e0e9324cSopenharmony_ci uint32_t nextIndex = FindNextIndex(readIndex, type, receiverId); 1242e0e9324cSopenharmony_ci bool noAvaliableData = false; 1243e0e9324cSopenharmony_ci if (nextIndex == readIndex) { 1244e0e9324cSopenharmony_ci noAvaliableData = true; 1245e0e9324cSopenharmony_ci } 1246e0e9324cSopenharmony_ci 1247e0e9324cSopenharmony_ci auto notifier = GetNotifierByReceiverId(receiverId); 1248e0e9324cSopenharmony_ci if (notifier == nullptr) { 1249e0e9324cSopenharmony_ci SHARING_LOGE("notifier is nullptr."); 1250e0e9324cSopenharmony_ci return; 1251e0e9324cSopenharmony_ci } 1252e0e9324cSopenharmony_ci 1253e0e9324cSopenharmony_ci bool readOver = circularBuffer_.size() - readIndex < 3; 1254e0e9324cSopenharmony_ci if (readOver && notifier->NeedAcceleration() && type == MEDIA_TYPE_VIDEO) { 1255e0e9324cSopenharmony_ci SHARING_LOGD("BufferDispatcher SendAccelerationDone."); 1256e0e9324cSopenharmony_ci notifier->SendAccelerationDone(); 1257e0e9324cSopenharmony_ci } 1258e0e9324cSopenharmony_ci 1259e0e9324cSopenharmony_ci notifier->SetNeedUpdate(noAvaliableData, type); 1260e0e9324cSopenharmony_ci 1261e0e9324cSopenharmony_ci if (type == MEDIA_TYPE_VIDEO) { 1262e0e9324cSopenharmony_ci notifier->videoIndex = nextIndex; 1263e0e9324cSopenharmony_ci } else if (type == MEDIA_TYPE_AUDIO) { 1264e0e9324cSopenharmony_ci notifier->audioIndex = nextIndex; 1265e0e9324cSopenharmony_ci } else { 1266e0e9324cSopenharmony_ci notifier->videoIndex = nextIndex; 1267e0e9324cSopenharmony_ci notifier->audioIndex = nextIndex; 1268e0e9324cSopenharmony_ci } 1269e0e9324cSopenharmony_ci 1270e0e9324cSopenharmony_ci MEDIA_LOGD("After UpdateReceiverReadIndex type %{public}d, aindex %{public}d, vindex %{public}d.", type, 1271e0e9324cSopenharmony_ci notifier->audioIndex, notifier->videoIndex); 1272e0e9324cSopenharmony_ci} 1273e0e9324cSopenharmony_ci 1274e0e9324cSopenharmony_ciuint32_t BufferDispatcher::FindNextIndex(uint32_t index, MediaType type) 1275e0e9324cSopenharmony_ci{ 1276e0e9324cSopenharmony_ci MEDIA_LOGD("trace."); 1277e0e9324cSopenharmony_ci if (index + 1 >= circularBuffer_.size() || index == INVALID_INDEX) { 1278e0e9324cSopenharmony_ci return index; 1279e0e9324cSopenharmony_ci } 1280e0e9324cSopenharmony_ci 1281e0e9324cSopenharmony_ci if (type == MEDIA_TYPE_AV) { 1282e0e9324cSopenharmony_ci return index + 1; 1283e0e9324cSopenharmony_ci } 1284e0e9324cSopenharmony_ci 1285e0e9324cSopenharmony_ci for (size_t i = index + 1; i < circularBuffer_.size(); i++) { 1286e0e9324cSopenharmony_ci if (circularBuffer_[i] && circularBuffer_[i]->mediaData && circularBuffer_[i]->mediaData->mediaType == type) { 1287e0e9324cSopenharmony_ci if (keyOnly_ && type == MEDIA_TYPE_VIDEO && !IsKeyVideoFrame(circularBuffer_[i])) { 1288e0e9324cSopenharmony_ci continue; 1289e0e9324cSopenharmony_ci } else { 1290e0e9324cSopenharmony_ci return i; 1291e0e9324cSopenharmony_ci } 1292e0e9324cSopenharmony_ci } 1293e0e9324cSopenharmony_ci } 1294e0e9324cSopenharmony_ci 1295e0e9324cSopenharmony_ci return index; 1296e0e9324cSopenharmony_ci} 1297e0e9324cSopenharmony_ci 1298e0e9324cSopenharmony_ciuint32_t BufferDispatcher::FindNextIndex(uint32_t index, MediaType type, uint32_t receiverId) 1299e0e9324cSopenharmony_ci{ 1300e0e9324cSopenharmony_ci MEDIA_LOGD("trace."); 1301e0e9324cSopenharmony_ci if (index + 1 >= circularBuffer_.size() || index == INVALID_INDEX) { 1302e0e9324cSopenharmony_ci return index; 1303e0e9324cSopenharmony_ci } 1304e0e9324cSopenharmony_ci 1305e0e9324cSopenharmony_ci if (type == MEDIA_TYPE_AV) { 1306e0e9324cSopenharmony_ci return index + 1; 1307e0e9324cSopenharmony_ci } 1308e0e9324cSopenharmony_ci 1309e0e9324cSopenharmony_ci auto notifier = GetNotifierByReceiverId(receiverId); 1310e0e9324cSopenharmony_ci if (notifier == nullptr) { 1311e0e9324cSopenharmony_ci SHARING_LOGE("FindNextIndex GetNotifier nullptr."); 1312e0e9324cSopenharmony_ci return INVALID_INDEX; 1313e0e9324cSopenharmony_ci } 1314e0e9324cSopenharmony_ci 1315e0e9324cSopenharmony_ci bool keyModeReceiver = notifier->IsKeyModeReceiver(); 1316e0e9324cSopenharmony_ci for (size_t i = index + 1; i < circularBuffer_.size(); i++) { 1317e0e9324cSopenharmony_ci if (circularBuffer_[i] && circularBuffer_[i]->mediaData && circularBuffer_[i]->mediaData->mediaType == type) { 1318e0e9324cSopenharmony_ci if ((keyOnly_ || keyModeReceiver) && type == MEDIA_TYPE_VIDEO) { 1319e0e9324cSopenharmony_ci if (!IsKeyVideoFrame(circularBuffer_[i])) { 1320e0e9324cSopenharmony_ci continue; 1321e0e9324cSopenharmony_ci } else { 1322e0e9324cSopenharmony_ci for (size_t bIndex = index + 1; bIndex < i; bIndex++) { 1323e0e9324cSopenharmony_ci SetReceiverReadFlag(receiverId, circularBuffer_[bIndex]); 1324e0e9324cSopenharmony_ci } 1325e0e9324cSopenharmony_ci return i; 1326e0e9324cSopenharmony_ci } 1327e0e9324cSopenharmony_ci } else { 1328e0e9324cSopenharmony_ci return i; 1329e0e9324cSopenharmony_ci } 1330e0e9324cSopenharmony_ci } 1331e0e9324cSopenharmony_ci } 1332e0e9324cSopenharmony_ci 1333e0e9324cSopenharmony_ci return index; 1334e0e9324cSopenharmony_ci} 1335e0e9324cSopenharmony_ci 1336e0e9324cSopenharmony_civoid BufferDispatcher::ResetAllIndex() 1337e0e9324cSopenharmony_ci{ 1338e0e9324cSopenharmony_ci SHARING_LOGD("trace."); 1339e0e9324cSopenharmony_ci std::lock_guard<std::mutex> locker(notifyMutex_); 1340e0e9324cSopenharmony_ci keyIndexList_.clear(); 1341e0e9324cSopenharmony_ci for (auto &[recvId, notifier] : notifiers_) { 1342e0e9324cSopenharmony_ci notifier->videoIndex = INVALID_INDEX; 1343e0e9324cSopenharmony_ci notifier->audioIndex = INVALID_INDEX; 1344e0e9324cSopenharmony_ci } 1345e0e9324cSopenharmony_ci 1346e0e9324cSopenharmony_ci videoNeedActivate_ = true; 1347e0e9324cSopenharmony_ci audioNeedActivate_ = true; 1348e0e9324cSopenharmony_ci lastAudioIndex_ = INVALID_INDEX; 1349e0e9324cSopenharmony_ci lastVideoIndex_ = INVALID_INDEX; 1350e0e9324cSopenharmony_ci} 1351e0e9324cSopenharmony_ci 1352e0e9324cSopenharmony_cibool BufferDispatcher::IsDataReaded(uint32_t receiverId, DataSpec::Ptr &dataSpec) 1353e0e9324cSopenharmony_ci{ 1354e0e9324cSopenharmony_ci MEDIA_LOGD("trace."); 1355e0e9324cSopenharmony_ci uint32_t index = FindReceiverIndex(receiverId); 1356e0e9324cSopenharmony_ci if (index == INVALID_INDEX) { 1357e0e9324cSopenharmony_ci return false; 1358e0e9324cSopenharmony_ci } 1359e0e9324cSopenharmony_ci 1360e0e9324cSopenharmony_ci return dataSpec->reserveFlag & RECV_FLAG_BASE << index; 1361e0e9324cSopenharmony_ci} 1362e0e9324cSopenharmony_ci 1363e0e9324cSopenharmony_cibool BufferDispatcher::IsVideoData(const DataSpec::Ptr &dataSpec) 1364e0e9324cSopenharmony_ci{ 1365e0e9324cSopenharmony_ci MEDIA_LOGD("trace."); 1366e0e9324cSopenharmony_ci if (dataSpec == nullptr || dataSpec->mediaData == nullptr) { 1367e0e9324cSopenharmony_ci SHARING_LOGE("BufferDispatcher EMPTY dataSpec OR mediadata."); 1368e0e9324cSopenharmony_ci return false; 1369e0e9324cSopenharmony_ci } 1370e0e9324cSopenharmony_ci 1371e0e9324cSopenharmony_ci return dataSpec->mediaData->mediaType == MEDIA_TYPE_VIDEO; 1372e0e9324cSopenharmony_ci} 1373e0e9324cSopenharmony_ci 1374e0e9324cSopenharmony_cibool BufferDispatcher::IsAudioData(const DataSpec::Ptr &dataSpec) 1375e0e9324cSopenharmony_ci{ 1376e0e9324cSopenharmony_ci MEDIA_LOGD("trace."); 1377e0e9324cSopenharmony_ci if (dataSpec == nullptr || dataSpec->mediaData == nullptr) { 1378e0e9324cSopenharmony_ci SHARING_LOGE("BufferDispatcher EMPTY dataSpec OR mediadata."); 1379e0e9324cSopenharmony_ci return false; 1380e0e9324cSopenharmony_ci } 1381e0e9324cSopenharmony_ci 1382e0e9324cSopenharmony_ci return dataSpec->mediaData->mediaType == MEDIA_TYPE_AUDIO; 1383e0e9324cSopenharmony_ci} 1384e0e9324cSopenharmony_ci 1385e0e9324cSopenharmony_cibool BufferDispatcher::IsKeyVideoFrame(const DataSpec::Ptr &dataSpec) 1386e0e9324cSopenharmony_ci{ 1387e0e9324cSopenharmony_ci MEDIA_LOGD("trace."); 1388e0e9324cSopenharmony_ci if (dataSpec == nullptr || dataSpec->mediaData == nullptr) { 1389e0e9324cSopenharmony_ci SHARING_LOGE("BufferDispatcher EMPTY dataSpec OR mediadata."); 1390e0e9324cSopenharmony_ci return false; 1391e0e9324cSopenharmony_ci } 1392e0e9324cSopenharmony_ci 1393e0e9324cSopenharmony_ci return IsVideoData(dataSpec) && dataSpec->mediaData->keyFrame; 1394e0e9324cSopenharmony_ci} 1395e0e9324cSopenharmony_ci 1396e0e9324cSopenharmony_cibool BufferDispatcher::HeadFrameNeedReserve() 1397e0e9324cSopenharmony_ci{ 1398e0e9324cSopenharmony_ci MEDIA_LOGD("trace."); 1399e0e9324cSopenharmony_ci if (!circularBuffer_.empty()) { 1400e0e9324cSopenharmony_ci uint8_t temp = readRefFlag_; 1401e0e9324cSopenharmony_ci MEDIA_LOGD("IsHeadFrameNeedReserve Head reserveFlag %{public}d readRefFlag_ %{public}d.", 1402e0e9324cSopenharmony_ci circularBuffer_.front()->reserveFlag.load(), readRefFlag_); 1403e0e9324cSopenharmony_ci return temp ^ circularBuffer_.front()->reserveFlag; 1404e0e9324cSopenharmony_ci } 1405e0e9324cSopenharmony_ci 1406e0e9324cSopenharmony_ci return false; 1407e0e9324cSopenharmony_ci} 1408e0e9324cSopenharmony_ci 1409e0e9324cSopenharmony_cibool BufferDispatcher::NeedExtendToDBCapacity() 1410e0e9324cSopenharmony_ci{ 1411e0e9324cSopenharmony_ci MEDIA_LOGD("trace."); 1412e0e9324cSopenharmony_ci std::shared_lock<std::shared_mutex> locker(bufferMutex_); 1413e0e9324cSopenharmony_ci return (circularBuffer_.size() >= circularBuffer_.capacity() && 1414e0e9324cSopenharmony_ci circularBuffer_.capacity() < doubleBufferCapacity_ && HeadFrameNeedReserve()); 1415e0e9324cSopenharmony_ci} 1416e0e9324cSopenharmony_ci 1417e0e9324cSopenharmony_cibool BufferDispatcher::NeedRestoreToNormalCapacity() 1418e0e9324cSopenharmony_ci{ 1419e0e9324cSopenharmony_ci MEDIA_LOGD("trace."); 1420e0e9324cSopenharmony_ci std::shared_lock<std::shared_mutex> locker(bufferMutex_); 1421e0e9324cSopenharmony_ci return audioFrameCnt_ >= circularBuffer_.capacity() && circularBuffer_.capacity() != INITIAL_BUFFER_CAPACITY; 1422e0e9324cSopenharmony_ci} 1423e0e9324cSopenharmony_ci 1424e0e9324cSopenharmony_civoid BufferDispatcher::ReCalculateCapacity(bool keyFrame) 1425e0e9324cSopenharmony_ci{ 1426e0e9324cSopenharmony_ci MEDIA_LOGD("trace."); 1427e0e9324cSopenharmony_ci baseCounter_++; 1428e0e9324cSopenharmony_ci if (baseCounter_ >= maxBufferCapacity_) { 1429e0e9324cSopenharmony_ci SHARING_LOGE("BufferDispatcher too many Audiodata need Set Capacity to default."); 1430e0e9324cSopenharmony_ci } 1431e0e9324cSopenharmony_ci 1432e0e9324cSopenharmony_ci if (baseCounter_ >= circularBuffer_.capacity() && !keyFrame) { 1433e0e9324cSopenharmony_ci uint32_t tmpSize = circularBuffer_.capacity() + bufferCapacityIncrement_ < maxBufferCapacity_ 1434e0e9324cSopenharmony_ci ? circularBuffer_.capacity() + bufferCapacityIncrement_ 1435e0e9324cSopenharmony_ci : maxBufferCapacity_; 1436e0e9324cSopenharmony_ci doubleBufferCapacity_ = tmpSize * 2 < maxBufferCapacity_ ? tmpSize * 2 : maxBufferCapacity_; // 2: increasement 1437e0e9324cSopenharmony_ci SHARING_LOGD("BufferDispatcher buffer Extended to %{public}d in adaptive capacity calculating.", tmpSize); 1438e0e9324cSopenharmony_ci SetBufferCapacity(tmpSize); 1439e0e9324cSopenharmony_ci return; 1440e0e9324cSopenharmony_ci } 1441e0e9324cSopenharmony_ci 1442e0e9324cSopenharmony_ci if (keyFrame) { 1443e0e9324cSopenharmony_ci baseBufferCapacity_ = baseCounter_ + bufferCapacityIncrement_ < maxBufferCapacity_ 1444e0e9324cSopenharmony_ci ? baseCounter_ + bufferCapacityIncrement_ 1445e0e9324cSopenharmony_ci : maxBufferCapacity_; 1446e0e9324cSopenharmony_ci if (baseBufferCapacity_ < INITIAL_BUFFER_CAPACITY) { 1447e0e9324cSopenharmony_ci baseBufferCapacity_ = INITIAL_BUFFER_CAPACITY; 1448e0e9324cSopenharmony_ci } 1449e0e9324cSopenharmony_ci doubleBufferCapacity_ = baseBufferCapacity_ * 2 < maxBufferCapacity_ // 2: increasement 1450e0e9324cSopenharmony_ci ? baseBufferCapacity_ * 2 // 2: increasement 1451e0e9324cSopenharmony_ci : maxBufferCapacity_; 1452e0e9324cSopenharmony_ci gop_ = baseCounter_; 1453e0e9324cSopenharmony_ci capacityEvaluating_ = gop_ > 0 ? false : true; 1454e0e9324cSopenharmony_ci SetBufferCapacity(baseBufferCapacity_); 1455e0e9324cSopenharmony_ci baseCounter_ = 0; 1456e0e9324cSopenharmony_ci SHARING_LOGI( 1457e0e9324cSopenharmony_ci "The gop is %{public}d and BufferDispatcher buffer Extended to %{public}d on base capacity confirmed.", 1458e0e9324cSopenharmony_ci GetCurrentGop(), baseBufferCapacity_); 1459e0e9324cSopenharmony_ci } 1460e0e9324cSopenharmony_ci} 1461e0e9324cSopenharmony_ci 1462e0e9324cSopenharmony_ciint32_t BufferDispatcher::NotifyThreadWorker(void *userParam) 1463e0e9324cSopenharmony_ci{ 1464e0e9324cSopenharmony_ci SHARING_LOGI("BufferDispatcher DataNotifier thread in."); 1465e0e9324cSopenharmony_ci RETURN_INVALID_IF_NULL(userParam); 1466e0e9324cSopenharmony_ci BufferDispatcher *dispatcher = (BufferDispatcher *)userParam; 1467e0e9324cSopenharmony_ci while (dispatcher->running_) { 1468e0e9324cSopenharmony_ci std::unique_lock<std::mutex> locker(dispatcher->notifyMutex_); 1469e0e9324cSopenharmony_ci uint32_t notifyRef = dispatcher->dataBitRef_ & dispatcher->recvBitRef_; 1470e0e9324cSopenharmony_ci MEDIA_LOGD("DataBitRef %{public}u recvBitRef_ %{public}d notifyRef_ %{public}d.", 1471e0e9324cSopenharmony_ci dispatcher->dataBitRef_.load(), dispatcher->recvBitRef_.load(), notifyRef); 1472e0e9324cSopenharmony_ci 1473e0e9324cSopenharmony_ci for (auto &[recvId, notifier] : dispatcher->notifiers_) { 1474e0e9324cSopenharmony_ci auto index = notifier->GetReadIndex(); 1475e0e9324cSopenharmony_ci if (((RECV_FLAG_BASE << (index * FIX_OFFSET_TWO)) & notifyRef) || 1476e0e9324cSopenharmony_ci ((RECV_FLAG_BASE << (index * FIX_OFFSET_TWO + FIX_OFFSET_ONE)) & notifyRef)) { 1477e0e9324cSopenharmony_ci MediaType notifyType; 1478e0e9324cSopenharmony_ci if (notifier->IsMixedReceiver()) { 1479e0e9324cSopenharmony_ci notifyType = MEDIA_TYPE_AV; 1480e0e9324cSopenharmony_ci } else { 1481e0e9324cSopenharmony_ci notifyType = (((RECV_FLAG_BASE << (index * FIX_OFFSET_TWO)) & notifyRef) ? MEDIA_TYPE_AUDIO 1482e0e9324cSopenharmony_ci : MEDIA_TYPE_VIDEO); 1483e0e9324cSopenharmony_ci } 1484e0e9324cSopenharmony_ci MEDIA_LOGD("notify the receiveId: %{public}d, notifyType: %{public}d, notifyRef: %{public}x.", recvId, 1485e0e9324cSopenharmony_ci notifyType, notifyRef); 1486e0e9324cSopenharmony_ci notifier->NotifyDataReceiver(notifyType); 1487e0e9324cSopenharmony_ci } 1488e0e9324cSopenharmony_ci } 1489e0e9324cSopenharmony_ci 1490e0e9324cSopenharmony_ci dispatcher->dataCV_.wait(locker, [&dispatcher]() { return dispatcher->continueNotify_.load(); }); 1491e0e9324cSopenharmony_ci dispatcher->continueNotify_ = false; 1492e0e9324cSopenharmony_ci } 1493e0e9324cSopenharmony_ci 1494e0e9324cSopenharmony_ci return 0; 1495e0e9324cSopenharmony_ci} 1496e0e9324cSopenharmony_ci 1497e0e9324cSopenharmony_civoid BufferDispatcher::NotifyReadReady(uint32_t receiverId, MediaType type) 1498e0e9324cSopenharmony_ci{ 1499e0e9324cSopenharmony_ci MEDIA_LOGD("trace."); 1500e0e9324cSopenharmony_ci auto notifier = GetNotifierByReceiverId(receiverId); 1501e0e9324cSopenharmony_ci if (notifier == nullptr) { 1502e0e9324cSopenharmony_ci SHARING_LOGE("notifier is nullptr."); 1503e0e9324cSopenharmony_ci return; 1504e0e9324cSopenharmony_ci } 1505e0e9324cSopenharmony_ci 1506e0e9324cSopenharmony_ci std::shared_lock<std::shared_mutex> lock(bufferMutex_); 1507e0e9324cSopenharmony_ci std::unique_lock<std::mutex> locker(notifyMutex_); 1508e0e9324cSopenharmony_ci if (type == MEDIA_TYPE_AV) { 1509e0e9324cSopenharmony_ci SetReceiverReadRef(receiverId, MEDIA_TYPE_VIDEO, true); 1510e0e9324cSopenharmony_ci SetReceiverReadRef(receiverId, MEDIA_TYPE_AUDIO, true); 1511e0e9324cSopenharmony_ci } else { 1512e0e9324cSopenharmony_ci SetReceiverReadRef(receiverId, type, true); 1513e0e9324cSopenharmony_ci } 1514e0e9324cSopenharmony_ci 1515e0e9324cSopenharmony_ci bool dataAvaliable = notifier->DataAvailable(type); 1516e0e9324cSopenharmony_ci MEDIA_LOGD("receiverId %{public}d MediaType %{public}d dataAvaliable %{public}d.", receiverId, type, 1517e0e9324cSopenharmony_ci dataAvaliable); 1518e0e9324cSopenharmony_ci if (type == MEDIA_TYPE_AV) { 1519e0e9324cSopenharmony_ci SetReceiverDataRef(receiverId, MEDIA_TYPE_VIDEO, dataAvaliable); 1520e0e9324cSopenharmony_ci SetReceiverDataRef(receiverId, MEDIA_TYPE_AUDIO, dataAvaliable); 1521e0e9324cSopenharmony_ci } else { 1522e0e9324cSopenharmony_ci SetReceiverDataRef(receiverId, type, dataAvaliable); 1523e0e9324cSopenharmony_ci } 1524e0e9324cSopenharmony_ci 1525e0e9324cSopenharmony_ci if (!dataAvaliable) { 1526e0e9324cSopenharmony_ci return; 1527e0e9324cSopenharmony_ci } 1528e0e9324cSopenharmony_ci 1529e0e9324cSopenharmony_ci continueNotify_ = true; 1530e0e9324cSopenharmony_ci dataCV_.notify_one(); 1531e0e9324cSopenharmony_ci} 1532e0e9324cSopenharmony_ci 1533e0e9324cSopenharmony_civoid BufferDispatcher::SetDataRef(uint32_t bitref) 1534e0e9324cSopenharmony_ci{ 1535e0e9324cSopenharmony_ci SHARING_LOGD("trace."); 1536e0e9324cSopenharmony_ci dataBitRef_ &= bitref; 1537e0e9324cSopenharmony_ci} 1538e0e9324cSopenharmony_ci 1539e0e9324cSopenharmony_ciuint32_t BufferDispatcher::GetDataRef() 1540e0e9324cSopenharmony_ci{ 1541e0e9324cSopenharmony_ci SHARING_LOGD("trace."); 1542e0e9324cSopenharmony_ci return dataBitRef_; 1543e0e9324cSopenharmony_ci} 1544e0e9324cSopenharmony_ci 1545e0e9324cSopenharmony_civoid BufferDispatcher::SetReadRef(uint32_t bitref) 1546e0e9324cSopenharmony_ci{ 1547e0e9324cSopenharmony_ci SHARING_LOGD("trace."); 1548e0e9324cSopenharmony_ci recvBitRef_ &= bitref; 1549e0e9324cSopenharmony_ci} 1550e0e9324cSopenharmony_ci 1551e0e9324cSopenharmony_ciuint32_t BufferDispatcher::GetReadRef() 1552e0e9324cSopenharmony_ci{ 1553e0e9324cSopenharmony_ci SHARING_LOGD("trace."); 1554e0e9324cSopenharmony_ci return recvBitRef_; 1555e0e9324cSopenharmony_ci} 1556e0e9324cSopenharmony_ci 1557e0e9324cSopenharmony_civoid BufferDispatcher::ActiveDataRef(MediaType type, bool keyFrame) 1558e0e9324cSopenharmony_ci{ 1559e0e9324cSopenharmony_ci MEDIA_LOGD("trace."); 1560e0e9324cSopenharmony_ci std::unique_lock<std::mutex> locker(notifyMutex_); 1561e0e9324cSopenharmony_ci uint32_t bitRef = 0x0000; 1562e0e9324cSopenharmony_ci for (auto &[recvId, notifier] : notifiers_) { 1563e0e9324cSopenharmony_ci auto index = notifier->GetReadIndex(); 1564e0e9324cSopenharmony_ci if (type == MEDIA_TYPE_AUDIO) { 1565e0e9324cSopenharmony_ci bitRef |= RECV_FLAG_BASE << (index * 2); // 2: fix offset, get audio notifyer id 1566e0e9324cSopenharmony_ci continue; 1567e0e9324cSopenharmony_ci } 1568e0e9324cSopenharmony_ci bool keyModeReceiver = false; 1569e0e9324cSopenharmony_ci keyModeReceiver = notifier->IsKeyModeReceiver(); 1570e0e9324cSopenharmony_ci if (keyFrame && keyModeReceiver && keyIndexList_.empty()) { 1571e0e9324cSopenharmony_ci notifier->videoIndex = circularBuffer_.size() - 1; 1572e0e9324cSopenharmony_ci } 1573e0e9324cSopenharmony_ci if ((!keyModeReceiver || (keyModeReceiver && keyFrame))) { 1574e0e9324cSopenharmony_ci if (index != INVALID_INDEX) { 1575e0e9324cSopenharmony_ci bitRef |= RECV_FLAG_BASE << (index * 2 + 1); // 2: fix offset, get video notifyer id 1576e0e9324cSopenharmony_ci } 1577e0e9324cSopenharmony_ci } 1578e0e9324cSopenharmony_ci } 1579e0e9324cSopenharmony_ci 1580e0e9324cSopenharmony_ci dataBitRef_ |= bitRef; 1581e0e9324cSopenharmony_ci} 1582e0e9324cSopenharmony_ci 1583e0e9324cSopenharmony_civoid BufferDispatcher::SetReceiverDataRef(uint32_t receiverId, MediaType type, bool ready) 1584e0e9324cSopenharmony_ci{ 1585e0e9324cSopenharmony_ci MEDIA_LOGD("trace."); 1586e0e9324cSopenharmony_ci uint32_t index = FindReceiverIndex(receiverId); 1587e0e9324cSopenharmony_ci if (index == INVALID_INDEX) { 1588e0e9324cSopenharmony_ci return; 1589e0e9324cSopenharmony_ci } 1590e0e9324cSopenharmony_ci 1591e0e9324cSopenharmony_ci if (type == MEDIA_TYPE_AUDIO) { 1592e0e9324cSopenharmony_ci uint32_t audioBit = index * 2; 1593e0e9324cSopenharmony_ci uint32_t bitRef = RECV_FLAG_BASE << audioBit; 1594e0e9324cSopenharmony_ci MEDIA_LOGD("Audio recvid %{public}d ,bitRef %{public}d ready %{public}d.", receiverId, bitRef, ready); 1595e0e9324cSopenharmony_ci if (!ready) { 1596e0e9324cSopenharmony_ci bitRef = ~bitRef; 1597e0e9324cSopenharmony_ci dataBitRef_ &= bitRef; 1598e0e9324cSopenharmony_ci } else { 1599e0e9324cSopenharmony_ci dataBitRef_ |= bitRef; 1600e0e9324cSopenharmony_ci } 1601e0e9324cSopenharmony_ci } else if (type == MEDIA_TYPE_VIDEO) { 1602e0e9324cSopenharmony_ci uint32_t videoBit = index * 2 + 1; 1603e0e9324cSopenharmony_ci uint32_t bitRef = RECV_FLAG_BASE << videoBit; 1604e0e9324cSopenharmony_ci MEDIA_LOGD("Video recvid %{public}d ,bitRef %{public}d ready %{public}d.", receiverId, bitRef, ready); 1605e0e9324cSopenharmony_ci if (!ready) { 1606e0e9324cSopenharmony_ci bitRef = ~bitRef; 1607e0e9324cSopenharmony_ci dataBitRef_ &= bitRef; 1608e0e9324cSopenharmony_ci } else { 1609e0e9324cSopenharmony_ci dataBitRef_ |= bitRef; 1610e0e9324cSopenharmony_ci } 1611e0e9324cSopenharmony_ci } 1612e0e9324cSopenharmony_ci} 1613e0e9324cSopenharmony_ci 1614e0e9324cSopenharmony_civoid BufferDispatcher::SetReceiverReadRef(uint32_t receiverId, MediaType type, bool ready) 1615e0e9324cSopenharmony_ci{ 1616e0e9324cSopenharmony_ci MEDIA_LOGD("trace."); 1617e0e9324cSopenharmony_ci uint32_t index = FindReceiverIndex(receiverId); 1618e0e9324cSopenharmony_ci if (index == INVALID_INDEX) { 1619e0e9324cSopenharmony_ci return; 1620e0e9324cSopenharmony_ci } 1621e0e9324cSopenharmony_ci 1622e0e9324cSopenharmony_ci if (type == MEDIA_TYPE_AUDIO) { 1623e0e9324cSopenharmony_ci uint32_t audioBit = index * 2; 1624e0e9324cSopenharmony_ci uint32_t bitRef = RECV_FLAG_BASE << audioBit; 1625e0e9324cSopenharmony_ci MEDIA_LOGD("Audio recvid %{public}d ,bitRef %{public}d ready %{public}d.", receiverId, bitRef, ready); 1626e0e9324cSopenharmony_ci 1627e0e9324cSopenharmony_ci if (!ready) { 1628e0e9324cSopenharmony_ci bitRef = ~bitRef; 1629e0e9324cSopenharmony_ci recvBitRef_ &= bitRef; 1630e0e9324cSopenharmony_ci } else { 1631e0e9324cSopenharmony_ci recvBitRef_ |= bitRef; 1632e0e9324cSopenharmony_ci } 1633e0e9324cSopenharmony_ci } else if (type == MEDIA_TYPE_VIDEO) { 1634e0e9324cSopenharmony_ci uint32_t videoBit = index * 2 + 1; 1635e0e9324cSopenharmony_ci uint32_t bitRef = RECV_FLAG_BASE << videoBit; 1636e0e9324cSopenharmony_ci MEDIA_LOGD("Video recvid %{public}d ,bitRef %{public}d ready %{public}d.", receiverId, bitRef, ready); 1637e0e9324cSopenharmony_ci 1638e0e9324cSopenharmony_ci if (!ready) { 1639e0e9324cSopenharmony_ci bitRef = ~bitRef; 1640e0e9324cSopenharmony_ci recvBitRef_ &= bitRef; 1641e0e9324cSopenharmony_ci } else { 1642e0e9324cSopenharmony_ci recvBitRef_ |= bitRef; 1643e0e9324cSopenharmony_ci } 1644e0e9324cSopenharmony_ci } 1645e0e9324cSopenharmony_ci} 1646e0e9324cSopenharmony_ci 1647e0e9324cSopenharmony_ciuint32_t BufferDispatcher::GetReceiverDataRef(uint32_t receiverId) 1648e0e9324cSopenharmony_ci{ 1649e0e9324cSopenharmony_ci SHARING_LOGD("trace."); 1650e0e9324cSopenharmony_ci return 0; 1651e0e9324cSopenharmony_ci} 1652e0e9324cSopenharmony_ci 1653e0e9324cSopenharmony_ciuint32_t BufferDispatcher::GetReceiverReadRef(uint32_t receiverId) 1654e0e9324cSopenharmony_ci{ 1655e0e9324cSopenharmony_ci SHARING_LOGD("trace."); 1656e0e9324cSopenharmony_ci uint32_t retBitRef = GetReceiverIndexRef(receiverId); 1657e0e9324cSopenharmony_ci retBitRef &= recvBitRef_; 1658e0e9324cSopenharmony_ci return retBitRef; 1659e0e9324cSopenharmony_ci} 1660e0e9324cSopenharmony_ci 1661e0e9324cSopenharmony_ciuint32_t BufferDispatcher::GetReceiverIndexRef(uint32_t receiverId) 1662e0e9324cSopenharmony_ci{ 1663e0e9324cSopenharmony_ci SHARING_LOGD("trace."); 1664e0e9324cSopenharmony_ci uint32_t index = FindReceiverIndex(receiverId); 1665e0e9324cSopenharmony_ci uint32_t audioBit = index * 2; 1666e0e9324cSopenharmony_ci uint32_t videoBit = index * 2 + 1; 1667e0e9324cSopenharmony_ci uint32_t retBitRef = 0x0000; 1668e0e9324cSopenharmony_ci retBitRef |= RECV_FLAG_BASE << audioBit; 1669e0e9324cSopenharmony_ci retBitRef |= RECV_FLAG_BASE << videoBit; 1670e0e9324cSopenharmony_ci return retBitRef; 1671e0e9324cSopenharmony_ci} 1672e0e9324cSopenharmony_ci 1673e0e9324cSopenharmony_civoid BufferDispatcher::ClearReadBit(uint32_t receiverId, MediaType type) 1674e0e9324cSopenharmony_ci{ 1675e0e9324cSopenharmony_ci MEDIA_LOGD("trace."); 1676e0e9324cSopenharmony_ci std::lock_guard<std::mutex> indexLocker(notifyMutex_); 1677e0e9324cSopenharmony_ci if (type != MEDIA_TYPE_AV) { 1678e0e9324cSopenharmony_ci SetReceiverReadRef(receiverId, type, false); 1679e0e9324cSopenharmony_ci } else { 1680e0e9324cSopenharmony_ci SetReceiverReadRef(receiverId, MEDIA_TYPE_VIDEO, false); 1681e0e9324cSopenharmony_ci SetReceiverReadRef(receiverId, MEDIA_TYPE_AUDIO, false); 1682e0e9324cSopenharmony_ci } 1683e0e9324cSopenharmony_ci} 1684e0e9324cSopenharmony_ci 1685e0e9324cSopenharmony_civoid BufferDispatcher::ClearDataBit(uint32_t receiverId, MediaType type) 1686e0e9324cSopenharmony_ci{ 1687e0e9324cSopenharmony_ci MEDIA_LOGD("trace."); 1688e0e9324cSopenharmony_ci std::lock_guard<std::mutex> indexLocker(notifyMutex_); 1689e0e9324cSopenharmony_ci if (type != MEDIA_TYPE_AV) { 1690e0e9324cSopenharmony_ci SetReceiverDataRef(receiverId, type, false); 1691e0e9324cSopenharmony_ci } else { 1692e0e9324cSopenharmony_ci SetReceiverDataRef(receiverId, MEDIA_TYPE_VIDEO, false); 1693e0e9324cSopenharmony_ci SetReceiverDataRef(receiverId, MEDIA_TYPE_AUDIO, false); 1694e0e9324cSopenharmony_ci } 1695e0e9324cSopenharmony_ci} 1696e0e9324cSopenharmony_ci 1697e0e9324cSopenharmony_cibool BufferDispatcher::IsRead(uint32_t receiverId, uint32_t index) 1698e0e9324cSopenharmony_ci{ 1699e0e9324cSopenharmony_ci MEDIA_LOGD("trace."); 1700e0e9324cSopenharmony_ci if (index >= circularBuffer_.size()) { 1701e0e9324cSopenharmony_ci return true; 1702e0e9324cSopenharmony_ci } else { 1703e0e9324cSopenharmony_ci return IsDataReaded(receiverId, circularBuffer_.at(index)); 1704e0e9324cSopenharmony_ci } 1705e0e9324cSopenharmony_ci} 1706e0e9324cSopenharmony_ci 1707e0e9324cSopenharmony_civoid BufferDispatcher::ActivateReceiverIndex(uint32_t index, MediaType type) 1708e0e9324cSopenharmony_ci{ 1709e0e9324cSopenharmony_ci MEDIA_LOGD("trace."); 1710e0e9324cSopenharmony_ci std::unique_lock<std::mutex> lock(notifyMutex_); 1711e0e9324cSopenharmony_ci for (auto &[recvId, notifier] : notifiers_) { 1712e0e9324cSopenharmony_ci if (type == MEDIA_TYPE_VIDEO) { 1713e0e9324cSopenharmony_ci if (notifier->videoIndex == INVALID_INDEX) { 1714e0e9324cSopenharmony_ci notifier->videoIndex = index; 1715e0e9324cSopenharmony_ci SHARING_LOGD("RecvId %{public}d Activate %{public}d.", notifier->GetReceiverId(), notifier->videoIndex); 1716e0e9324cSopenharmony_ci videoNeedActivate_ = false; 1717e0e9324cSopenharmony_ci } 1718e0e9324cSopenharmony_ci } else { 1719e0e9324cSopenharmony_ci if (notifier->audioIndex == INVALID_INDEX) { 1720e0e9324cSopenharmony_ci notifier->audioIndex = index; 1721e0e9324cSopenharmony_ci SHARING_LOGD("RecvId %{public}d Activate %{public}d.", notifier->GetReceiverId(), notifier->audioIndex); 1722e0e9324cSopenharmony_ci audioNeedActivate_ = false; 1723e0e9324cSopenharmony_ci } 1724e0e9324cSopenharmony_ci } 1725e0e9324cSopenharmony_ci } 1726e0e9324cSopenharmony_ci} 1727e0e9324cSopenharmony_civoid BufferDispatcher::UnlockWaitingReceiverIndex(MediaType type) 1728e0e9324cSopenharmony_ci{ 1729e0e9324cSopenharmony_ci SHARING_LOGD("trace."); 1730e0e9324cSopenharmony_ci} 1731e0e9324cSopenharmony_ci 1732e0e9324cSopenharmony_civoid BufferDispatcher::SetReceiverReadFlag(uint32_t receiverId, DataSpec::Ptr &dataSpec) 1733e0e9324cSopenharmony_ci{ 1734e0e9324cSopenharmony_ci MEDIA_LOGD("trace."); 1735e0e9324cSopenharmony_ci RETURN_IF_NULL(dataSpec); 1736e0e9324cSopenharmony_ci uint32_t index = FindReceiverIndex(receiverId); 1737e0e9324cSopenharmony_ci if (index != INVALID_INDEX) { 1738e0e9324cSopenharmony_ci dataSpec->reserveFlag |= RECV_FLAG_BASE << index; 1739e0e9324cSopenharmony_ci MEDIA_LOGD("mediaType: %{public}d, pts: %{public}" PRIu64 1740e0e9324cSopenharmony_ci ", reserveFlag: %{public}x, receiverId: %{public}d, index: %{public}d.", 1741e0e9324cSopenharmony_ci dataSpec->mediaData->mediaType, dataSpec->mediaData->pts, dataSpec->reserveFlag.load(), receiverId, 1742e0e9324cSopenharmony_ci index); 1743e0e9324cSopenharmony_ci } 1744e0e9324cSopenharmony_ci} 1745e0e9324cSopenharmony_ci 1746e0e9324cSopenharmony_civoid BufferDispatcher::CancelReserve() 1747e0e9324cSopenharmony_ci{ 1748e0e9324cSopenharmony_ci SHARING_LOGD("trace."); 1749e0e9324cSopenharmony_ci for (auto &data : circularBuffer_) { 1750e0e9324cSopenharmony_ci data->reserveFlag = 0xff; 1751e0e9324cSopenharmony_ci } 1752e0e9324cSopenharmony_ci} 1753e0e9324cSopenharmony_ci 1754e0e9324cSopenharmony_civoid BufferDispatcher::SetSpsNalu(MediaData::Ptr spsbuf) 1755e0e9324cSopenharmony_ci{ 1756e0e9324cSopenharmony_ci SHARING_LOGD("trace."); 1757e0e9324cSopenharmony_ci spsBuf_ = spsbuf; 1758e0e9324cSopenharmony_ci} 1759e0e9324cSopenharmony_ci 1760e0e9324cSopenharmony_ciconst MediaData::Ptr BufferDispatcher::GetSPS() 1761e0e9324cSopenharmony_ci{ 1762e0e9324cSopenharmony_ci MEDIA_LOGD("trace."); 1763e0e9324cSopenharmony_ci return spsBuf_; 1764e0e9324cSopenharmony_ci} 1765e0e9324cSopenharmony_ci 1766e0e9324cSopenharmony_civoid BufferDispatcher::SetPpsNalu(MediaData::Ptr ppsbuf) 1767e0e9324cSopenharmony_ci{ 1768e0e9324cSopenharmony_ci SHARING_LOGD("trace."); 1769e0e9324cSopenharmony_ci ppsBuf_ = ppsbuf; 1770e0e9324cSopenharmony_ci} 1771e0e9324cSopenharmony_ci 1772e0e9324cSopenharmony_ciconst MediaData::Ptr BufferDispatcher::GetPPS() 1773e0e9324cSopenharmony_ci{ 1774e0e9324cSopenharmony_ci MEDIA_LOGD("trace."); 1775e0e9324cSopenharmony_ci return ppsBuf_; 1776e0e9324cSopenharmony_ci} 1777e0e9324cSopenharmony_ci 1778e0e9324cSopenharmony_ciuint32_t BufferDispatcher::GetCurrentGop() 1779e0e9324cSopenharmony_ci{ 1780e0e9324cSopenharmony_ci SHARING_LOGD("trace."); 1781e0e9324cSopenharmony_ci return gop_; 1782e0e9324cSopenharmony_ci} 1783e0e9324cSopenharmony_ci 1784e0e9324cSopenharmony_civoid BufferDispatcher::OnKeyRedirect() 1785e0e9324cSopenharmony_ci{ 1786e0e9324cSopenharmony_ci SHARING_LOGD("trace."); 1787e0e9324cSopenharmony_ci std::unique_lock<std::mutex> lock(notifyMutex_); 1788e0e9324cSopenharmony_ci if (keyIndexList_.empty()) { 1789e0e9324cSopenharmony_ci return; 1790e0e9324cSopenharmony_ci } 1791e0e9324cSopenharmony_ci 1792e0e9324cSopenharmony_ci auto nextIndex = keyIndexList_.back(); 1793e0e9324cSopenharmony_ci 1794e0e9324cSopenharmony_ci for (auto &[recvId, notifier] : notifiers_) { 1795e0e9324cSopenharmony_ci if (notifier->IsKeyRedirectReceiver()) { 1796e0e9324cSopenharmony_ci SHARING_LOGD("receiverId: %{public}u, videoIndex: %{public}d, nextIndex: %{public}d.", 1797e0e9324cSopenharmony_ci notifier->GetReceiverId(), notifier->videoIndex, nextIndex); 1798e0e9324cSopenharmony_ci auto curIndex = notifier->videoIndex; 1799e0e9324cSopenharmony_ci notifier->videoIndex = nextIndex; 1800e0e9324cSopenharmony_ci for (auto i = curIndex; i < nextIndex; i++) { 1801e0e9324cSopenharmony_ci SetReceiverReadFlag(notifier->GetReceiverId(), circularBuffer_[i]); 1802e0e9324cSopenharmony_ci } 1803e0e9324cSopenharmony_ci if (!rapidMode_) { 1804e0e9324cSopenharmony_ci auto receiver = notifier->GetBufferReceiver(); 1805e0e9324cSopenharmony_ci if (receiver != nullptr) { 1806e0e9324cSopenharmony_ci receiver->EnableKeyRedirect(false); 1807e0e9324cSopenharmony_ci } 1808e0e9324cSopenharmony_ci } 1809e0e9324cSopenharmony_ci } 1810e0e9324cSopenharmony_ci } 1811e0e9324cSopenharmony_ci} 1812e0e9324cSopenharmony_ci 1813e0e9324cSopenharmony_civoid BufferDispatcher::EnableRapidMode(bool enable) 1814e0e9324cSopenharmony_ci{ 1815e0e9324cSopenharmony_ci SHARING_LOGD("trace."); 1816e0e9324cSopenharmony_ci rapidMode_ = enable; 1817e0e9324cSopenharmony_ci} 1818e0e9324cSopenharmony_ci 1819e0e9324cSopenharmony_ci} // namespace Sharing 1820e0e9324cSopenharmony_ci} // namespace OHOS 1821