12a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// Copyright (c) 2013 The Chromium Authors. All rights reserved.
22a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// Use of this source code is governed by a BSD-style license that can be
32a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// found in the LICENSE file.
42a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
52a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#ifndef MEDIA_BASE_ANDROID_MEDIA_CODEC_BRIDGE_H_
62a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#define MEDIA_BASE_ANDROID_MEDIA_CODEC_BRIDGE_H_
72a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
82a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include <jni.h>
92a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include <string>
102a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
112a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "base/android/scoped_java_ref.h"
12eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch#include "base/time/time.h"
13c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)#include "media/base/audio_decoder_config.h"
14c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)#include "media/base/video_decoder_config.h"
152a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "ui/gfx/size.h"
162a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
172a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)namespace media {
182a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
19eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdochstruct SubsampleEntry;
20eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch
2158537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)// These must be in sync with MediaCodecBridge.MEDIA_CODEC_XXX constants in
2258537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)// MediaCodecBridge.java.
2358537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)enum MediaCodecStatus {
2458537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  MEDIA_CODEC_OK,
2558537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  MEDIA_CODEC_DEQUEUE_INPUT_AGAIN_LATER,
2658537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  MEDIA_CODEC_DEQUEUE_OUTPUT_AGAIN_LATER,
2758537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  MEDIA_CODEC_OUTPUT_BUFFERS_CHANGED,
2858537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  MEDIA_CODEC_OUTPUT_FORMAT_CHANGED,
2958537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  MEDIA_CODEC_INPUT_END_OF_STREAM,
3058537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  MEDIA_CODEC_OUTPUT_END_OF_STREAM,
3158537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  MEDIA_CODEC_NO_KEY,
3258537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  MEDIA_CODEC_STOPPED,
3358537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  MEDIA_CODEC_ERROR
3458537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)};
3558537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)
36a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)// Codec direction.  Keep this in sync with MediaCodecBridge.java.
37a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)enum MediaCodecDirection {
38a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  MEDIA_CODEC_DECODER,
39a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  MEDIA_CODEC_ENCODER,
40a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)};
41a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)
422a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// This class serves as a bridge for native code to call java functions inside
432a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// Android MediaCodec class. For more information on Android MediaCodec, check
442a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// http://developer.android.com/reference/android/media/MediaCodec.html
452a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// Note: MediaCodec is only available on JB and greater.
46c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)// Use AudioCodecBridge or VideoCodecBridge to create an instance of this
47c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)// object.
48a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)//
49a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)// TODO(fischman,xhwang): replace this (and the enums that go with it) with
50a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)// chromium's JNI auto-generation hotness.
5190dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)class MEDIA_EXPORT MediaCodecBridge {
522a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) public:
532a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // Returns true if MediaCodec is available on the device.
54a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  // All other static methods check IsAvailable() internally. There's no need
55a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  // to check IsAvailable() explicitly before calling them.
562a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  static bool IsAvailable();
572a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
58a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  // Returns true if MediaCodec.setParameters() is available on the device.
59a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  static bool SupportsSetParameters();
60a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)
611675a649fd7a8b3cb80ffddae2dc181f122353c5Ben Murdoch  // Returns true if MediaCodec.getName() is available on the device.
621675a649fd7a8b3cb80ffddae2dc181f122353c5Ben Murdoch  static bool SupportsGetName();
631675a649fd7a8b3cb80ffddae2dc181f122353c5Ben Murdoch
6458537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  // Returns whether MediaCodecBridge has a decoder that |is_secure| and can
6558537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  // decode |codec| type.
6658537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  static bool CanDecode(const std::string& codec, bool is_secure);
6758537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)
68f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  // Represents supported codecs on android.
69a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  // TODO(qinmin): Currently the codecs string only contains one codec. Do we
70a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  // need to support codecs separated by comma. (e.g. "vp8" -> "vp8, vp8.0")?
7158537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  struct CodecsInfo {
72a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)    std::string codecs;  // E.g. "vp8" or "avc1".
73a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)    std::string name;    // E.g. "OMX.google.vp8.decoder".
74a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)    MediaCodecDirection direction;
7558537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  };
7658537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)
7758537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  // Get a list of supported codecs.
78a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  static std::vector<CodecsInfo> GetCodecsInfo();
7958537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)
801675a649fd7a8b3cb80ffddae2dc181f122353c5Ben Murdoch  // Get default codec name for |mime_type|.
811675a649fd7a8b3cb80ffddae2dc181f122353c5Ben Murdoch  static std::string GetDefaultCodecName(const std::string& mime_type,
821675a649fd7a8b3cb80ffddae2dc181f122353c5Ben Murdoch                                         MediaCodecDirection direction);
831675a649fd7a8b3cb80ffddae2dc181f122353c5Ben Murdoch
84c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  virtual ~MediaCodecBridge();
852a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
862a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // Resets both input and output, all indices previously returned in calls to
872a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // DequeueInputBuffer() and DequeueOutputBuffer() become invalid.
882a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // Please note that this clears all the inputs in the media codec. In other
892a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // words, there will be no outputs until new input is provided.
9058537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  // Returns MEDIA_CODEC_ERROR if an unexpected error happens, or Media_CODEC_OK
9158537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  // otherwise.
9258537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  MediaCodecStatus Reset();
932a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
942a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // Finishes the decode/encode session. The instance remains active
952a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // and ready to be StartAudio/Video()ed again. HOWEVER, due to the buggy
962a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // vendor's implementation , b/8125974, Stop() -> StartAudio/Video() may not
972a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // work on some devices. For reliability, Stop() -> delete and recreate new
982a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // instance -> StartAudio/Video() is recommended.
992a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  void Stop();
1002a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
1012a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // Used for getting output format. This is valid after DequeueInputBuffer()
1022a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // returns a format change by returning INFO_OUTPUT_FORMAT_CHANGED
1032a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  void GetOutputFormat(int* width, int* height);
1042a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
105a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  // Returns the number of input buffers used by the codec.
106a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  int GetInputBuffersCount();
107a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)
1082a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // Submits a byte array to the given input buffer. Call this after getting an
109a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  // available buffer from DequeueInputBuffer().  If |data| is NULL, assume the
110a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  // input buffer has already been populated (but still obey |size|).
1115d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  // |data_size| must be less than kint32max (because Java).
11258537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  MediaCodecStatus QueueInputBuffer(int index,
11358537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)                                    const uint8* data,
1145d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)                                    size_t data_size,
11558537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)                                    const base::TimeDelta& presentation_time);
1162a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
1175d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  // Similar to the above call, but submits a buffer that is encrypted.  Note:
1185d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  // NULL |subsamples| indicates the whole buffer is encrypted.  If |data| is
1195d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  // NULL, assume the input buffer has already been populated (but still obey
1205d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  // |data_size|).  |data_size| must be less than kint32max (because Java).
12158537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  MediaCodecStatus QueueSecureInputBuffer(
12258537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)      int index,
123a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)      const uint8* data,
1245d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      size_t data_size,
125a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)      const uint8* key_id,
126a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)      int key_id_size,
127a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)      const uint8* iv,
128a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)      int iv_size,
129a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)      const SubsampleEntry* subsamples,
130a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)      int subsamples_size,
131eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch      const base::TimeDelta& presentation_time);
132eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch
1332a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // Submits an empty buffer with a EOS (END OF STREAM) flag.
1342a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  void QueueEOS(int input_buffer_index);
1352a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
13658537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  // Returns:
13758537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  // MEDIA_CODEC_OK if an input buffer is ready to be filled with valid data,
13858537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  // MEDIA_CODEC_ENQUEUE_INPUT_AGAIN_LATER if no such buffer is available, or
13958537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  // MEDIA_CODEC_ERROR if unexpected error happens.
14058537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  // Note: Never use infinite timeout as this would block the decoder thread and
14158537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  // prevent the decoder job from being released.
14258537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  MediaCodecStatus DequeueInputBuffer(const base::TimeDelta& timeout,
14358537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)                                      int* index);
1442a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
1452a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // Dequeues an output buffer, block at most timeout_us microseconds.
14658537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  // Returns the status of this operation. If OK is returned, the output
14758537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  // parameters should be populated. Otherwise, the values of output parameters
148a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  // should not be used.  Output parameters other than index/offset/size are
149a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  // optional and only set if not NULL.
15058537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  // Note: Never use infinite timeout as this would block the decoder thread and
15158537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  // prevent the decoder job from being released.
15258537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  // TODO(xhwang): Can we drop |end_of_stream| and return
15358537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  // MEDIA_CODEC_OUTPUT_END_OF_STREAM?
15458537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  MediaCodecStatus DequeueOutputBuffer(const base::TimeDelta& timeout,
15558537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)                                       int* index,
15658537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)                                       size_t* offset,
15758537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)                                       size_t* size,
15858537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)                                       base::TimeDelta* presentation_time,
159a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)                                       bool* end_of_stream,
160a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)                                       bool* key_frame);
1612a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
162a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  // Returns the buffer to the codec. If you previously specified a surface when
163a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  // configuring this video decoder you can optionally render the buffer.
1642a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  void ReleaseOutputBuffer(int index, bool render);
1652a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
166a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  // Returns the number of output buffers used by the codec.
167a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  int GetOutputBuffersCount();
168a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)
169a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  // Returns the capacity of each output buffer used by the codec.
170a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  size_t GetOutputBuffersCapacity();
171a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)
17290dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  // Gets output buffers from media codec and keeps them inside the java class.
1734e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  // To access them, use DequeueOutputBuffer(). Returns whether output buffers
1744e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  // were successfully obtained.
1754e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  bool GetOutputBuffers() WARN_UNUSED_RESULT;
17690dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)
177a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  // Returns an input buffer's base pointer and capacity.
178a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  void GetInputBuffer(int input_buffer_index, uint8** data, size_t* capacity);
179a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)
180a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  // Copy |dst_size| bytes from output buffer |index|'s |offset| onwards into
181a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  // |*dst|.
182a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  bool CopyFromOutputBuffer(int index, size_t offset, void* dst, int dst_size);
183a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)
18490dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  static bool RegisterMediaCodecBridge(JNIEnv* env);
1852a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
186c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) protected:
1871e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)  // Returns true if |mime_type| is known to be unaccelerated (i.e. backed by a
1881e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)  // software codec instead of a hardware one).
189a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  static bool IsKnownUnaccelerated(const std::string& mime_type,
190a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)                                   MediaCodecDirection direction);
1911e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)
192a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  MediaCodecBridge(const std::string& mime,
193a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)                   bool is_secure,
194a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)                   MediaCodecDirection direction);
1952a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
1962a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // Calls start() against the media codec instance. Used in StartXXX() after
1974e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  // configuring media codec. Returns whether media codec was successfully
1984e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  // started.
1994e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  bool StartInternal() WARN_UNUSED_RESULT;
200c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
201c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  jobject media_codec() { return j_media_codec_.obj(); }
202a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  MediaCodecDirection direction_;
2032a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
204c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) private:
2054e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  // Fills a particular input buffer; returns false if |data_size| exceeds the
2064e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  // input buffer's capacity (and doesn't touch the input buffer in that case).
2074e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  bool FillInputBuffer(int index,
2084e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)                       const uint8* data,
209a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)                       size_t data_size) WARN_UNUSED_RESULT;
210eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch
2112a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // Java MediaCodec instance.
2122a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  base::android::ScopedJavaGlobalRef<jobject> j_media_codec_;
2132a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
2142a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  DISALLOW_COPY_AND_ASSIGN(MediaCodecBridge);
2152a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)};
2162a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
217c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)class AudioCodecBridge : public MediaCodecBridge {
218c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) public:
21990dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  // Returns an AudioCodecBridge instance if |codec| is supported, or a NULL
22090dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  // pointer otherwise.
2211e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)  static AudioCodecBridge* Create(const AudioCodec& codec);
2221e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)
2231e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)  // See MediaCodecBridge::IsKnownUnaccelerated().
2241e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)  static bool IsKnownUnaccelerated(const AudioCodec& codec);
225c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
226c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  // Start the audio codec bridge.
2271e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)  bool Start(const AudioCodec& codec, int sample_rate, int channel_count,
22890dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)             const uint8* extra_data, size_t extra_data_size,
2294e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)             bool play_audio, jobject media_crypto) WARN_UNUSED_RESULT;
23090dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)
23190dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  // Play the output buffer. This call must be called after
2320529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  // DequeueOutputBuffer() and before ReleaseOutputBuffer. Returns the playback
2330529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  // head position expressed in frames.
2340529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  int64 PlayOutputBuffer(int index, size_t size);
23590dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)
236a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)  // Set the volume of the audio output.
237a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)  void SetVolume(double volume);
238a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)
23990dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) private:
24058537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  explicit AudioCodecBridge(const std::string& mime);
241868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)
242868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  // Configure the java MediaFormat object with the extra codec data passed in.
2431e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)  bool ConfigureMediaFormat(jobject j_format, const AudioCodec& codec,
244868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)                            const uint8* extra_data, size_t extra_data_size);
245c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)};
246c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
247a3f7b4e666c476898878fa745f637129375cd889Ben Murdochclass MEDIA_EXPORT VideoCodecBridge : public MediaCodecBridge {
248c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) public:
2491e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)  // See MediaCodecBridge::IsKnownUnaccelerated().
250a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  static bool IsKnownUnaccelerated(const VideoCodec& codec,
251a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)                                   MediaCodecDirection direction);
252a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)
253a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  // Create, start, and return a VideoCodecBridge decoder or NULL on failure.
254a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  static VideoCodecBridge* CreateDecoder(
255a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)      const VideoCodec& codec,  // e.g. media::kCodecVP8
256a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)      bool is_secure,
257a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)      const gfx::Size& size,  // Output frame size.
258a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)      jobject surface,        // Output surface, optional.
259a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)      jobject media_crypto);  // MediaCrypto object, optional.
260a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)
261a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  // Create, start, and return a VideoCodecBridge encoder or NULL on failure.
262a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  static VideoCodecBridge* CreateEncoder(
263a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)      const VideoCodec& codec,  // e.g. media::kCodecVP8
264a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)      const gfx::Size& size,    // input frame size
265a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)      int bit_rate,             // bits/second
266a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)      int frame_rate,           // frames/second
267a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)      int i_frame_interval,     // count
268a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)      int color_format);        // MediaCodecInfo.CodecCapabilities.
269a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)
270a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  void SetVideoBitrate(int bps);
271a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  void RequestKeyFrameSoon();
27290dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)
273f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  // Returns whether adaptive playback is supported for this object given
274f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  // the new size.
275f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  bool IsAdaptivePlaybackSupported(int width, int height);
276f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)
277f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  // Test-only method to set the return value of IsAdaptivePlaybackSupported().
278f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  // Without this function, the return value of that function will be device
279f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  // dependent. If |adaptive_playback_supported| is equal to 0, the return value
280f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  // will be false. If |adaptive_playback_supported| is larger than 0, the
281f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  // return value will be true.
282f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  void set_adaptive_playback_supported_for_testing(
283f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)      int adaptive_playback_supported) {
284f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)    adaptive_playback_supported_for_testing_ = adaptive_playback_supported;
285f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  }
286f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)
28790dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) private:
288a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  VideoCodecBridge(const std::string& mime,
289a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)                   bool is_secure,
290a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)                   MediaCodecDirection direction);
291f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)
292f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  int adaptive_playback_supported_for_testing_;
293c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)};
294c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
2952a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}  // namespace media
2962a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
2972a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#endif  // MEDIA_BASE_ANDROID_MEDIA_CODEC_BRIDGE_H_
298