// Copyright 2014 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 "cobalt/media/formats/webm/webm_cluster_parser.h"

#include <algorithm>
#include <cstdlib>
#include <string>
#include <vector>

#include "base/basictypes.h"
#include "base/bind.h"
#include "base/logging.h"
#include "base/memory/scoped_ptr.h"
#include "base/string_number_conversions.h"
#include "cobalt/media/base/audio_decoder_config.h"
#include "cobalt/media/base/decrypt_config.h"
#include "cobalt/media/base/mock_media_log.h"
#include "cobalt/media/base/timestamp_constants.h"
#include "cobalt/media/formats/webm/cluster_builder.h"
#include "cobalt/media/formats/webm/opus_packet_builder.h"
#include "cobalt/media/formats/webm/webm_constants.h"
#include "starboard/types.h"
#include "testing/gmock/include/gmock/gmock.h"
#include "testing/gtest/include/gtest/gtest.h"

using ::testing::HasSubstr;
using ::testing::InSequence;
using ::testing::Return;
using ::testing::StrictMock;
using ::testing::Mock;
using ::testing::_;

namespace cobalt {
namespace media {

typedef WebMTracksParser::TextTracks TextTracks;

// Matchers for verifying common media log entry strings.
MATCHER_P(OpusPacketDurationTooHigh, actual_duration_ms, "") {
  return CONTAINS_STRING(
      arg, "Warning, demuxed Opus packet with encoded duration: " +
               base::IntToString(actual_duration_ms) +
               "ms. Should be no greater than 120ms.");
}

MATCHER_P(WebMSimpleBlockDurationEstimated, estimated_duration_ms, "") {
  return CONTAINS_STRING(arg, "Estimating WebM block duration to be " +
                                  base::IntToString(estimated_duration_ms) +
                                  "ms for the last (Simple)Block in the "
                                  "Cluster for this Track. Use BlockGroups "
                                  "with BlockDurations at the end of each "
                                  "Track in a Cluster to avoid estimation.");
}

MATCHER_P2(WebMBlockDurationMismatchesOpusDuration, block_duration_ms,
           opus_duration_ms, "") {
  return CONTAINS_STRING(
      arg, "BlockDuration (" + base::IntToString(block_duration_ms) +
               "ms) differs significantly from encoded duration (" +
               base::IntToString(opus_duration_ms) + "ms).");
}

namespace {

// Timecode scale for millisecond timestamps.
const int kTimecodeScale = 1000000;

const int kAudioTrackNum = 1;
const int kVideoTrackNum = 2;
const int kTextTrackNum = 3;
const int kTestAudioFrameDefaultDurationInMs = 13;
const int kTestVideoFrameDefaultDurationInMs = 17;

// Test duration defaults must differ from parser estimation defaults to know
// which durations parser used when emitting buffers.
static_assert(
    static_cast<int>(kTestAudioFrameDefaultDurationInMs) !=
        static_cast<int>(WebMClusterParser::kDefaultAudioBufferDurationInMs),
    "test default is the same as estimation fallback audio duration");
static_assert(
    static_cast<int>(kTestVideoFrameDefaultDurationInMs) !=
        static_cast<int>(WebMClusterParser::kDefaultVideoBufferDurationInMs),
    "test default is the same as estimation fallback video duration");

struct BlockInfo {
  int track_num;
  int timestamp;

  // Negative value is allowed only for block groups (not simple blocks) and
  // directs CreateCluster() to exclude BlockDuration entry from the cluster for
  // this BlockGroup. The absolute value is used for parser verification.
  // For simple blocks, this value must be non-negative, and is used only for
  // parser verification.
  double duration;

  bool use_simple_block;

  // Default data will be used if no data given.
  const uint8_t* data;
  int data_length;

