blob: 3518ad71c6f333812d648fb40cb21632c27d55c5 [file] [log] [blame]
// 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_SDK_MEDIA_CODEC_BRIDGE_H_
#define MEDIA_BASE_ANDROID_SDK_MEDIA_CODEC_BRIDGE_H_
#include <jni.h>
#include <set>
#include <string>
#include "base/android/scoped_java_ref.h"
#include "base/macros.h"
#include "base/time/time.h"
#include "media/base/android/media_codec_bridge.h"
#include "media/base/audio_decoder_config.h"
#include "media/base/media_export.h"
#include "media/base/video_decoder_config.h"
#include "ui/gfx/geometry/size.h"
namespace media {
// This class implements MediaCodecBridge using android MediaCodec SDK APIs.
class MEDIA_EXPORT SdkMediaCodecBridge : public MediaCodecBridge {
public:
~SdkMediaCodecBridge() override;
// MediaCodecBridge implementations.
MediaCodecStatus Reset() override;
bool Start() override;
void Stop() override;
void GetOutputFormat(int* width, int* height) override;
int GetOutputSamplingRate() override;
MediaCodecStatus QueueInputBuffer(
int index,
const uint8* data,
size_t data_size,
const base::TimeDelta& presentation_time) override;
using MediaCodecBridge::QueueSecureInputBuffer;
MediaCodecStatus QueueSecureInputBuffer(
int index,
const uint8* data,
size_t data_size,
const std::vector<char>& key_id,
const std::vector<char>& iv,
const SubsampleEntry* subsamples,
int subsamples_size,
const base::TimeDelta& presentation_time) override;
void QueueEOS(int input_buffer_index) override;
MediaCodecStatus DequeueInputBuffer(const base::TimeDelta& timeout,
int* index) override;
MediaCodecStatus DequeueOutputBuffer(const base::TimeDelta& timeout,
int* index,
size_t* offset,
size_t* size,
base::TimeDelta* presentation_time,
bool* end_of_stream,
bool* key_frame) override;
void ReleaseOutputBuffer(int index, bool render) override;
int GetOutputBuffersCount() override;
size_t GetOutputBuffersCapacity() override;
void GetInputBuffer(int input_buffer_index,
uint8** data,
size_t* capacity) override;
bool CopyFromOutputBuffer(int index,
size_t offset,
void* dst,
int dst_size) override;
static bool RegisterSdkMediaCodecBridge(JNIEnv* env);
protected:
SdkMediaCodecBridge(const std::string& mime,
bool is_secure,
MediaCodecDirection direction);
// Called to get the buffer address given the output buffer index and offset.
// This function returns the size of the output and |addr| is the pointer to
// the address to read.
int GetOutputBufferAddress(int index, size_t offset, void** addr);
jobject media_codec() { return j_media_codec_.obj(); }
MediaCodecDirection direction_;
private:
// Java MediaCodec instance.
base::android::ScopedJavaGlobalRef<jobject> j_media_codec_;
DISALLOW_COPY_AND_ASSIGN(SdkMediaCodecBridge);
};
// Class for handling audio decoding using android MediaCodec APIs.
// TODO(qinmin): implement the logic to switch between NDK and SDK
// MediaCodecBridge.
class MEDIA_EXPORT AudioCodecBridge : public SdkMediaCodecBridge {
public:
// Returns an AudioCodecBridge instance if |codec| is supported, or a NULL
// pointer otherwise.
static AudioCodecBridge* Create(const AudioCodec& codec);
// See MediaCodecUtil::IsKnownUnaccelerated().
static bool IsKnownUnaccelerated(const AudioCodec& codec);
// Start the audio codec bridge.
bool ConfigureAndStart(const AudioCodec& codec,
int sample_rate,
int channel_count,
const uint8* extra_data,
size_t extra_data_size,
int64 codec_delay_ns,
int64 seek_preroll_ns,
bool play_audio,
jobject media_crypto) WARN_UNUSED_RESULT;
// Plays the output buffer right away or save for later playback if |postpone|
// is set to true. This call must be called after DequeueOutputBuffer() and
// before ReleaseOutputBuffer. The data is extracted from the output buffers
// using |index|, |size| and |offset|. Returns the playback head position
// expressed in frames.
// When |postpone| is set to true, the next PlayOutputBuffer() should have
// postpone == false, and it will play two buffers: the postponed one and
// the one identified by |index|.
int64 PlayOutputBuffer(int index,
size_t size,
size_t offset,
bool postpone = false);
// Set the volume of the audio output.
void SetVolume(double volume);
private:
explicit AudioCodecBridge(const std::string& 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,
int64 codec_delay_ns,
int64 seek_preroll_ns);
};
// Class for handling video encoding/decoding using android MediaCodec APIs.
// TODO(qinmin): implement the logic to switch between NDK and SDK
// MediaCodecBridge.
class MEDIA_EXPORT VideoCodecBridge : public SdkMediaCodecBridge {
public:
// See MediaCodecUtil::IsKnownUnaccelerated().
static bool IsKnownUnaccelerated(const VideoCodec& codec,
MediaCodecDirection direction);
// Create, start, and return a VideoCodecBridge decoder or NULL on failure.
static VideoCodecBridge* CreateDecoder(
const VideoCodec& codec, // e.g. media::kCodecVP8
bool is_secure,
const gfx::Size& size, // Output frame size.
jobject surface, // Output surface, optional.
jobject media_crypto); // MediaCrypto object, optional.
// Create, start, and return a VideoCodecBridge encoder or NULL on failure.
static VideoCodecBridge* CreateEncoder(
const VideoCodec& codec, // e.g. media::kCodecVP8
const gfx::Size& size, // input frame size
int bit_rate, // bits/second
int frame_rate, // frames/second
int i_frame_interval, // count
int color_format); // MediaCodecInfo.CodecCapabilities.
void SetVideoBitrate(int bps);
void RequestKeyFrameSoon();
// Returns whether adaptive playback is supported for this object given
// the new size.
bool IsAdaptivePlaybackSupported(int width, int height);
// Test-only method to set the return value of IsAdaptivePlaybackSupported().
// Without this function, the return value of that function will be device
// dependent. If |adaptive_playback_supported| is equal to 0, the return value
// will be false. If |adaptive_playback_supported| is larger than 0, the
// return value will be true.
void set_adaptive_playback_supported_for_testing(
int adaptive_playback_supported) {
adaptive_playback_supported_for_testing_ = adaptive_playback_supported;
}
private:
VideoCodecBridge(const std::string& mime,
bool is_secure,
MediaCodecDirection direction);
int adaptive_playback_supported_for_testing_;
};
} // namespace media
#endif // MEDIA_BASE_ANDROID_SDK_MEDIA_CODEC_BRIDGE_H_