blob: a169b18c37da9915a54d2be3fe2c8c000ce57148 [file] [log] [blame]
// Copyright 2022 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_SHARED_UWP_AUDIO_RENDERER_PASSTHROUGH_H_
#define STARBOARD_SHARED_UWP_AUDIO_RENDERER_PASSTHROUGH_H_
#include <functional>
#include <queue>
#include "starboard/atomic.h"
#include "starboard/common/mutex.h"
#include "starboard/common/ref_counted.h"
#include "starboard/media.h"
#include "starboard/shared/internal_only.h"
#include "starboard/shared/starboard/media/media_util.h"
#include "starboard/shared/starboard/player/decoded_audio_internal.h"
#include "starboard/shared/starboard/player/filter/audio_decoder_internal.h"
#include "starboard/shared/starboard/player/filter/audio_renderer_internal.h"
#include "starboard/shared/starboard/player/filter/media_time_provider.h"
#include "starboard/shared/starboard/player/input_buffer_internal.h"
#include "starboard/shared/starboard/player/job_queue.h"
#include "starboard/shared/uwp/wasapi_audio_sink.h"
#include "starboard/types.h"
namespace starboard {
namespace shared {
namespace uwp {
using ::starboard::shared::starboard::player::DecodedAudio;
using ::starboard::shared::starboard::player::JobQueue;
using ::starboard::shared::starboard::player::filter::AudioDecoder;
using ::starboard::shared::starboard::player::filter::AudioRenderer;
using ::starboard::shared::starboard::player::filter::MediaTimeProvider;
class AudioRendererPassthrough : public AudioRenderer,
public MediaTimeProvider,
private JobQueue::JobOwner {
public:
typedef starboard::media::AudioStreamInfo AudioStreamInfo;
AudioRendererPassthrough(scoped_ptr<AudioDecoder> audio_decoder,
const AudioStreamInfo& audio_stream_info);
~AudioRendererPassthrough() override;
void Initialize(const ErrorCB& error_cb,
const PrerolledCB& prerolled_cb,
const EndedCB& ended_cb) override;
void WriteSamples(const InputBuffers& input_buffers) override;
void WriteEndOfStream() override;
void SetVolume(double volume) override;
bool IsEndOfStreamWritten() const override;
bool IsEndOfStreamPlayed() const override;
bool CanAcceptMoreData() const override;
// MediaTimeProvider methods
void Play() override;
void Pause() override;
void SetPlaybackRate(double playback_rate) override;
void Seek(int64_t seek_to_time) override;
int64_t GetCurrentMediaTime(bool* is_playing,
bool* is_eos_played,
bool* is_underflow,
double* playback_rate) override;
private:
void OnDecoderConsumed();
void OnDecoderOutput();
void ProcessAudioBuffers();
bool TryToWriteAudioBufferToSink(scoped_refptr<DecodedAudio> decoded_audio);
// After end of stream is written, stop the audio sink after it finishes audio
// output.
void TryToEndStream();
// Calculates the playback time elapsed (microseconds) since the last time the
// timestamp was queried using WASAPIAudioSink::GetCurrentPlaybackTime().
int64_t CalculateElapsedPlaybackTime(uint64_t update_time);
// Calculates the final output timestamp (microseconds) of a DecodedAudio.
int64_t CalculateLastOutputTime(scoped_refptr<DecodedAudio>& decoded_audio);
const int kMaxDecodedAudios = 16;
// About 250 ms of (E)AC3 audio.
const int kNumPrerollDecodedAudios = 8;
ErrorCB error_cb_;
PrerolledCB prerolled_cb_;
EndedCB ended_cb_;
Mutex mutex_;
bool paused_ = true;
bool seeking_ = false;
double playback_rate_ = 1.0;
int64_t seeking_to_time_ = 0;
atomic_bool end_of_stream_written_{false};
atomic_bool end_of_stream_played_{false};
// Use DecodedAudio to store decrypted and formatted encoded audio data.
std::queue<scoped_refptr<DecodedAudio>> pending_inputs_;
atomic_bool can_accept_more_data_;
JobQueue::JobToken process_audio_buffers_job_token_;
std::function<void()> process_audio_buffers_job_;
int64_t total_frames_sent_to_sink_ = 0;
int total_buffers_sent_to_sink_ = 0;
const int channels_;
const SbMediaAudioCodec codec_ = kSbMediaAudioCodecNone;
scoped_ptr<AudioDecoder> decoder_;
scoped_ptr<WASAPIAudioSink> sink_;
// |iec_sample_rate_| is the sample rate of the stream when stored in an IEC
// 61937 format. This may be different from the decoded sample rate.
const int iec_sample_rate_;
// Used to calculate the media time in GetCurrentMediaTime().
LARGE_INTEGER performance_frequency_;
};
} // namespace uwp
} // namespace shared
} // namespace starboard
#endif // STARBOARD_SHARED_UWP_AUDIO_RENDERER_PASSTHROUGH_H_