  bool is_key_frame;
};

const BlockInfo kDefaultBlockInfo[] = {
    {kAudioTrackNum, 0, 23, true, NULL, 0, true},
    {kAudioTrackNum, 23, 23, true, NULL, 0, true},
    // Assumes not using DefaultDuration
    {kVideoTrackNum, 33, 34, true, NULL, 0, true},
    {kAudioTrackNum, 46, 23, true, NULL, 0, false},
    {kVideoTrackNum, 67, 33, false, NULL, 0, true},
    {kAudioTrackNum, 69, 23, false, NULL, 0, false},
    {kVideoTrackNum, 100, 33, false, NULL, 0, false},
};

const uint8_t kEncryptedFrame[] = {
    // Block is encrypted
    0x01,

    // IV
    0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08};

scoped_ptr<Cluster> CreateCluster(int timecode, const BlockInfo* block_info,
                                  int block_count) {
  ClusterBuilder cb;
  cb.SetClusterTimecode(0);

  uint8_t kDefaultBlockData[] = {0x00};

  for (int i = 0; i < block_count; i++) {
    const uint8_t* data;
    int data_length;
    if (block_info[i].data != NULL) {
      data = block_info[i].data;
      data_length = block_info[i].data_length;
    } else {
      data = kDefaultBlockData;
      data_length = sizeof(kDefaultBlockData);
    }

    if (block_info[i].use_simple_block) {
      CHECK_GE(block_info[i].duration, 0);
      cb.AddSimpleBlock(block_info[i].track_num, block_info[i].timestamp,
                        block_info[i].is_key_frame ? 0x80 : 0x00, data,
                        data_length);
      continue;
    }

    if (block_info[i].duration < 0) {
      cb.AddBlockGroupWithoutBlockDuration(
          block_info[i].track_num, block_info[i].timestamp, 0,
          block_info[i].is_key_frame, data, data_length);
      continue;
    }

    cb.AddBlockGroup(block_info[i].track_num, block_info[i].timestamp,
                     block_info[i].duration, 0, block_info[i].is_key_frame,
                     data, data_length);
  }

  return cb.Finish();
}

// Creates a Cluster with one encrypted Block. |bytes_to_write| is number of
// bytes of the encrypted frame to write.
scoped_ptr<Cluster> CreateEncryptedCluster(int bytes_to_write) {
  CHECK_GT(bytes_to_write, 0);
  CHECK_LE(bytes_to_write, static_cast<int>(sizeof(kEncryptedFrame)));

  ClusterBuilder cb;
  cb.SetClusterTimecode(0);
  cb.AddSimpleBlock(kVideoTrackNum, 0, 0, kEncryptedFrame, bytes_to_write);
  return cb.Finish();
}

bool VerifyBuffers(const StreamParser::BufferQueueMap& buffer_queue_map,
                   const BlockInfo* block_info, int block_count) {
  int buffer_count = 0;
  for (const auto& it : buffer_queue_map) buffer_count += it.second.size();
  if (block_count != buffer_count) {
    DVLOG(1) << __FUNCTION__ << " : block_count (" << block_count
             << ") mismatches buffer_count (" << buffer_count << ")";
    return false;
  }

  size_t audio_offset = 0;
  size_t video_offset = 0;
  size_t text_offset = 0;
  for (int i = 0; i < block_count; i++) {
    const StreamParser::BufferQueue* buffers = NULL;
    size_t* offset;
    StreamParserBuffer::Type expected_type = DemuxerStream::UNKNOWN;

    const auto& it = buffer_queue_map.find(block_info[i].track_num);
    EXPECT_NE(buffer_queue_map.end(), it);
    buffers = &it->second;
    if (block_info[i].track_num == kAudioTrackNum) {
      offset = &audio_offset;
      expected_type = DemuxerStream::AUDIO;
    } else if (block_info[i].track_num == kVideoTrackNum) {
      offset = &video_offset;
      expected_type = DemuxerStream::VIDEO;
    } else if (block_info[i].track_num == kTextTrackNum) {
      offset = &text_offset;
      expected_type = DemuxerStream::TEXT;
    } else {
      LOG(ERROR) << "Unexpected track number " << block_info[i].track_num;
      return false;
    }

    if (*offset >= buffers->size()) {
      DVLOG(1) << __FUNCTION__ << " : Too few buffers (" << buffers->size()
               << ") for track_num (" << block_info[i].track_num
               << "), expected at least " << *offset + 1 << " buffers";
      return false;
    }

    scoped_refptr<StreamParserBuffer> buffer = (*buffers)[(*offset)++];

    EXPECT_EQ(block_info[i].timestamp, buffer->timestamp().InMilliseconds());
    EXPECT_EQ(std::abs(block_info[i].duration),
              buffer->duration().InMillisecondsF());
    EXPECT_EQ(expected_type, buffer->type());
    EXPECT_EQ(block_info[i].track_num, buffer->track_id());
    EXPECT_EQ(block_info[i].is_key_frame, buffer->is_key_frame());
  }

  return true;
}

bool VerifyBuffers(const scoped_ptr<WebMClusterParser>& parser,
                   const BlockInfo* block_info, int block_count) {
  StreamParser::BufferQueueMap buffers;
  parser->GetBuffers(&buffers);
  return VerifyBuffers(buffers, block_info, block_count);
}

bool VerifyTextBuffers(const scoped_ptr<WebMClusterParser>& parser,
                       const BlockInfo* block_info_ptr, int block_count,
                       int text_track_num,
                       const WebMClusterParser::BufferQueue& text_buffers) {
  const BlockInfo* const block_info_end = block_info_ptr + block_count;

  typedef WebMClusterParser::BufferQueue::const_iterator TextBufferIter;
  TextBufferIter buffer_iter = text_buffers.begin();
  const TextBufferIter buffer_end = text_buffers.end();

  while (block_info_ptr != block_info_end) {
    const BlockInfo& block_info = *block_info_ptr++;

    if (block_info.track_num != text_track_num) continue;

    EXPECT_FALSE(block_info.use_simple_block);
    EXPECT_FALSE(buffer_iter == buffer_end);

    const scoped_refptr<StreamParserBuffer> buffer = *buffer_iter++;
    EXPECT_EQ(block_info.timestamp, buffer->timestamp().InMilliseconds());
    EXPECT_EQ(std::abs(block_info.duration),
              buffer->duration().InMillisecondsF());
    EXPECT_EQ(DemuxerStream::TEXT, buffer->type());
    EXPECT_EQ(text_track_num, buffer->track_id());
  }

  EXPECT_TRUE(buffer_iter == buffer_end);
  return true;
}

void VerifyEncryptedBuffer(scoped_refptr<StreamParserBuffer> buffer) {
  EXPECT_TRUE(buffer->decrypt_config());
  EXPECT_EQ(static_cast<size_t>(DecryptConfig::kDecryptionKeySize),
            buffer->decrypt_config()->iv().length());
}

void AppendToEnd(const StreamParser::BufferQueue& src,
                 StreamParser::BufferQueue* dest) {
  for (StreamParser::BufferQueue::const_iterator itr = src.begin();
       itr != src.end(); ++itr) {
    dest->push_back(*itr);
  }
}

}  // namespace

class WebMClusterParserTest : public testing::Test {
 public:
  WebMClusterParserTest()
      : media_log_(new StrictMock<MockMediaLog>()),
        parser_(CreateDefaultParser()) {}

 protected:
  void ResetParserToHaveDefaultDurations() {
    base::TimeDelta default_audio_duration =
        base::TimeDelta::FromMilliseconds(kTestAudioFrameDefaultDurationInMs);
    base::TimeDelta default_video_duration =
        base::TimeDelta::FromMilliseconds(kTestVideoFrameDefaultDurationInMs);
    ASSERT_GE(default_audio_duration, base::TimeDelta());
    ASSERT_GE(default_video_duration, base::TimeDelta());
    ASSERT_NE(kNoTimestamp, default_audio_duration);
    ASSERT_NE(kNoTimestamp, default_video_duration);

    parser_.reset(CreateParserWithDefaultDurationsAndOptionalTextTracks(
        default_audio_duration, default_video_duration));
  }

  // Helper that hard-codes some non-varying constructor parameters.
  WebMClusterParser* CreateParserHelper(
      base::TimeDelta audio_default_duration,
      base::TimeDelta video_default_duration,
      const WebMTracksParser::TextTracks& text_tracks,
      const std::set<int64_t>& ignored_tracks,
      const std::string& audio_encryption_key_id,
      const std::string& video_encryption_key_id,
      const AudioCodec audio_codec) {
    return new WebMClusterParser(
        kTimecodeScale, kAudioTrackNum, audio_default_duration, kVideoTrackNum,
        video_default_duration, text_tracks, ignored_tracks,
        audio_encryption_key_id, video_encryption_key_id, audio_codec,
        media_log_);
  }

  // Create a default version of the parser for test.
  WebMClusterParser* CreateDefaultParser() {
    return CreateParserHelper(kNoTimestamp, kNoTimestamp, TextTracks(),
                              std::set<int64_t>(), std::string(), std::string(),
                              kUnknownAudioCodec);
  }

  // Create a parser for test with custom audio and video default durations, and
  // optionally custom text tracks.
  WebMClusterParser* CreateParserWithDefaultDurationsAndOptionalTextTracks(
      base::TimeDelta audio_default_duration,
      base::TimeDelta video_default_duration,
      const WebMTracksParser::TextTracks& text_tracks = TextTracks()) {
    return CreateParserHelper(audio_default_duration, video_default_duration,
                              text_tracks, std::set<int64_t>(), std::string(),
                              std::string(), kUnknownAudioCodec);
  }

