* Copyright (c) 2025 Huawei Device Co., Ltd.
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#ifndef SAMPLE_QUEUE_CONTROLLER_H
#define SAMPLE_QUEUE_CONTROLLER_H
#include <atomic>
#include <memory>
#include <mutex>
#include "common/media_source.h"
#include "demuxer/sample_queue.h"
#include "osal/task/task.h"
#include "osal/utils/steady_clock.h"
namespace OHOS {
namespace Media {
struct SpeedCountInfo {
static constexpr double TIME_TO_US = 1000000.0;
std::atomic<uint64_t> totalFrameCount = 0;
std::atomic<uint64_t> totalEffectiveRunTimeUs = 0;
std::atomic<uint64_t> lastEventTimeUs = 0;
uint64_t GetCurrentTimeUs();
void IncrementFrameCount();
void OnEventTimeRecord();
double GetSpeed() const;
uint64_t GetTotalFrameCount() const;
uint64_t GetTotalEffectiveRunTimeUs() const;
};
class SampleQueueController {
public:
explicit SampleQueueController();
~SampleQueueController() = default;
uint64_t GetQueueSize(int32_t trackId);
void SetQueueSize(int32_t trackId, uint64_t size);
void AddQueueSize(int32_t trackId, uint64_t size);
bool ShouldStartConsume(int32_t trackId, std::shared_ptr<SampleQueue> sampleQueue,
const std::unique_ptr<Task> &task, bool inPreroll);
bool ShouldStopConsume(int32_t trackId, std::shared_ptr<SampleQueue> sampleQueue,
const std::unique_ptr<Task> &task);
bool ShouldStartProduce(int32_t trackId, std::shared_ptr<SampleQueue> sampleQueue,
const std::unique_ptr<Task> &task);
bool ShouldStopProduce(int32_t trackId, std::shared_ptr<SampleQueue> sampleQueue,
const std::unique_ptr<Task> &task);
void ProduceIncrementFrameCount(int32_t trackId);
void ProduceOnEventTimeRecord(int32_t trackId);
void ConsumeSpeed(int32_t trackId);
void SetSpeed(float speed);
float GetSpeed();
void SetBufferingDuration(std::shared_ptr<Plugins::PlayStrategy> strategy);
uint64_t GetBufferingDuration();
uint64_t GetPlayBufferingDuration();
void DisableFirstBufferingDuration();
bool CheckWaterLineStopProduce(int32_t trackId, std::shared_ptr<SampleQueue> sampleQueue);
bool CheckWaterLineStartConsume(int32_t trackId, std::shared_ptr<SampleQueue> sampleQueue);
uint64_t GetCacheDuration(std::shared_ptr<SampleQueue> sampleQueue);
static constexpr uint64_t QUEUE_SIZE_MIN = 30;
static constexpr uint64_t START_CONSUME_WATER_LOOP = 5 * 1000 * 1000;
static constexpr uint64_t STOP_CONSUME_WATER_LOOP = 0;
static constexpr uint64_t START_PRODUCE_WATER_LOOP = 5 * 1000 * 1000;
static constexpr uint64_t STOP_PRODUCE_WATER_LOOP = 10 * 1000 * 1000;
static constexpr uint64_t FIRST_START_CONSUME_WATER_LOOP = 2 * 1000 * 1000;
static constexpr uint32_t ADD_ONCE_MAX_SIZE = 100;
private:
std::map<int32_t, std::shared_ptr<SpeedCountInfo>> produceSpeedCountInfo_;
std::map<int32_t, std::shared_ptr<SpeedCountInfo>> consumeSpeedCountInfo_;
std::map<int32_t, uint64_t> queueSizeMap_;
std::map<int32_t, bool> isFirstArrived_;
std::atomic<bool> isSetFirstBufferingDuration_ {};
std::atomic<uint64_t> bufferingDuration_ {};
std::atomic<uint64_t> firstBufferingDuration_ {};
std::atomic<float> speed_ {1.0f};
std::map<int32_t, int64_t> stopConsumeStartTime_;
};
}
}
#endif