Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(33)

Unified Diff: extensions/renderer/api/display_source/wifi_display/wifi_display_media_packetizer_unittest.cc

Issue 1796123002: Implement WiFi Display elementary stream packetizer. (Closed) Base URL: https://chromium.googlesource.com/chromium/src@master
Patch Set: Comments Created 4 years, 9 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
Index: extensions/renderer/api/display_source/wifi_display/wifi_display_media_packetizer_unittest.cc
diff --git a/extensions/renderer/api/display_source/wifi_display/wifi_display_media_packetizer_unittest.cc b/extensions/renderer/api/display_source/wifi_display/wifi_display_media_packetizer_unittest.cc
new file mode 100644
index 0000000000000000000000000000000000000000..a8b769a4421ace00b07782a61c9e5344a614f764
--- /dev/null
+++ b/extensions/renderer/api/display_source/wifi_display/wifi_display_media_packetizer_unittest.cc
@@ -0,0 +1,166 @@
+// Copyright 2016 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.
+
+#include "base/big_endian.h"
+#include "extensions/renderer/api/display_source/wifi_display/wifi_display_elementary_stream_packetizer.h"
+#include "testing/gtest/include/gtest/gtest.h"
+
+namespace extensions {
+
+namespace {
+
+namespace pes {
+const unsigned kDtsFlag = 0x0040u;
+const unsigned kMarkerFlag = 0x8000u;
+const unsigned kPtsFlag = 0x0080u;
+const size_t kUnitDataAlignment = sizeof(uint32_t);
+}
+
+uint64_t ParseTimeStamp(const uint8_t ts_bytes[5], uint8_t pts_dts_indicator) {
+ EXPECT_EQ(pts_dts_indicator, (ts_bytes[0] & 0xF0u) >> 4);
+ EXPECT_EQ(0x01u, ts_bytes[0] & 0x01u);
+ EXPECT_EQ(0x01u, ts_bytes[2] & 0x01u);
+ EXPECT_EQ(0x01u, ts_bytes[4] & 0x01u);
+ uint64_t ts = 0u;
+ ts = (ts_bytes[0] & 0x0Eu) >> 1;
+ ts = (ts << 8) | ts_bytes[1];
+ ts = (ts << 7) | ((ts_bytes[2] & 0xFEu) >> 1);
+ ts = (ts << 8) | ts_bytes[3];
+ ts = (ts << 7) | ((ts_bytes[4] & 0xFEu) >> 1);
+ return ts;
+}
+
+class WiFiDisplayElementaryStreamUnitPacketizationTest
+ : public testing::TestWithParam<
+ testing::tuple<unsigned, base::TimeDelta, base::TimeDelta>> {
+ protected:
+ static base::TimeTicks SumOrNull(const base::TimeTicks& base,
+ const base::TimeDelta& delta) {
+ return delta.is_max() ? base::TimeTicks() : base + delta;
+ }
+
+ WiFiDisplayElementaryStreamUnitPacketizationTest()
+ : unit_(testing::get<0>(GetParam())),
+ now_(base::TimeTicks::Now()),
+ dts_(SumOrNull(now_, testing::get<1>(GetParam()))),
+ pts_(SumOrNull(now_, testing::get<2>(GetParam()))) {}
+
+ void CheckElementaryStreamPacketHeader(
+ const WiFiDisplayElementaryStreamPacket& packet,
+ uint8_t stream_id) {
+ base::BigEndianReader header_reader(
+ reinterpret_cast<const char*>(packet.header().begin()),
+ packet.header().size());
+ uint8_t parsed_packet_start_code_prefix[3];
+ EXPECT_TRUE(
+ header_reader.ReadBytes(parsed_packet_start_code_prefix,
+ sizeof(parsed_packet_start_code_prefix)));
+ EXPECT_EQ(0x00u, parsed_packet_start_code_prefix[0]);
+ EXPECT_EQ(0x00u, parsed_packet_start_code_prefix[1]);
+ EXPECT_EQ(0x01u, parsed_packet_start_code_prefix[2]);
+ uint8_t parsed_stream_id;
+ EXPECT_TRUE(header_reader.ReadU8(&parsed_stream_id));
+ EXPECT_EQ(stream_id, parsed_stream_id);
+ uint16_t parsed_packet_length;
+ EXPECT_TRUE(header_reader.ReadU16(&parsed_packet_length));
+ size_t packet_length = static_cast<size_t>(header_reader.remaining()) +
+ packet.unit_header().size() + packet.unit().size();
+ if (packet_length >> 16)
+ packet_length = 0u;
+ EXPECT_EQ(packet_length, parsed_packet_length);
+ uint16_t parsed_flags;
+ EXPECT_TRUE(header_reader.ReadU16(&parsed_flags));
+ EXPECT_EQ(
+ 0u, parsed_flags & ~(pes::kMarkerFlag | pes::kPtsFlag | pes::kDtsFlag));
+ const bool parsed_pts_flag = (parsed_flags & pes::kPtsFlag) != 0u;
+ const bool parsed_dts_flag = (parsed_flags & pes::kDtsFlag) != 0u;
+ EXPECT_EQ(!pts_.is_null(), parsed_pts_flag);
+ EXPECT_EQ(!pts_.is_null() && !dts_.is_null(), parsed_dts_flag);
+ uint8_t parsed_header_length;
+ EXPECT_TRUE(header_reader.ReadU8(&parsed_header_length));
+ EXPECT_EQ(header_reader.remaining(), parsed_header_length);
+ if (parsed_pts_flag) {
+ uint8_t parsed_pts_bytes[5];
+ EXPECT_TRUE(
+ header_reader.ReadBytes(parsed_pts_bytes, sizeof(parsed_pts_bytes)));
+ const uint64_t parsed_pts =
+ ParseTimeStamp(parsed_pts_bytes, parsed_dts_flag ? 0x3u : 0x2u);
+ if (parsed_dts_flag) {
+ uint8_t parsed_dts_bytes[5];
+ EXPECT_TRUE(header_reader.ReadBytes(parsed_dts_bytes,
+ sizeof(parsed_dts_bytes)));
+ const uint64_t parsed_dts = ParseTimeStamp(parsed_dts_bytes, 0x1u);
+ EXPECT_EQ(
+ static_cast<uint64_t>(90 * (pts_ - dts_).InMicroseconds() / 1000),
+ (parsed_pts - parsed_dts) & UINT64_C(0x1FFFFFFFF));
+ }
+ }
+ while (header_reader.remaining() > 0) {
+ uint8_t parsed_stuffing_byte;
+ EXPECT_TRUE(header_reader.ReadU8(&parsed_stuffing_byte));
+ EXPECT_EQ(0xFFu, parsed_stuffing_byte);
+ }
+ EXPECT_EQ(0, header_reader.remaining());
+ }
+
+ void CheckElementaryStreamPacketUnitHeader(
+ const WiFiDisplayElementaryStreamPacket& packet,
+ const uint8_t* unit_header_data,
+ size_t unit_header_size) {
+ EXPECT_EQ(unit_header_data, packet.unit_header().begin());
+ EXPECT_EQ(unit_header_size, packet.unit_header().size());
+ }
+
+ void CheckElementaryStreamPacketUnit(
+ const WiFiDisplayElementaryStreamPacket& packet) {
+ EXPECT_EQ(0u, (packet.header().size() + packet.unit_header().size()) %
+ pes::kUnitDataAlignment);
+ EXPECT_EQ(unit_.data(), packet.unit().begin());
+ EXPECT_EQ(unit_.size(), packet.unit().size());
+ }
+
+ enum { kVideoOnlyUnitSize = 0x8000u }; // Not exact. Be on the safe side.
+
+ const std::vector<uint8_t> unit_;
+ const base::TimeTicks now_;
+ const base::TimeTicks dts_;
+ const base::TimeTicks pts_;
+};
+
+TEST_P(WiFiDisplayElementaryStreamUnitPacketizationTest,
+ EncodeToElementaryStreamPacket) {
+ const size_t kMaxUnitHeaderSize = 4u;
+
+ const uint8_t stream_id =
+ unit_.size() >= kVideoOnlyUnitSize
+ ? WiFiDisplayElementaryStreamPacketizer::kFirstVideoStreamId
+ : WiFiDisplayElementaryStreamPacketizer::kFirstAudioStreamId;
+
+ WiFiDisplayElementaryStreamPacketizer packetizer;
+ uint8_t unit_header_data[kMaxUnitHeaderSize];
+ for (size_t unit_header_size = 0u; unit_header_size <= kMaxUnitHeaderSize;
+ ++unit_header_size) {
+ WiFiDisplayElementaryStreamPacket packet =
+ packetizer.EncodeElementaryStreamUnit(stream_id, unit_header_data,
+ unit_header_size, unit_.data(),
+ unit_.size(), pts_, dts_);
+ CheckElementaryStreamPacketHeader(packet, stream_id);
+ CheckElementaryStreamPacketUnitHeader(packet, unit_header_data,
+ unit_header_size);
+ CheckElementaryStreamPacketUnit(packet);
+ }
+}
+
+INSTANTIATE_TEST_CASE_P(
+ WiFiDisplayElementaryStreamUnitPacketizationTests,
+ WiFiDisplayElementaryStreamUnitPacketizationTest,
+ testing::Combine(testing::Values(123u, 180u, 0x10000u),
+ testing::Values(base::TimeDelta::Max(),
+ base::TimeDelta::FromMicroseconds(0)),
+ testing::Values(base::TimeDelta::Max(),
+ base::TimeDelta::FromMicroseconds(
+ 1000 * INT64_C(0x123456789) / 90))));
+
+} // namespace
+} // namespace extensions

Powered by Google App Engine
This is Rietveld 408576698