| // 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" |
| #include "ui/gfx/hdr_metadata.h" |
| |
| namespace media { |
| |
| class VideoColorSpace; |
| |
| // Configuration info for MediaCodec. |
| class MEDIA_EXPORT VideoCodecConfig { |
| public: |
| VideoCodecConfig(); |
| |
| VideoCodecConfig(const VideoCodecConfig&) = delete; |
| VideoCodecConfig& operator=(const VideoCodecConfig&) = delete; |
| |
| ~VideoCodecConfig(); |
| |
| VideoCodec codec = VideoCodec::kUnknown; |
| |
| 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. |
| absl::optional<gfx::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; |
| }; |
| |
| // 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::VideoCodec::kVP8 |
| 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(const MediaCodecBridgeImpl&) = delete; |
| MediaCodecBridgeImpl& operator=(const MediaCodecBridgeImpl&) = delete; |
| |
| ~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, |
| EncryptionScheme encryption_scheme, |
| absl::optional<EncryptionPattern> encryption_pattern, |
| 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; |
| size_t GetMaxInputSize() 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_; |
| }; |
| |
| } // namespace media |
| |
| #endif // MEDIA_BASE_ANDROID_MEDIA_CODEC_BRIDGE_IMPL_H_ |