| /* |
| * Copyright (C) 2024 The Android Open Source Project |
| * |
| * Licensed under the Apache License, Version 2.0 (the "License"); |
| * you may not use this file except in compliance with the License. |
| * You may obtain a copy of the License at |
| * |
| * http://www.apache.org/licenses/LICENSE-2.0 |
| * |
| * Unless required by applicable law or agreed to in writing, software |
| * distributed under the License is distributed on an "AS IS" BASIS, |
| * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
| * See the License for the specific language governing permissions and |
| * limitations under the License. |
| */ |
| |
| //#define LOG_NDEBUG 0 |
| #define LOG_TAG "CodecCapabilitiesTest" |
| |
| #include <utils/Log.h> |
| |
| #include <memory> |
| |
| #include <gtest/gtest.h> |
| |
| #include <binder/Parcel.h> |
| |
| #include <media/CodecCapabilities.h> |
| #include <media/CodecCapabilitiesUtils.h> |
| #include <media/MediaCodecInfo.h> |
| |
| #include <media/stagefright/MediaCodecConstants.h> |
| #include <media/stagefright/MediaCodecList.h> |
| #include <media/stagefright/foundation/ABuffer.h> |
| #include <media/stagefright/foundation/AString.h> |
| |
| using namespace android; |
| |
| class AudioCapsAacTest : public testing::Test { |
| protected: |
| AudioCapsAacTest() { |
| std::string mediaType = MIMETYPE_AUDIO_AAC; |
| |
| sp<AMessage> details = new AMessage; |
| details->setString("bitrate-range", "8000-960000"); |
| details->setString("max-channel-count", "8"); |
| details->setString("sample-rate-ranges", |
| "7350,8000,11025,12000,16000,22050,24000,32000,44100,48000"); |
| |
| std::vector<ProfileLevel> profileLevel{ |
| ProfileLevel(2, 0), |
| ProfileLevel(5, 0), |
| ProfileLevel(29, 0), |
| ProfileLevel(23, 0), |
| ProfileLevel(39, 0), |
| ProfileLevel(20, 0), |
| ProfileLevel(42, 0), |
| }; |
| |
| audioCaps = AudioCapabilities::Create(mediaType, profileLevel, details); |
| } |
| |
| std::shared_ptr<AudioCapabilities> audioCaps; |
| }; |
| |
| TEST_F(AudioCapsAacTest, AudioCaps_Aac_Bitrate) { |
| const Range<int32_t>& bitrateRange = audioCaps->getBitrateRange(); |
| EXPECT_EQ(bitrateRange.lower(), 8000) << "bitrate range1 does not match. lower: " |
| << bitrateRange.lower(); |
| EXPECT_EQ(bitrateRange.upper(), 510000) << "bitrate range1 does not match. upper: " |
| << bitrateRange.upper(); |
| } |
| |
| TEST_F(AudioCapsAacTest, AudioCaps_Aac_InputChannelCount) { |
| int32_t maxInputChannelCount = audioCaps->getMaxInputChannelCount(); |
| EXPECT_EQ(maxInputChannelCount, 8); |
| int32_t minInputChannelCount = audioCaps->getMinInputChannelCount(); |
| EXPECT_EQ(minInputChannelCount, 1); |
| } |
| |
| TEST_F(AudioCapsAacTest, AudioCaps_Aac_SupportedSampleRates) { |
| const std::vector<int32_t>& sampleRates = audioCaps->getSupportedSampleRates(); |
| EXPECT_EQ(sampleRates, std::vector<int32_t>({7350, 8000, 11025, 12000, 16000, 22050, |
| 24000, 32000, 44100, 48000})); |
| |
| EXPECT_FALSE(audioCaps->isSampleRateSupported(6000)) |
| << "isSampleRateSupported returned true for unsupported sample rate"; |
| EXPECT_TRUE(audioCaps->isSampleRateSupported(8000)) |
| << "isSampleRateSupported returned false for supported sample rate"; |
| EXPECT_TRUE(audioCaps->isSampleRateSupported(12000)) |
| << "isSampleRateSupported returned false for supported sample rate"; |
| EXPECT_FALSE(audioCaps->isSampleRateSupported(44000)) |
| << "isSampleRateSupported returned true for unsupported sample rate"; |
| EXPECT_TRUE(audioCaps->isSampleRateSupported(48000)) |
| << "isSampleRateSupported returned true for unsupported sample rate"; |
| } |
| |
| class AudioCapsRawTest : public testing::Test { |
| protected: |
| AudioCapsRawTest() { |
| std::string mediaType = MIMETYPE_AUDIO_RAW; |
| |
| sp<AMessage> details = new AMessage; |
| details->setString("bitrate-range", "1-10000000"); |
| details->setString("channel-ranges", "1,2,3,4,5,6,7,8,9,10,11,12"); |
| details->setString("sample-rate-ranges", "8000-192000"); |
| |
| std::vector<ProfileLevel> profileLevel; |
| |
| audioCaps = AudioCapabilities::Create(mediaType, profileLevel, details); |
| } |
| |
| std::shared_ptr<AudioCapabilities> audioCaps; |
| }; |
| |
| TEST_F(AudioCapsRawTest, AudioCaps_Raw_Bitrate) { |
| const Range<int32_t>& bitrateRange = audioCaps->getBitrateRange(); |
| EXPECT_EQ(bitrateRange.lower(), 1); |
| EXPECT_EQ(bitrateRange.upper(), 10000000); |
| } |
| |
| TEST_F(AudioCapsRawTest, AudioCaps_Raw_InputChannelCount) { |
| int32_t maxInputChannelCount = audioCaps->getMaxInputChannelCount(); |
| EXPECT_EQ(maxInputChannelCount, 12); |
| int32_t minInputChannelCount = audioCaps->getMinInputChannelCount(); |
| EXPECT_EQ(minInputChannelCount, 1); |
| } |
| |
| TEST_F(AudioCapsRawTest, AudioCaps_Raw_InputChannelCountRanges) { |
| const std::vector<Range<int32_t>>& inputChannelCountRanges |
| = audioCaps->getInputChannelCountRanges(); |
| std::vector<Range<int32_t>> expectedOutput({{1,1}, {2,2}, {3,3}, {4,4}, {5,5}, |
| {6,6}, {7,7}, {8,8}, {9,9}, {10,10}, {11,11}, {12,12}}); |
| ASSERT_EQ(inputChannelCountRanges.size(), expectedOutput.size()); |
| for (int i = 0; i < inputChannelCountRanges.size(); i++) { |
| EXPECT_EQ(inputChannelCountRanges.at(i).lower(), expectedOutput.at(i).lower()); |
| EXPECT_EQ(inputChannelCountRanges.at(i).upper(), expectedOutput.at(i).upper()); |
| } |
| } |
| |
| TEST_F(AudioCapsRawTest, AudioCaps_Raw_SupportedSampleRates) { |
| const std::vector<Range<int32_t>>& sampleRateRanges = audioCaps->getSupportedSampleRateRanges(); |
| EXPECT_EQ(sampleRateRanges.size(), 1); |
| EXPECT_EQ(sampleRateRanges.at(0).lower(), 8000); |
| EXPECT_EQ(sampleRateRanges.at(0).upper(), 192000); |
| |
| EXPECT_EQ(audioCaps->isSampleRateSupported(7000), false); |
| EXPECT_EQ(audioCaps->isSampleRateSupported(10000), true); |
| EXPECT_EQ(audioCaps->isSampleRateSupported(193000), false); |
| } |
| |
| class VideoCapsHevcTest : public testing::Test { |
| protected: |
| VideoCapsHevcTest() { |
| std::string mediaType = MIMETYPE_VIDEO_HEVC; |
| |
| sp<AMessage> details = new AMessage; |
| details->setString("alignment", "2x2"); |
| details->setString("bitrate-range", "1-120000000"); |
| details->setString("block-count-range", "1-32640"); |
| details->setString("block-size", "16x16"); |
| details->setString("blocks-per-second-range", "1-3916800"); |
| details->setInt32("feature-adaptive-playback", 0); |
| details->setInt32("feature-can-swap-width-height", 1); |
| details->setString("max-concurrent-instances", "16"); |
| details->setString("measured-frame-rate-1280x720-range", "547-553"); |
| details->setString("measured-frame-rate-1920x1080-range", "569-572"); |
| details->setString("measured-frame-rate-352x288-range", "1150-1250"); |
| details->setString("measured-frame-rate-3840x2160-range", "159-159"); |
| details->setString("measured-frame-rate-640x360-range", "528-529"); |
| details->setString("measured-frame-rate-720x480-range", "546-548"); |
| details->setString("performance-point-1280x720-range", "240"); |
| details->setString("performance-point-3840x2160-range", "120"); |
| details->setString("size-range", "64x64-3840x2176"); |
| |
| std::vector<ProfileLevel> profileLevel{ |
| ProfileLevel(1, 8388608), |
| ProfileLevel(2, 8388608), |
| ProfileLevel(4096, 8388608), |
| ProfileLevel(8192, 8388608), |
| }; |
| |
| videoCaps = VideoCapabilities::Create(mediaType, profileLevel, details); |
| } |
| |
| std::shared_ptr<VideoCapabilities> videoCaps; |
| }; |
| |
| TEST_F(VideoCapsHevcTest, VideoCaps_HEVC_Alignment) { |
| int32_t widthAlignment = videoCaps->getWidthAlignment(); |
| EXPECT_EQ(widthAlignment, 2); |
| int32_t heightAlignment = videoCaps->getHeightAlignment(); |
| EXPECT_EQ(heightAlignment, 2); |
| } |
| |
| TEST_F(VideoCapsHevcTest, VideoCaps_HEVC_BitrateRange) { |
| const Range<int32_t>& bitrateRange = videoCaps->getBitrateRange(); |
| EXPECT_EQ(bitrateRange.lower(), 1); |
| EXPECT_EQ(bitrateRange.upper(), 120000000); |
| } |
| |
| TEST_F(VideoCapsHevcTest, VideoCaps_HEVC_SupportedWidthsAndHeights) { |
| const Range<int32_t>& supportedWidths = videoCaps->getSupportedWidths(); |
| EXPECT_EQ(supportedWidths.upper(), 3840); |
| const Range<int32_t>& supportedHeights = videoCaps->getSupportedHeights(); |
| EXPECT_EQ(supportedHeights.upper(), 3840); |
| } |
| |
| TEST_F(VideoCapsHevcTest, VideoCaps_HEVC_SupportedFrameRates) { |
| const Range<int32_t>& supportedFrameRates = videoCaps->getSupportedFrameRates(); |
| EXPECT_EQ(supportedFrameRates.lower(), 0); |
| EXPECT_EQ(supportedFrameRates.upper(), 960); |
| |
| std::optional<Range<double>> supportedFR720p = videoCaps->getSupportedFrameRatesFor(1280, 720); |
| EXPECT_EQ(supportedFR720p.value().upper(), 960.0); |
| std::optional<Range<double>> supportedFR1080p |
| = videoCaps->getSupportedFrameRatesFor(1920, 1080); |
| EXPECT_EQ(supportedFR1080p.value().upper(), 480.0); |
| std::optional<Range<double>> supportedFR4k = videoCaps->getSupportedFrameRatesFor(3840, 2160); |
| EXPECT_EQ(std::round(supportedFR4k.value().upper()), 121); |
| } |
| |
| TEST_F(VideoCapsHevcTest, VideoCaps_HEVC_AchievableFrameRates) { |
| std::optional<Range<double>> achievableFR1080p |
| = videoCaps->getAchievableFrameRatesFor(1920, 1080); |
| ASSERT_NE(achievableFR1080p, std::nullopt) << "resolution not supported"; |
| EXPECT_EQ(achievableFR1080p.value().lower(), 569); |
| EXPECT_EQ(achievableFR1080p.value().upper(), 572); |
| } |
| |
| class EncoderCapsAacTest : public testing::Test { |
| protected: |
| EncoderCapsAacTest() { |
| std::string mediaType = MIMETYPE_AUDIO_AAC; |
| |
| sp<AMessage> details = new AMessage; |
| details->setString("bitrate-range", "8000-960000"); |
| details->setString("max-channel-count", "6"); |
| details->setString("sample-rate-ranges", |
| "8000,11025,12000,16000,22050,24000,32000,44100,48000"); |
| |
| std::vector<ProfileLevel> profileLevel{ |
| ProfileLevel(2, 0), |
| ProfileLevel(5, 0), |
| ProfileLevel(29, 0), |
| ProfileLevel(23, 0), |
| ProfileLevel(39, 0), |
| }; |
| |
| encoderCaps = EncoderCapabilities::Create(mediaType, profileLevel, details); |
| } |
| |
| std::shared_ptr<EncoderCapabilities> encoderCaps; |
| }; |
| |
| |
| TEST_F(EncoderCapsAacTest, EncoderCaps_AAC_ComplexityRange) { |
| const Range<int>& complexityRange = encoderCaps->getComplexityRange(); |
| EXPECT_EQ(complexityRange.lower(), 0); |
| EXPECT_EQ(complexityRange.upper(), 0); |
| } |
| |
| TEST_F(EncoderCapsAacTest, EncoderCaps_AAC_QualityRange) { |
| const Range<int>& qualityRange = encoderCaps->getQualityRange(); |
| EXPECT_EQ(qualityRange.lower(), 0); |
| EXPECT_EQ(qualityRange.upper(), 0); |
| } |
| |
| TEST_F(EncoderCapsAacTest, EncoderCaps_AAC_SupportedBitrateMode) { |
| EXPECT_FALSE(encoderCaps->isBitrateModeSupported(BITRATE_MODE_CBR)); |
| EXPECT_TRUE(encoderCaps->isBitrateModeSupported(BITRATE_MODE_VBR)); |
| EXPECT_FALSE(encoderCaps->isBitrateModeSupported(BITRATE_MODE_CQ)); |
| EXPECT_FALSE(encoderCaps->isBitrateModeSupported(BITRATE_MODE_CBR_FD)); |
| } |
| |
| class EncoderCapsFlacTest : public testing::Test { |
| protected: |
| EncoderCapsFlacTest() { |
| std::string mediaType = MIMETYPE_AUDIO_FLAC; |
| |
| sp<AMessage> details = new AMessage; |
| details->setString("bitrate-range", "1-21000000"); |
| details->setString("complexity-default", "5"); |
| details->setString("complexity-range", "0-8"); |
| details->setString("feature-bitrate-modes", "CQ"); |
| details->setString("max-channel-count", "2"); |
| details->setString("sample-rate-ranges", "1-655350"); |
| |
| std::vector<ProfileLevel> profileLevel; |
| |
| encoderCaps = EncoderCapabilities::Create(mediaType, profileLevel, details); |
| } |
| |
| std::shared_ptr<EncoderCapabilities> encoderCaps; |
| }; |
| |
| TEST_F(EncoderCapsFlacTest, EncoderCaps_FLAC_ComplexityRange) { |
| const Range<int>& complexityRange = encoderCaps->getComplexityRange(); |
| EXPECT_EQ(complexityRange.lower(), 0); |
| EXPECT_EQ(complexityRange.upper(), 8); |
| } |
| |
| TEST_F(EncoderCapsFlacTest, EncoderCaps_FLAC_QualityRange) { |
| const Range<int>& qualityRange = encoderCaps->getQualityRange(); |
| EXPECT_EQ(qualityRange.lower(), 0); |
| EXPECT_EQ(qualityRange.upper(), 0); |
| } |
| |
| TEST_F(EncoderCapsFlacTest, EncoderCaps_FLAC_SupportedBitrateMode) { |
| EXPECT_FALSE(encoderCaps->isBitrateModeSupported(BITRATE_MODE_CBR)); |
| EXPECT_FALSE(encoderCaps->isBitrateModeSupported(BITRATE_MODE_VBR)); |
| EXPECT_TRUE(encoderCaps->isBitrateModeSupported(BITRATE_MODE_CQ)); |
| EXPECT_FALSE(encoderCaps->isBitrateModeSupported(BITRATE_MODE_CBR_FD)); |
| } |
| |
| class EncoderCapsHevcTest : public testing::Test { |
| protected: |
| EncoderCapsHevcTest() { |
| std::string mediaType = MIMETYPE_VIDEO_HEVC; |
| |
| sp<AMessage> details = new AMessage; |
| details->setString("alignment", "2x2"); |
| details->setString("bitrate-range", "1-120000000"); |
| details->setString("block-count-range", "1-8160"); |
| details->setString("block-size", "32x32"); |
| details->setString("blocks-per-second-range", "1-979200"); |
| details->setString("feature-bitrate-modes", "VBR,CBR,CQ,CBR-FD"); |
| details->setInt32("feature-can-swap-width-height", 1); |
| details->setInt32("feature-qp-bounds", 0); |
| details->setInt32("feature-vq-minimum-quality", 0); |
| details->setString("max-concurrent-instances", "16"); |
| details->setString("measured-frame-rate-1280x720-range", "154-198"); |
| details->setString("measured-frame-rate-1920x1080-range", "46-97"); |
| details->setString("measured-frame-rate-320x240-range", "371-553"); |
| details->setString("measured-frame-rate-720x480-range", "214-305"); |
| details->setString("performance-point-1280x720-range", "240"); |
| details->setString("performance-point-3840x2160-range", "120"); |
| details->setString("quality-default", "57"); |
| details->setString("quality-range", "0-100"); |
| details->setString("quality-scale", "linear"); |
| details->setString("size-range", "64x64-3840x2176"); |
| |
| std::vector<ProfileLevel> profileLevel{ |
| ProfileLevel(1, 2097152), |
| ProfileLevel(2, 2097152), |
| ProfileLevel(4096, 2097152), |
| ProfileLevel(8192, 2097152), |
| }; |
| |
| encoderCaps = EncoderCapabilities::Create(mediaType, profileLevel, details); |
| } |
| |
| std::shared_ptr<EncoderCapabilities> encoderCaps; |
| }; |
| |
| TEST_F(EncoderCapsHevcTest, EncoderCaps_HEVC_ComplexityRange) { |
| const Range<int>& complexityRange = encoderCaps->getComplexityRange(); |
| EXPECT_EQ(complexityRange.lower(), 0); |
| EXPECT_EQ(complexityRange.upper(), 0); |
| } |
| |
| TEST_F(EncoderCapsHevcTest, EncoderCaps_HEVC_QualityRange) { |
| const Range<int>& qualityRange = encoderCaps->getQualityRange(); |
| EXPECT_EQ(qualityRange.lower(), 0); |
| EXPECT_EQ(qualityRange.upper(), 100); |
| } |
| |
| TEST_F(EncoderCapsHevcTest, EncoderCaps_HEVC_SupportedBitrateMode) { |
| EXPECT_TRUE(encoderCaps->isBitrateModeSupported(BITRATE_MODE_CBR)); |
| EXPECT_TRUE(encoderCaps->isBitrateModeSupported(BITRATE_MODE_VBR)); |
| EXPECT_TRUE(encoderCaps->isBitrateModeSupported(BITRATE_MODE_CQ)); |
| EXPECT_TRUE(encoderCaps->isBitrateModeSupported(BITRATE_MODE_CBR_FD)); |
| } |