普通文本  |  501行  |  16.95 KB

// Copyright 2013 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/test/simple_test_tick_clock.h"
#include "media/cast/framer/framer.h"
#include "media/cast/rtp_receiver/mock_rtp_payload_feedback.h"
#include "testing/gtest/include/gtest/gtest.h"

namespace media {
namespace cast {

class FramerTest : public ::testing::Test {
 protected:
  FramerTest()
      : mock_rtp_payload_feedback_(),
        framer_(&testing_clock_, &mock_rtp_payload_feedback_, 0, true, 0) {
    payload_.assign(kMaxIpPacketSize, 0);

    EXPECT_CALL(mock_rtp_payload_feedback_, CastFeedback(testing::_))
        .WillRepeatedly(testing::Return());
  }

  virtual ~FramerTest() {}

  std::vector<uint8> payload_;
  RtpCastHeader rtp_header_;
  MockRtpPayloadFeedback mock_rtp_payload_feedback_;
  Framer framer_;
  base::SimpleTestTickClock testing_clock_;

  DISALLOW_COPY_AND_ASSIGN(FramerTest);
};

TEST_F(FramerTest, EmptyState) {
  transport::EncodedFrame frame;
  bool next_frame = false;
  bool multiple = false;
  EXPECT_FALSE(framer_.GetEncodedFrame(&frame, &next_frame, &multiple));
}

TEST_F(FramerTest, AlwaysStartWithKey) {
  transport::EncodedFrame frame;
  bool next_frame = false;
  bool complete = false;
  bool multiple = false;
  bool duplicate = false;

  // Insert non key first frame.
  complete = framer_.InsertPacket(
      payload_.data(), payload_.size(), rtp_header_, &duplicate);
  EXPECT_TRUE(complete);
  EXPECT_FALSE(framer_.GetEncodedFrame(&frame, &next_frame, &multiple));
  rtp_header_.frame_id = 1;
  rtp_header_.reference_frame_id = 1;
  rtp_header_.is_key_frame = true;
  complete = framer_.InsertPacket(
      payload_.data(), payload_.size(), rtp_header_, &duplicate);
  EXPECT_TRUE(complete);
  EXPECT_TRUE(framer_.GetEncodedFrame(&frame, &next_frame, &multiple));
  EXPECT_TRUE(next_frame);
  EXPECT_TRUE(multiple);
  EXPECT_EQ(transport::EncodedFrame::KEY, frame.dependency);
  EXPECT_EQ(1u, frame.frame_id);
  EXPECT_EQ(1u, frame.referenced_frame_id);
  framer_.ReleaseFrame(frame.frame_id);
}

TEST_F(FramerTest, CompleteFrame) {
  transport::EncodedFrame frame;
  bool next_frame = false;
  bool complete = false;
  bool multiple = false;
  bool duplicate = false;

  // Start with a complete key frame.
  rtp_header_.is_key_frame = true;
  complete = framer_.InsertPacket(
      payload_.data(), payload_.size(), rtp_header_, &duplicate);
  EXPECT_TRUE(complete);
  EXPECT_TRUE(framer_.GetEncodedFrame(&frame, &next_frame, &multiple));
  EXPECT_TRUE(next_frame);
  EXPECT_FALSE(multiple);
  EXPECT_EQ(transport::EncodedFrame::KEY, frame.dependency);
  EXPECT_EQ(0u, frame.frame_id);
  EXPECT_EQ(0u, frame.referenced_frame_id);
  framer_.ReleaseFrame(frame.frame_id);

  // Incomplete delta.
  ++rtp_header_.frame_id;
  rtp_header_.reference_frame_id = rtp_header_.frame_id - 1;
  rtp_header_.is_key_frame = false;
  rtp_header_.max_packet_id = 2;
  complete = framer_.InsertPacket(
      payload_.data(), payload_.size(), rtp_header_, &duplicate);
  EXPECT_FALSE(complete);
  EXPECT_FALSE(framer_.GetEncodedFrame(&frame, &next_frame, &multiple));

  // Complete delta - can't skip, as incomplete sequence.
  ++rtp_header_.frame_id;
  rtp_header_.reference_frame_id = rtp_header_.frame_id - 1;
  rtp_header_.max_packet_id = 0;
  complete = framer_.InsertPacket(
      payload_.data(), payload_.size(), rtp_header_, &duplicate);
  EXPECT_TRUE(complete);
  EXPECT_FALSE(framer_.GetEncodedFrame(&frame, &next_frame, &multiple));
}

TEST_F(FramerTest, DuplicatePackets) {
  transport::EncodedFrame frame;
  bool next_frame = false;
  bool complete = false;
  bool multiple = false;
  bool duplicate = false;

  // Start with an incomplete key frame.
  rtp_header_.is_key_frame = true;
  rtp_header_.max_packet_id = 1;
  duplicate = true;
  complete = framer_.InsertPacket(
      payload_.data(), payload_.size(), rtp_header_, &duplicate);
  EXPECT_FALSE(complete);
  EXPECT_FALSE(duplicate);
  EXPECT_FALSE(framer_.GetEncodedFrame(&frame, &next_frame, &multiple));

  // Add same packet again in incomplete key frame.
  duplicate = false;
  complete = framer_.InsertPacket(
      payload_.data(), payload_.size(), rtp_header_, &duplicate);
  EXPECT_FALSE(complete);
  EXPECT_TRUE(duplicate);
  EXPECT_FALSE(framer_.GetEncodedFrame(&frame, &next_frame, &multiple));

  // Complete key frame.
  rtp_header_.packet_id = 1;
  duplicate = true;
  complete = framer_.InsertPacket(
      payload_.data(), payload_.size(), rtp_header_, &duplicate);
  EXPECT_TRUE(complete);
  EXPECT_FALSE(duplicate);
  EXPECT_TRUE(framer_.GetEncodedFrame(&frame, &next_frame, &multiple));
  EXPECT_EQ(transport::EncodedFrame::KEY, frame.dependency);
  EXPECT_FALSE(multiple);
  EXPECT_EQ(0u, frame.referenced_frame_id);

  // Add same packet again in complete key frame.
  duplicate = false;
  complete = framer_.InsertPacket(
      payload_.data(), payload_.size(), rtp_header_, &duplicate);
  EXPECT_FALSE(complete);
  EXPECT_TRUE(duplicate);
  EXPECT_TRUE(framer_.GetEncodedFrame(&frame, &next_frame, &multiple));
  EXPECT_EQ(transport::EncodedFrame::KEY, frame.dependency);
  EXPECT_EQ(0u, frame.frame_id);
  EXPECT_FALSE(multiple);
  EXPECT_EQ(0u, frame.referenced_frame_id);
  framer_.ReleaseFrame(frame.frame_id);

  // Incomplete delta frame.
  ++rtp_header_.frame_id;
  rtp_header_.reference_frame_id = rtp_header_.frame_id - 1;
  rtp_header_.packet_id = 0;
  rtp_header_.is_key_frame = false;
  duplicate = true;
  complete = framer_.InsertPacket(
      payload_.data(), payload_.size(), rtp_header_, &duplicate);
  EXPECT_FALSE(complete);
  EXPECT_FALSE(duplicate);
  EXPECT_FALSE(framer_.GetEncodedFrame(&frame, &next_frame, &multiple));

  // Add same packet again in incomplete delta frame.
  duplicate = false;
  complete = framer_.InsertPacket(
      payload_.data(), payload_.size(), rtp_header_, &duplicate);
  EXPECT_FALSE(complete);
  EXPECT_TRUE(duplicate);
  EXPECT_FALSE(framer_.GetEncodedFrame(&frame, &next_frame, &multiple));

  // Complete delta frame.
  rtp_header_.packet_id = 1;
  duplicate = true;
  complete = framer_.InsertPacket(
      payload_.data(), payload_.size(), rtp_header_, &duplicate);
  EXPECT_TRUE(complete);
  EXPECT_FALSE(duplicate);
  EXPECT_TRUE(framer_.GetEncodedFrame(&frame, &next_frame, &multiple));
  EXPECT_EQ(transport::EncodedFrame::DEPENDENT, frame.dependency);
  EXPECT_EQ(1u, frame.frame_id);
  EXPECT_EQ(0u, frame.referenced_frame_id);
  EXPECT_FALSE(multiple);

  // Add same packet again in complete delta frame.
  duplicate = false;
  complete = framer_.InsertPacket(
      payload_.data(), payload_.size(), rtp_header_, &duplicate);
  EXPECT_FALSE(complete);
  EXPECT_TRUE(duplicate);
  EXPECT_TRUE(framer_.GetEncodedFrame(&frame, &next_frame, &multiple));
  EXPECT_EQ(transport::EncodedFrame::DEPENDENT, frame.dependency);
  EXPECT_EQ(1u, frame.frame_id);
  EXPECT_EQ(0u, frame.referenced_frame_id);
  EXPECT_FALSE(multiple);
}

TEST_F(FramerTest, ContinuousSequence) {
  transport::EncodedFrame frame;
  bool next_frame = false;
  bool complete = false;
  bool multiple = false;
  bool duplicate = false;

  // Start with a complete key frame.
  rtp_header_.is_key_frame = true;
  complete = framer_.InsertPacket(
      payload_.data(), payload_.size(), rtp_header_, &duplicate);
  EXPECT_TRUE(complete);
  EXPECT_TRUE(framer_.GetEncodedFrame(&frame, &next_frame, &multiple));
  EXPECT_TRUE(next_frame);
  EXPECT_FALSE(multiple);
  EXPECT_EQ(transport::EncodedFrame::KEY, frame.dependency);
  EXPECT_EQ(0u, frame.frame_id);
  EXPECT_EQ(0u, frame.referenced_frame_id);
  framer_.ReleaseFrame(frame.frame_id);

  // Complete - not continuous.
  rtp_header_.frame_id = 2;
  rtp_header_.reference_frame_id = rtp_header_.frame_id - 1;
  rtp_header_.is_key_frame = false;
  complete = framer_.InsertPacket(
      payload_.data(), payload_.size(), rtp_header_, &duplicate);
  EXPECT_TRUE(complete);
  EXPECT_FALSE(framer_.GetEncodedFrame(&frame, &next_frame, &multiple));
}

TEST_F(FramerTest, Wrap) {
  // Insert key frame, frame_id = 255 (will jump to that)
  transport::EncodedFrame frame;
  bool next_frame = false;
  bool multiple = true;
  bool duplicate = false;

  // Start with a complete key frame.
  rtp_header_.is_key_frame = true;
  rtp_header_.frame_id = 255;
  rtp_header_.reference_frame_id = 255;
  framer_.InsertPacket(
      payload_.data(), payload_.size(), rtp_header_, &duplicate);
  EXPECT_TRUE(framer_.GetEncodedFrame(&frame, &next_frame, &multiple));
  EXPECT_TRUE(next_frame);
  EXPECT_FALSE(multiple);
  EXPECT_EQ(transport::EncodedFrame::KEY, frame.dependency);
  EXPECT_EQ(255u, frame.frame_id);
  EXPECT_EQ(255u, frame.referenced_frame_id);
  framer_.ReleaseFrame(frame.frame_id);

  // Insert wrapped delta frame - should be continuous.
  rtp_header_.is_key_frame = false;
  rtp_header_.frame_id = 256;
  framer_.InsertPacket(
      payload_.data(), payload_.size(), rtp_header_, &duplicate);
  EXPECT_TRUE(framer_.GetEncodedFrame(&frame, &next_frame, &multiple));
  EXPECT_TRUE(next_frame);
  EXPECT_FALSE(multiple);
  EXPECT_EQ(transport::EncodedFrame::DEPENDENT, frame.dependency);
  EXPECT_EQ(256u, frame.frame_id);
  EXPECT_EQ(255u, frame.referenced_frame_id);
  framer_.ReleaseFrame(frame.frame_id);
}

TEST_F(FramerTest, Reset) {
  transport::EncodedFrame frame;
  bool next_frame = false;
  bool complete = false;
  bool multiple = true;
  bool duplicate = false;

  // Start with a complete key frame.
  rtp_header_.is_key_frame = true;
  complete = framer_.InsertPacket(
      payload_.data(), payload_.size(), rtp_header_, &duplicate);
  EXPECT_TRUE(complete);
  framer_.Reset();
  EXPECT_FALSE(framer_.GetEncodedFrame(&frame, &next_frame, &multiple));
}

TEST_F(FramerTest, RequireKeyAfterReset) {
  transport::EncodedFrame frame;
  bool next_frame = false;
  bool multiple = false;
  bool duplicate = false;

  framer_.Reset();

  // Start with a complete key frame.
  rtp_header_.is_key_frame = false;
  rtp_header_.frame_id = 0;
  framer_.InsertPacket(
      payload_.data(), payload_.size(), rtp_header_, &duplicate);
  EXPECT_FALSE(framer_.GetEncodedFrame(&frame, &next_frame, &multiple));
  rtp_header_.frame_id = 1;
  rtp_header_.reference_frame_id = 1;
  rtp_header_.is_key_frame = true;
  framer_.InsertPacket(
      payload_.data(), payload_.size(), rtp_header_, &duplicate);
  EXPECT_TRUE(framer_.GetEncodedFrame(&frame, &next_frame, &multiple));
  EXPECT_TRUE(next_frame);
  EXPECT_TRUE(multiple);
}

TEST_F(FramerTest, BasicNonLastReferenceId) {
  transport::EncodedFrame frame;
  bool next_frame = false;
  bool multiple = false;
  bool duplicate = false;

  rtp_header_.is_key_frame = true;
  rtp_header_.frame_id = 0;
  framer_.InsertPacket(
      payload_.data(), payload_.size(), rtp_header_, &duplicate);

  EXPECT_TRUE(framer_.GetEncodedFrame(&frame, &next_frame, &multiple));
  EXPECT_FALSE(multiple);
  framer_.ReleaseFrame(frame.frame_id);

  rtp_header_.is_key_frame = false;
  rtp_header_.reference_frame_id = 0;
  rtp_header_.frame_id = 5;
  framer_.InsertPacket(
      payload_.data(), payload_.size(), rtp_header_, &duplicate);

  EXPECT_TRUE(framer_.GetEncodedFrame(&frame, &next_frame, &multiple));
  EXPECT_FALSE(next_frame);
  EXPECT_FALSE(multiple);
}

TEST_F(FramerTest, InOrderReferenceFrameSelection) {
  // Create pattern: 0, 1, 4, 5.
  transport::EncodedFrame frame;
  bool next_frame = false;
  bool multiple = false;
  bool duplicate = false;

  rtp_header_.is_key_frame = true;
  rtp_header_.frame_id = 0;
  framer_.InsertPacket(
      payload_.data(), payload_.size(), rtp_header_, &duplicate);
  rtp_header_.is_key_frame = false;
  rtp_header_.frame_id = 1;
  framer_.InsertPacket(
      payload_.data(), payload_.size(), rtp_header_, &duplicate);

  // Insert frame #2 partially.
  rtp_header_.frame_id = 2;
  rtp_header_.max_packet_id = 1;
  framer_.InsertPacket(
      payload_.data(), payload_.size(), rtp_header_, &duplicate);
  rtp_header_.frame_id = 4;
  rtp_header_.max_packet_id = 0;
  rtp_header_.reference_frame_id = 0;
  framer_.InsertPacket(
      payload_.data(), payload_.size(), rtp_header_, &duplicate);
  EXPECT_TRUE(framer_.GetEncodedFrame(&frame, &next_frame, &multiple));
  EXPECT_EQ(transport::EncodedFrame::KEY, frame.dependency);
  EXPECT_EQ(0u, frame.frame_id);
  EXPECT_EQ(0u, frame.referenced_frame_id);
  EXPECT_FALSE(multiple);
  framer_.ReleaseFrame(frame.frame_id);
  EXPECT_TRUE(framer_.GetEncodedFrame(&frame, &next_frame, &multiple));
  EXPECT_TRUE(next_frame);
  EXPECT_TRUE(multiple);
  EXPECT_EQ(transport::EncodedFrame::DEPENDENT, frame.dependency);
  EXPECT_EQ(1u, frame.frame_id);
  EXPECT_EQ(0u, frame.referenced_frame_id);
  framer_.ReleaseFrame(frame.frame_id);
  EXPECT_TRUE(framer_.GetEncodedFrame(&frame, &next_frame, &multiple));
  EXPECT_FALSE(next_frame);
  EXPECT_FALSE(multiple);
  EXPECT_EQ(transport::EncodedFrame::DEPENDENT, frame.dependency);
  EXPECT_EQ(4u, frame.frame_id);
  EXPECT_EQ(0u, frame.referenced_frame_id);
  framer_.ReleaseFrame(frame.frame_id);
  // Insert remaining packet of frame #2 - should no be continuous.
  rtp_header_.frame_id = 2;
  rtp_header_.packet_id = 1;
  framer_.InsertPacket(
      payload_.data(), payload_.size(), rtp_header_, &duplicate);
  EXPECT_FALSE(framer_.GetEncodedFrame(&frame, &next_frame, &multiple));
  rtp_header_.frame_id = 5;
  rtp_header_.reference_frame_id = rtp_header_.frame_id - 1;
  rtp_header_.packet_id = 0;
  rtp_header_.max_packet_id = 0;
  framer_.InsertPacket(
      payload_.data(), payload_.size(), rtp_header_, &duplicate);
  EXPECT_TRUE(framer_.GetEncodedFrame(&frame, &next_frame, &multiple));
  EXPECT_TRUE(next_frame);
  EXPECT_FALSE(multiple);
  EXPECT_EQ(transport::EncodedFrame::DEPENDENT, frame.dependency);
  EXPECT_EQ(5u, frame.frame_id);
  EXPECT_EQ(4u, frame.referenced_frame_id);
}

TEST_F(FramerTest, AudioWrap) {
  // All audio frames are marked as key frames.
  transport::EncodedFrame frame;
  bool next_frame = false;
  bool multiple = false;
  bool duplicate = false;

  rtp_header_.is_key_frame = true;
  rtp_header_.frame_id = 254;
  rtp_header_.reference_frame_id = 254;

  framer_.InsertPacket(
      payload_.data(), payload_.size(), rtp_header_, &duplicate);
  EXPECT_TRUE(framer_.GetEncodedFrame(&frame, &next_frame, &multiple));
  EXPECT_TRUE(next_frame);
  EXPECT_FALSE(multiple);
  EXPECT_EQ(transport::EncodedFrame::KEY, frame.dependency);
  EXPECT_EQ(254u, frame.frame_id);
  EXPECT_EQ(254u, frame.referenced_frame_id);
  framer_.ReleaseFrame(frame.frame_id);

  rtp_header_.frame_id = 255;
  rtp_header_.reference_frame_id = 255;
  framer_.InsertPacket(
      payload_.data(), payload_.size(), rtp_header_, &duplicate);

  // Insert wrapped frame - should be continuous.
  rtp_header_.frame_id = 256;
  rtp_header_.reference_frame_id = 256;
  framer_.InsertPacket(
      payload_.data(), payload_.size(), rtp_header_, &duplicate);

  EXPECT_TRUE(framer_.GetEncodedFrame(&frame, &next_frame, &multiple));
  EXPECT_TRUE(next_frame);
  EXPECT_TRUE(multiple);
  EXPECT_EQ(transport::EncodedFrame::KEY, frame.dependency);
  EXPECT_EQ(255u, frame.frame_id);
  EXPECT_EQ(255u, frame.referenced_frame_id);
  framer_.ReleaseFrame(frame.frame_id);

  EXPECT_TRUE(framer_.GetEncodedFrame(&frame, &next_frame, &multiple));
  EXPECT_TRUE(next_frame);
  EXPECT_FALSE(multiple);
  EXPECT_EQ(transport::EncodedFrame::KEY, frame.dependency);
  EXPECT_EQ(256u, frame.frame_id);
  EXPECT_EQ(256u, frame.referenced_frame_id);
  framer_.ReleaseFrame(frame.frame_id);
}

TEST_F(FramerTest, AudioWrapWithMissingFrame) {
  // All audio frames are marked as key frames.
  transport::EncodedFrame frame;
  bool next_frame = false;
  bool multiple = true;
  bool duplicate = false;

  // Insert and get first packet.
  rtp_header_.is_key_frame = true;
  rtp_header_.frame_id = 253;
  rtp_header_.reference_frame_id = 253;
  framer_.InsertPacket(
      payload_.data(), payload_.size(), rtp_header_, &duplicate);
  EXPECT_TRUE(framer_.GetEncodedFrame(&frame, &next_frame, &multiple));
  EXPECT_TRUE(next_frame);
  EXPECT_FALSE(multiple);
  EXPECT_EQ(transport::EncodedFrame::KEY, frame.dependency);
  EXPECT_EQ(253u, frame.frame_id);
  EXPECT_EQ(253u, frame.referenced_frame_id);
  framer_.ReleaseFrame(frame.frame_id);

  // Insert third and fourth packets.
  rtp_header_.frame_id = 255;
  rtp_header_.reference_frame_id = 255;
  framer_.InsertPacket(
      payload_.data(), payload_.size(), rtp_header_, &duplicate);
  rtp_header_.frame_id = 256;
  rtp_header_.reference_frame_id = 256;
  framer_.InsertPacket(
      payload_.data(), payload_.size(), rtp_header_, &duplicate);

  // Get third and fourth packets.
  EXPECT_TRUE(framer_.GetEncodedFrame(&frame, &next_frame, &multiple));
  EXPECT_FALSE(next_frame);
  EXPECT_TRUE(multiple);
  EXPECT_EQ(transport::EncodedFrame::KEY, frame.dependency);
  EXPECT_EQ(255u, frame.frame_id);
  EXPECT_EQ(255u, frame.referenced_frame_id);
  framer_.ReleaseFrame(frame.frame_id);
  EXPECT_TRUE(framer_.GetEncodedFrame(&frame, &next_frame, &multiple));
  EXPECT_TRUE(next_frame);
  EXPECT_FALSE(multiple);
  EXPECT_EQ(transport::EncodedFrame::KEY, frame.dependency);
  EXPECT_EQ(256u, frame.frame_id);
  EXPECT_EQ(256u, frame.referenced_frame_id);
  framer_.ReleaseFrame(frame.frame_id);
}

}  // namespace cast
}  // namespace media