/*
* Copyright (C) 2011 The Android Open Source Project
*
* 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 FRAMEWORKS_EX_VARIABLESPEED_JNI_VARIABLESPEED_H_
#define FRAMEWORKS_EX_VARIABLESPEED_JNI_VARIABLESPEED_H_
#include <jni.h>
#include <SLES/OpenSLES.h>
#include <SLES/OpenSLES_Android.h>
#include <SLES/OpenSLES_AndroidConfiguration.h>
#include <integral_types.h>
#include <utils/threads.h>
#include <profile_timer.h>
#include <decode_buffer.h>
#include <queue>
#include <stack>
namespace video_editing {
class SolaTimeScaler;
}
// This is the audio engine class.
// It forms the bulk of the variablespeed library.
// It should not be used directly, but rather used indirectly from the java
// native methods.
class AudioEngine {
public:
AudioEngine(size_t targetFrames, float windowDuration,
float windowOverlapDuration, size_t maxPlayBufferCount,
float initialRate, size_t decodeInitialSize, size_t decodeMaxSize,
size_t startPositionMillis, int audioStreamType);
virtual ~AudioEngine();
bool PlayUri(const char* uri);
bool PlayFileDescriptor(int fd, int64 offset, int64 length);
void SetVariableSpeed(float speed);
void RequestStart();
void RequestStop();
int GetCurrentPosition();
int GetTotalDuration();
void DecodingBufferQueueCallback(
SLAndroidSimpleBufferQueueItf queueItf, void *context);
void DecodingEventCallback(SLPlayItf caller, SLuint32 event);
void PrefetchEventCallback(SLPrefetchStatusItf caller, SLuint32 event);
void PlayingBufferQueueCallback();
static AudioEngine* GetEngine();
static void SetEngine(AudioEngine* engine);
static bool CompareAndSetEngine(AudioEngine* expect, AudioEngine* update);
static void DeleteEngine();
private:
bool PlayFromThisSource(const SLDataSource& audioSrc);
void EnqueueMoreAudioIfNecessary(SLAndroidSimpleBufferQueueItf bufferQueue);
bool EnqueueNextBufferOfAudio(SLAndroidSimpleBufferQueueItf bufferQueue);
void PrefetchDurationSampleRateAndChannels(
SLPlayItf playItf, SLPrefetchStatusItf prefetchItf);
video_editing::SolaTimeScaler* GetTimeScaler();
bool Finished();
bool GetWasStartRequested();
bool GetWasStopRequested();
void ClearRequestStart();
void SetEndOfDecoderReached();
bool GetEndOfDecoderReached();
bool DecodeBufferTooFull();
void ClearDecodeBuffer();
bool IsDecodeBufferEmpty();
bool GetHasReachedPlayingBuffersLimit();
bool HasSampleRateAndChannels();
SLuint32 GetSLSampleRate();
SLuint32 GetSLChannels();
size_t GetChannelCount();
// The single global audio engine instance.
static AudioEngine* audioEngine_;
// Protects access to the shared decode buffer.
android::Mutex decodeBufferLock_;
// Buffer into which we put the audio data as we decode.
// Protected by decodeBufferLock_.
DecodeBuffer decodeBuffer_;
// Protects access to the playingBuffers_ and freeBuffers_.
android::Mutex playBufferLock_;
// The buffers we're using for playback.
std::queue<int16*> playingBuffers_;
std::stack<int16*> freeBuffers_;
// The time scaler.
video_editing::SolaTimeScaler* timeScaler_;
// The frame buffer, used for converting between PCM data and float for
// time scaler.
float* floatBuffer_;
float* injectBuffer_;
// Required when we create the audio player.
// Set during the first callback from the decoder.
// Guarded by callbackLock_.
SLuint32 mSampleRate;
SLuint32 mChannels;
size_t targetFrames_;
float windowDuration_;
float windowOverlapDuration_;
size_t maxPlayBufferCount_;
float initialRate_;
size_t startPositionMillis_;
// The type of audio stream as defined by the STREAM_XXX constants in
// android.media.AudioManager. These constant values actually match the
// corresponding SL_ANDROID_STREAM_XXX constants defined by
// include/SLES/OpenSLES_AndroidConfiguration.h
int audioStreamType_;
// The prefetch callback signal, for letting the prefetch callback method
// indicate when it is done.
android::Mutex prefetchLock_;
android::Condition prefetchCondition_;
// Protects access to the CallbackContext object.
// I don't believe this to be necessary, I think that it's thread-confined,
// but it also won't do any harm.
android::Mutex callbackLock_;
// Protects access to the shared member variables below.
android::Mutex lock_;
// Protected by lock_.
// Stores the total duration of the track.
SLmillisecond totalDurationMs_;
// Protected by lock_.
// Stores the current position of the decoder head.
SLmillisecond decoderCurrentPosition_;
// Protected by lock_.
// Set externally via RequestStart(), this determines when we begin to
// playback audio.
// Until this is set to true, our audio player will remain stopped.
bool startRequested_;
// Protected by lock_.
// Set externally via RequestStop(), this tells us top stop playing
// and therefore shut everything down.
bool stopRequested_;
// Protected by lock_.
// This is set to true once we reach the end of the decoder stream.
bool finishedDecoding_;
DISALLOW_COPY_AND_ASSIGN(AudioEngine);
};
#endif // FRAMEWORKS_EX_VARIABLESPEED_JNI_VARIABLESPEED_H_