C++程序  |  168行  |  5.55 KB

/*
 * 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_