TestMediaDataDecoder.cpp (4873B)
1 /* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ 2 /* This Source Code Form is subject to the terms of the Mozilla Public 3 * License, v. 2.0. If a copy of the MPL was not distributed with this 4 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ 5 6 #include <type_traits> 7 8 #include "H264.h" 9 #include "PDMFactory.h" 10 #include "gtest/gtest.h" 11 #include "mozilla/UniquePtr.h" 12 #include "mozilla/gtest/WaitFor.h" 13 14 using namespace mozilla; 15 16 using MDD = MediaDataDecoder; 17 using ParamType = std::underlying_type<MDD::PropertyName>::type; 18 19 class PropertyTest : public ::testing::TestWithParam<ParamType> { 20 public: 21 static void SetUpTestSuite() { 22 sFactory = MakeRefPtr<PDMFactory>(); 23 sAVCInfo = MakeUnique<VideoInfo>(sDummyVideoSize); 24 sAVCInfo->mMimeType = "video/avc"_ns; 25 sAVCInfo->mExtraData = H264::CreateExtraData( 26 H264_PROFILE::H264_PROFILE_BASE, 0 /* constraint */, 27 H264_LEVEL::H264_LEVEL_1, sDummyVideoSize); 28 sVP9Info = MakeUnique<VideoInfo>(sDummyVideoSize); 29 sVP9Info->mMimeType = "video/vp9"_ns; 30 sVP9Info->SetAlpha(true); 31 } 32 33 static void TearDownTestSuite() { 34 sFactory = nullptr; 35 sTaskQueue = nullptr; 36 sAVCInfo.reset(); 37 sVP9Info.reset(); 38 } 39 40 static constexpr gfx::IntSize sDummyVideoSize{640, 480}; 41 static RefPtr<PDMFactory> sFactory; 42 static RefPtr<TaskQueue> sTaskQueue; 43 static UniquePtr<VideoInfo> sAVCInfo; 44 static UniquePtr<VideoInfo> sVP9Info; 45 }; 46 47 constinit RefPtr<PDMFactory> PropertyTest::sFactory; 48 constinit RefPtr<TaskQueue> PropertyTest::sTaskQueue; 49 constinit UniquePtr<VideoInfo> PropertyTest::sAVCInfo; 50 constinit UniquePtr<VideoInfo> PropertyTest::sVP9Info; 51 52 void CheckEquals(VideoInfo& aVideoInfo, MDD::PropertyName aPropertyName, 53 const Maybe<MDD::PropertyValue>&& aExpectedValue, 54 const char* aCallSite) { 55 using V = Maybe<MDD::PropertyValue>; 56 auto d = WaitFor( 57 PropertyTest::sFactory->CreateDecoder(CreateDecoderParams{aVideoInfo})); 58 EXPECT_TRUE(d.isOk()); 59 RefPtr<MDD> dec = d.unwrap(); 60 auto t = WaitFor(dec->Init()); 61 EXPECT_TRUE(t.isOk()); 62 EXPECT_EQ(t.unwrap(), TrackInfo::TrackType::kVideoTrack); 63 const V v = dec->GetDecodeProperty(aPropertyName); 64 // Although Maybe supports operator<<(), PropertyValue/Variant doesn't and 65 // needs special care. 66 auto maybeStr = [](const V& v) -> std::string { 67 if (v.isNothing()) { 68 return "undefined"; 69 } 70 // Only uint32_t for now. 71 return std::to_string(v.ref().match([](uint32_t x) { return x; })); 72 }; 73 74 EXPECT_TRUE(v == aExpectedValue) 75 << "[" << aCallSite << "] " 76 << "Decode property: " << MDD::EnumValueToString(aPropertyName) 77 << std::endl 78 << " Actual: " << maybeStr(v) 79 << " Expected: " << maybeStr(aExpectedValue); 80 } 81 82 #define CHECK_NOT_DEFINED(info, prop) \ 83 do { \ 84 CheckEquals(info, prop, Nothing(), __func__); \ 85 } while (0) 86 87 #ifdef MOZ_WIDGET_ANDROID 88 void CheckAndroid(VideoInfo& aVideoInfo, MDD::PropertyName aProperty) { 89 switch (aProperty) { 90 case MDD::PropertyName::MaxNumVideoBuffers: 91 [[fallthrough]]; 92 case MDD::PropertyName::MinNumVideoBuffers: 93 CheckEquals(aVideoInfo, aProperty, Some(MDD::PropertyValue(3U)), 94 __func__); 95 break; 96 case MDD::PropertyName::MaxNumCurrentImages: 97 CheckEquals(aVideoInfo, aProperty, Some(MDD::PropertyValue(1U)), 98 __func__); 99 break; 100 default: 101 CHECK_NOT_DEFINED(aVideoInfo, aProperty); 102 } 103 } 104 #endif 105 106 #ifdef MOZ_APPLEMEDIA 107 void CheckApple(VideoInfo& aVideoInfo, MDD::PropertyName aProperty) { 108 switch (aProperty) { 109 case MDD::PropertyName::MinNumVideoBuffers: 110 CheckEquals(aVideoInfo, aProperty, Some(MDD::PropertyValue(10U)), 111 __func__); 112 break; 113 default: 114 CHECK_NOT_DEFINED(aVideoInfo, aProperty); 115 } 116 } 117 #endif 118 119 INSTANTIATE_TEST_SUITE_P(TestMediaDataDecoder, PropertyTest, 120 ::testing::Range<ParamType>(0, 121 MDD::sPropertyNameCount), 122 [](const ::testing::TestParamInfo<ParamType>& info) { 123 return std::string(MDD::EnumValueToString( 124 static_cast<MDD::PropertyName>(info.param))); 125 }); 126 127 TEST_P(PropertyTest, DefaultValues) { 128 auto param = static_cast<MDD::PropertyName>(GetParam()); 129 #ifdef MOZ_WIDGET_ANDROID 130 CheckAndroid(*sAVCInfo, param); 131 #elif defined(MOZ_APPLEMEDIA) 132 CheckApple(*sAVCInfo, param); 133 #else 134 CHECK_NOT_DEFINED(*sAVCInfo, param); 135 #endif 136 } 137 138 // On Android, VP9 video with alpha channel is decoded with libvpx. 139 #ifdef MOZ_WIDGET_ANDROID 140 TEST_P(PropertyTest, NotDefinedForVP9WithAlphaOnAndroid) { 141 CHECK_NOT_DEFINED(*sVP9Info, static_cast<MDD::PropertyName>(GetParam())); 142 } 143 #endif