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