// Copyright (c) 2013 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#ifndef MEDIA_BASE_ANDROID_MEDIA_CODEC_BRIDGE_H_
#define MEDIA_BASE_ANDROID_MEDIA_CODEC_BRIDGE_H_

#include <jni.h>
#include <string>

#include "base/android/scoped_java_ref.h"
#include "base/time/time.h"
#include "media/base/audio_decoder_config.h"
#include "media/base/video_decoder_config.h"
#include "ui/gfx/size.h"

namespace media {

struct SubsampleEntry;

// This class serves as a bridge for native code to call java functions inside
// Android MediaCodec class. For more information on Android MediaCodec, check
// http://developer.android.com/reference/android/media/MediaCodec.html
// Note: MediaCodec is only available on JB and greater.
// Use AudioCodecBridge or VideoCodecBridge to create an instance of this
// object.
class MEDIA_EXPORT MediaCodecBridge {
 public:
  enum DequeueBufferInfo {
    INFO_OUTPUT_BUFFERS_CHANGED = -3,
    INFO_OUTPUT_FORMAT_CHANGED = -2,
    INFO_TRY_AGAIN_LATER = -1,
    INFO_MEDIA_CODEC_ERROR = -1000,
  };

  static const base::TimeDelta kTimeOutInfinity;
  static const base::TimeDelta kTimeOutNoWait;

  // Returns true if MediaCodec is available on the device.
  static bool IsAvailable();

  virtual ~MediaCodecBridge();

  // Resets both input and output, all indices previously returned in calls to
  // DequeueInputBuffer() and DequeueOutputBuffer() become invalid.
  // Please note that this clears all the inputs in the media codec. In other
  // words, there will be no outputs until new input is provided.
  void Reset();

  // Finishes the decode/encode session. The instance remains active
  // and ready to be StartAudio/Video()ed again. HOWEVER, due to the buggy
  // vendor's implementation , b/8125974, Stop() -> StartAudio/Video() may not
  // work on some devices. For reliability, Stop() -> delete and recreate new
  // instance -> StartAudio/Video() is recommended.
  void Stop();

  // Used for getting output format. This is valid after DequeueInputBuffer()
  // returns a format change by returning INFO_OUTPUT_FORMAT_CHANGED
  void GetOutputFormat(int* width, int* height);

  // Submits a byte array to the given input buffer. Call this after getting an
  // available buffer from DequeueInputBuffer(). Returns the number of bytes
  // put to the input buffer.
  size_t QueueInputBuffer(int index, const uint8* data, int size,
                          const base::TimeDelta& presentation_time);

  // Similar to the above call, but submits a buffer that is encrypted.
  size_t QueueSecureInputBuffer(
      int index, const uint8* data, int data_size,
      const uint8* key_id, int key_id_size,
      const uint8* iv, int iv_size,
      const SubsampleEntry* subsamples, int subsamples_size,
      const base::TimeDelta& presentation_time);

  // Submits an empty buffer with a EOS (END OF STREAM) flag.
  void QueueEOS(int input_buffer_index);

  // Returns an index (>=0) of an input buffer to be filled with valid data,
  // INFO_TRY_AGAIN_LATER if no such buffer is currently available, or
  // INFO_MEDIA_CODEC_ERROR if unexpected error happens.
  // Use kTimeOutInfinity for infinite timeout.
  int DequeueInputBuffer(base::TimeDelta timeout);

  // Dequeues an output buffer, block at most timeout_us microseconds.
  // Returns the index of an output buffer that has been successfully decoded
  // or one of DequeueBufferInfo above.
  // Use kTimeOutInfinity for infinite timeout.
  int DequeueOutputBuffer(
      base::TimeDelta timeout, size_t* offset, size_t* size,
      base::TimeDelta* presentation_time, bool* end_of_stream);

  // Returns the buffer to the codec. If you previously specified a surface
  // when configuring this video decoder you can optionally render the buffer.
  void ReleaseOutputBuffer(int index, bool render);

  // Gets output buffers from media codec and keeps them inside the java class.
  // To access them, use DequeueOutputBuffer().
  void GetOutputBuffers();

  static bool RegisterMediaCodecBridge(JNIEnv* env);

 protected:
  explicit MediaCodecBridge(const char* mime);

  // Calls start() against the media codec instance. Used in StartXXX() after
  // configuring media codec.
  void StartInternal();

  jobject media_codec() { return j_media_codec_.obj(); }

 private:
  // Fills a particular input buffer and returns the size of copied data.
  size_t FillInputBuffer(int index, const uint8* data, int data_size);

  // Java MediaCodec instance.
  base::android::ScopedJavaGlobalRef<jobject> j_media_codec_;

  DISALLOW_COPY_AND_ASSIGN(MediaCodecBridge);
};

class AudioCodecBridge : public MediaCodecBridge {
 public:
  // Returns an AudioCodecBridge instance if |codec| is supported, or a NULL
  // pointer otherwise.
  static AudioCodecBridge* Create(const AudioCodec codec);

  // Start the audio codec bridge.
  bool Start(const AudioCodec codec, int sample_rate, int channel_count,
             const uint8* extra_data, size_t extra_data_size,
             bool play_audio, jobject media_crypto);

  // Play the output buffer. This call must be called after
  // DequeueOutputBuffer() and before ReleaseOutputBuffer.
  void PlayOutputBuffer(int index, size_t size);

 private:
  explicit AudioCodecBridge(const char* mime);

  // Configure the java MediaFormat object with the extra codec data passed in.
  bool ConfigureMediaFormat(jobject j_format, const AudioCodec codec,
                            const uint8* extra_data, size_t extra_data_size);
};

class MEDIA_EXPORT VideoCodecBridge : public MediaCodecBridge {
 public:
  // Returns an VideoCodecBridge instance if |codec| is supported, or a NULL
  // pointer otherwise.
  static VideoCodecBridge* Create(const VideoCodec codec);

  // Start the video codec bridge.
  // TODO(qinmin): Pass codec specific data if available.
  bool Start(const VideoCodec codec, const gfx::Size& size, jobject surface,
             jobject media_crypto);

 private:
  explicit VideoCodecBridge(const char* mime);
};

}  // namespace media

#endif  // MEDIA_BASE_ANDROID_MEDIA_CODEC_BRIDGE_H_

