diff --git a/modules/rtp_rtcp/source/rtp_format_vp8.cc b/modules/rtp_rtcp/source/rtp_format_vp8.cc index 568b446b9..06b6dfb85 100644 --- a/modules/rtp_rtcp/source/rtp_format_vp8.cc +++ b/modules/rtp_rtcp/source/rtp_format_vp8.cc @@ -8,10 +8,6 @@ * be found in the AUTHORS file in the root of the source tree. */ -/* - * This file contains the implementation of the VP8 packetizer class. - */ - #include "rtp_format_vp8.h" #include // assert @@ -19,18 +15,17 @@ namespace webrtc { -RTPFormatVP8::RTPFormatVP8(const WebRtc_UWord8* payload_data, - const WebRtc_UWord32 payload_size, +RtpFormatVp8::RtpFormatVp8(const WebRtc_UWord8* payload_data, + WebRtc_UWord32 payload_size, const RTPFragmentationHeader* fragmentation, - const VP8PacketizerMode mode) -: - payload_data_(payload_data), - payload_size_(payload_size), - bytes_sent_(0), - mode_(mode), - beginning_(true), - first_fragment_(true), - vp8_header_bytes_(1) + VP8PacketizerMode mode) + : payload_data_(payload_data), + payload_size_(payload_size), + payload_bytes_sent_(0), + mode_(mode), + beginning_(true), + first_fragment_(true), + vp8_header_bytes_(1) { if (fragmentation == NULL) { @@ -44,23 +39,38 @@ RTPFormatVP8::RTPFormatVP8(const WebRtc_UWord8* payload_data, } } -bool RTPFormatVP8::NextPacket(const int max_payload_len, WebRtc_UWord8* buffer, - int* bytes_to_send) -{ - // Convenience variables - const int num_fragments = frag_info_.fragmentationVectorSize; +RtpFormatVp8::RtpFormatVp8(const WebRtc_UWord8* payload_data, + WebRtc_UWord32 payload_size) + : payload_data_(payload_data), + payload_size_(payload_size), + frag_info_(), + payload_bytes_sent_(0), + mode_(kSloppy), + beginning_(true), + first_fragment_(true), + vp8_header_bytes_(1) +{} +int RtpFormatVp8::GetFragIdx() +{ // Which fragment are we in? int frag_ix = 0; - while ((frag_ix + 1 < num_fragments) && - (bytes_sent_ >= frag_info_.fragmentationOffset[frag_ix + 1])) + while ((frag_ix + 1 < frag_info_.fragmentationVectorSize) && + (payload_bytes_sent_ >= frag_info_.fragmentationOffset[frag_ix + 1])) { ++frag_ix; } + return frag_ix; +} - // How much data to send in this packet? - int send_bytes = 0; - bool last_fragment = false; +int RtpFormatVp8::NextPacket(int max_payload_len, WebRtc_UWord8* buffer, + int* bytes_to_send, bool* last_packet) +{ + // Convenience variables + const int num_fragments = frag_info_.fragmentationVectorSize; + int frag_ix = GetFragIdx(); //TODO (hlundin): Store frag_ix as a member? + int send_bytes = 0; // How much data to send in this packet. + bool end_of_fragment = false; switch (mode_) { @@ -75,16 +85,17 @@ bool RTPFormatVP8::NextPacket(const int max_payload_len, WebRtc_UWord8* buffer, { // Pack as many whole partitions we can into this packet; // don't fragment. - while (send_bytes + vp8_header_bytes_ + while ((frag_ix < num_fragments) && + (send_bytes + vp8_header_bytes_ + frag_info_.fragmentationLength[frag_ix] - <= max_payload_len) + <= max_payload_len)) { send_bytes += frag_info_.fragmentationLength[frag_ix]; ++frag_ix; } // This packet ends on a complete fragment. - last_fragment = true; + end_of_fragment = true; break; // Jump out of case statement. } } @@ -99,7 +110,7 @@ bool RTPFormatVP8::NextPacket(const int max_payload_len, WebRtc_UWord8* buffer, { // Find out how much is left to send in the current partition. const int remaining_bytes = frag_info_.fragmentationOffset[frag_ix] - - bytes_sent_ + frag_info_.fragmentationLength[frag_ix]; + - payload_bytes_sent_ + frag_info_.fragmentationLength[frag_ix]; assert(remaining_bytes > 0); assert(remaining_bytes <= frag_info_.fragmentationLength[frag_ix]); @@ -112,7 +123,7 @@ bool RTPFormatVP8::NextPacket(const int max_payload_len, WebRtc_UWord8* buffer, { // last packet from this partition send_bytes = remaining_bytes; - last_fragment = true; + end_of_fragment = true; } break; } @@ -120,17 +131,17 @@ bool RTPFormatVP8::NextPacket(const int max_payload_len, WebRtc_UWord8* buffer, case kSloppy: { // Send a full packet, or what is left of the payload. - const int remaining_bytes = payload_size_ - bytes_sent_; + const int remaining_bytes = payload_size_ - payload_bytes_sent_; if (remaining_bytes + vp8_header_bytes_ > max_payload_len) { send_bytes = max_payload_len - vp8_header_bytes_; - last_fragment = false; + end_of_fragment = false; } else { send_bytes = remaining_bytes; - last_fragment = true; + end_of_fragment = true; } break; } @@ -138,20 +149,23 @@ bool RTPFormatVP8::NextPacket(const int max_payload_len, WebRtc_UWord8* buffer, default: // Should not end up here assert(false); + return -1; } // Write the payload header and the payload to buffer. - *bytes_to_send = WriteHeaderAndPayload(send_bytes, last_fragment, buffer); + *bytes_to_send = WriteHeaderAndPayload(send_bytes, end_of_fragment, buffer); + if (*bytes_to_send < 0) + { + return -1; + } - // Anything left to send? - if (bytes_sent_ < payload_size_) - return false; - else - return true; + *last_packet = payload_bytes_sent_ >= payload_size_; + assert(!*last_packet || (payload_bytes_sent_ == payload_size_)); + return 0; } -int RTPFormatVP8::WriteHeaderAndPayload(const int send_bytes, - const bool last_fragment, +int RtpFormatVp8::WriteHeaderAndPayload(int send_bytes, + bool end_of_fragment, WebRtc_UWord8* buffer) { // Write the VP8 payload header. @@ -160,25 +174,34 @@ int RTPFormatVP8::WriteHeaderAndPayload(const int send_bytes, // | RSV |I|N|FI |B| // +-+-+-+-+-+-+-+-+ + if (send_bytes < 0) + { + return -1; + } + if (payload_bytes_sent_ + send_bytes > payload_size_) + { + return -1; + } + // PictureID always present in first packet - const int pictureid_present = beginning_; + const int picture_id_present = beginning_; // TODO(hlundin): must pipe this info from VP8 encoder - const int nonref_frame = 0; + const int kNonrefFrame = 0; - buffer[0] = 0 | (pictureid_present << 4) // I - | (nonref_frame << 3) // N - | (!first_fragment_ << 2) | (!last_fragment << 1) // FI - | (beginning_); + buffer[0] = 0; + if (picture_id_present) buffer[0] |= (0x01 << 4); // I + if (kNonrefFrame) buffer[0] |= (0x01 << 3); // N + if (!first_fragment_) buffer[0] |= (0x01 << 2); // FI + if (!end_of_fragment) buffer[0] |= (0x01 << 1); // FI + if (beginning_) buffer[0] |= 0x01; // B - // Copy the payload. - assert(bytes_sent_ + send_bytes <= payload_size_); - memcpy(&buffer[vp8_header_bytes_], &payload_data_[bytes_sent_], send_bytes); + memcpy(&buffer[vp8_header_bytes_], &payload_data_[payload_bytes_sent_], + send_bytes); - // Update state variables. beginning_ = false; // next packet cannot be first packet in frame // next packet starts new fragment if this ended one - first_fragment_ = last_fragment; - bytes_sent_ += send_bytes; + first_fragment_ = end_of_fragment; + payload_bytes_sent_ += send_bytes; // Return total length of written data. return send_bytes + vp8_header_bytes_; diff --git a/modules/rtp_rtcp/source/rtp_format_vp8.h b/modules/rtp_rtcp/source/rtp_format_vp8.h index b525e0df8..c8464a5d9 100644 --- a/modules/rtp_rtcp/source/rtp_format_vp8.h +++ b/modules/rtp_rtcp/source/rtp_format_vp8.h @@ -10,78 +10,16 @@ /* * This file contains the declaration of the VP8 packetizer class. - */ - -#ifndef WEBRTC_MODULES_RTP_RTCP_RTP_FORMAT_VP8_H_ -#define WEBRTC_MODULES_RTP_RTCP_RTP_FORMAT_VP8_H_ - -#include "module_common_types.h" -#include "typedefs.h" - -namespace webrtc -{ - -// VP8 packetization modes. -enum VP8PacketizerMode -{ - kStrict = 0, // split partitions if too large; never aggregate partitions - kAggregate, // split partitions if too large; aggregate partitions/fragments - kSloppy, // split entire payload without considering partition boundaries -}; - -// Packetizer for VP8. -class RTPFormatVP8 -{ -public: - // Constructor. - // Initialize with payload from encoder and fragmentation info. - // If fragmentation info is NULL, mode will be forced to kSloppy. - RTPFormatVP8(const WebRtc_UWord8* payload_data, - const WebRtc_UWord32 payload_size, - const RTPFragmentationHeader* fragmentation, - const VP8PacketizerMode mode = kStrict); - - // Get the next payload with VP8 payload header. - // max_payload_len limits the sum length of payload and VP8 payload header. - // buffer is a pointer to where the output will be written. - // bytes_to_send is an output variable that will contain number of bytes - // written to buffer. - bool NextPacket(const int max_payload_len, WebRtc_UWord8* buffer, - int* bytes_to_send); - -private: - // Write the payload header and copy the payload to the buffer. - // Will copy send_bytes bytes from the current position on the payload data. - // last_fragment indicates that this packet ends with the last byte of a - // partition. - int WriteHeaderAndPayload(const int send_bytes, const bool last_fragment, - WebRtc_UWord8* buffer); - - const WebRtc_UWord8* payload_data_; - const WebRtc_UWord32 payload_size_; - RTPFragmentationHeader frag_info_; - int bytes_sent_; - VP8PacketizerMode mode_; - bool beginning_; // first partition in this frame - bool first_fragment_; // first fragment of a partition - const int vp8_header_bytes_; // length of VP8 payload header -}; - -} - -#endif /* WEBRTC_MODULES_RTP_RTCP_RTP_FORMAT_VP8_H_ */ -/* - * Copyright (c) 2011 The WebRTC project authors. All Rights Reserved. + * A packetizer object is created for each encoded video frame. The + * constructor is called with the payload data and size, + * together with the fragmentation information and a packetizer mode + * of choice. Alternatively, if no fragmentation info is available, the + * second constructor can be used with only payload data and size; in that + * case the mode kSloppy is used. * - * Use of this source code is governed by a BSD-style license - * that can be found in the LICENSE file in the root of the source - * tree. An additional intellectual property rights grant can be found - * in the file PATENTS. All contributing project authors may - * be found in the AUTHORS file in the root of the source tree. - */ - -/* - * This file contains the declaration of the VP8 packetizer class. + * After creating the packetizer, the method NextPacket is called + * repeatedly to get all packets for the frame. The method returns + * false as long as there are more packets left to fetch. */ #ifndef WEBRTC_MODULES_RTP_RTCP_RTP_FORMAT_VP8_H_ @@ -93,46 +31,54 @@ private: namespace webrtc { -// VP8 packetization modes. enum VP8PacketizerMode { kStrict = 0, // split partitions if too large; never aggregate partitions - kAggregate, // split partitions if too large; aggregate partitions/fragments + kAggregate, // split partitions if too large; aggregate whole partitions kSloppy, // split entire payload without considering partition boundaries }; // Packetizer for VP8. -class RTPFormatVP8 +class RtpFormatVp8 { public: - // Constructor. // Initialize with payload from encoder and fragmentation info. - // If fragmentation info is NULL, mode will be forced to kSloppy. - RTPFormatVP8(const WebRtc_UWord8* payload_data, - const WebRtc_UWord32 payload_size, + // The payload_data must be exactly one encoded VP8 frame. + RtpFormatVp8(const WebRtc_UWord8* payload_data, + WebRtc_UWord32 payload_size, const RTPFragmentationHeader* fragmentation, - const VP8PacketizerMode mode = kStrict); + VP8PacketizerMode mode); + + // Initialize without fragmentation info. Mode kSloppy will be used. + // The payload_data must be exactly one encoded VP8 frame. + RtpFormatVp8(const WebRtc_UWord8* payload_data, + WebRtc_UWord32 payload_size); // Get the next payload with VP8 payload header. // max_payload_len limits the sum length of payload and VP8 payload header. // buffer is a pointer to where the output will be written. // bytes_to_send is an output variable that will contain number of bytes // written to buffer. - bool NextPacket(const int max_payload_len, WebRtc_UWord8* buffer, - int* bytes_to_send); + // Returns true for the last packet of the frame, false otherwise (i.e., + // call the function again to get the next packet). + int NextPacket(int max_payload_len, WebRtc_UWord8* buffer, + int* bytes_to_send, bool* last_packet); private: + // Determine from which fragment the next byte to send will be taken. + int GetFragIdx(); + // Write the payload header and copy the payload to the buffer. // Will copy send_bytes bytes from the current position on the payload data. // last_fragment indicates that this packet ends with the last byte of a // partition. - int WriteHeaderAndPayload(const int send_bytes, const bool last_fragment, + int WriteHeaderAndPayload(int send_bytes, bool end_of_fragment, WebRtc_UWord8* buffer); const WebRtc_UWord8* payload_data_; const WebRtc_UWord32 payload_size_; RTPFragmentationHeader frag_info_; - int bytes_sent_; + int payload_bytes_sent_; VP8PacketizerMode mode_; bool beginning_; // first partition in this frame bool first_fragment_; // first fragment of a partition diff --git a/modules/rtp_rtcp/source/rtp_sender_video.cc b/modules/rtp_rtcp/source/rtp_sender_video.cc index 688648d8a..5de67cdaf 100644 --- a/modules/rtp_rtcp/source/rtp_sender_video.cc +++ b/modules/rtp_rtcp/source/rtp_sender_video.cc @@ -1106,14 +1106,17 @@ RTPSenderVideo::SendVP8(const FrameType frameType, WebRtc_UWord16 maxPayloadLengthVP8 = _rtpSender.MaxPayloadLength() - FECPacketOverhead() - rtpHeaderLength; - RTPFormatVP8 packetizer(data, payloadBytesToSend, fragmentation, kStrict); + RtpFormatVp8 packetizer(data, payloadBytesToSend, fragmentation, kStrict); bool last = false; while (!last) { // Write VP8 Payload Descriptor and VP8 payload. - last = packetizer.NextPacket(maxPayloadLengthVP8, - &dataBuffer[rtpHeaderLength], &payloadBytesInPacket); + if (packetizer.NextPacket(maxPayloadLengthVP8, + &dataBuffer[rtpHeaderLength], &payloadBytesInPacket, &last) < 0) + { + return -1; + } // Write RTP header. // Set marker bit true if this is the last packet in frame. diff --git a/modules/rtp_rtcp/test/test_rtp_format_vp8/test_rtp_format_vp8.gyp b/modules/rtp_rtcp/test/test_rtp_format_vp8/test_rtp_format_vp8.gyp index 20d7281d2..d28efd79f 100644 --- a/modules/rtp_rtcp/test/test_rtp_format_vp8/test_rtp_format_vp8.gyp +++ b/modules/rtp_rtcp/test/test_rtp_format_vp8/test_rtp_format_vp8.gyp @@ -18,65 +18,13 @@ '../../source/rtp_rtcp.gyp:rtp_rtcp', '../../../../../testing/gtest.gyp:gtest', '../../../../../testing/gtest.gyp:gtest_main', -# '../../../signal_processing_library/main/source/spl.gyp:spl', ], 'include_dirs': [ '../../source', ], -# 'direct_dependent_settings': { -# 'include_dirs': [ -# '../interface', -# ], -# }, 'sources': [ 'unit_test.h', 'unit_test.cc', - '../../source/rtp_format_vp8.h', - '../../source/rtp_format_vp8.cc', - ], - }, - ], -} - -# Local Variables: -# tab-width:2 -# indent-tabs-mode:nil -# End: -# vim: set expandtab tabstop=2 shiftwidth=2: -# Copyright (c) 2011 The WebRTC project authors. All Rights Reserved. -# -# Use of this source code is governed by a BSD-style license -# that can be found in the LICENSE file in the root of the source -# tree. An additional intellectual property rights grant can be found -# in the file PATENTS. All contributing project authors may -# be found in the AUTHORS file in the root of the source tree. - -{ - 'includes': [ - '../../../../common_settings.gypi', # Common settings - ], - 'targets': [ - { - 'target_name': 'test_rtp_format_vp8', - 'type': 'executable', - 'dependencies': [ - '../../source/rtp_rtcp.gyp:rtp_rtcp', - '../../../../../testing/gtest.gyp:gtest', - '../../../../../testing/gtest.gyp:gtest_main', -# '../../../signal_processing_library/main/source/spl.gyp:spl', - ], - 'include_dirs': [ - '../../source', - ], -# 'direct_dependent_settings': { -# 'include_dirs': [ -# '../interface', -# ], -# }, - 'sources': [ - 'unit_test.h', - 'unit_test.cc', - '../../source/rtp_format_vp8.h', '../../source/rtp_format_vp8.cc', ], }, diff --git a/modules/rtp_rtcp/test/test_rtp_format_vp8/unit_test.cc b/modules/rtp_rtcp/test/test_rtp_format_vp8/unit_test.cc index b1962f82c..7dae82bf7 100644 --- a/modules/rtp_rtcp/test/test_rtp_format_vp8/unit_test.cc +++ b/modules/rtp_rtcp/test/test_rtp_format_vp8/unit_test.cc @@ -13,19 +13,30 @@ * This file includes unit tests for the VP8 packetizer. */ -#include "unit_test.h" +#include + +#include "typedefs.h" #include "rtp_format_vp8.h" -namespace webrtc { +namespace { -RTPFormatVP8Test::RTPFormatVP8Test() -{ -} +using webrtc::RTPFragmentationHeader; +using webrtc::RtpFormatVp8; -void RTPFormatVP8Test::SetUp() { - payload_data = new WebRtc_UWord8[30]; - payload_size = 30; - for (int i = 0; i < payload_size; i++) +const WebRtc_UWord32 kPayloadSize = 30; + +class RtpFormatVp8Test : public ::testing::Test { + protected: + RtpFormatVp8Test() {}; + virtual void SetUp(); + virtual void TearDown(); + WebRtc_UWord8* payload_data; + RTPFragmentationHeader* fragmentation; +}; + +void RtpFormatVp8Test::SetUp() { + payload_data = new WebRtc_UWord8[kPayloadSize]; + for (int i = 0; i < kPayloadSize; i++) { payload_data[i] = i / 10; // integer division } @@ -39,7 +50,7 @@ void RTPFormatVP8Test::SetUp() { fragmentation->fragmentationOffset[2] = 20; } -void RTPFormatVP8Test::TearDown() { +void RtpFormatVp8Test::TearDown() { delete [] payload_data; delete fragmentation; } @@ -57,15 +68,18 @@ void RTPFormatVP8Test::TearDown() { #define EXPECT_BIT_B_EQ(x,a) EXPECT_EQ((((x)&0x01) > 0), (a > 0)) -TEST_F(RTPFormatVP8Test, TestStrictMode) +TEST_F(RtpFormatVp8Test, TestStrictMode) { WebRtc_UWord8 buffer[20]; int send_bytes = 0; + bool last; - RTPFormatVP8 packetizer = RTPFormatVP8(payload_data, payload_size, fragmentation, kStrict); + RtpFormatVp8 packetizer = RtpFormatVp8(payload_data, kPayloadSize, + fragmentation, webrtc::kStrict); // get first packet - EXPECT_FALSE(packetizer.NextPacket(8, buffer, &send_bytes)); + EXPECT_EQ(0, packetizer.NextPacket(8, buffer, &send_bytes, &last)); + EXPECT_FALSE(last); EXPECT_EQ(send_bytes,8); EXPECT_RSV_ZERO(buffer[0]); EXPECT_BIT_I_EQ(buffer[0], 1); @@ -78,7 +92,8 @@ TEST_F(RTPFormatVP8Test, TestStrictMode) } // get second packet - EXPECT_FALSE(packetizer.NextPacket(8, buffer, &send_bytes)); + EXPECT_EQ(0, packetizer.NextPacket(8, buffer, &send_bytes, &last)); + EXPECT_FALSE(last); EXPECT_EQ(send_bytes,4); // 3 remaining from partition, 1 header EXPECT_RSV_ZERO(buffer[0]); EXPECT_BIT_I_EQ(buffer[0], 0); @@ -92,7 +107,8 @@ TEST_F(RTPFormatVP8Test, TestStrictMode) // Second partition // Get first (and only) packet - EXPECT_FALSE(packetizer.NextPacket(20, buffer, &send_bytes)); + EXPECT_EQ(0, packetizer.NextPacket(20, buffer, &send_bytes, &last)); + EXPECT_FALSE(last); EXPECT_EQ(send_bytes,11); EXPECT_RSV_ZERO(buffer[0]); EXPECT_BIT_I_EQ(buffer[0], 0); @@ -106,7 +122,8 @@ TEST_F(RTPFormatVP8Test, TestStrictMode) // Third partition // Get first packet (of three) - EXPECT_FALSE(packetizer.NextPacket(5, buffer, &send_bytes)); + EXPECT_EQ(0, packetizer.NextPacket(5, buffer, &send_bytes, &last)); + EXPECT_FALSE(last); EXPECT_EQ(send_bytes,5); EXPECT_RSV_ZERO(buffer[0]); EXPECT_BIT_I_EQ(buffer[0], 0); @@ -119,7 +136,8 @@ TEST_F(RTPFormatVP8Test, TestStrictMode) } // Get second packet (of three) - EXPECT_FALSE(packetizer.NextPacket(5, buffer, &send_bytes)); + EXPECT_EQ(0, packetizer.NextPacket(5, buffer, &send_bytes, &last)); + EXPECT_FALSE(last); EXPECT_EQ(send_bytes,5); EXPECT_RSV_ZERO(buffer[0]); EXPECT_BIT_I_EQ(buffer[0], 0); @@ -132,7 +150,8 @@ TEST_F(RTPFormatVP8Test, TestStrictMode) } // Get third and last packet - EXPECT_TRUE(packetizer.NextPacket(5, buffer, &send_bytes)); // last packet in frame + EXPECT_EQ(0, packetizer.NextPacket(5, buffer, &send_bytes, &last)); + EXPECT_TRUE(last); // last packet in frame EXPECT_EQ(send_bytes,3); // 2 bytes payload left, 1 header EXPECT_RSV_ZERO(buffer[0]); EXPECT_BIT_I_EQ(buffer[0], 0); @@ -146,72 +165,78 @@ TEST_F(RTPFormatVP8Test, TestStrictMode) } -TEST_F(RTPFormatVP8Test, TestAggregateMode) +TEST_F(RtpFormatVp8Test, TestAggregateMode) { - WebRtc_UWord8 buffer[30]; + WebRtc_UWord8 buffer[kPayloadSize]; int send_bytes = 0; + bool last; - RTPFormatVP8 packetizer = RTPFormatVP8(payload_data, payload_size, fragmentation, - kAggregate); + RtpFormatVp8 packetizer = RtpFormatVp8(payload_data, kPayloadSize, + fragmentation, webrtc::kAggregate); // get first packet - // first two partitions aggregated - EXPECT_FALSE(packetizer.NextPacket(25, buffer, &send_bytes)); - EXPECT_EQ(send_bytes,21); // Two 10-byte partitions and 1 byte header + // first half of first partition + EXPECT_EQ(0, packetizer.NextPacket(6, buffer, &send_bytes, &last)); + EXPECT_FALSE(last); + EXPECT_EQ(send_bytes,6); // First 5 from first partition, 1 header EXPECT_RSV_ZERO(buffer[0]); EXPECT_BIT_I_EQ(buffer[0], 1); EXPECT_BIT_N_EQ(buffer[0], 0); - EXPECT_FI_EQ(buffer[0], 0x00); + EXPECT_FI_EQ(buffer[0], 0x01); EXPECT_BIT_B_EQ(buffer[0], 1); - for (int i = 1; i < 11; i++) + for (int i = 1; i < 6; i++) { EXPECT_EQ(buffer[i], 0); } - for (int i = 11; i < 21; i++) - { - EXPECT_EQ(buffer[i], 1); - } // get second packet - // first half of last partition - EXPECT_FALSE(packetizer.NextPacket(6, buffer, &send_bytes)); - EXPECT_EQ(send_bytes,6); // First 5 from last partition, 1 header - EXPECT_RSV_ZERO(buffer[0]); - EXPECT_BIT_I_EQ(buffer[0], 0); - EXPECT_BIT_N_EQ(buffer[0], 0); - EXPECT_FI_EQ(buffer[0], 0x01); - EXPECT_BIT_B_EQ(buffer[0], 0); - for (int i = 1; i < 6; i++) - { - EXPECT_EQ(buffer[i], 2); - } - - // get third packet - // second half of last partition - EXPECT_TRUE(packetizer.NextPacket(6, buffer, &send_bytes)); // last packet - EXPECT_EQ(send_bytes,6); // Last 5 from last partition, 1 header + // second half of first partition + EXPECT_EQ(0, packetizer.NextPacket(10, buffer, &send_bytes, &last)); + EXPECT_FALSE(last); + EXPECT_EQ(send_bytes,6); // Last 5 from first partition, 1 header EXPECT_RSV_ZERO(buffer[0]); EXPECT_BIT_I_EQ(buffer[0], 0); EXPECT_BIT_N_EQ(buffer[0], 0); EXPECT_FI_EQ(buffer[0], 0x02); EXPECT_BIT_B_EQ(buffer[0], 0); for (int i = 1; i < 6; i++) + { + EXPECT_EQ(buffer[i], 0); + } + + // get third packet + // last two partitions aggregated + EXPECT_EQ(0, packetizer.NextPacket(25, buffer, &send_bytes, &last)); + EXPECT_TRUE(last); // last packet + EXPECT_EQ(send_bytes,21); // Two 10-byte partitions and 1 byte header + EXPECT_RSV_ZERO(buffer[0]); + EXPECT_BIT_I_EQ(buffer[0], 0); + EXPECT_BIT_N_EQ(buffer[0], 0); + EXPECT_FI_EQ(buffer[0], 0x00); + EXPECT_BIT_B_EQ(buffer[0], 0); + for (int i = 1; i < 11; i++) + { + EXPECT_EQ(buffer[i], 1); + } + for (int i = 11; i < 21; i++) { EXPECT_EQ(buffer[i], 2); } } -TEST_F(RTPFormatVP8Test, TestSloppyMode) +TEST_F(RtpFormatVp8Test, TestSloppyMode) { - WebRtc_UWord8 buffer[30]; + WebRtc_UWord8 buffer[kPayloadSize]; int send_bytes = 0; + bool last; - RTPFormatVP8 packetizer = RTPFormatVP8(payload_data, payload_size, fragmentation, - kSloppy); + RtpFormatVp8 packetizer = RtpFormatVp8(payload_data, kPayloadSize, + fragmentation, webrtc::kSloppy); // get first packet - EXPECT_FALSE(packetizer.NextPacket(9, buffer, &send_bytes)); + EXPECT_EQ(0, packetizer.NextPacket(9, buffer, &send_bytes, &last)); + EXPECT_FALSE(last); EXPECT_EQ(send_bytes,9); // 8 bytes payload and 1 byte header EXPECT_RSV_ZERO(buffer[0]); EXPECT_BIT_I_EQ(buffer[0], 1); @@ -225,7 +250,8 @@ TEST_F(RTPFormatVP8Test, TestSloppyMode) // get second packet // fragments of first and second partitions - EXPECT_FALSE(packetizer.NextPacket(9, buffer, &send_bytes)); + EXPECT_EQ(0, packetizer.NextPacket(9, buffer, &send_bytes, &last)); + EXPECT_FALSE(last); EXPECT_EQ(send_bytes,9); // 8 bytes (2+6) payload and 1 byte header EXPECT_RSV_ZERO(buffer[0]); EXPECT_BIT_I_EQ(buffer[0], 0); @@ -243,7 +269,8 @@ TEST_F(RTPFormatVP8Test, TestSloppyMode) // get third packet // fragments of second and third partitions - EXPECT_FALSE(packetizer.NextPacket(9, buffer, &send_bytes)); + EXPECT_EQ(0, packetizer.NextPacket(9, buffer, &send_bytes, &last)); + EXPECT_FALSE(last); EXPECT_EQ(send_bytes,9); // 8 bytes (4+4) payload and 1 byte header EXPECT_RSV_ZERO(buffer[0]); EXPECT_BIT_I_EQ(buffer[0], 0); @@ -261,7 +288,8 @@ TEST_F(RTPFormatVP8Test, TestSloppyMode) // get fourth packet // second half of last partition - EXPECT_TRUE(packetizer.NextPacket(9, buffer, &send_bytes)); // last packet + EXPECT_EQ(0, packetizer.NextPacket(9, buffer, &send_bytes, &last)); + EXPECT_TRUE(last); // last packet EXPECT_EQ(send_bytes,7); // Last 6 from last partition, 1 header EXPECT_RSV_ZERO(buffer[0]); EXPECT_BIT_I_EQ(buffer[0], 0); @@ -276,16 +304,18 @@ TEST_F(RTPFormatVP8Test, TestSloppyMode) } // Verify that sloppy mode is forced if fragmentation info is missing. -TEST_F(RTPFormatVP8Test, TestSloppyModeFallback) +TEST_F(RtpFormatVp8Test, TestSloppyModeFallback) { - WebRtc_UWord8 buffer[30]; + WebRtc_UWord8 buffer[kPayloadSize]; int send_bytes = 0; + bool last; - RTPFormatVP8 packetizer = RTPFormatVP8(payload_data, payload_size, NULL /*fragmentation*/, - kStrict); // should be changed to kSlopy + RtpFormatVp8 packetizer = RtpFormatVp8(payload_data, kPayloadSize, + NULL /*fragInfo*/, webrtc::kStrict); // should be changed to kSloppy // get first packet - EXPECT_FALSE(packetizer.NextPacket(9, buffer, &send_bytes)); + EXPECT_EQ(0, packetizer.NextPacket(9, buffer, &send_bytes, &last)); + EXPECT_FALSE(last); EXPECT_EQ(send_bytes,9); // 8 bytes payload and 1 byte header EXPECT_RSV_ZERO(buffer[0]); EXPECT_BIT_I_EQ(buffer[0], 1); @@ -299,7 +329,8 @@ TEST_F(RTPFormatVP8Test, TestSloppyModeFallback) // get second packet // fragments of first and second partitions - EXPECT_FALSE(packetizer.NextPacket(9, buffer, &send_bytes)); + EXPECT_EQ(0, packetizer.NextPacket(9, buffer, &send_bytes, &last)); + EXPECT_FALSE(last); EXPECT_EQ(send_bytes,9); // 8 bytes (2+6) payload and 1 byte header EXPECT_RSV_ZERO(buffer[0]); EXPECT_BIT_I_EQ(buffer[0], 0); @@ -317,7 +348,8 @@ TEST_F(RTPFormatVP8Test, TestSloppyModeFallback) // get third packet // fragments of second and third partitions - EXPECT_FALSE(packetizer.NextPacket(9, buffer, &send_bytes)); + EXPECT_EQ(0, packetizer.NextPacket(9, buffer, &send_bytes, &last)); + EXPECT_FALSE(last); EXPECT_EQ(send_bytes,9); // 8 bytes (4+4) payload and 1 byte header EXPECT_RSV_ZERO(buffer[0]); EXPECT_BIT_I_EQ(buffer[0], 0); @@ -335,7 +367,8 @@ TEST_F(RTPFormatVP8Test, TestSloppyModeFallback) // get fourth packet // second half of last partition - EXPECT_TRUE(packetizer.NextPacket(9, buffer, &send_bytes)); // last packet + EXPECT_EQ(0, packetizer.NextPacket(9, buffer, &send_bytes, &last)); + EXPECT_TRUE(last); // last packet EXPECT_EQ(send_bytes,7); // Last 6 from last partition, 1 header EXPECT_RSV_ZERO(buffer[0]); EXPECT_BIT_I_EQ(buffer[0], 0); @@ -355,362 +388,4 @@ int main(int argc, char** argv) { return RUN_ALL_TESTS(); } -} -/* - * Copyright (c) 2011 The WebRTC project authors. All Rights Reserved. - * - * Use of this source code is governed by a BSD-style license - * that can be found in the LICENSE file in the root of the source - * tree. An additional intellectual property rights grant can be found - * in the file PATENTS. All contributing project authors may - * be found in the AUTHORS file in the root of the source tree. - */ - - -/* - * This file includes unit tests for the VP8 packetizer. - */ - -#include "unit_test.h" -#include "rtp_format_vp8.h" - -namespace webrtc { - -RTPFormatVP8Test::RTPFormatVP8Test() -{ -} - -void RTPFormatVP8Test::SetUp() { - payload_data = new WebRtc_UWord8[30]; - payload_size = 30; - for (int i = 0; i < payload_size; i++) - { - payload_data[i] = i / 10; // integer division - } - fragmentation = new RTPFragmentationHeader; - fragmentation->VerifyAndAllocateFragmentationHeader(3); - fragmentation->fragmentationLength[0] = 10; - fragmentation->fragmentationLength[1] = 10; - fragmentation->fragmentationLength[2] = 10; - fragmentation->fragmentationOffset[0] = 0; - fragmentation->fragmentationOffset[1] = 10; - fragmentation->fragmentationOffset[2] = 20; -} - -void RTPFormatVP8Test::TearDown() { - delete [] payload_data; - delete fragmentation; -} - -#define EXPECT_BIT_EQ(x,n,a) EXPECT_EQ((((x)>>n)&0x1), a) - -#define EXPECT_RSV_ZERO(x) EXPECT_EQ(((x)&0xE0), 0) - -//#define EXPECT_BIT_I_EQ(x,a) EXPECT_EQ((((x)&0x10) > 0), (a > 0)) -#define EXPECT_BIT_I_EQ(x,a) EXPECT_BIT_EQ(x, 4, a) - -#define EXPECT_BIT_N_EQ(x,a) EXPECT_EQ((((x)&0x08) > 0), (a > 0)) - -#define EXPECT_FI_EQ(x,a) EXPECT_EQ((((x)&0x06) >> 1), a) - -#define EXPECT_BIT_B_EQ(x,a) EXPECT_EQ((((x)&0x01) > 0), (a > 0)) - -TEST_F(RTPFormatVP8Test, TestStrictMode) -{ - WebRtc_UWord8 buffer[20]; - int send_bytes = 0; - - RTPFormatVP8 packetizer = RTPFormatVP8(payload_data, payload_size, fragmentation, kStrict); - - // get first packet - EXPECT_FALSE(packetizer.NextPacket(8, buffer, &send_bytes)); - EXPECT_EQ(send_bytes,8); - EXPECT_RSV_ZERO(buffer[0]); - EXPECT_BIT_I_EQ(buffer[0], 1); - EXPECT_BIT_N_EQ(buffer[0], 0); - EXPECT_FI_EQ(buffer[0], 0x01); - EXPECT_BIT_B_EQ(buffer[0], 1); - for (int i = 1; i < 8; i++) - { - EXPECT_EQ(buffer[i], 0); - } - - // get second packet - EXPECT_FALSE(packetizer.NextPacket(8, buffer, &send_bytes)); - EXPECT_EQ(send_bytes,4); // 3 remaining from partition, 1 header - EXPECT_RSV_ZERO(buffer[0]); - EXPECT_BIT_I_EQ(buffer[0], 0); - EXPECT_BIT_N_EQ(buffer[0], 0); - EXPECT_FI_EQ(buffer[0], 0x02); - EXPECT_BIT_B_EQ(buffer[0], 0); - for (int i = 1; i < 4; i++) - { - EXPECT_EQ(buffer[i], 0); - } - - // Second partition - // Get first (and only) packet - EXPECT_FALSE(packetizer.NextPacket(20, buffer, &send_bytes)); - EXPECT_EQ(send_bytes,11); - EXPECT_RSV_ZERO(buffer[0]); - EXPECT_BIT_I_EQ(buffer[0], 0); - EXPECT_BIT_N_EQ(buffer[0], 0); - EXPECT_FI_EQ(buffer[0], 0x00); - EXPECT_BIT_B_EQ(buffer[0], 0); - for (int i = 1; i < 11; i++) - { - EXPECT_EQ(buffer[i], 1); - } - - // Third partition - // Get first packet (of three) - EXPECT_FALSE(packetizer.NextPacket(5, buffer, &send_bytes)); - EXPECT_EQ(send_bytes,5); - EXPECT_RSV_ZERO(buffer[0]); - EXPECT_BIT_I_EQ(buffer[0], 0); - EXPECT_BIT_N_EQ(buffer[0], 0); - EXPECT_FI_EQ(buffer[0], 0x01); // first fragment - EXPECT_BIT_B_EQ(buffer[0], 0); - for (int i = 1; i < 5; i++) - { - EXPECT_EQ(buffer[i], 2); - } - - // Get second packet (of three) - EXPECT_FALSE(packetizer.NextPacket(5, buffer, &send_bytes)); - EXPECT_EQ(send_bytes,5); - EXPECT_RSV_ZERO(buffer[0]); - EXPECT_BIT_I_EQ(buffer[0], 0); - EXPECT_BIT_N_EQ(buffer[0], 0); - EXPECT_FI_EQ(buffer[0], 0x03); // middle fragment - EXPECT_BIT_B_EQ(buffer[0], 0); - for (int i = 1; i < 5; i++) - { - EXPECT_EQ(buffer[i], 2); - } - - // Get third and last packet - EXPECT_TRUE(packetizer.NextPacket(5, buffer, &send_bytes)); // last packet in frame - EXPECT_EQ(send_bytes,3); // 2 bytes payload left, 1 header - EXPECT_RSV_ZERO(buffer[0]); - EXPECT_BIT_I_EQ(buffer[0], 0); - EXPECT_BIT_N_EQ(buffer[0], 0); - EXPECT_FI_EQ(buffer[0], 0x02); // last fragment - EXPECT_BIT_B_EQ(buffer[0], 0); - for (int i = 1; i < 3; i++) - { - EXPECT_EQ(buffer[i], 2); - } - -} - -TEST_F(RTPFormatVP8Test, TestAggregateMode) -{ - WebRtc_UWord8 buffer[30]; - int send_bytes = 0; - - RTPFormatVP8 packetizer = RTPFormatVP8(payload_data, payload_size, fragmentation, - kAggregate); - - // get first packet - // first two partitions aggregated - EXPECT_FALSE(packetizer.NextPacket(25, buffer, &send_bytes)); - EXPECT_EQ(send_bytes,21); // Two 10-byte partitions and 1 byte header - EXPECT_RSV_ZERO(buffer[0]); - EXPECT_BIT_I_EQ(buffer[0], 1); - EXPECT_BIT_N_EQ(buffer[0], 0); - EXPECT_FI_EQ(buffer[0], 0x00); - EXPECT_BIT_B_EQ(buffer[0], 1); - for (int i = 1; i < 11; i++) - { - EXPECT_EQ(buffer[i], 0); - } - for (int i = 11; i < 21; i++) - { - EXPECT_EQ(buffer[i], 1); - } - - // get second packet - // first half of last partition - EXPECT_FALSE(packetizer.NextPacket(6, buffer, &send_bytes)); - EXPECT_EQ(send_bytes,6); // First 5 from last partition, 1 header - EXPECT_RSV_ZERO(buffer[0]); - EXPECT_BIT_I_EQ(buffer[0], 0); - EXPECT_BIT_N_EQ(buffer[0], 0); - EXPECT_FI_EQ(buffer[0], 0x01); - EXPECT_BIT_B_EQ(buffer[0], 0); - for (int i = 1; i < 6; i++) - { - EXPECT_EQ(buffer[i], 2); - } - - // get third packet - // second half of last partition - EXPECT_TRUE(packetizer.NextPacket(6, buffer, &send_bytes)); // last packet - EXPECT_EQ(send_bytes,6); // Last 5 from last partition, 1 header - EXPECT_RSV_ZERO(buffer[0]); - EXPECT_BIT_I_EQ(buffer[0], 0); - EXPECT_BIT_N_EQ(buffer[0], 0); - EXPECT_FI_EQ(buffer[0], 0x02); - EXPECT_BIT_B_EQ(buffer[0], 0); - for (int i = 1; i < 6; i++) - { - EXPECT_EQ(buffer[i], 2); - } - -} - -TEST_F(RTPFormatVP8Test, TestSloppyMode) -{ - WebRtc_UWord8 buffer[30]; - int send_bytes = 0; - - RTPFormatVP8 packetizer = RTPFormatVP8(payload_data, payload_size, fragmentation, - kSloppy); - - // get first packet - EXPECT_FALSE(packetizer.NextPacket(9, buffer, &send_bytes)); - EXPECT_EQ(send_bytes,9); // 8 bytes payload and 1 byte header - EXPECT_RSV_ZERO(buffer[0]); - EXPECT_BIT_I_EQ(buffer[0], 1); - EXPECT_BIT_N_EQ(buffer[0], 0); - EXPECT_FI_EQ(buffer[0], 0x01); - EXPECT_BIT_B_EQ(buffer[0], 1); - for (int i = 1; i < 9; i++) - { - EXPECT_EQ(buffer[i], 0); - } - - // get second packet - // fragments of first and second partitions - EXPECT_FALSE(packetizer.NextPacket(9, buffer, &send_bytes)); - EXPECT_EQ(send_bytes,9); // 8 bytes (2+6) payload and 1 byte header - EXPECT_RSV_ZERO(buffer[0]); - EXPECT_BIT_I_EQ(buffer[0], 0); - EXPECT_BIT_N_EQ(buffer[0], 0); - EXPECT_FI_EQ(buffer[0], 0x03); - EXPECT_BIT_B_EQ(buffer[0], 0); - for (int i = 1; i <= 2; i++) - { - EXPECT_EQ(buffer[i], 0); - } - for (int i = 3; i < 9; i++) - { - EXPECT_EQ(buffer[i], 1); - } - - // get third packet - // fragments of second and third partitions - EXPECT_FALSE(packetizer.NextPacket(9, buffer, &send_bytes)); - EXPECT_EQ(send_bytes,9); // 8 bytes (4+4) payload and 1 byte header - EXPECT_RSV_ZERO(buffer[0]); - EXPECT_BIT_I_EQ(buffer[0], 0); - EXPECT_BIT_N_EQ(buffer[0], 0); - EXPECT_FI_EQ(buffer[0], 0x03); - EXPECT_BIT_B_EQ(buffer[0], 0); - for (int i = 1; i <= 4; i++) - { - EXPECT_EQ(buffer[i], 1); - } - for (int i = 5; i < 9; i++) - { - EXPECT_EQ(buffer[i], 2); - } - - // get fourth packet - // second half of last partition - EXPECT_TRUE(packetizer.NextPacket(9, buffer, &send_bytes)); // last packet - EXPECT_EQ(send_bytes,7); // Last 6 from last partition, 1 header - EXPECT_RSV_ZERO(buffer[0]); - EXPECT_BIT_I_EQ(buffer[0], 0); - EXPECT_BIT_N_EQ(buffer[0], 0); - EXPECT_FI_EQ(buffer[0], 0x02); - EXPECT_BIT_B_EQ(buffer[0], 0); - for (int i = 1; i < 5; i++) - { - EXPECT_EQ(buffer[i], 2); - } - -} - -// Verify that sloppy mode is forced if fragmentation info is missing. -TEST_F(RTPFormatVP8Test, TestSloppyModeFallback) -{ - WebRtc_UWord8 buffer[30]; - int send_bytes = 0; - - RTPFormatVP8 packetizer = RTPFormatVP8(payload_data, payload_size, NULL /*fragmentation*/, - kStrict); // should be changed to kSlopy - - // get first packet - EXPECT_FALSE(packetizer.NextPacket(9, buffer, &send_bytes)); - EXPECT_EQ(send_bytes,9); // 8 bytes payload and 1 byte header - EXPECT_RSV_ZERO(buffer[0]); - EXPECT_BIT_I_EQ(buffer[0], 1); - EXPECT_BIT_N_EQ(buffer[0], 0); - EXPECT_FI_EQ(buffer[0], 0x01); - EXPECT_BIT_B_EQ(buffer[0], 1); - for (int i = 1; i < 9; i++) - { - EXPECT_EQ(buffer[i], 0); - } - - // get second packet - // fragments of first and second partitions - EXPECT_FALSE(packetizer.NextPacket(9, buffer, &send_bytes)); - EXPECT_EQ(send_bytes,9); // 8 bytes (2+6) payload and 1 byte header - EXPECT_RSV_ZERO(buffer[0]); - EXPECT_BIT_I_EQ(buffer[0], 0); - EXPECT_BIT_N_EQ(buffer[0], 0); - EXPECT_FI_EQ(buffer[0], 0x03); - EXPECT_BIT_B_EQ(buffer[0], 0); - for (int i = 1; i <= 2; i++) - { - EXPECT_EQ(buffer[i], 0); - } - for (int i = 3; i < 9; i++) - { - EXPECT_EQ(buffer[i], 1); - } - - // get third packet - // fragments of second and third partitions - EXPECT_FALSE(packetizer.NextPacket(9, buffer, &send_bytes)); - EXPECT_EQ(send_bytes,9); // 8 bytes (4+4) payload and 1 byte header - EXPECT_RSV_ZERO(buffer[0]); - EXPECT_BIT_I_EQ(buffer[0], 0); - EXPECT_BIT_N_EQ(buffer[0], 0); - EXPECT_FI_EQ(buffer[0], 0x03); - EXPECT_BIT_B_EQ(buffer[0], 0); - for (int i = 1; i <= 4; i++) - { - EXPECT_EQ(buffer[i], 1); - } - for (int i = 5; i < 9; i++) - { - EXPECT_EQ(buffer[i], 2); - } - - // get fourth packet - // second half of last partition - EXPECT_TRUE(packetizer.NextPacket(9, buffer, &send_bytes)); // last packet - EXPECT_EQ(send_bytes,7); // Last 6 from last partition, 1 header - EXPECT_RSV_ZERO(buffer[0]); - EXPECT_BIT_I_EQ(buffer[0], 0); - EXPECT_BIT_N_EQ(buffer[0], 0); - EXPECT_FI_EQ(buffer[0], 0x02); - EXPECT_BIT_B_EQ(buffer[0], 0); - for (int i = 1; i < 5; i++) - { - EXPECT_EQ(buffer[i], 2); - } - -} - -int main(int argc, char** argv) { - ::testing::InitGoogleTest(&argc, argv); - - return RUN_ALL_TESTS(); -} - -} +} // namespace diff --git a/modules/rtp_rtcp/test/test_rtp_format_vp8/unit_test.h b/modules/rtp_rtcp/test/test_rtp_format_vp8/unit_test.h deleted file mode 100644 index 0090cf15b..000000000 --- a/modules/rtp_rtcp/test/test_rtp_format_vp8/unit_test.h +++ /dev/null @@ -1,78 +0,0 @@ -/* - * Copyright (c) 2011 The WebRTC project authors. All Rights Reserved. - * - * Use of this source code is governed by a BSD-style license - * that can be found in the LICENSE file in the root of the source - * tree. An additional intellectual property rights grant can be found - * in the file PATENTS. All contributing project authors may - * be found in the AUTHORS file in the root of the source tree. - */ - - -/* - * This header file includes declaration for unit tests for the VP8 packetizer. - */ - -#ifndef WEBRTC_RTP_FORMAT_VP8_UNIT_TEST_H_ -#define WEBRTC_RTP_FORMAT_VP8_UNIT_TEST_H_ - -#include - -#include "typedefs.h" - -namespace webrtc { - -class RTPFragmentationHeader; - -class RTPFormatVP8Test : public ::testing::Test { - protected: - RTPFormatVP8Test(); - virtual void SetUp(); - virtual void TearDown(); - WebRtc_UWord8* payload_data; - WebRtc_UWord32 payload_size; - RTPFragmentationHeader* fragmentation; -}; - -} - -#endif // WEBRTC_RTP_FORMAT_VP8_UNIT_TEST_H_ -/* - * Copyright (c) 2011 The WebRTC project authors. All Rights Reserved. - * - * Use of this source code is governed by a BSD-style license - * that can be found in the LICENSE file in the root of the source - * tree. An additional intellectual property rights grant can be found - * in the file PATENTS. All contributing project authors may - * be found in the AUTHORS file in the root of the source tree. - */ - - -/* - * This header file includes declaration for unit tests for the VP8 packetizer. - */ - -#ifndef WEBRTC_RTP_FORMAT_VP8_UNIT_TEST_H_ -#define WEBRTC_RTP_FORMAT_VP8_UNIT_TEST_H_ - -#include - -#include "typedefs.h" - -namespace webrtc { - -class RTPFragmentationHeader; - -class RTPFormatVP8Test : public ::testing::Test { - protected: - RTPFormatVP8Test(); - virtual void SetUp(); - virtual void TearDown(); - WebRtc_UWord8* payload_data; - WebRtc_UWord32 payload_size; - RTPFragmentationHeader* fragmentation; -}; - -} - -#endif // WEBRTC_RTP_FORMAT_VP8_UNIT_TEST_H_