1/*
2 * Copyright (C) 2011 The Android Open Source Project
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 *      http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
17#ifndef FRAMEWORKS_EX_VARIABLESPEED_JNI_VARIABLESPEED_H_
18#define FRAMEWORKS_EX_VARIABLESPEED_JNI_VARIABLESPEED_H_
19
20#include <jni.h>
21
22#include <SLES/OpenSLES.h>
23#include <SLES/OpenSLES_Android.h>
24#include <SLES/OpenSLES_AndroidConfiguration.h>
25
26#include <integral_types.h>
27#include <utils/threads.h>
28
29#include <profile_timer.h>
30#include <decode_buffer.h>
31
32#include <queue>
33#include <stack>
34
35namespace video_editing {
36  class SolaTimeScaler;
37}
38
39// This is the audio engine class.
40// It forms the bulk  of the variablespeed library.
41// It should not be used directly, but rather used indirectly from the java
42// native methods.
43class AudioEngine {
44 public:
45  AudioEngine(size_t targetFrames, float windowDuration,
46      float windowOverlapDuration, size_t maxPlayBufferCount,
47      float initialRate, size_t decodeInitialSize, size_t decodeMaxSize,
48      size_t startPositionMillis, int audioStreamType);
49  virtual ~AudioEngine();
50
51  bool PlayUri(const char* uri);
52  bool PlayFileDescriptor(int fd, int64 offset, int64 length);
53  void SetVariableSpeed(float speed);
54  void RequestStart();
55  void RequestStop();
56  int GetCurrentPosition();
57  int GetTotalDuration();
58
59  void DecodingBufferQueueCallback(
60      SLAndroidSimpleBufferQueueItf queueItf, void *context);
61  void DecodingEventCallback(SLPlayItf caller, SLuint32 event);
62  void PrefetchEventCallback(SLPrefetchStatusItf caller, SLuint32 event);
63  void PlayingBufferQueueCallback();
64
65  static AudioEngine* GetEngine();
66  static void SetEngine(AudioEngine* engine);
67  static void DeleteEngine();
68
69 private:
70  bool PlayFromThisSource(const SLDataSource& audioSrc);
71  void EnqueueMoreAudioIfNecessary(SLAndroidSimpleBufferQueueItf bufferQueue);
72  bool EnqueueNextBufferOfAudio(SLAndroidSimpleBufferQueueItf bufferQueue);
73  void PrefetchDurationSampleRateAndChannels(
74      SLPlayItf playItf, SLPrefetchStatusItf prefetchItf);
75  video_editing::SolaTimeScaler* GetTimeScaler();
76  bool Finished();
77  bool GetWasStartRequested();
78  bool GetWasStopRequested();
79  void ClearRequestStart();
80  void SetEndOfDecoderReached();
81  bool GetEndOfDecoderReached();
82  bool DecodeBufferTooFull();
83  void ClearDecodeBuffer();
84  bool IsDecodeBufferEmpty();
85  bool GetHasReachedPlayingBuffersLimit();
86  bool HasSampleRateAndChannels();
87  SLuint32 GetSLSampleRate();
88  SLuint32 GetSLChannels();
89  size_t GetChannelCount();
90
91  // The single global audio engine instance.
92  static AudioEngine* audioEngine_;
93
94  // Protects access to the shared decode buffer.
95  android::Mutex decodeBufferLock_;
96  // Buffer into which we put the audio data as we decode.
97  // Protected by decodeBufferLock_.
98  DecodeBuffer decodeBuffer_;
99
100  // Protects access to the playingBuffers_ and freeBuffers_.
101  android::Mutex playBufferLock_;
102  // The buffers we're using for playback.
103  std::queue<int16*> playingBuffers_;
104  std::stack<int16*> freeBuffers_;
105
106  // The time scaler.
107  video_editing::SolaTimeScaler* timeScaler_;
108
109  // The frame buffer, used for converting between PCM data and float for
110  // time scaler.
111  float* floatBuffer_;
112  float* injectBuffer_;
113
114  // Required when we create the audio player.
115  // Set during the first callback from the decoder.
116  // Guarded by callbackLock_.
117  SLuint32 mSampleRate;
118  SLuint32 mChannels;
119
120  size_t targetFrames_;
121  float windowDuration_;
122  float windowOverlapDuration_;
123  size_t maxPlayBufferCount_;
124  float initialRate_;
125  size_t startPositionMillis_;
126  // The type of audio stream as defined by the STREAM_XXX constants in
127  // android.media.AudioManager. These constant values actually match the
128  // corresponding SL_ANDROID_STREAM_XXX constants defined by
129  // include/SLES/OpenSLES_AndroidConfiguration.h
130  int audioStreamType_;
131
132  // The prefetch callback signal, for letting the prefetch callback method
133  // indicate when it is done.
134  android::Mutex prefetchLock_;
135  android::Condition prefetchCondition_;
136
137  // Protects access to the CallbackContext object.
138  // I don't believe this to be necessary, I think that it's thread-confined,
139  // but it also won't do any harm.
140  android::Mutex callbackLock_;
141
142  // Protects access to the shared member variables below.
143  android::Mutex lock_;
144  // Protected by lock_.
145  // Stores the total duration of the track.
146  SLmillisecond totalDurationMs_;
147  // Protected by lock_.
148  // Stores the current position of the decoder head.
149  SLmillisecond decoderCurrentPosition_;
150  // Protected by lock_.
151  // Set externally via RequestStart(), this determines when we begin to
152  // playback audio.
153  // Until this is set to true, our audio player will remain stopped.
154  bool startRequested_;
155  // Protected by lock_.
156  // Set externally via RequestStop(), this tells us top stop playing
157  // and therefore shut everything down.
158  bool stopRequested_;
159  // Protected by lock_.
160  // This is set to true once we reach the end of the decoder stream.
161  bool finishedDecoding_;
162
163  DISALLOW_COPY_AND_ASSIGN(AudioEngine);
164};
165
166#endif  // FRAMEWORKS_EX_VARIABLESPEED_JNI_VARIABLESPEED_H_
167