Home | History | Annotate | Download | only in android
      1 // Copyright (c) 2013 The Chromium Authors. All rights reserved.
      2 // Use of this source code is governed by a BSD-style license that can be
      3 // found in the LICENSE file.
      4 
      5 #ifndef MEDIA_BASE_ANDROID_MEDIA_CODEC_BRIDGE_H_
      6 #define MEDIA_BASE_ANDROID_MEDIA_CODEC_BRIDGE_H_
      7 
      8 #include <jni.h>
      9 #include <string>
     10 
     11 #include "base/android/scoped_java_ref.h"
     12 #include "base/time/time.h"
     13 #include "media/base/audio_decoder_config.h"
     14 #include "media/base/video_decoder_config.h"
     15 #include "ui/gfx/size.h"
     16 
     17 namespace media {
     18 
     19 struct SubsampleEntry;
     20 
     21 // This class serves as a bridge for native code to call java functions inside
     22 // Android MediaCodec class. For more information on Android MediaCodec, check
     23 // http://developer.android.com/reference/android/media/MediaCodec.html
     24 // Note: MediaCodec is only available on JB and greater.
     25 // Use AudioCodecBridge or VideoCodecBridge to create an instance of this
     26 // object.
     27 class MEDIA_EXPORT MediaCodecBridge {
     28  public:
     29   enum DequeueBufferInfo {
     30     INFO_OUTPUT_BUFFERS_CHANGED = -3,
     31     INFO_OUTPUT_FORMAT_CHANGED = -2,
     32     INFO_TRY_AGAIN_LATER = -1,
     33     INFO_MEDIA_CODEC_ERROR = -1000,
     34   };
     35 
     36   static const base::TimeDelta kTimeOutInfinity;
     37   static const base::TimeDelta kTimeOutNoWait;
     38 
     39   // Returns true if MediaCodec is available on the device.
     40   static bool IsAvailable();
     41 
     42   virtual ~MediaCodecBridge();
     43 
     44   // Resets both input and output, all indices previously returned in calls to
     45   // DequeueInputBuffer() and DequeueOutputBuffer() become invalid.
     46   // Please note that this clears all the inputs in the media codec. In other
     47   // words, there will be no outputs until new input is provided.
     48   // Returns MEDIA_CODEC_ERROR if an unexpected error happens, or Media_CODEC_OK
     49   // otherwise.
     50   int Reset();
     51 
     52   // Finishes the decode/encode session. The instance remains active
     53   // and ready to be StartAudio/Video()ed again. HOWEVER, due to the buggy
     54   // vendor's implementation , b/8125974, Stop() -> StartAudio/Video() may not
     55   // work on some devices. For reliability, Stop() -> delete and recreate new
     56   // instance -> StartAudio/Video() is recommended.
     57   void Stop();
     58 
     59   // Used for getting output format. This is valid after DequeueInputBuffer()
     60   // returns a format change by returning INFO_OUTPUT_FORMAT_CHANGED
     61   void GetOutputFormat(int* width, int* height);
     62 
     63   // Submits a byte array to the given input buffer. Call this after getting an
     64   // available buffer from DequeueInputBuffer(). Returns the number of bytes
     65   // put to the input buffer.
     66   size_t QueueInputBuffer(int index, const uint8* data, int size,
     67                           const base::TimeDelta& presentation_time);
     68 
     69   // Similar to the above call, but submits a buffer that is encrypted.
     70   size_t QueueSecureInputBuffer(
     71       int index, const uint8* data, int data_size,
     72       const uint8* key_id, int key_id_size,
     73       const uint8* iv, int iv_size,
     74       const SubsampleEntry* subsamples, int subsamples_size,
     75       const base::TimeDelta& presentation_time);
     76 
     77   // Submits an empty buffer with a EOS (END OF STREAM) flag.
     78   void QueueEOS(int input_buffer_index);
     79 
     80   // Returns an index (>=0) of an input buffer to be filled with valid data,
     81   // INFO_TRY_AGAIN_LATER if no such buffer is currently available, or
     82   // INFO_MEDIA_CODEC_ERROR if unexpected error happens.
     83   // Use kTimeOutInfinity for infinite timeout.
     84   int DequeueInputBuffer(base::TimeDelta timeout);
     85 
     86   // Dequeues an output buffer, block at most timeout_us microseconds.
     87   // Returns the index of an output buffer that has been successfully decoded
     88   // or one of DequeueBufferInfo above.
     89   // Use kTimeOutInfinity for infinite timeout.
     90   int DequeueOutputBuffer(
     91       base::TimeDelta timeout, size_t* offset, size_t* size,
     92       base::TimeDelta* presentation_time, bool* end_of_stream);
     93 
     94   // Returns the buffer to the codec. If you previously specified a surface
     95   // when configuring this video decoder you can optionally render the buffer.
     96   void ReleaseOutputBuffer(int index, bool render);
     97 
     98   // Gets output buffers from media codec and keeps them inside the java class.
     99   // To access them, use DequeueOutputBuffer().
    100   void GetOutputBuffers();
    101 
    102   static bool RegisterMediaCodecBridge(JNIEnv* env);
    103 
    104  protected:
    105   explicit MediaCodecBridge(const char* mime);
    106 
    107   // Calls start() against the media codec instance. Used in StartXXX() after
    108   // configuring media codec.
    109   void StartInternal();
    110 
    111   jobject media_codec() { return j_media_codec_.obj(); }
    112 
    113  private:
    114   // Fills a particular input buffer and returns the size of copied data.
    115   size_t FillInputBuffer(int index, const uint8* data, int data_size);
    116 
    117   // Java MediaCodec instance.
    118   base::android::ScopedJavaGlobalRef<jobject> j_media_codec_;
    119 
    120   DISALLOW_COPY_AND_ASSIGN(MediaCodecBridge);
    121 };
    122 
    123 class AudioCodecBridge : public MediaCodecBridge {
    124  public:
    125   // Returns an AudioCodecBridge instance if |codec| is supported, or a NULL
    126   // pointer otherwise.
    127   static AudioCodecBridge* Create(const AudioCodec codec);
    128 
    129   // Start the audio codec bridge.
    130   bool Start(const AudioCodec codec, int sample_rate, int channel_count,
    131              const uint8* extra_data, size_t extra_data_size,
    132              bool play_audio, jobject media_crypto);
    133 
    134   // Play the output buffer. This call must be called after
    135   // DequeueOutputBuffer() and before ReleaseOutputBuffer.
    136   void PlayOutputBuffer(int index, size_t size);
    137 
    138   // Set the volume of the audio output.
    139   void SetVolume(double volume);
    140 
    141  private:
    142   explicit AudioCodecBridge(const char* mime);
    143 
    144   // Configure the java MediaFormat object with the extra codec data passed in.
    145   bool ConfigureMediaFormat(jobject j_format, const AudioCodec codec,
    146                             const uint8* extra_data, size_t extra_data_size);
    147 };
    148 
    149 class MEDIA_EXPORT VideoCodecBridge : public MediaCodecBridge {
    150  public:
    151   // Returns an VideoCodecBridge instance if |codec| is supported, or a NULL
    152   // pointer otherwise.
    153   static VideoCodecBridge* Create(const VideoCodec codec);
    154 
    155   // Start the video codec bridge.
    156   // TODO(qinmin): Pass codec specific data if available.
    157   bool Start(const VideoCodec codec, const gfx::Size& size, jobject surface,
    158              jobject media_crypto);
    159 
    160  private:
    161   explicit VideoCodecBridge(const char* mime);
    162 };
    163 
    164 }  // namespace media
    165 
    166 #endif  // MEDIA_BASE_ANDROID_MEDIA_CODEC_BRIDGE_H_
    167 
    168