blob: e689e961ac33146cab321f582b7b64ee2adfe7a8 [file] [log] [blame]
// Copyright 2019 The Cobalt Authors. All Rights Reserved.
//
// 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 STARBOARD_ANDROID_SHARED_AUDIO_SINK_MIN_REQUIRED_FRAMES_TESTER_H_
#define STARBOARD_ANDROID_SHARED_AUDIO_SINK_MIN_REQUIRED_FRAMES_TESTER_H_
#include <atomic>
#include <functional>
#include <vector>
#include "starboard/common/condition_variable.h"
#include "starboard/common/mutex.h"
#include "starboard/media.h"
#include "starboard/shared/starboard/thread_checker.h"
#include "starboard/thread.h"
namespace starboard {
namespace android {
namespace shared {
class AudioTrackAudioSink;
// The class is to detect min required frames for audio sink to play audio
// without underflow.
class MinRequiredFramesTester {
public:
typedef std::function<void(int number_of_channels,
SbMediaAudioSampleType sample_type,
int sample_rate,
int min_required_frames)>
OnMinRequiredFramesReceivedCallback;
MinRequiredFramesTester(int max_required_frames,
int required_frames_increment,
int min_stable_played_frames);
~MinRequiredFramesTester();
void AddTest(int number_of_channels,
SbMediaAudioSampleType sample_type,
int sample_rate,
const OnMinRequiredFramesReceivedCallback& received_cb,
int default_required_frames);
void Start();
private:
struct TestTask {
TestTask(int number_of_channels,
SbMediaAudioSampleType sample_type,
int sample_rate,
OnMinRequiredFramesReceivedCallback received_cb,
int default_required_frames)
: number_of_channels(number_of_channels),
sample_type(sample_type),
sample_rate(sample_rate),
received_cb(received_cb),
default_required_frames(default_required_frames) {}
const int number_of_channels;
const SbMediaAudioSampleType sample_type;
const int sample_rate;
const OnMinRequiredFramesReceivedCallback received_cb;
const int default_required_frames;
};
static void* TesterThreadEntryPoint(void* context);
void TesterThreadFunc();
static void UpdateSourceStatusFunc(int* frames_in_buffer,
int* offset_in_frames,
bool* is_playing,
bool* is_eos_reached,
void* context);
static void ConsumeFramesFunc(int frames_consumed,
SbTime frames_consumed_at,
void* context);
static void ErrorFunc(bool capability_changed, void* context);
void UpdateSourceStatus(int* frames_in_buffer,
int* offset_in_frames,
bool* is_playing,
bool* is_eos_reached);
void ConsumeFrames(int frames_consumed);
MinRequiredFramesTester(const MinRequiredFramesTester&) = delete;
MinRequiredFramesTester& operator=(const MinRequiredFramesTester&) = delete;
const int max_required_frames_;
const int required_frames_increment_;
const int min_stable_played_frames_;
::starboard::shared::starboard::ThreadChecker thread_checker_;
std::vector<const TestTask> test_tasks_;
AudioTrackAudioSink* audio_sink_ = nullptr;
int min_required_frames_;
// Used only by audio sink thread.
int total_consumed_frames_;
int last_underrun_count_;
int last_total_consumed_frames_;
Mutex mutex_;
ConditionVariable condition_variable_;
SbThread tester_thread_ = kSbThreadInvalid;
std::atomic_bool destroying_;
};
} // namespace shared
} // namespace android
} // namespace starboard
#endif // STARBOARD_ANDROID_SHARED_AUDIO_SINK_MIN_REQUIRED_FRAMES_TESTER_H_