blob: 3497ca5bbb2992c27c08d4b91d1ed1ceb552658a [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_MEDIA_CODEC_BRIDGE_IMPL_H_
#define MEDIA_BASE_ANDROID_MEDIA_CODEC_BRIDGE_IMPL_H_
#include <stddef.h>
#include <stdint.h>
#include <string>
#include "base/android/scoped_java_ref.h"
#include "base/callback.h"
#include "base/macros.h"
#include "base/time/time.h"
#include "media/base/android/media_codec_bridge.h"
#include "media/base/android/media_codec_direction.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 {
class VideoColorSpace;
struct HDRMetadata;
// Configuration info for MediaCodec.
class MEDIA_EXPORT VideoCodecConfig {
public:
VideoCodecConfig();
~VideoCodecConfig();
VideoCodec codec = kUnknownVideoCodec;
CodecType codec_type = CodecType::kAny;
// The initial coded size. The actual size might change at any time, so this
// is only a hint.
gfx::Size initial_expected_coded_size;
// The surface that MediaCodec is configured to output to.
base::android::ScopedJavaGlobalRef<jobject> surface;
// The MediaCrypto that MediaCodec is configured with for an encrypted stream.
base::android::ScopedJavaGlobalRef<jobject> media_crypto;
// Codec specific data (SPS and PPS for H264). See MediaCodec docs.
std::vector<uint8_t> csd0;
std::vector<uint8_t> csd1;
VideoColorSpace container_color_space;
// VP9 HDR metadata is only embedded in the container. HDR10 metadata is
// embedded in the video stream.
base::Optional<HDRMetadata> hdr_metadata;
// Enables the async MediaCodec.Callback API. |on_buffers_available_cb|
// will be called when input or output buffers are available. This will be
// called on an arbitrary thread, so use BindToCurrentLoop if needed.
//
// May only be used on API level 23 and higher.
base::RepeatingClosure on_buffers_available_cb;
private:
DISALLOW_COPY_AND_ASSIGN(VideoCodecConfig);
};
// A bridge to a Java MediaCodec.
class MEDIA_EXPORT MediaCodecBridgeImpl : public MediaCodecBridge {
public:
// Creates and starts a new MediaCodec configured for decoding. Returns
// nullptr on failure.
static std::unique_ptr<MediaCodecBridge> CreateVideoDecoder(
const VideoCodecConfig& config);
// Creates and starts a new MediaCodec configured for encoding. Returns
// nullptr on failure.
static std::unique_ptr<MediaCodecBridge> CreateVideoEncoder(
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.
// Creates and starts a new MediaCodec configured for decoding. Returns
// nullptr on failure.
static std::unique_ptr<MediaCodecBridge> CreateAudioDecoder(
const AudioDecoderConfig& config,
const base::android::JavaRef<jobject>& media_crypto,
// Enables the async MediaCodec.Callback API. |on_buffers_available_cb|
// will be called when input or output buffers are available. This will be
// called on an arbitrary thread, so use BindToCurrentLoop if needed.
//
// May only be used on API level 23 and higher.
base::RepeatingClosure on_buffers_available_cb =
base::RepeatingClosure());
// Required for tests that wish to use a |on_buffers_available_cb| when
// creating a MediaCodec. Does nothing unless on API level 23+.
static void SetupCallbackHandlerForTesting();
~MediaCodecBridgeImpl() override;
// MediaCodecBridge implementation.
void Stop() override;
MediaCodecStatus Flush() override;
MediaCodecStatus GetOutputSize(gfx::Size* size) override;
MediaCodecStatus GetOutputSamplingRate(int* sampling_rate) override;
MediaCodecStatus GetOutputChannelCount(int* channel_count) override;
MediaCodecStatus QueueInputBuffer(int index,
const uint8_t* data,
size_t data_size,
base::TimeDelta presentation_time) override;
MediaCodecStatus QueueSecureInputBuffer(
int index,
const uint8_t* data,
size_t data_size,
const std::string& key_id,
const std::string& iv,
const std::vector<SubsampleEntry>& subsamples,
const EncryptionScheme& encryption_scheme,
base::TimeDelta presentation_time) override;
void QueueEOS(int input_buffer_index) override;
MediaCodecStatus DequeueInputBuffer(base::TimeDelta timeout,
int* index) override;
MediaCodecStatus DequeueOutputBuffer(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;
MediaCodecStatus GetInputBuffer(int input_buffer_index,
uint8_t** data,
size_t* capacity) override;
MediaCodecStatus CopyFromOutputBuffer(int index,
size_t offset,
void* dst,
size_t num) override;
std::string GetName() override;
bool SetSurface(const base::android::JavaRef<jobject>& surface) override;
void SetVideoBitrate(int bps, int frame_rate) override;
void RequestKeyFrameSoon() override;
CodecType GetCodecType() const override;
private:
MediaCodecBridgeImpl(CodecType codec_type,
base::android::ScopedJavaGlobalRef<jobject> j_bridge,
base::RepeatingClosure on_buffers_available_cb =
base::RepeatingClosure());
// Fills the given input buffer. Returns false if |data_size| exceeds the
// input buffer's capacity (and doesn't touch the input buffer in that case).
bool FillInputBuffer(int index,
const uint8_t* data,
size_t data_size) WARN_UNUSED_RESULT;
// Gets the address of the data in the given output buffer given by |index|
// and |offset|. The number of bytes available to read is written to
// |*capacity| and the address is written to |*addr|. Returns
// MEDIA_CODEC_ERROR if an error occurs, or MEDIA_CODEC_OK otherwise.
MediaCodecStatus GetOutputBufferAddress(int index,
size_t offset,
const uint8_t** addr,
size_t* capacity);
void OnBuffersAvailable(
JNIEnv* /* env */,
const base::android::JavaParamRef<jobject>& /* obj */) override;
const CodecType codec_type_;
base::RepeatingClosure on_buffers_available_cb_;
// The Java MediaCodecBridge instance.
base::android::ScopedJavaGlobalRef<jobject> j_bridge_;
DISALLOW_COPY_AND_ASSIGN(MediaCodecBridgeImpl);
};
} // namespace media
#endif // MEDIA_BASE_ANDROID_MEDIA_CODEC_BRIDGE_IMPL_H_