  // Create a parser for test with custom ignored tracks.
  WebMClusterParser* CreateParserWithIgnoredTracks(
      std::set<int64_t>& ignored_tracks) {
    return CreateParserHelper(kNoTimestamp, kNoTimestamp, TextTracks(),
                              ignored_tracks, std::string(), std::string(),
                              kUnknownAudioCodec);
  }

  // Create a parser for test with custom encryption key ids and audio codec.
  WebMClusterParser* CreateParserWithKeyIdsAndAudioCodec(
      const std::string& audio_encryption_key_id,
      const std::string& video_encryption_key_id,
      const AudioCodec audio_codec) {
    return CreateParserHelper(kNoTimestamp, kNoTimestamp, TextTracks(),
                              std::set<int64_t>(), audio_encryption_key_id,
                              video_encryption_key_id, audio_codec);
  }

  scoped_refptr<StrictMock<MockMediaLog>> media_log_;
  scoped_ptr<WebMClusterParser> parser_;

 private:
  DISALLOW_COPY_AND_ASSIGN(WebMClusterParserTest);
};

TEST_F(WebMClusterParserTest, HeldBackBufferHoldsBackAllTracks) {
  // If a buffer is missing duration and is being held back, then all other
  // tracks' buffers that have same or higher (decode) timestamp should be held
  // back too to keep the timestamps emitted for a cluster monotonically
  // non-decreasing and in same order as parsed.
  InSequence s;

  // Reset the parser to have 3 tracks: text, video (no default frame duration),
  // and audio (with a default frame duration).
  TextTracks text_tracks;
  text_tracks.insert(
      std::make_pair(TextTracks::key_type(kTextTrackNum),
                     TextTrackConfig(kTextSubtitles, "", "", "")));
  base::TimeDelta default_audio_duration =
      base::TimeDelta::FromMilliseconds(kTestAudioFrameDefaultDurationInMs);
  ASSERT_GE(default_audio_duration, base::TimeDelta());
  ASSERT_NE(kNoTimestamp, default_audio_duration);
  parser_.reset(CreateParserWithDefaultDurationsAndOptionalTextTracks(
      default_audio_duration, kNoTimestamp, text_tracks));

  const int kExpectedVideoEstimationInMs = 33;

  const BlockInfo kBlockInfo[] = {
      {kVideoTrackNum, 0, 33, true, NULL, 0, false},
      {kAudioTrackNum, 0, 23, false, NULL, 0, false},
      {kTextTrackNum, 10, 42, false, NULL, 0, true},
      {kAudioTrackNum, 23, kTestAudioFrameDefaultDurationInMs, true, NULL, 0,
       false},
      {kVideoTrackNum, 33, 33, true, NULL, 0, false},
      {kAudioTrackNum, 36, kTestAudioFrameDefaultDurationInMs, true, NULL, 0,
       false},
      {kVideoTrackNum, 66, kExpectedVideoEstimationInMs, true, NULL, 0, false},
      {kAudioTrackNum, 70, kTestAudioFrameDefaultDurationInMs, true, NULL, 0,
       false},
      {kAudioTrackNum, 83, kTestAudioFrameDefaultDurationInMs, true, NULL, 0,
       false},
  };

  const int kExpectedBuffersOnPartialCluster[] = {
      0,  // Video simple block without DefaultDuration should be held back
      0,  // Audio buffer ready, but not emitted because its TS >= held back
          // video
      0,  // Text buffer ready, but not emitted because its TS >= held back
          // video
      0,  // 2nd audio buffer ready, also not emitted for same reason as first
      4,  // All previous buffers emitted, 2nd video held back with no duration
      4,  // 2nd video still has no duration, 3rd audio ready but not emitted
      6,  // All previous buffers emitted, 3rd video held back with no duration
      6,  // 3rd video still has no duration, 4th audio ready but not emitted
      9,  // Cluster end emits all buffers and 3rd video's duration is estimated
  };

  ASSERT_EQ(arraysize(kBlockInfo), arraysize(kExpectedBuffersOnPartialCluster));
  int block_count = arraysize(kBlockInfo);

  // Iteratively create a cluster containing the first N+1 blocks and parse all
  // but the last byte of the cluster (except when N==|block_count|, just parse
  // the whole cluster). Verify that the corresponding entry in
  // |kExpectedBuffersOnPartialCluster| identifies the exact subset of
  // |kBlockInfo| returned by the parser.
  for (int i = 0; i < block_count; ++i) {
    if (i > 0) parser_->Reset();
    // Since we don't know exactly the offsets of each block in the full
    // cluster, build a cluster with exactly one additional block so that
    // parse of all but one byte should deterministically parse all but the
    // last full block. Don't |exceed block_count| blocks though.
    int blocks_in_cluster = std::min(i + 2, block_count);
    scoped_ptr<Cluster> cluster(
        CreateCluster(0, kBlockInfo, blocks_in_cluster));
    // Parse all but the last byte unless we need to parse the full cluster.
    bool parse_full_cluster = i == (block_count - 1);

    if (parse_full_cluster) {
      EXPECT_MEDIA_LOG(
          WebMSimpleBlockDurationEstimated(kExpectedVideoEstimationInMs));
    }

    int result = parser_->Parse(cluster->data(), parse_full_cluster
                                                     ? cluster->size()
                                                     : cluster->size() - 1);
    if (parse_full_cluster) {
      DVLOG(1) << "Verifying parse result of full cluster of "
               << blocks_in_cluster << " blocks";
      EXPECT_EQ(cluster->size(), result);
    } else {
      DVLOG(1) << "Verifying parse result of cluster of " << blocks_in_cluster
               << " blocks with last block incomplete";
      EXPECT_GT(cluster->size(), result);
      EXPECT_LT(0, result);
    }

    EXPECT_TRUE(VerifyBuffers(parser_, kBlockInfo,
                              kExpectedBuffersOnPartialCluster[i]));
  }
}

TEST_F(WebMClusterParserTest, Reset) {
  InSequence s;

  int block_count = arraysize(kDefaultBlockInfo);
  scoped_ptr<Cluster> cluster(CreateCluster(0, kDefaultBlockInfo, block_count));

  // Send slightly less than the full cluster so all but the last block is
  // parsed.
  int result = parser_->Parse(cluster->data(), cluster->size() - 1);
  EXPECT_GT(result, 0);
  EXPECT_LT(result, cluster->size());

  ASSERT_TRUE(VerifyBuffers(parser_, kDefaultBlockInfo, block_count - 1));
  parser_->Reset();

  // Now parse a whole cluster to verify that all the blocks will get parsed.
  result = parser_->Parse(cluster->data(), cluster->size());
  EXPECT_EQ(cluster->size(), result);
  ASSERT_TRUE(VerifyBuffers(parser_, kDefaultBlockInfo, block_count));
}

TEST_F(WebMClusterParserTest, ParseClusterWithSingleCall) {
  int block_count = arraysize(kDefaultBlockInfo);
  scoped_ptr<Cluster> cluster(CreateCluster(0, kDefaultBlockInfo, block_count));

  int result = parser_->Parse(cluster->data(), cluster->size());
  EXPECT_EQ(cluster->size(), result);
  ASSERT_TRUE(VerifyBuffers(parser_, kDefaultBlockInfo, block_count));
}

TEST_F(WebMClusterParserTest, ParseClusterWithMultipleCalls) {
  int block_count = arraysize(kDefaultBlockInfo);
  scoped_ptr<Cluster> cluster(CreateCluster(0, kDefaultBlockInfo, block_count));

  const uint8_t* data = cluster->data();
  int size = cluster->size();
  int default_parse_size = 3;
  int parse_size = std::min(default_parse_size, size);

  StreamParser::BufferQueueMap buffers;
  while (size > 0) {
    int result = parser_->Parse(data, parse_size);
    ASSERT_GE(result, 0);
    ASSERT_LE(result, parse_size);

    if (result == 0) {
      // The parser needs more data so increase the parse_size a little.
      parse_size += default_parse_size;
      parse_size = std::min(parse_size, size);
      continue;
    }

    StreamParser::BufferQueueMap bqm;
    parser_->GetBuffers(&bqm);
    for (const auto& it : bqm) {
      AppendToEnd(it.second, &buffers[it.first]);
    }

    parse_size = default_parse_size;

    data += result;
    size -= result;
  }
  ASSERT_TRUE(VerifyBuffers(buffers, kDefaultBlockInfo, block_count));
}

// Verify that both BlockGroups with the BlockDuration before the Block
// and BlockGroups with the BlockDuration after the Block are supported
// correctly.
// Note: Raw bytes are use here because ClusterBuilder only generates
// one of these scenarios.
TEST_F(WebMClusterParserTest, ParseBlockGroup) {
  const BlockInfo kBlockInfo[] = {
      {kAudioTrackNum, 0, 23, false, NULL, 0, true},
      {kVideoTrackNum, 33, 34, false, NULL, 0, true},
  };
  int block_count = arraysize(kBlockInfo);

  const uint8_t kClusterData[] = {
      0x1F, 0x43, 0xB6, 0x75, 0x9B,  // Cluster(size=27)
      0xE7, 0x81, 0x00,              // Timecode(size=1, value=0)
      // BlockGroup with BlockDuration before Block.
      0xA0, 0x8A,        // BlockGroup(size=10)
      0x9B, 0x81, 0x17,  // BlockDuration(size=1, value=23)
      0xA1, 0x85, 0x81, 0x00, 0x00, 0x00, 0xaa,  // Block(size=5, track=1, ts=0)
      // BlockGroup with BlockDuration after Block.
      0xA0, 0x8A,  // BlockGroup(size=10)
      0xA1, 0x85, 0x82, 0x00, 0x21, 0x00,
      0x55,              // Block(size=5, track=2, ts=33)
      0x9B, 0x81, 0x22,  // BlockDuration(size=1, value=34)
  };
  const int kClusterSize = sizeof(kClusterData);

  int result = parser_->Parse(kClusterData, kClusterSize);
  EXPECT_EQ(kClusterSize, result);
  ASSERT_TRUE(VerifyBuffers(parser_, kBlockInfo, block_count));
}

TEST_F(WebMClusterParserTest, ParseSimpleBlockAndBlockGroupMixture) {
  const BlockInfo kBlockInfo[] = {
      {kAudioTrackNum, 0, 23, true, NULL, 0, false},
      {kAudioTrackNum, 23, 23, false, NULL, 0, false},
      {kVideoTrackNum, 33, 34, true, NULL, 0, false},
      {kAudioTrackNum, 46, 23, false, NULL, 0, false},
      {kVideoTrackNum, 67, 33, false, NULL, 0, false},
  };
  int block_count = arraysize(kBlockInfo);
  scoped_ptr<Cluster> cluster(CreateCluster(0, kBlockInfo, block_count));

  int result = parser_->Parse(cluster->data(), cluster->size());
  EXPECT_EQ(cluster->size(), result);
  ASSERT_TRUE(VerifyBuffers(parser_, kBlockInfo, block_count));
}

TEST_F(WebMClusterParserTest, IgnoredTracks) {
  std::set<int64_t> ignored_tracks;
  ignored_tracks.insert(kTextTrackNum);

  parser_.reset(CreateParserWithIgnoredTracks(ignored_tracks));

  const BlockInfo kInputBlockInfo[] = {
      {kAudioTrackNum, 0, 23, true, NULL, 0, false},
      {kAudioTrackNum, 23, 23, true, NULL, 0, false},
      {kVideoTrackNum, 33, 34, true, NULL, 0, false},
      {kTextTrackNum, 33, 99, true, NULL, 0, false},
      {kAudioTrackNum, 46, 23, true, NULL, 0, false},
      {kVideoTrackNum, 67, 34, true, NULL, 0, false},
  };
  int input_block_count = arraysize(kInputBlockInfo);

  const BlockInfo kOutputBlockInfo[] = {
      {kAudioTrackNum, 0, 23, true, NULL, 0, false},
      {kAudioTrackNum, 23, 23, true, NULL, 0, false},
      {kVideoTrackNum, 33, 34, true, NULL, 0, false},
      {kAudioTrackNum, 46, 23, true, NULL, 0, false},
      {kVideoTrackNum, 67, 34, true, NULL, 0, false},
  };
  int output_block_count = arraysize(kOutputBlockInfo);

  scoped_ptr<Cluster> cluster(
      CreateCluster(0, kInputBlockInfo, input_block_count));

  EXPECT_MEDIA_LOG(WebMSimpleBlockDurationEstimated(23));
  EXPECT_MEDIA_LOG(WebMSimpleBlockDurationEstimated(34));
  int result = parser_->Parse(cluster->data(), cluster->size());
  EXPECT_EQ(cluster->size(), result);
  ASSERT_TRUE(VerifyBuffers(parser_, kOutputBlockInfo, output_block_count));
}

TEST_F(WebMClusterParserTest, ParseTextTracks) {
  TextTracks text_tracks;

  text_tracks.insert(
      std::make_pair(TextTracks::key_type(kTextTrackNum),
                     TextTrackConfig(kTextSubtitles, "", "", "")));

  parser_.reset(CreateParserWithDefaultDurationsAndOptionalTextTracks(
      kNoTimestamp, kNoTimestamp, text_tracks));

  const BlockInfo kInputBlockInfo[] = {
      {kAudioTrackNum, 0, 23, true, NULL, 0, false},
      {kAudioTrackNum, 23, 23, true, NULL, 0, false},
      {kVideoTrackNum, 33, 34, true, NULL, 0, false},
      {kTextTrackNum, 33, 42, false, NULL, 0, true},
      {kAudioTrackNum, 46, 23, true, NULL, 0, false},
      {kTextTrackNum, 55, 44, false, NULL, 0, true},
      {kVideoTrackNum, 67, 34, true, NULL, 0, false},
  };
  int input_block_count = arraysize(kInputBlockInfo);

  scoped_ptr<Cluster> cluster(
      CreateCluster(0, kInputBlockInfo, input_block_count));

  EXPECT_MEDIA_LOG(WebMSimpleBlockDurationEstimated(23));
  EXPECT_MEDIA_LOG(WebMSimpleBlockDurationEstimated(34));
  int result = parser_->Parse(cluster->data(), cluster->size());
  EXPECT_EQ(cluster->size(), result);
  ASSERT_TRUE(VerifyBuffers(parser_, kInputBlockInfo, input_block_count));
}

TEST_F(WebMClusterParserTest, TextTracksSimpleBlock) {
  TextTracks text_tracks;

  text_tracks.insert(
      std::make_pair(TextTracks::key_type(kTextTrackNum),
                     TextTrackConfig(kTextSubtitles, "", "", "")));

  parser_.reset(CreateParserWithDefaultDurationsAndOptionalTextTracks(
      kNoTimestamp, kNoTimestamp, text_tracks));

  const BlockInfo kInputBlockInfo[] = {
      {kTextTrackNum, 33, 42, true},
  };
  int input_block_count = arraysize(kInputBlockInfo);

  scoped_ptr<Cluster> cluster(
      CreateCluster(0, kInputBlockInfo, input_block_count));

  int result = parser_->Parse(cluster->data(), cluster->size());
  EXPECT_LT(result, 0);
}

TEST_F(WebMClusterParserTest, ParseMultipleTextTracks) {
  TextTracks text_tracks;

  const int kSubtitleTextTrackNum = kTextTrackNum;
  const int kCaptionTextTrackNum = kTextTrackNum + 1;

  text_tracks.insert(
      std::make_pair(TextTracks::key_type(kSubtitleTextTrackNum),
                     TextTrackConfig(kTextSubtitles, "", "", "")));

  text_tracks.insert(
      std::make_pair(TextTracks::key_type(kCaptionTextTrackNum),
                     TextTrackConfig(kTextCaptions, "", "", "")));

  parser_.reset(CreateParserWithDefaultDurationsAndOptionalTextTracks(
      kNoTimestamp, kNoTimestamp, text_tracks));

  const BlockInfo kInputBlockInfo[] = {
      {kAudioTrackNum, 0, 23, true, NULL, 0, false},
      {kAudioTrackNum, 23, 23, true, NULL, 0, false},
      {kVideoTrackNum, 33, 34, true, NULL, 0, false},
      {kSubtitleTextTrackNum, 33, 42, false, NULL, 0, false},
      {kAudioTrackNum, 46, 23, true, NULL, 0, false},
      {kCaptionTextTrackNum, 55, 44, false, NULL, 0, false},
      {kVideoTrackNum, 67, 34, true, NULL, 0, false},
      {kSubtitleTextTrackNum, 67, 33, false, NULL, 0, false},
  };
  int input_block_count = arraysize(kInputBlockInfo);

  scoped_ptr<Cluster> cluster(
      CreateCluster(0, kInputBlockInfo, input_block_count));

  EXPECT_MEDIA_LOG(WebMSimpleBlockDurationEstimated(23));
  EXPECT_MEDIA_LOG(WebMSimpleBlockDurationEstimated(34));
  int result = parser_->Parse(cluster->data(), cluster->size());
  EXPECT_EQ(cluster->size(), result);

  const WebMClusterParser::TextBufferQueueMap& text_map =
      parser_->GetTextBuffers();
  for (WebMClusterParser::TextBufferQueueMap::const_iterator itr =
           text_map.begin();
       itr != text_map.end(); ++itr) {
    const TextTracks::const_iterator find_result = text_tracks.find(itr->first);
    ASSERT_TRUE(find_result != text_tracks.end());
    ASSERT_TRUE(VerifyTextBuffers(parser_, kInputBlockInfo, input_block_count,
                                  itr->first, itr->second));
  }
}

TEST_F(WebMClusterParserTest, ParseEncryptedBlock) {
  scoped_ptr<Cluster> cluster(CreateEncryptedCluster(sizeof(kEncryptedFrame)));

  parser_.reset(CreateParserWithKeyIdsAndAudioCodec(
      std::string(), "video_key_id", kUnknownAudioCodec));

  // The encrypted cluster contains just one block, video.
  EXPECT_MEDIA_LOG(WebMSimpleBlockDurationEstimated(
      WebMClusterParser::kDefaultVideoBufferDurationInMs));

  int result = parser_->Parse(cluster->data(), cluster->size());
  EXPECT_EQ(cluster->size(), result);
  StreamParser::BufferQueueMap buffers;
  parser_->GetBuffers(&buffers);
  EXPECT_EQ(1UL, buffers[kVideoTrackNum].size());
  scoped_refptr<StreamParserBuffer> buffer = buffers[kVideoTrackNum][0];
  VerifyEncryptedBuffer(buffer);
}

TEST_F(WebMClusterParserTest, ParseBadEncryptedBlock) {
  scoped_ptr<Cluster> cluster(
      CreateEncryptedCluster(sizeof(kEncryptedFrame) - 1));

  parser_.reset(CreateParserWithKeyIdsAndAudioCodec(
      std::string(), "video_key_id", kUnknownAudioCodec));
  int result = parser_->Parse(cluster->data(), cluster->size());
  EXPECT_EQ(-1, result);
}

TEST_F(WebMClusterParserTest, ParseInvalidZeroSizedCluster) {
  const uint8_t kBuffer[] = {
      0x1F, 0x43, 0xB6, 0x75, 0x80,  // CLUSTER (size = 0)
  };

  EXPECT_EQ(-1, parser_->Parse(kBuffer, sizeof(kBuffer)));
}

TEST_F(WebMClusterParserTest, ParseInvalidUnknownButActuallyZeroSizedCluster) {
  const uint8_t kBuffer[] = {
      0x1F, 0x43, 0xB6, 0x75, 0xFF,  // CLUSTER (size = "unknown")
      0x1F, 0x43, 0xB6, 0x75, 0x85,  // CLUSTER (size = 5)
  };

  EXPECT_EQ(-1, parser_->Parse(kBuffer, sizeof(kBuffer)));
}

TEST_F(WebMClusterParserTest, ParseInvalidTextBlockGroupWithoutDuration) {
  // Text track frames must have explicitly specified BlockGroup BlockDurations.
  TextTracks text_tracks;

  text_tracks.insert(
      std::make_pair(TextTracks::key_type(kTextTrackNum),
                     TextTrackConfig(kTextSubtitles, "", "", "")));

  parser_.reset(CreateParserWithDefaultDurationsAndOptionalTextTracks(
      kNoTimestamp, kNoTimestamp, text_tracks));

  const BlockInfo kBlockInfo[] = {
      {kTextTrackNum, 33, -42, false, NULL, 0, false},
  };
  int block_count = arraysize(kBlockInfo);
  scoped_ptr<Cluster> cluster(CreateCluster(0, kBlockInfo, block_count));
  int result = parser_->Parse(cluster->data(), cluster->size());
  EXPECT_LT(result, 0);
}

TEST_F(WebMClusterParserTest, ParseWithDefaultDurationsSimpleBlocks) {
  InSequence s;
  ResetParserToHaveDefaultDurations();

  EXPECT_LT(kTestAudioFrameDefaultDurationInMs, 23);
  EXPECT_LT(kTestVideoFrameDefaultDurationInMs, 33);

  const BlockInfo kBlockInfo[] = {
      {kAudioTrackNum, 0, kTestAudioFrameDefaultDurationInMs, true, NULL, 0,
       false},
      {kAudioTrackNum, 23, kTestAudioFrameDefaultDurationInMs, true, NULL, 0,
       false},
      {kVideoTrackNum, 33, kTestVideoFrameDefaultDurationInMs, true, NULL, 0,
       false},
      {kAudioTrackNum, 46, kTestAudioFrameDefaultDurationInMs, true, NULL, 0,
       false},
      {kVideoTrackNum, 67, kTestVideoFrameDefaultDurationInMs, true, NULL, 0,
       false},
      {kAudioTrackNum, 69, kTestAudioFrameDefaultDurationInMs, true, NULL, 0,
       false},
      {kVideoTrackNum, 100, kTestVideoFrameDefaultDurationInMs, true, NULL, 0,
       false},
  };

  int block_count = arraysize(kBlockInfo);
  scoped_ptr<Cluster> cluster(CreateCluster(0, kBlockInfo, block_count));

  // Send slightly less than the full cluster so all but the last block is
  // parsed. Though all the blocks are simple blocks, none should be held aside
  // for duration estimation prior to end of cluster detection because all the
  // tracks have DefaultDurations.
  int result = parser_->Parse(cluster->data(), cluster->size() - 1);
  EXPECT_GT(result, 0);
  EXPECT_LT(result, cluster->size());
  ASSERT_TRUE(VerifyBuffers(parser_, kBlockInfo, block_count - 1));

  parser_->Reset();

  // Now parse a whole cluster to verify that all the blocks will get parsed.
  result = parser_->Parse(cluster->data(), cluster->size());
  EXPECT_EQ(cluster->size(), result);
  ASSERT_TRUE(VerifyBuffers(parser_, kBlockInfo, block_count));
}

TEST_F(WebMClusterParserTest, ParseWithoutAnyDurationsSimpleBlocks) {
  InSequence s;

  // Absent DefaultDuration information, SimpleBlock durations are derived from
  // inter-buffer track timestamp delta if within the cluster. Duration for the
  // last block in a cluster is estimated independently for each track in the
  // cluster. For video tracks we use the maximum seen so far. For audio we use
  // the the minimum.
  // TODO(chcunningham): Move audio over to use the maximum.

  const int kExpectedAudioEstimationInMs = 22;
  const int kExpectedVideoEstimationInMs = 34;
  const BlockInfo kBlockInfo1[] = {
      {kAudioTrackNum, 0, 23, true, NULL, 0, false},
      {kAudioTrackNum, 23, 22, true, NULL, 0, false},
      {kVideoTrackNum, 33, 33, true, NULL, 0, false},
      {kAudioTrackNum, 45, 23, true, NULL, 0, false},
      {kVideoTrackNum, 66, 34, true, NULL, 0, false},
      {kAudioTrackNum, 68, kExpectedAudioEstimationInMs, true, NULL, 0, false},
      {kVideoTrackNum, 100, kExpectedVideoEstimationInMs, true, NULL, 0, false},
  };

  int block_count1 = arraysize(kBlockInfo1);
  scoped_ptr<Cluster> cluster1(CreateCluster(0, kBlockInfo1, block_count1));

  // Send slightly less than the first full cluster so all but the last video
  // block is parsed. Verify the last fully parsed audio and video buffer are
  // both missing from the result (parser should hold them aside for duration
  // estimation prior to end of cluster detection in the absence of
  // DefaultDurations.)
  int result = parser_->Parse(cluster1->data(), cluster1->size() - 1);
  EXPECT_GT(result, 0);
  EXPECT_LT(result, cluster1->size());
  ASSERT_TRUE(VerifyBuffers(parser_, kBlockInfo1, block_count1 - 3));
  StreamParser::BufferQueueMap buffers;
  parser_->GetBuffers(&buffers);
  EXPECT_EQ(3UL, buffers[kAudioTrackNum].size());
  EXPECT_EQ(1UL, buffers[kVideoTrackNum].size());

  parser_->Reset();

  // Now parse the full first cluster and verify all the blocks are parsed.
  EXPECT_MEDIA_LOG(
      WebMSimpleBlockDurationEstimated(kExpectedAudioEstimationInMs));
  EXPECT_MEDIA_LOG(
      WebMSimpleBlockDurationEstimated(kExpectedVideoEstimationInMs));
  result = parser_->Parse(cluster1->data(), cluster1->size());
  EXPECT_EQ(cluster1->size(), result);
  ASSERT_TRUE(VerifyBuffers(parser_, kBlockInfo1, block_count1));

  // Verify that the estimated frame duration is tracked across clusters for
  // each track.
  const BlockInfo kBlockInfo2[] = {
      // Estimate carries over across clusters
      {kAudioTrackNum, 200, kExpectedAudioEstimationInMs, true, NULL, 0, false},
      // Estimate carries over across clusters
      {kVideoTrackNum, 201, kExpectedVideoEstimationInMs, true, NULL, 0, false},
  };

  int block_count2 = arraysize(kBlockInfo2);
  scoped_ptr<Cluster> cluster2(CreateCluster(0, kBlockInfo2, block_count2));
  EXPECT_MEDIA_LOG(
      WebMSimpleBlockDurationEstimated(kExpectedAudioEstimationInMs));
  EXPECT_MEDIA_LOG(
      WebMSimpleBlockDurationEstimated(kExpectedVideoEstimationInMs));
  result = parser_->Parse(cluster2->data(), cluster2->size());
  EXPECT_EQ(cluster2->size(), result);
  ASSERT_TRUE(VerifyBuffers(parser_, kBlockInfo2, block_count2));
}

TEST_F(WebMClusterParserTest, ParseWithoutAnyDurationsBlockGroups) {
  InSequence s;

  // Absent DefaultDuration and BlockDuration information, BlockGroup block
  // durations are derived from inter-buffer track timestamp delta if within the
  // cluster. Duration for the last block in a cluster is estimated
  // independently for each track in the cluster. For video tracks we use the
  // maximum seen so far. For audio we use the the minimum.
  // TODO(chcunningham): Move audio over to use the maximum.

  const int kExpectedAudioEstimationInMs = 22;
  const int kExpectedVideoEstimationInMs = 34;
  const BlockInfo kBlockInfo1[] = {
      {kAudioTrackNum, 0, -23, false, NULL, 0, false},
      {kAudioTrackNum, 23, -22, false, NULL, 0, false},
      {kVideoTrackNum, 33, -33, false, NULL, 0, false},
      {kAudioTrackNum, 45, -23, false, NULL, 0, false},
      {kVideoTrackNum, 66, -34, false, NULL, 0, false},
      {kAudioTrackNum, 68, -kExpectedAudioEstimationInMs, false, NULL, 0,
       false},
      {kVideoTrackNum, 100, -kExpectedVideoEstimationInMs, false, NULL, 0,
       false},
  };

  int block_count1 = arraysize(kBlockInfo1);
  scoped_ptr<Cluster> cluster1(CreateCluster(0, kBlockInfo1, block_count1));

  // Send slightly less than the first full cluster so all but the last video
  // block is parsed. Verify the last fully parsed audio and video buffer are
  // both missing from the result (parser should hold them aside for duration
  // estimation prior to end of cluster detection in the absence of
  // DefaultDurations.)
  int result = parser_->Parse(cluster1->data(), cluster1->size() - 1);
  EXPECT_GT(result, 0);
  EXPECT_LT(result, cluster1->size());
  ASSERT_TRUE(VerifyBuffers(parser_, kBlockInfo1, block_count1 - 3));
  StreamParser::BufferQueueMap buffers;
  parser_->GetBuffers(&buffers);
  EXPECT_EQ(3UL, buffers[kAudioTrackNum].size());
  EXPECT_EQ(1UL, buffers[kVideoTrackNum].size());

  parser_->Reset();

  // Now parse the full first cluster and verify all the blocks are parsed.
  EXPECT_MEDIA_LOG(
      WebMSimpleBlockDurationEstimated(kExpectedAudioEstimationInMs));
  EXPECT_MEDIA_LOG(
      WebMSimpleBlockDurationEstimated(kExpectedVideoEstimationInMs));
  result = parser_->Parse(cluster1->data(), cluster1->size());
  EXPECT_EQ(cluster1->size(), result);
  ASSERT_TRUE(VerifyBuffers(parser_, kBlockInfo1, block_count1));

  // Verify that the estimated frame duration is tracked across clusters for
  // each track.
  const BlockInfo kBlockInfo2[] = {
      {kAudioTrackNum, 200, -kExpectedAudioEstimationInMs, false, NULL, 0,
       false},
      {kVideoTrackNum, 201, -kExpectedVideoEstimationInMs, false, NULL, 0,
       false},
  };

  int block_count2 = arraysize(kBlockInfo2);
  scoped_ptr<Cluster> cluster2(CreateCluster(0, kBlockInfo2, block_count2));
  EXPECT_MEDIA_LOG(
      WebMSimpleBlockDurationEstimated(kExpectedAudioEstimationInMs));
  EXPECT_MEDIA_LOG(
      WebMSimpleBlockDurationEstimated(kExpectedVideoEstimationInMs));
  result = parser_->Parse(cluster2->data(), cluster2->size());
  EXPECT_EQ(cluster2->size(), result);
  ASSERT_TRUE(VerifyBuffers(parser_, kBlockInfo2, block_count2));
}

// TODO(wolenetz): Is parser behavior correct? See http://crbug.com/363433.
TEST_F(WebMClusterParserTest,
       ParseWithDefaultDurationsBlockGroupsWithoutDurations) {
  InSequence s;
  ResetParserToHaveDefaultDurations();

  EXPECT_LT(kTestAudioFrameDefaultDurationInMs, 23);
  EXPECT_LT(kTestVideoFrameDefaultDurationInMs, 33);

  const BlockInfo kBlockInfo[] = {
      {kAudioTrackNum, 0, -kTestAudioFrameDefaultDurationInMs, false, NULL, 0,
       false},
      {kAudioTrackNum, 23, -kTestAudioFrameDefaultDurationInMs, false, NULL, 0,
       false},
      {kVideoTrackNum, 33, -kTestVideoFrameDefaultDurationInMs, false, NULL, 0,
       false},
      {kAudioTrackNum, 46, -kTestAudioFrameDefaultDurationInMs, false, NULL, 0,
       false},
      {kVideoTrackNum, 67, -kTestVideoFrameDefaultDurationInMs, false, NULL, 0,
       false},
      {kAudioTrackNum, 69, -kTestAudioFrameDefaultDurationInMs, false, NULL, 0,
       false},
      {kVideoTrackNum, 100, -kTestVideoFrameDefaultDurationInMs, false, NULL, 0,
       false},
  };

  int block_count = arraysize(kBlockInfo);
  scoped_ptr<Cluster> cluster(CreateCluster(0, kBlockInfo, block_count));

  // Send slightly less than the full cluster so all but the last block is
  // parsed. None should be held aside for duration estimation prior to end of
  // cluster detection because all the tracks have DefaultDurations.
  int result = parser_->Parse(cluster->data(), cluster->size() - 1);
  EXPECT_GT(result, 0);
  EXPECT_LT(result, cluster->size());
  ASSERT_TRUE(VerifyBuffers(parser_, kBlockInfo, block_count - 1));

  parser_->Reset();

  // Now parse a whole cluster to verify that all the blocks will get parsed.
  result = parser_->Parse(cluster->data(), cluster->size());
  EXPECT_EQ(cluster->size(), result);
  ASSERT_TRUE(VerifyBuffers(parser_, kBlockInfo, block_count));
}

TEST_F(WebMClusterParserTest,
       ParseDegenerateClusterYieldsHardcodedEstimatedDurations) {
  const BlockInfo kBlockInfo[] = {
      {kAudioTrackNum, 0, WebMClusterParser::kDefaultAudioBufferDurationInMs,
       true},
      {kVideoTrackNum, 0, WebMClusterParser::kDefaultVideoBufferDurationInMs,
       true},
  };

  int block_count = arraysize(kBlockInfo);
  scoped_ptr<Cluster> cluster(CreateCluster(0, kBlockInfo, block_count));
  EXPECT_MEDIA_LOG(WebMSimpleBlockDurationEstimated(
      WebMClusterParser::kDefaultAudioBufferDurationInMs));
  EXPECT_MEDIA_LOG(WebMSimpleBlockDurationEstimated(
      WebMClusterParser::kDefaultVideoBufferDurationInMs));
  int result = parser_->Parse(cluster->data(), cluster->size());
  EXPECT_EQ(cluster->size(), result);
  ASSERT_TRUE(VerifyBuffers(parser_, kBlockInfo, block_count));
}

TEST_F(WebMClusterParserTest,
       ParseDegenerateClusterWithDefaultDurationsYieldsDefaultDurations) {
  ResetParserToHaveDefaultDurations();

  const BlockInfo kBlockInfo[] = {
      {kAudioTrackNum, 0, kTestAudioFrameDefaultDurationInMs, true},
      {kVideoTrackNum, 0, kTestVideoFrameDefaultDurationInMs, true},
  };

  int block_count = arraysize(kBlockInfo);
  scoped_ptr<Cluster> cluster(CreateCluster(0, kBlockInfo, block_count));
  int result = parser_->Parse(cluster->data(), cluster->size());
  EXPECT_EQ(cluster->size(), result);
  ASSERT_TRUE(VerifyBuffers(parser_, kBlockInfo, block_count));
}

TEST_F(WebMClusterParserTest, ReadOpusDurationsSimpleBlockAtEndOfCluster) {
  int loop_count = 0;
  for (const auto* packet_ptr : BuildAllOpusPackets()) {
    InSequence s;

    // Get a new parser each iteration to prevent exceeding the media log cap.
    parser_.reset(CreateParserWithKeyIdsAndAudioCodec(
        std::string(), std::string(), kCodecOpus));

    const BlockInfo kBlockInfo[] = {{kAudioTrackNum, 0,
                                     packet_ptr->duration_ms(),
                                     true,  // Make it a SimpleBlock.
                                     packet_ptr->data(), packet_ptr->size()}};

    int block_count = arraysize(kBlockInfo);
    scoped_ptr<Cluster> cluster(CreateCluster(0, kBlockInfo, block_count));
    int duration_ms = packet_ptr->duration_ms();  // Casts from double.
    if (duration_ms > 120) {
      EXPECT_MEDIA_LOG(OpusPacketDurationTooHigh(duration_ms));
    }

    int result = parser_->Parse(cluster->data(), cluster->size());
    EXPECT_EQ(cluster->size(), result);
    ASSERT_TRUE(VerifyBuffers(parser_, kBlockInfo, block_count));

    // Fail early if any iteration fails to meet the logging expectations.
    ASSERT_TRUE(Mock::VerifyAndClearExpectations(media_log_.get()));

    loop_count++;
  }

  // Test should minimally cover all the combinations of config and frame count.
  ASSERT_GE(loop_count, kNumPossibleOpusConfigs * kMaxOpusPacketFrameCount);
}

TEST_F(WebMClusterParserTest, PreferOpusDurationsOverBlockDurations) {
  int loop_count = 0;
  for (const auto* packet_ptr : BuildAllOpusPackets()) {
    InSequence s;

    // Get a new parser each iteration to prevent exceeding the media log cap.
    parser_.reset(CreateParserWithKeyIdsAndAudioCodec(
        std::string(), std::string(), kCodecOpus));

    // Setting BlockDuration != Opus duration to see which one the parser uses.
    int block_duration_ms = packet_ptr->duration_ms() + 10;
    if (packet_ptr->duration_ms() > 120) {
      EXPECT_MEDIA_LOG(OpusPacketDurationTooHigh(packet_ptr->duration_ms()));
    }

    EXPECT_MEDIA_LOG(WebMBlockDurationMismatchesOpusDuration(
        block_duration_ms, packet_ptr->duration_ms()));

    BlockInfo block_infos[] = {{kAudioTrackNum, 0, block_duration_ms,
                                false,  // Not a SimpleBlock.
                                packet_ptr->data(), packet_ptr->size()}};

    int block_count = arraysize(block_infos);
    scoped_ptr<Cluster> cluster(CreateCluster(0, block_infos, block_count));
    int result = parser_->Parse(cluster->data(), cluster->size());
    EXPECT_EQ(cluster->size(), result);

    // BlockInfo duration will be used to verify buffer duration, so changing
    // duration to be that of the Opus packet to verify it was preferred.
    block_infos[0].duration = packet_ptr->duration_ms();

    ASSERT_TRUE(VerifyBuffers(parser_, block_infos, block_count));

    // Fail early if any iteration fails to meet the logging expectations.
    ASSERT_TRUE(Mock::VerifyAndClearExpectations(media_log_.get()));

    loop_count++;
  }

  // Test should minimally cover all the combinations of config and frame count.
  ASSERT_GE(loop_count, kNumPossibleOpusConfigs * kMaxOpusPacketFrameCount);
}

// Tests that BlockDuration is used to set duration on buffer rather than
// encoded duration in Opus packet (or hard coded duration estimates). Encoded
// Opus duration is usually preferred but cannot be known when encrypted.
TEST_F(WebMClusterParserTest, DontReadEncodedDurationWhenEncrypted) {
  // Non-empty dummy value signals encryption is active for audio.
  std::string audio_encryption_id("audio_key_id");

  // Reset parser to expect Opus codec audio and use audio encryption key id.
  parser_.reset(CreateParserWithKeyIdsAndAudioCodec(audio_encryption_id,
                                                    std::string(), kCodecOpus));

  // Single Block with BlockDuration and encrypted data.
  const BlockInfo kBlockInfo[] = {{kAudioTrackNum, 0,
                                   kTestAudioFrameDefaultDurationInMs,
                                   false,            // Not a SimpleBlock
                                   kEncryptedFrame,  // Encrypted frame data
                                   arraysize(kEncryptedFrame)}};

  int block_count = arraysize(kBlockInfo);
  scoped_ptr<Cluster> cluster(CreateCluster(0, kBlockInfo, block_count));
  int result = parser_->Parse(cluster->data(), cluster->size());
  EXPECT_EQ(cluster->size(), result);

  // Will verify that duration of buffer matches that of BlockDuration.
  ASSERT_TRUE(VerifyBuffers(parser_, kBlockInfo, block_count));
}

}  // namespace media
}  // namespace cobalt
