content/media/gtest/TestVideoTrackEncoder.cpp

Sat, 03 Jan 2015 20:18:00 +0100

author
Michael Schloh von Bennewitz <michael@schloh.com>
date
Sat, 03 Jan 2015 20:18:00 +0100
branch
TOR_BUG_3246
changeset 7
129ffea94266
permissions
-rw-r--r--

Conditionally enable double key logic according to:
private browsing mode or privacy.thirdparty.isolate preference and
implement in GetCookieStringCommon and FindCookie where it counts...
With some reservations of how to convince FindCookie users to test
condition and pass a nullptr when disabling double key logic.

michael@0 1 /* This Source Code Form is subject to the terms of the Mozilla Public
michael@0 2 * License, v. 2.0. If a copy of the MPL was not distributed with this
michael@0 3 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
michael@0 4
michael@0 5 #include "gtest/gtest.h"
michael@0 6 #include <algorithm>
michael@0 7
michael@0 8 #include "mozilla/ArrayUtils.h"
michael@0 9 #include "VP8TrackEncoder.h"
michael@0 10 #include "ImageContainer.h"
michael@0 11 #include "MediaStreamGraph.h"
michael@0 12 #include "WebMWriter.h" // TODO: it's weird to include muxer header to get the class definition of VP8 METADATA
michael@0 13
michael@0 14 using ::testing::TestWithParam;
michael@0 15 using ::testing::Values;
michael@0 16
michael@0 17 using namespace mozilla::layers;
michael@0 18 using namespace mozilla;
michael@0 19
michael@0 20 // A helper object to generate of different YUV planes.
michael@0 21 class YUVBufferGenerator {
michael@0 22 public:
michael@0 23 YUVBufferGenerator() {}
michael@0 24
michael@0 25 void Init(const mozilla::gfx::IntSize &aSize)
michael@0 26 {
michael@0 27 mImageSize = aSize;
michael@0 28
michael@0 29 int yPlaneLen = aSize.width * aSize.height;
michael@0 30 int cbcrPlaneLen = (yPlaneLen + 1) / 2;
michael@0 31 int frameLen = yPlaneLen + cbcrPlaneLen;
michael@0 32
michael@0 33 // Generate source buffer.
michael@0 34 mSourceBuffer.SetLength(frameLen);
michael@0 35
michael@0 36 // Fill Y plane.
michael@0 37 memset(mSourceBuffer.Elements(), 0x10, yPlaneLen);
michael@0 38
michael@0 39 // Fill Cb/Cr planes.
michael@0 40 memset(mSourceBuffer.Elements() + yPlaneLen, 0x80, cbcrPlaneLen);
michael@0 41 }
michael@0 42
michael@0 43 mozilla::gfx::IntSize GetSize() const
michael@0 44 {
michael@0 45 return mImageSize;
michael@0 46 }
michael@0 47
michael@0 48 void Generate(nsTArray<nsRefPtr<Image> > &aImages)
michael@0 49 {
michael@0 50 aImages.AppendElement(CreateI420Image());
michael@0 51 aImages.AppendElement(CreateNV12Image());
michael@0 52 aImages.AppendElement(CreateNV21Image());
michael@0 53 }
michael@0 54
michael@0 55 private:
michael@0 56 Image *CreateI420Image()
michael@0 57 {
michael@0 58 PlanarYCbCrImage *image = new PlanarYCbCrImage(new BufferRecycleBin());
michael@0 59 PlanarYCbCrData data;
michael@0 60
michael@0 61 const uint32_t yPlaneSize = mImageSize.width * mImageSize.height;
michael@0 62 const uint32_t halfWidth = (mImageSize.width + 1) / 2;
michael@0 63 const uint32_t halfHeight = (mImageSize.height + 1) / 2;
michael@0 64 const uint32_t uvPlaneSize = halfWidth * halfHeight;
michael@0 65
michael@0 66 // Y plane.
michael@0 67 uint8_t *y = mSourceBuffer.Elements();
michael@0 68 data.mYChannel = y;
michael@0 69 data.mYSize.width = mImageSize.width;
michael@0 70 data.mYSize.height = mImageSize.height;
michael@0 71 data.mYStride = mImageSize.width;
michael@0 72 data.mYSkip = 0;
michael@0 73
michael@0 74 // Cr plane.
michael@0 75 uint8_t *cr = y + yPlaneSize + uvPlaneSize;
michael@0 76 data.mCrChannel = cr;
michael@0 77 data.mCrSkip = 0;
michael@0 78
michael@0 79 // Cb plane
michael@0 80 uint8_t *cb = y + yPlaneSize;
michael@0 81 data.mCbChannel = cb;
michael@0 82 data.mCbSkip = 0;
michael@0 83
michael@0 84 // CrCb plane vectors.
michael@0 85 data.mCbCrStride = halfWidth;
michael@0 86 data.mCbCrSize.width = halfWidth;
michael@0 87 data.mCbCrSize.height = halfHeight;
michael@0 88
michael@0 89 image->SetData(data);
michael@0 90 return image;
michael@0 91 }
michael@0 92
michael@0 93 Image *CreateNV12Image()
michael@0 94 {
michael@0 95 PlanarYCbCrImage *image = new PlanarYCbCrImage(new BufferRecycleBin());
michael@0 96 PlanarYCbCrData data;
michael@0 97
michael@0 98 const uint32_t yPlaneSize = mImageSize.width * mImageSize.height;
michael@0 99 const uint32_t halfWidth = (mImageSize.width + 1) / 2;
michael@0 100 const uint32_t halfHeight = (mImageSize.height + 1) / 2;
michael@0 101
michael@0 102 // Y plane.
michael@0 103 uint8_t *y = mSourceBuffer.Elements();
michael@0 104 data.mYChannel = y;
michael@0 105 data.mYSize.width = mImageSize.width;
michael@0 106 data.mYSize.height = mImageSize.height;
michael@0 107 data.mYStride = mImageSize.width;
michael@0 108 data.mYSkip = 0;
michael@0 109
michael@0 110 // Cr plane.
michael@0 111 uint8_t *cr = y + yPlaneSize;
michael@0 112 data.mCrChannel = cr;
michael@0 113 data.mCrSkip = 1;
michael@0 114
michael@0 115 // Cb plane
michael@0 116 uint8_t *cb = y + yPlaneSize + 1;
michael@0 117 data.mCbChannel = cb;
michael@0 118 data.mCbSkip = 1;
michael@0 119
michael@0 120 // 4:2:0.
michael@0 121 data.mCbCrStride = mImageSize.width;
michael@0 122 data.mCbCrSize.width = halfWidth;
michael@0 123 data.mCbCrSize.height = halfHeight;
michael@0 124
michael@0 125 image->SetData(data);
michael@0 126 return image;
michael@0 127 }
michael@0 128
michael@0 129 Image *CreateNV21Image()
michael@0 130 {
michael@0 131 PlanarYCbCrImage *image = new PlanarYCbCrImage(new BufferRecycleBin());
michael@0 132 PlanarYCbCrData data;
michael@0 133
michael@0 134 const uint32_t yPlaneSize = mImageSize.width * mImageSize.height;
michael@0 135 const uint32_t halfWidth = (mImageSize.width + 1) / 2;
michael@0 136 const uint32_t halfHeight = (mImageSize.height + 1) / 2;
michael@0 137
michael@0 138 // Y plane.
michael@0 139 uint8_t *y = mSourceBuffer.Elements();
michael@0 140 data.mYChannel = y;
michael@0 141 data.mYSize.width = mImageSize.width;
michael@0 142 data.mYSize.height = mImageSize.height;
michael@0 143 data.mYStride = mImageSize.width;
michael@0 144 data.mYSkip = 0;
michael@0 145
michael@0 146 // Cr plane.
michael@0 147 uint8_t *cr = y + yPlaneSize + 1;
michael@0 148 data.mCrChannel = cr;
michael@0 149 data.mCrSkip = 1;
michael@0 150
michael@0 151 // Cb plane
michael@0 152 uint8_t *cb = y + yPlaneSize;
michael@0 153 data.mCbChannel = cb;
michael@0 154 data.mCbSkip = 1;
michael@0 155
michael@0 156 // 4:2:0.
michael@0 157 data.mCbCrStride = mImageSize.width;
michael@0 158 data.mCbCrSize.width = halfWidth;
michael@0 159 data.mCbCrSize.height = halfHeight;
michael@0 160
michael@0 161 image->SetData(data);
michael@0 162 return image;
michael@0 163 }
michael@0 164
michael@0 165 private:
michael@0 166 mozilla::gfx::IntSize mImageSize;
michael@0 167 nsTArray<uint8_t> mSourceBuffer;
michael@0 168 };
michael@0 169
michael@0 170 struct InitParam {
michael@0 171 bool mShouldSucceed; // This parameter should cause success or fail result
michael@0 172 int mWidth; // frame width
michael@0 173 int mHeight; // frame height
michael@0 174 mozilla::TrackRate mTrackRate; // track rate. 90K is the most commond track rate.
michael@0 175 };
michael@0 176
michael@0 177 class TestVP8TrackEncoder: public VP8TrackEncoder
michael@0 178 {
michael@0 179 public:
michael@0 180 ::testing::AssertionResult TestInit(const InitParam &aParam)
michael@0 181 {
michael@0 182 nsresult result = Init(aParam.mWidth, aParam.mHeight, aParam.mWidth, aParam.mHeight, aParam.mTrackRate);
michael@0 183
michael@0 184 if (((NS_FAILED(result) && aParam.mShouldSucceed)) || (NS_SUCCEEDED(result) && !aParam.mShouldSucceed))
michael@0 185 {
michael@0 186 return ::testing::AssertionFailure()
michael@0 187 << " width = " << aParam.mWidth
michael@0 188 << " height = " << aParam.mHeight
michael@0 189 << " TrackRate = " << aParam.mTrackRate << ".";
michael@0 190 }
michael@0 191 else
michael@0 192 {
michael@0 193 return ::testing::AssertionSuccess();
michael@0 194 }
michael@0 195 }
michael@0 196 };
michael@0 197
michael@0 198 // Init test
michael@0 199 TEST(VP8VideoTrackEncoder, Initialization)
michael@0 200 {
michael@0 201 InitParam params[] = {
michael@0 202 // Failure cases.
michael@0 203 { false, 640, 480, 0 }, // Trackrate should be larger than 1.
michael@0 204 { false, 640, 480, -1 }, // Trackrate should be larger than 1.
michael@0 205 { false, 0, 0, 90000 }, // Height/ width should be larger than 1.
michael@0 206 { false, 0, 1, 90000 }, // Height/ width should be larger than 1.
michael@0 207 { false, 1, 0, 90000}, // Height/ width should be larger than 1.
michael@0 208
michael@0 209 // Success cases
michael@0 210 { true, 640, 480, 90000}, // Standard VGA
michael@0 211 { true, 800, 480, 90000}, // Standard WVGA
michael@0 212 { true, 960, 540, 90000}, // Standard qHD
michael@0 213 { true, 1280, 720, 90000} // Standard HD
michael@0 214 };
michael@0 215
michael@0 216 for (size_t i = 0; i < ArrayLength(params); i++)
michael@0 217 {
michael@0 218 TestVP8TrackEncoder encoder;
michael@0 219 EXPECT_TRUE(encoder.TestInit(params[i]));
michael@0 220 }
michael@0 221 }
michael@0 222
michael@0 223 // Get MetaData test
michael@0 224 TEST(VP8VideoTrackEncoder, FetchMetaData)
michael@0 225 {
michael@0 226 InitParam params[] = {
michael@0 227 // Success cases
michael@0 228 { true, 640, 480, 90000}, // Standard VGA
michael@0 229 { true, 800, 480, 90000}, // Standard WVGA
michael@0 230 { true, 960, 540, 90000}, // Standard qHD
michael@0 231 { true, 1280, 720, 90000} // Standard HD
michael@0 232 };
michael@0 233
michael@0 234 for (size_t i = 0; i < ArrayLength(params); i++)
michael@0 235 {
michael@0 236 TestVP8TrackEncoder encoder;
michael@0 237 EXPECT_TRUE(encoder.TestInit(params[i]));
michael@0 238
michael@0 239 nsRefPtr<TrackMetadataBase> meta = encoder.GetMetadata();
michael@0 240 nsRefPtr<VP8Metadata> vp8Meta(static_cast<VP8Metadata*>(meta.get()));
michael@0 241
michael@0 242 // METADATA should be depend on how to initiate encoder.
michael@0 243 EXPECT_TRUE(vp8Meta->mWidth == params[i].mWidth);
michael@0 244 EXPECT_TRUE(vp8Meta->mHeight == params[i].mHeight);
michael@0 245 }
michael@0 246 }
michael@0 247
michael@0 248 // Encode test
michael@0 249 // XXX(bug 1018402): Disable this test when compiled with VS2013 because it
michael@0 250 // crashes.
michael@0 251 #if !defined(_MSC_VER) || _MSC_VER < 1800
michael@0 252 TEST(VP8VideoTrackEncoder, FrameEncode)
michael@0 253 {
michael@0 254 // Initiate VP8 encoder
michael@0 255 TestVP8TrackEncoder encoder;
michael@0 256 InitParam param = {true, 640, 480, 90000};
michael@0 257 encoder.TestInit(param);
michael@0 258
michael@0 259 // Create YUV images as source.
michael@0 260 nsTArray<nsRefPtr<Image>> images;
michael@0 261 YUVBufferGenerator generator;
michael@0 262 generator.Init(mozilla::gfx::IntSize(640, 480));
michael@0 263 generator.Generate(images);
michael@0 264
michael@0 265 // Put generated YUV frame into video segment.
michael@0 266 // Duration of each frame is 1 second.
michael@0 267 VideoSegment segment;
michael@0 268 for (nsTArray<nsRefPtr<Image>>::size_type i = 0; i < images.Length(); i++)
michael@0 269 {
michael@0 270 nsRefPtr<Image> image = images[i];
michael@0 271 segment.AppendFrame(image.forget(), mozilla::TrackTicks(90000), generator.GetSize());
michael@0 272 }
michael@0 273
michael@0 274 // track change notification.
michael@0 275 encoder.NotifyQueuedTrackChanges(nullptr, 0, 0, 0, 0, segment);
michael@0 276
michael@0 277 // Pull Encoded Data back from encoder.
michael@0 278 EncodedFrameContainer container;
michael@0 279 EXPECT_TRUE(NS_SUCCEEDED(encoder.GetEncodedTrack(container)));
michael@0 280 }
michael@0 281 #endif // _MSC_VER
michael@0 282
michael@0 283 // EOS test
michael@0 284 TEST(VP8VideoTrackEncoder, EncodeComplete)
michael@0 285 {
michael@0 286 // Initiate VP8 encoder
michael@0 287 TestVP8TrackEncoder encoder;
michael@0 288 InitParam param = {true, 640, 480, 90000};
michael@0 289 encoder.TestInit(param);
michael@0 290
michael@0 291 // track end notification.
michael@0 292 VideoSegment segment;
michael@0 293 encoder.NotifyQueuedTrackChanges(nullptr, 0, 0, 0, MediaStreamListener::TRACK_EVENT_ENDED, segment);
michael@0 294
michael@0 295 // Pull Encoded Data back from encoder. Since we have sent
michael@0 296 // EOS to encoder, encoder.GetEncodedTrack should return
michael@0 297 // NS_OK immidiately.
michael@0 298 EncodedFrameContainer container;
michael@0 299 EXPECT_TRUE(NS_SUCCEEDED(encoder.GetEncodedTrack(container)));
michael@0 300 }

mercurial