| Index: webrtc/call/flexfec_receive_stream_unittest.cc
 | 
| diff --git a/webrtc/call/flexfec_receive_stream_unittest.cc b/webrtc/call/flexfec_receive_stream_unittest.cc
 | 
| new file mode 100644
 | 
| index 0000000000000000000000000000000000000000..a7a3158ee555e9ab00019216dd5f2add83b3137b
 | 
| --- /dev/null
 | 
| +++ b/webrtc/call/flexfec_receive_stream_unittest.cc
 | 
| @@ -0,0 +1,132 @@
 | 
| +/*
 | 
| + *  Copyright (c) 2016 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.
 | 
| + */
 | 
| +
 | 
| +#include "webrtc/base/basictypes.h"
 | 
| +#include "webrtc/call/flexfec_receive_stream.h"
 | 
| +#include "webrtc/modules/rtp_rtcp/include/flexfec_receiver.h"
 | 
| +#include "webrtc/modules/rtp_rtcp/source/byte_io.h"
 | 
| +#include "webrtc/modules/rtp_rtcp/mocks/mock_recovered_packet_receiver.h"
 | 
| +#include "webrtc/test/gmock.h"
 | 
| +#include "webrtc/test/gtest.h"
 | 
| +
 | 
| +namespace webrtc {
 | 
| +
 | 
| +TEST(FlexfecReceiveStreamTest, ConstructDestruct) {
 | 
| +  FlexfecReceiveStream::Config config;
 | 
| +  config.flexfec_payload_type = 118;
 | 
| +  config.flexfec_ssrc = 424223;
 | 
| +  config.protected_media_ssrcs = {912512};
 | 
| +  MockRecoveredPacketReceiver callback;
 | 
| +
 | 
| +  internal::FlexfecReceiveStream receive_stream(config, &callback);
 | 
| +}
 | 
| +
 | 
| +TEST(FlexfecReceiveStreamTest, StartStop) {
 | 
| +  FlexfecReceiveStream::Config config;
 | 
| +  config.flexfec_payload_type = 118;
 | 
| +  config.flexfec_ssrc = 1652392;
 | 
| +  config.protected_media_ssrcs = {23300443};
 | 
| +  MockRecoveredPacketReceiver callback;
 | 
| +  internal::FlexfecReceiveStream receive_stream(config, &callback);
 | 
| +
 | 
| +  receive_stream.Start();
 | 
| +  receive_stream.Stop();
 | 
| +}
 | 
| +
 | 
| +TEST(FlexfecReceiveStreamTest, DoesNotProcessPacketWhenNoMediaSsrcGiven) {
 | 
| +  FlexfecReceiveStream::Config config;
 | 
| +  config.flexfec_payload_type = 118;
 | 
| +  config.flexfec_ssrc = 424223;
 | 
| +  config.protected_media_ssrcs = {};
 | 
| +  MockRecoveredPacketReceiver callback;
 | 
| +  internal::FlexfecReceiveStream receive_stream(config, &callback);
 | 
| +  const uint8_t packet[] = {0x00, 0x11, 0x22, 0x33};
 | 
| +  const size_t packet_length = sizeof(packet);
 | 
| +
 | 
| +  EXPECT_FALSE(
 | 
| +      receive_stream.AddAndProcessReceivedPacket(packet, packet_length));
 | 
| +}
 | 
| +
 | 
| +// TODO(brandtr): Remove when we support multistream protection.
 | 
| +TEST(FlexfecReceiveStreamTest, CannotProtectMultipleMediaStreams) {
 | 
| +  FlexfecReceiveStream::Config config;
 | 
| +  config.flexfec_payload_type = 118;
 | 
| +  config.flexfec_ssrc = 424223;
 | 
| +  config.protected_media_ssrcs = {123, 456};
 | 
| +  MockRecoveredPacketReceiver callback;
 | 
| +  internal::FlexfecReceiveStream receive_stream(config, &callback);
 | 
| +
 | 
| +  ASSERT_EQ(1U, receive_stream.config().protected_media_ssrcs.size());
 | 
| +  EXPECT_EQ(config.protected_media_ssrcs[0],
 | 
| +            receive_stream.config().protected_media_ssrcs[0]);
 | 
| +}
 | 
| +
 | 
| +// Create a FlexFEC packet that protects a single media packet and ensure
 | 
| +// that the callback is called. Correctness of recovery is checked in the
 | 
| +// FlexfecReceiver unit tests.
 | 
| +TEST(FlexfecReceiveStreamTest, RecoversPacketWhenStarted) {
 | 
| +  constexpr uint8_t kFlexfecPlType = 118;
 | 
| +  constexpr uint8_t kFlexfecSeqNum[] = {0x00, 0x01};
 | 
| +  constexpr uint8_t kFlexfecTs[] = {0x00, 0x11, 0x22, 0x33};
 | 
| +  constexpr uint8_t kFlexfecSsrc[] = {0x00, 0x00, 0x00, 0x01};
 | 
| +  constexpr uint8_t kMediaPlType = 107;
 | 
| +  constexpr uint8_t kMediaSeqNum[] = {0x00, 0x02};
 | 
| +  constexpr uint8_t kMediaTs[] = {0xaa, 0xbb, 0xcc, 0xdd};
 | 
| +  constexpr uint8_t kMediaSsrc[] = {0x00, 0x00, 0x00, 0x02};
 | 
| +
 | 
| +  // This packet mask protects a single media packet, i.e., the FlexFEC payload
 | 
| +  // is a copy of that media packet. When inserted in the FlexFEC pipeline,
 | 
| +  // it will thus trivially recover the lost media packet.
 | 
| +  constexpr uint8_t kKBit0 = 1 << 7;
 | 
| +  constexpr uint8_t kFlexfecPktMask[] = {kKBit0 | 0x00, 0x01};
 | 
| +  constexpr uint8_t kPayloadLength[] = {0x00, 0x04};
 | 
| +  constexpr uint8_t kSsrcCount = 1;
 | 
| +  constexpr uint8_t kReservedBits = 0x00;
 | 
| +  constexpr uint8_t kPayloadBits = 0x00;
 | 
| +  // clang-format off
 | 
| +  constexpr uint8_t kFlexfecPacket[] = {
 | 
| +      // RTP header.
 | 
| +      0x80,            kFlexfecPlType,  kFlexfecSeqNum[0],  kFlexfecSeqNum[1],
 | 
| +      kFlexfecTs[0],   kFlexfecTs[1],   kFlexfecTs[2],      kFlexfecTs[3],
 | 
| +      kFlexfecSsrc[0], kFlexfecSsrc[1], kFlexfecSsrc[2],    kFlexfecSsrc[3],
 | 
| +      // FlexFEC header.
 | 
| +      0x00,            kMediaPlType,    kPayloadLength[0],  kPayloadLength[1],
 | 
| +      kMediaTs[0],     kMediaTs[1],     kMediaTs[2],        kMediaTs[3],
 | 
| +      kSsrcCount,      kReservedBits,   kReservedBits,      kReservedBits,
 | 
| +      kMediaSsrc[0],   kMediaSsrc[1],   kMediaSsrc[2],      kMediaSsrc[3],
 | 
| +      kMediaSeqNum[0], kMediaSeqNum[1], kFlexfecPktMask[0], kFlexfecPktMask[1],
 | 
| +      // FEC payload.
 | 
| +      kPayloadBits,    kPayloadBits,    kPayloadBits,       kPayloadBits};
 | 
| +  // clang-format on
 | 
| +  constexpr size_t kFlexfecPacketLength = sizeof(kFlexfecPacket);
 | 
| +
 | 
| +  FlexfecReceiveStream::Config config;
 | 
| +  config.flexfec_payload_type = kFlexfecPlType;
 | 
| +  config.flexfec_ssrc = ByteReader<uint32_t>::ReadBigEndian(kFlexfecSsrc);
 | 
| +  config.protected_media_ssrcs = {
 | 
| +      ByteReader<uint32_t>::ReadBigEndian(kMediaSsrc)};
 | 
| +  testing::StrictMock<MockRecoveredPacketReceiver> recovered_packet_receiver;
 | 
| +  internal::FlexfecReceiveStream receive_stream(config,
 | 
| +                                                &recovered_packet_receiver);
 | 
| +
 | 
| +  // Do not call back before being started.
 | 
| +  receive_stream.AddAndProcessReceivedPacket(kFlexfecPacket,
 | 
| +                                             kFlexfecPacketLength);
 | 
| +
 | 
| +  // Call back after being started.
 | 
| +  receive_stream.Start();
 | 
| +  EXPECT_CALL(
 | 
| +      recovered_packet_receiver,
 | 
| +      OnRecoveredPacket(::testing::_, kRtpHeaderSize + kPayloadLength[1]));
 | 
| +  receive_stream.AddAndProcessReceivedPacket(kFlexfecPacket,
 | 
| +                                             kFlexfecPacketLength);
 | 
| +}
 | 
| +
 | 
| +}  // namespace webrtc
 | 
| 
 |