summaryrefslogtreecommitdiffstats
path: root/variablespeed/jni/variablespeed.h
blob: 74710e52a626f998d7218232ede0f38d7956fc4e (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
/*
 * 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();
  SLuint32 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_