diff --git a/media/webm/cluster_builder.cc b/media/webm/cluster_builder.cc deleted file mode 100644 index e320cbb665..0000000000 --- a/media/webm/cluster_builder.cc +++ /dev/null @@ -1,175 +0,0 @@ -// Copyright (c) 2012 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 "media/webm/cluster_builder.h" - -#include "base/logging.h" -#include "media/base/data_buffer.h" - -namespace media { - -static const uint8 kClusterHeader[] = { - 0x1F, 0x43, 0xB6, 0x75, // CLUSTER ID - 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // cluster(size = 0) - 0xE7, // Timecode ID - 0x88, // timecode(size=8) - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // timecode value -}; - -static const uint8 kSimpleBlockHeader[] = { - 0xA3, // SimpleBlock ID - 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // SimpleBlock(size = 0) -}; - -static const uint8 kBlockGroupHeader[] = { - 0xA0, // BlockGroup ID - 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // BlockGroup(size = 0) - 0x9B, // BlockDuration ID - 0x88, // BlockDuration(size = 8) - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // duration - 0xA1, // Block ID - 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Block(size = 0) -}; - -enum { - kClusterSizeOffset = 4, - kClusterTimecodeOffset = 14, - - kSimpleBlockSizeOffset = 1, - - kBlockGroupSizeOffset = 1, - kBlockGroupDurationOffset = 11, - kBlockGroupBlockSizeOffset = 20, - - kInitialBufferSize = 32768, -}; - -Cluster::Cluster(scoped_ptr data, int size) - : data_(data.Pass()), size_(size) {} -Cluster::~Cluster() {} - -ClusterBuilder::ClusterBuilder() { Reset(); } -ClusterBuilder::~ClusterBuilder() {} - -void ClusterBuilder::SetClusterTimecode(int64 cluster_timecode) { - DCHECK_EQ(cluster_timecode_, -1); - - cluster_timecode_ = cluster_timecode; - - // Write the timecode into the header. - uint8* buf = buffer_.get() + kClusterTimecodeOffset; - for (int i = 7; i >= 0; --i) { - buf[i] = cluster_timecode & 0xff; - cluster_timecode >>= 8; - } -} - -void ClusterBuilder::AddSimpleBlock(int track_num, int64 timecode, int flags, - const uint8* data, int size) { - int block_size = size + 4; - int bytes_needed = sizeof(kSimpleBlockHeader) + block_size; - if (bytes_needed > (buffer_size_ - bytes_used_)) - ExtendBuffer(bytes_needed); - - uint8* buf = buffer_.get() + bytes_used_; - int block_offset = bytes_used_; - memcpy(buf, kSimpleBlockHeader, sizeof(kSimpleBlockHeader)); - UpdateUInt64(block_offset + kSimpleBlockSizeOffset, block_size); - buf += sizeof(kSimpleBlockHeader); - - WriteBlock(buf, track_num, timecode, flags, data, size); - - bytes_used_ += bytes_needed; -} - -void ClusterBuilder::AddBlockGroup(int track_num, int64 timecode, int duration, - int flags, const uint8* data, int size) { - int block_size = size + 4; - int bytes_needed = sizeof(kBlockGroupHeader) + block_size; - int block_group_size = bytes_needed - 9; - - if (bytes_needed > (buffer_size_ - bytes_used_)) - ExtendBuffer(bytes_needed); - - uint8* buf = buffer_.get() + bytes_used_; - int block_group_offset = bytes_used_; - memcpy(buf, kBlockGroupHeader, sizeof(kBlockGroupHeader)); - UpdateUInt64(block_group_offset + kBlockGroupSizeOffset, block_group_size); - UpdateUInt64(block_group_offset + kBlockGroupDurationOffset, duration); - UpdateUInt64(block_group_offset + kBlockGroupBlockSizeOffset, block_size); - buf += sizeof(kBlockGroupHeader); - - // Make sure the 4 most-significant bits are 0. - // http://www.matroska.org/technical/specs/index.html#block_structure - flags &= 0x0f; - - WriteBlock(buf, track_num, timecode, flags, data, size); - - bytes_used_ += bytes_needed; -} - -void ClusterBuilder::WriteBlock(uint8* buf, int track_num, int64 timecode, - int flags, const uint8* data, int size) { - DCHECK_GE(track_num, 0); - DCHECK_LE(track_num, 126); - DCHECK_GE(flags, 0); - DCHECK_LE(flags, 0xff); - DCHECK(data); - DCHECK_GT(size, 0); - DCHECK_NE(cluster_timecode_, -1); - - int64 timecode_delta = timecode - cluster_timecode_; - DCHECK_GE(timecode_delta, -32768); - DCHECK_LE(timecode_delta, 32767); - - buf[0] = 0x80 | (track_num & 0x7F); - buf[1] = (timecode_delta >> 8) & 0xff; - buf[2] = timecode_delta & 0xff; - buf[3] = flags & 0xff; - memcpy(buf + 4, data, size); -} - -scoped_ptr ClusterBuilder::Finish() { - DCHECK_NE(cluster_timecode_, -1); - - UpdateUInt64(kClusterSizeOffset, bytes_used_ - (kClusterSizeOffset + 8)); - - scoped_ptr ret(new Cluster(buffer_.Pass(), bytes_used_)); - Reset(); - return ret.Pass(); -} - -void ClusterBuilder::Reset() { - buffer_size_ = kInitialBufferSize; - buffer_.reset(new uint8[buffer_size_]); - memcpy(buffer_.get(), kClusterHeader, sizeof(kClusterHeader)); - bytes_used_ = sizeof(kClusterHeader); - cluster_timecode_ = -1; -} - -void ClusterBuilder::ExtendBuffer(int bytes_needed) { - int new_buffer_size = 2 * buffer_size_; - - while ((new_buffer_size - bytes_used_) < bytes_needed) - new_buffer_size *= 2; - - scoped_ptr new_buffer(new uint8[new_buffer_size]); - - memcpy(new_buffer.get(), buffer_.get(), bytes_used_); - buffer_.reset(new_buffer.release()); - buffer_size_ = new_buffer_size; -} - -void ClusterBuilder::UpdateUInt64(int offset, int64 value) { - DCHECK_LE(offset + 7, buffer_size_); - uint8* buf = buffer_.get() + offset; - - // Fill the last 7 bytes of size field in big-endian order. - for (int i = 7; i > 0; i--) { - buf[i] = value & 0xff; - value >>= 8; - } -} - -} // namespace media diff --git a/media/webm/cluster_builder.h b/media/webm/cluster_builder.h deleted file mode 100644 index 3482cfbb90..0000000000 --- a/media/webm/cluster_builder.h +++ /dev/null @@ -1,59 +0,0 @@ -// Copyright (c) 2012 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. - -#ifndef MEDIA_WEBM_CLUSTER_BUILDER_H_ -#define MEDIA_WEBM_CLUSTER_BUILDER_H_ - -#include "base/basictypes.h" -#include "base/memory/scoped_ptr.h" -#include "media/base/buffers.h" - -namespace media { - -class Cluster { - public: - Cluster(scoped_ptr data, int size); - ~Cluster(); - - const uint8* data() const { return data_.get(); } - int size() const { return size_; } - - private: - scoped_ptr data_; - int size_; - - DISALLOW_IMPLICIT_CONSTRUCTORS(Cluster); -}; - -class ClusterBuilder { - public: - ClusterBuilder(); - ~ClusterBuilder(); - - void SetClusterTimecode(int64 cluster_timecode); - void AddSimpleBlock(int track_num, int64 timecode, int flags, - const uint8* data, int size); - void AddBlockGroup(int track_num, int64 timecode, int duration, int flags, - const uint8* data, int size); - - scoped_ptr Finish(); - - private: - void Reset(); - void ExtendBuffer(int bytes_needed); - void UpdateUInt64(int offset, int64 value); - void WriteBlock(uint8* buf, int track_num, int64 timecode, int flags, - const uint8* data, int size); - - scoped_ptr buffer_; - int buffer_size_; - int bytes_used_; - int64 cluster_timecode_; - - DISALLOW_COPY_AND_ASSIGN(ClusterBuilder); -}; - -} // namespace media - -#endif // MEDIA_WEBM_CLUSTER_BUILDER_H_ diff --git a/media/webm/tracks_builder.cc b/media/webm/tracks_builder.cc deleted file mode 100644 index 370ca82a18..0000000000 --- a/media/webm/tracks_builder.cc +++ /dev/null @@ -1,211 +0,0 @@ -// Copyright (c) 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 "media/webm/tracks_builder.h" - -#include "media/webm/webm_constants.h" - -namespace media { - -// Returns size of an integer, formatted using Matroska serialization. -static int GetUIntMkvSize(uint64 value) { - if (value < 0x07FULL) - return 1; - if (value < 0x03FFFULL) - return 2; - if (value < 0x01FFFFFULL) - return 3; - if (value < 0x0FFFFFFFULL) - return 4; - if (value < 0x07FFFFFFFFULL) - return 5; - if (value < 0x03FFFFFFFFFFULL) - return 6; - if (value < 0x01FFFFFFFFFFFFULL) - return 7; - return 8; -} - -// Returns the minimium size required to serialize an integer value. -static int GetUIntSize(uint64 value) { - if (value < 0x0100ULL) - return 1; - if (value < 0x010000ULL) - return 2; - if (value < 0x01000000ULL) - return 3; - if (value < 0x0100000000ULL) - return 4; - if (value < 0x010000000000ULL) - return 5; - if (value < 0x01000000000000ULL) - return 6; - if (value < 0x0100000000000000ULL) - return 7; - return 8; -} - -static int MasterElementSize(int element_id, int payload_size) { - return GetUIntSize(element_id) + GetUIntMkvSize(payload_size) + payload_size; -} - -static int IntElementSize(int element_id, int value) { - return GetUIntSize(element_id) + 1 + GetUIntSize(value); -} - -static int StringElementSize(int element_id, const std::string& value) { - return GetUIntSize(element_id) + - GetUIntMkvSize(value.length()) + - value.length(); -} - -static void SerializeInt(uint8** buf_ptr, int* buf_size_ptr, - int64 value, int size) { - uint8*& buf = *buf_ptr; - int& buf_size = *buf_size_ptr; - - for (int idx = 1; idx <= size; ++idx) { - *buf++ = static_cast(value >> ((size - idx) * 8)); - --buf_size; - } -} - -static void WriteElementId(uint8** buf, int* buf_size, int element_id) { - SerializeInt(buf, buf_size, element_id, GetUIntSize(element_id)); -} - -static void WriteUInt(uint8** buf, int* buf_size, uint64 value) { - const int size = GetUIntMkvSize(value); - value |= (1ULL << (size * 7)); // Matroska formatting - SerializeInt(buf, buf_size, value, size); -} - -static void WriteMasterElement(uint8** buf, int* buf_size, - int element_id, int payload_size) { - WriteElementId(buf, buf_size, element_id); - WriteUInt(buf, buf_size, payload_size); -} - -static void WriteIntElement(uint8** buf, int* buf_size, - int element_id, int value) { - WriteElementId(buf, buf_size, element_id); - - const int size = GetUIntSize(value); - WriteUInt(buf, buf_size, size); - - SerializeInt(buf, buf_size, value, size); -} - -static void WriteStringElement(uint8** buf_ptr, int* buf_size_ptr, - int element_id, const std::string& value) { - uint8*& buf = *buf_ptr; - int& buf_size = *buf_size_ptr; - - WriteElementId(&buf, &buf_size, element_id); - - const uint64 size = value.length(); - WriteUInt(&buf, &buf_size, size); - - memcpy(buf, value.data(), size); - buf += size; - buf_size -= size; -} - -TracksBuilder::TracksBuilder() {} -TracksBuilder::~TracksBuilder() {} - -void TracksBuilder::AddTrack( - int track_num, - int track_type, - const std::string& codec_id, - const std::string& name, - const std::string& language) { - tracks_.push_back(Track(track_num, track_type, codec_id, name, language)); -} - -std::vector TracksBuilder::Finish() { - // Allocate the storage - std::vector buffer; - buffer.resize(GetTracksSize()); - - // Populate the storage with a tracks header - WriteTracks(&buffer[0], buffer.size()); - - return buffer; -} - -int TracksBuilder::GetTracksSize() const { - return MasterElementSize(kWebMIdTracks, GetTracksPayloadSize()); -} - -int TracksBuilder::GetTracksPayloadSize() const { - int payload_size = 0; - - for (TrackList::const_iterator itr = tracks_.begin(); - itr != tracks_.end(); ++itr) { - payload_size += itr->GetSize(); - } - - return payload_size; -} - -void TracksBuilder::WriteTracks(uint8* buf, int buf_size) const { - WriteMasterElement(&buf, &buf_size, kWebMIdTracks, GetTracksPayloadSize()); - - for (TrackList::const_iterator itr = tracks_.begin(); - itr != tracks_.end(); ++itr) { - itr->Write(&buf, &buf_size); - } -} - -TracksBuilder::Track::Track(int track_num, int track_type, - const std::string& codec_id, - const std::string& name, - const std::string& language) - : track_num_(track_num), - track_type_(track_type), - codec_id_(codec_id), - name_(name), - language_(language) { -} - -int TracksBuilder::Track::GetSize() const { - return MasterElementSize(kWebMIdTrackEntry, GetPayloadSize()); -} - -int TracksBuilder::Track::GetPayloadSize() const { - int size = 0; - - size += IntElementSize(kWebMIdTrackNumber, track_num_); - size += IntElementSize(kWebMIdTrackType, track_type_); - - if (!codec_id_.empty()) - size += StringElementSize(kWebMIdCodecID, codec_id_); - - if (!name_.empty()) - size += StringElementSize(kWebMIdName, name_); - - if (!language_.empty()) - size += StringElementSize(kWebMIdLanguage, language_); - - return size; -} - -void TracksBuilder::Track::Write(uint8** buf, int* buf_size) const { - WriteMasterElement(buf, buf_size, kWebMIdTrackEntry, GetPayloadSize()); - - WriteIntElement(buf, buf_size, kWebMIdTrackNumber, track_num_); - WriteIntElement(buf, buf_size, kWebMIdTrackType, track_type_); - - if (!codec_id_.empty()) - WriteStringElement(buf, buf_size, kWebMIdCodecID, codec_id_); - - if (!name_.empty()) - WriteStringElement(buf, buf_size, kWebMIdName, name_); - - if (!language_.empty()) - WriteStringElement(buf, buf_size, kWebMIdLanguage, language_); -} - -} // namespace media diff --git a/media/webm/tracks_builder.h b/media/webm/tracks_builder.h deleted file mode 100644 index 87ceaed3ad..0000000000 --- a/media/webm/tracks_builder.h +++ /dev/null @@ -1,56 +0,0 @@ -// Copyright (c) 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. - -#ifndef MEDIA_WEBM_TRACKS_BUILDER_H_ -#define MEDIA_WEBM_TRACKS_BUILDER_H_ - -#include -#include -#include - -#include "base/basictypes.h" - -namespace media { - -class TracksBuilder { - public: - TracksBuilder(); - ~TracksBuilder(); - - void AddTrack(int track_num, int track_type, const std::string& codec_id, - const std::string& name, const std::string& language); - - std::vector Finish(); - - private: - int GetTracksSize() const; - int GetTracksPayloadSize() const; - void WriteTracks(uint8* buffer, int buffer_size) const; - - class Track { - public: - Track(int track_num, int track_type, const std::string& codec_id, - const std::string& name, const std::string& language); - - int GetSize() const; - void Write(uint8** buf, int* buf_size) const; - private: - int GetPayloadSize() const; - - int track_num_; - int track_type_; - std::string codec_id_; - std::string name_; - std::string language_; - }; - - typedef std::list TrackList; - TrackList tracks_; - - DISALLOW_COPY_AND_ASSIGN(TracksBuilder); -}; - -} // namespace media - -#endif // MEDIA_WEBM_TRACKS_BUILDER_H_ diff --git a/media/webm/webm_audio_client.cc b/media/webm/webm_audio_client.cc deleted file mode 100644 index e52f44b4a9..0000000000 --- a/media/webm/webm_audio_client.cc +++ /dev/null @@ -1,112 +0,0 @@ -// Copyright (c) 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 "media/webm/webm_audio_client.h" - -#include "media/base/audio_decoder_config.h" -#include "media/base/channel_layout.h" -#include "media/webm/webm_constants.h" - -namespace media { - -WebMAudioClient::WebMAudioClient(const LogCB& log_cb) - : log_cb_(log_cb) { - Reset(); -} - -WebMAudioClient::~WebMAudioClient() { -} - -void WebMAudioClient::Reset() { - channels_ = -1; - samples_per_second_ = -1; - output_samples_per_second_ = -1; -} - -bool WebMAudioClient::InitializeConfig( - const std::string& codec_id, const std::vector& codec_private, - bool is_encrypted, AudioDecoderConfig* config) { - DCHECK(config); - - AudioCodec audio_codec = kUnknownAudioCodec; - if (codec_id == "A_VORBIS") { - audio_codec = kCodecVorbis; - } else { - MEDIA_LOG(log_cb_) << "Unsupported audio codec_id " << codec_id; - return false; - } - - if (samples_per_second_ <= 0) - return false; - - // Set channel layout default if a Channels element was not present. - if (channels_ == -1) - channels_ = 1; - - ChannelLayout channel_layout = GuessChannelLayout(channels_); - - if (channel_layout == CHANNEL_LAYOUT_UNSUPPORTED) { - MEDIA_LOG(log_cb_) << "Unsupported channel count " << channels_; - return false; - } - - int samples_per_second = samples_per_second_; - if (output_samples_per_second_ > 0) - samples_per_second = output_samples_per_second_; - - const uint8* extra_data = NULL; - size_t extra_data_size = 0; - if (codec_private.size() > 0) { - extra_data = &codec_private[0]; - extra_data_size = codec_private.size(); - } - - config->Initialize( - audio_codec, kSampleFormatPlanarF32, channel_layout, - samples_per_second, extra_data, extra_data_size, is_encrypted, true); - return config->IsValidConfig(); -} - -bool WebMAudioClient::OnUInt(int id, int64 val) { - if (id == kWebMIdChannels) { - if (channels_ != -1) { - MEDIA_LOG(log_cb_) << "Multiple values for id " << std::hex << id - << " specified. (" << channels_ << " and " << val - << ")"; - return false; - } - - channels_ = val; - } - return true; -} - -bool WebMAudioClient::OnFloat(int id, double val) { - double* dst = NULL; - - switch (id) { - case kWebMIdSamplingFrequency: - dst = &samples_per_second_; - break; - case kWebMIdOutputSamplingFrequency: - dst = &output_samples_per_second_; - break; - default: - return true; - } - - if (val <= 0) - return false; - - if (*dst != -1) { - MEDIA_LOG(log_cb_) << "Multiple values for id " << std::hex << id - << " specified (" << *dst << " and " << val << ")"; - return false; - } - - *dst = val; - return true; -} - -} // namespace media diff --git a/media/webm/webm_audio_client.h b/media/webm/webm_audio_client.h deleted file mode 100644 index 1338f5cbd6..0000000000 --- a/media/webm/webm_audio_client.h +++ /dev/null @@ -1,52 +0,0 @@ -// Copyright (c) 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. - -#ifndef MEDIA_WEBM_WEBM_AUDIO_CLIENT_H_ -#define MEDIA_WEBM_WEBM_AUDIO_CLIENT_H_ - -#include -#include - -#include "media/base/media_log.h" -#include "media/webm/webm_parser.h" - -namespace media { -class AudioDecoderConfig; - -// Helper class used to parse an Audio element inside a TrackEntry element. -class WebMAudioClient : public WebMParserClient { - public: - explicit WebMAudioClient(const LogCB& log_cb); - virtual ~WebMAudioClient(); - - // Reset this object's state so it can process a new audio track element. - void Reset(); - - // Initialize |config| with the data in |codec_id|, |codec_private|, - // |is_encrypted| and the fields parsed from the last audio track element this - // object was used to parse. - // Returns true if |config| was successfully initialized. - // Returns false if there was unexpected values in the provided parameters or - // audio track element fields. - bool InitializeConfig(const std::string& codec_id, - const std::vector& codec_private, - bool is_encrypted, - AudioDecoderConfig* config); - - private: - // WebMParserClient implementation. - virtual bool OnUInt(int id, int64 val) OVERRIDE; - virtual bool OnFloat(int id, double val) OVERRIDE; - - LogCB log_cb_; - int channels_; - double samples_per_second_; - double output_samples_per_second_; - - DISALLOW_COPY_AND_ASSIGN(WebMAudioClient); -}; - -} // namespace media - -#endif // MEDIA_WEBM_WEBM_AUDIO_CLIENT_H_ diff --git a/media/webm/webm_cluster_parser.cc b/media/webm/webm_cluster_parser.cc deleted file mode 100644 index 9991d6b4d1..0000000000 --- a/media/webm/webm_cluster_parser.cc +++ /dev/null @@ -1,420 +0,0 @@ -// Copyright (c) 2012 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 "media/webm/webm_cluster_parser.h" - -#include - -#include "base/logging.h" -#include "base/sys_byteorder.h" -#include "media/base/buffers.h" -#include "media/base/decrypt_config.h" -#include "media/webm/webm_constants.h" -#include "media/webm/webm_crypto_helpers.h" - -namespace media { - -WebMClusterParser::TextTrackIterator::TextTrackIterator( - const TextTrackMap& text_track_map) : - iterator_(text_track_map.begin()), - iterator_end_(text_track_map.end()) { -} - -WebMClusterParser::TextTrackIterator::TextTrackIterator( - const TextTrackIterator& rhs) : - iterator_(rhs.iterator_), - iterator_end_(rhs.iterator_end_) { -} - -WebMClusterParser::TextTrackIterator::~TextTrackIterator() { -} - -bool WebMClusterParser::TextTrackIterator::operator()( - int* track_num, - const BufferQueue** buffers) { - if (iterator_ == iterator_end_) { - *track_num = 0; - *buffers = NULL; - - return false; - } - - *track_num = iterator_->first; - *buffers = &iterator_->second.buffers(); - - ++iterator_; - return true; -} - -WebMClusterParser::WebMClusterParser( - int64 timecode_scale, int audio_track_num, int video_track_num, - const WebMTracksParser::TextTracks& text_tracks, - const std::set& ignored_tracks, - const std::string& audio_encryption_key_id, - const std::string& video_encryption_key_id, - const LogCB& log_cb) - : timecode_multiplier_(timecode_scale / 1000.0), - ignored_tracks_(ignored_tracks), - audio_encryption_key_id_(audio_encryption_key_id), - video_encryption_key_id_(video_encryption_key_id), - parser_(kWebMIdCluster, this), - last_block_timecode_(-1), - block_data_size_(-1), - block_duration_(-1), - block_add_id_(-1), - block_additional_data_size_(-1), - cluster_timecode_(-1), - cluster_start_time_(kNoTimestamp()), - cluster_ended_(false), - audio_(audio_track_num, false), - video_(video_track_num, true), - log_cb_(log_cb) { - for (WebMTracksParser::TextTracks::const_iterator it = text_tracks.begin(); - it != text_tracks.end(); - ++it) { - text_track_map_.insert(std::make_pair(it->first, Track(it->first, false))); - } -} - -WebMClusterParser::~WebMClusterParser() {} - -void WebMClusterParser::Reset() { - last_block_timecode_ = -1; - cluster_timecode_ = -1; - cluster_start_time_ = kNoTimestamp(); - cluster_ended_ = false; - parser_.Reset(); - audio_.Reset(); - video_.Reset(); - ResetTextTracks(); -} - -int WebMClusterParser::Parse(const uint8* buf, int size) { - audio_.Reset(); - video_.Reset(); - ResetTextTracks(); - - int result = parser_.Parse(buf, size); - - if (result < 0) { - cluster_ended_ = false; - return result; - } - - cluster_ended_ = parser_.IsParsingComplete(); - if (cluster_ended_) { - // If there were no buffers in this cluster, set the cluster start time to - // be the |cluster_timecode_|. - if (cluster_start_time_ == kNoTimestamp()) { - DCHECK_GT(cluster_timecode_, -1); - cluster_start_time_ = base::TimeDelta::FromMicroseconds( - cluster_timecode_ * timecode_multiplier_); - } - - // Reset the parser if we're done parsing so that - // it is ready to accept another cluster on the next - // call. - parser_.Reset(); - - last_block_timecode_ = -1; - cluster_timecode_ = -1; - } - - return result; -} - -WebMClusterParser::TextTrackIterator -WebMClusterParser::CreateTextTrackIterator() const { - return TextTrackIterator(text_track_map_); -} - -WebMParserClient* WebMClusterParser::OnListStart(int id) { - if (id == kWebMIdCluster) { - cluster_timecode_ = -1; - cluster_start_time_ = kNoTimestamp(); - } else if (id == kWebMIdBlockGroup) { - block_data_.reset(); - block_data_size_ = -1; - block_duration_ = -1; - } else if (id == kWebMIdBlockAdditions) { - block_add_id_ = -1; - block_additional_data_.reset(); - block_additional_data_size_ = -1; - } - - return this; -} - -bool WebMClusterParser::OnListEnd(int id) { - if (id != kWebMIdBlockGroup) - return true; - - // Make sure the BlockGroup actually had a Block. - if (block_data_size_ == -1) { - MEDIA_LOG(log_cb_) << "Block missing from BlockGroup."; - return false; - } - - bool result = ParseBlock(false, block_data_.get(), block_data_size_, - block_additional_data_.get(), - block_additional_data_size_, block_duration_); - block_data_.reset(); - block_data_size_ = -1; - block_duration_ = -1; - block_add_id_ = -1; - block_additional_data_.reset(); - block_additional_data_size_ = -1; - return result; -} - -bool WebMClusterParser::OnUInt(int id, int64 val) { - int64* dst; - switch (id) { - case kWebMIdTimecode: - dst = &cluster_timecode_; - break; - case kWebMIdBlockDuration: - dst = &block_duration_; - break; - case kWebMIdBlockAddID: - dst = &block_add_id_; - break; - default: - return true; - } - if (*dst != -1) - return false; - *dst = val; - return true; -} - -bool WebMClusterParser::ParseBlock(bool is_simple_block, const uint8* buf, - int size, const uint8* additional, - int additional_size, int duration) { - if (size < 4) - return false; - - // Return an error if the trackNum > 127. We just aren't - // going to support large track numbers right now. - if (!(buf[0] & 0x80)) { - MEDIA_LOG(log_cb_) << "TrackNumber over 127 not supported"; - return false; - } - - int track_num = buf[0] & 0x7f; - int timecode = buf[1] << 8 | buf[2]; - int flags = buf[3] & 0xff; - int lacing = (flags >> 1) & 0x3; - - if (lacing) { - MEDIA_LOG(log_cb_) << "Lacing " << lacing << " is not supported yet."; - return false; - } - - // Sign extend negative timecode offsets. - if (timecode & 0x8000) - timecode |= ~0xffff; - - const uint8* frame_data = buf + 4; - int frame_size = size - (frame_data - buf); - return OnBlock(is_simple_block, track_num, timecode, duration, flags, - frame_data, frame_size, additional, additional_size); -} - -bool WebMClusterParser::OnBinary(int id, const uint8* data, int size) { - switch (id) { - case kWebMIdSimpleBlock: - return ParseBlock(true, data, size, NULL, -1, -1); - - case kWebMIdBlock: - if (block_data_) { - MEDIA_LOG(log_cb_) << "More than 1 Block in a BlockGroup is not " - "supported."; - return false; - } - block_data_.reset(new uint8[size]); - memcpy(block_data_.get(), data, size); - block_data_size_ = size; - return true; - - case kWebMIdBlockAdditional: { - uint64 block_add_id = base::HostToNet64(block_add_id_); - if (block_additional_data_) { - // TODO(vigneshv): Technically, more than 1 BlockAdditional is allowed - // as per matroska spec. But for now we don't have a use case to - // support parsing of such files. Take a look at this again when such a - // case arises. - MEDIA_LOG(log_cb_) << "More than 1 BlockAdditional in a BlockGroup is " - "not supported."; - return false; - } - // First 8 bytes of side_data in DecoderBuffer is the BlockAddID - // element's value in Big Endian format. This is done to mimic ffmpeg - // demuxer's behavior. - block_additional_data_size_ = size + sizeof(block_add_id); - block_additional_data_.reset(new uint8[block_additional_data_size_]); - memcpy(block_additional_data_.get(), &block_add_id, - sizeof(block_add_id)); - memcpy(block_additional_data_.get() + 8, data, size); - return true; - } - - default: - return true; - } -} - -bool WebMClusterParser::OnBlock(bool is_simple_block, int track_num, - int timecode, - int block_duration, - int flags, - const uint8* data, int size, - const uint8* additional, int additional_size) { - DCHECK_GE(size, 0); - if (cluster_timecode_ == -1) { - MEDIA_LOG(log_cb_) << "Got a block before cluster timecode."; - return false; - } - - // TODO(acolwell): Should relative negative timecode offsets be rejected? Or - // only when the absolute timecode is negative? See http://crbug.com/271794 - if (timecode < 0) { - MEDIA_LOG(log_cb_) << "Got a block with negative timecode offset " - << timecode; - return false; - } - - if (last_block_timecode_ != -1 && timecode < last_block_timecode_) { - MEDIA_LOG(log_cb_) - << "Got a block with a timecode before the previous block."; - return false; - } - - Track* track = NULL; - std::string encryption_key_id; - if (track_num == audio_.track_num()) { - track = &audio_; - encryption_key_id = audio_encryption_key_id_; - } else if (track_num == video_.track_num()) { - track = &video_; - encryption_key_id = video_encryption_key_id_; - } else if (ignored_tracks_.find(track_num) != ignored_tracks_.end()) { - return true; - } else if (Track* const text_track = FindTextTrack(track_num)) { - if (is_simple_block) // BlockGroup is required for WebVTT cues - return false; - if (block_duration < 0) // not specified - return false; - track = text_track; - } else { - MEDIA_LOG(log_cb_) << "Unexpected track number " << track_num; - return false; - } - - last_block_timecode_ = timecode; - - base::TimeDelta timestamp = base::TimeDelta::FromMicroseconds( - (cluster_timecode_ + timecode) * timecode_multiplier_); - - // The first bit of the flags is set when a SimpleBlock contains only - // keyframes. If this is a Block, then inspection of the payload is - // necessary to determine whether it contains a keyframe or not. - // http://www.matroska.org/technical/specs/index.html - bool is_keyframe = - is_simple_block ? (flags & 0x80) != 0 : track->IsKeyframe(data, size); - - scoped_refptr buffer = - StreamParserBuffer::CopyFrom(data, size, additional, additional_size, - is_keyframe); - - // Every encrypted Block has a signal byte and IV prepended to it. Current - // encrypted WebM request for comments specification is here - // http://wiki.webmproject.org/encryption/webm-encryption-rfc - if (!encryption_key_id.empty()) { - scoped_ptr config(WebMCreateDecryptConfig( - data, size, - reinterpret_cast(encryption_key_id.data()), - encryption_key_id.size())); - if (!config) - return false; - buffer->set_decrypt_config(config.Pass()); - } - - buffer->set_timestamp(timestamp); - if (cluster_start_time_ == kNoTimestamp()) - cluster_start_time_ = timestamp; - - if (block_duration >= 0) { - buffer->set_duration(base::TimeDelta::FromMicroseconds( - block_duration * timecode_multiplier_)); - } - - return track->AddBuffer(buffer); -} - -WebMClusterParser::Track::Track(int track_num, bool is_video) - : track_num_(track_num), - is_video_(is_video) { -} - -WebMClusterParser::Track::~Track() {} - -bool WebMClusterParser::Track::AddBuffer( - const scoped_refptr& buffer) { - DVLOG(2) << "AddBuffer() : " << track_num_ - << " ts " << buffer->timestamp().InSecondsF() - << " dur " << buffer->duration().InSecondsF() - << " kf " << buffer->IsKeyframe() - << " size " << buffer->data_size(); - - buffers_.push_back(buffer); - return true; -} - -void WebMClusterParser::Track::Reset() { - buffers_.clear(); -} - -bool WebMClusterParser::Track::IsKeyframe(const uint8* data, int size) const { - // For now, assume that all blocks are keyframes for datatypes other than - // video. This is a valid assumption for Vorbis, WebVTT, & Opus. - if (!is_video_) - return true; - - // Make sure the block is big enough for the minimal keyframe header size. - if (size < 7) - return false; - - // The LSb of the first byte must be a 0 for a keyframe. - // http://tools.ietf.org/html/rfc6386 Section 19.1 - if ((data[0] & 0x01) != 0) - return false; - - // Verify VP8 keyframe startcode. - // http://tools.ietf.org/html/rfc6386 Section 19.1 - if (data[3] != 0x9d || data[4] != 0x01 || data[5] != 0x2a) - return false; - - return true; -} - -void WebMClusterParser::ResetTextTracks() { - for (TextTrackMap::iterator it = text_track_map_.begin(); - it != text_track_map_.end(); - ++it) { - it->second.Reset(); - } -} - -WebMClusterParser::Track* -WebMClusterParser::FindTextTrack(int track_num) { - const TextTrackMap::iterator it = text_track_map_.find(track_num); - - if (it == text_track_map_.end()) - return NULL; - - return &it->second; -} - -} // namespace media diff --git a/media/webm/webm_cluster_parser.h b/media/webm/webm_cluster_parser.h deleted file mode 100644 index e156d47c23..0000000000 --- a/media/webm/webm_cluster_parser.h +++ /dev/null @@ -1,155 +0,0 @@ -// Copyright (c) 2012 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. - -#ifndef MEDIA_WEBM_WEBM_CLUSTER_PARSER_H_ -#define MEDIA_WEBM_WEBM_CLUSTER_PARSER_H_ - -#include -#include -#include -#include - -#include "base/memory/scoped_ptr.h" -#include "media/base/media_export.h" -#include "media/base/media_log.h" -#include "media/base/stream_parser_buffer.h" -#include "media/webm/webm_parser.h" -#include "media/webm/webm_tracks_parser.h" - -namespace media { - -class MEDIA_EXPORT WebMClusterParser : public WebMParserClient { - private: - // Helper class that manages per-track state. - class Track { - public: - Track(int track_num, bool is_video); - ~Track(); - - int track_num() const { return track_num_; } - const std::deque >& buffers() const { - return buffers_; - } - - bool AddBuffer(const scoped_refptr& buffer); - - // Clears all buffer state. - void Reset(); - - // Helper function used to inspect block data to determine if the - // block is a keyframe. - // |data| contains the bytes in the block. - // |size| indicates the number of bytes in |data|. - bool IsKeyframe(const uint8* data, int size) const; - - private: - int track_num_; - std::deque > buffers_; - bool is_video_; - }; - - typedef std::map TextTrackMap; - - public: - typedef std::deque > BufferQueue; - - class MEDIA_EXPORT TextTrackIterator { - public: - explicit TextTrackIterator(const TextTrackMap& text_track_map); - TextTrackIterator(const TextTrackIterator& rhs); - ~TextTrackIterator(); - - // To visit each text track. If the iterator is exhausted, it returns - // as parameters the values 0 and NULL, and the function returns false. - // Otherwise, it returns the buffers for the associated track, and the - // function returns true. - bool operator()(int* track_num, const BufferQueue** buffers); - private: - TextTrackIterator& operator=(const TextTrackIterator&); - - TextTrackMap::const_iterator iterator_; - const TextTrackMap::const_iterator iterator_end_; - }; - - WebMClusterParser(int64 timecode_scale, - int audio_track_num, - int video_track_num, - const WebMTracksParser::TextTracks& text_tracks, - const std::set& ignored_tracks, - const std::string& audio_encryption_key_id, - const std::string& video_encryption_key_id, - const LogCB& log_cb); - virtual ~WebMClusterParser(); - - // Resets the parser state so it can accept a new cluster. - void Reset(); - - // Parses a WebM cluster element in |buf|. - // - // Returns -1 if the parse fails. - // Returns 0 if more data is needed. - // Returns the number of bytes parsed on success. - int Parse(const uint8* buf, int size); - - base::TimeDelta cluster_start_time() const { return cluster_start_time_; } - const BufferQueue& audio_buffers() const { return audio_.buffers(); } - const BufferQueue& video_buffers() const { return video_.buffers(); } - - // Returns an iterator object, allowing each text track to be visited. - TextTrackIterator CreateTextTrackIterator() const; - - // Returns true if the last Parse() call stopped at the end of a cluster. - bool cluster_ended() const { return cluster_ended_; } - - private: - // WebMParserClient methods. - virtual WebMParserClient* OnListStart(int id) OVERRIDE; - virtual bool OnListEnd(int id) OVERRIDE; - virtual bool OnUInt(int id, int64 val) OVERRIDE; - virtual bool OnBinary(int id, const uint8* data, int size) OVERRIDE; - - bool ParseBlock(bool is_simple_block, const uint8* buf, int size, - const uint8* additional, int additional_size, int duration); - bool OnBlock(bool is_simple_block, int track_num, int timecode, int duration, - int flags, const uint8* data, int size, - const uint8* additional, int additional_size); - - // Resets the Track objects associated with each text track. - void ResetTextTracks(); - - // Search for the indicated track_num among the text tracks. Returns NULL - // if that track num is not a text track. - Track* FindTextTrack(int track_num); - - double timecode_multiplier_; // Multiplier used to convert timecodes into - // microseconds. - std::set ignored_tracks_; - std::string audio_encryption_key_id_; - std::string video_encryption_key_id_; - - WebMListParser parser_; - - int64 last_block_timecode_; - scoped_ptr block_data_; - int block_data_size_; - int64 block_duration_; - int64 block_add_id_; - scoped_ptr block_additional_data_; - int block_additional_data_size_; - - int64 cluster_timecode_; - base::TimeDelta cluster_start_time_; - bool cluster_ended_; - - Track audio_; - Track video_; - TextTrackMap text_track_map_; - LogCB log_cb_; - - DISALLOW_IMPLICIT_CONSTRUCTORS(WebMClusterParser); -}; - -} // namespace media - -#endif // MEDIA_WEBM_WEBM_CLUSTER_PARSER_H_ diff --git a/media/webm/webm_cluster_parser_unittest.cc b/media/webm/webm_cluster_parser_unittest.cc deleted file mode 100644 index 5c5837fa86..0000000000 --- a/media/webm/webm_cluster_parser_unittest.cc +++ /dev/null @@ -1,533 +0,0 @@ -// Copyright (c) 2012 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 - -#include "base/bind.h" -#include "base/logging.h" -#include "media/base/decrypt_config.h" -#include "media/webm/cluster_builder.h" -#include "media/webm/webm_cluster_parser.h" -#include "media/webm/webm_constants.h" -#include "testing/gmock/include/gmock/gmock.h" -#include "testing/gtest/include/gtest/gtest.h" - -using ::testing::InSequence; -using ::testing::Return; -using ::testing::_; - -namespace media { - -enum { - kTimecodeScale = 1000000, // Timecode scale for millisecond timestamps. - kAudioTrackNum = 1, - kVideoTrackNum = 2, - kTextTrackNum = 3, -}; - -struct BlockInfo { - int track_num; - int timestamp; - int duration; - bool use_simple_block; -}; - -static const BlockInfo kDefaultBlockInfo[] = { - { kAudioTrackNum, 0, 23, true }, - { kAudioTrackNum, 23, 23, true }, - { kVideoTrackNum, 33, 34, true }, - { kAudioTrackNum, 46, 23, true }, - { kVideoTrackNum, 67, 33, false }, - { kAudioTrackNum, 69, 23, false }, - { kVideoTrackNum, 100, 33, false }, -}; - -static const uint8 kEncryptedFrame[] = { - 0x01, // Block is encrypted - 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08 // IV -}; - -static scoped_ptr CreateCluster(int timecode, - const BlockInfo* block_info, - int block_count) { - ClusterBuilder cb; - cb.SetClusterTimecode(0); - - for (int i = 0; i < block_count; i++) { - uint8 data[] = { 0x00 }; - if (block_info[i].use_simple_block) { - cb.AddSimpleBlock(block_info[i].track_num, - block_info[i].timestamp, - 0, data, sizeof(data)); - continue; - } - - CHECK_GE(block_info[i].duration, 0); - cb.AddBlockGroup(block_info[i].track_num, - block_info[i].timestamp, - block_info[i].duration, - 0, data, sizeof(data)); - } - - return cb.Finish(); -} - -// Creates a Cluster with one encrypted Block. |bytes_to_write| is number of -// bytes of the encrypted frame to write. -static scoped_ptr CreateEncryptedCluster(int bytes_to_write) { - CHECK_GT(bytes_to_write, 0); - CHECK_LE(bytes_to_write, static_cast(sizeof(kEncryptedFrame))); - - ClusterBuilder cb; - cb.SetClusterTimecode(0); - cb.AddSimpleBlock(kVideoTrackNum, 0, 0, kEncryptedFrame, bytes_to_write); - return cb.Finish(); -} - -static bool VerifyBuffers(const WebMClusterParser::BufferQueue& audio_buffers, - const WebMClusterParser::BufferQueue& video_buffers, - const WebMClusterParser::BufferQueue& text_buffers, - const BlockInfo* block_info, - int block_count) { - size_t audio_offset = 0; - size_t video_offset = 0; - size_t text_offset = 0; - for (int i = 0; i < block_count; i++) { - const WebMClusterParser::BufferQueue* buffers = NULL; - size_t* offset; - - if (block_info[i].track_num == kAudioTrackNum) { - buffers = &audio_buffers; - offset = &audio_offset; - } else if (block_info[i].track_num == kVideoTrackNum) { - buffers = &video_buffers; - offset = &video_offset; - } else if (block_info[i].track_num == kTextTrackNum) { - buffers = &text_buffers; - offset = &text_offset; - } else { - LOG(ERROR) << "Unexpected track number " << block_info[i].track_num; - return false; - } - - if (*offset >= buffers->size()) - return false; - - scoped_refptr buffer = (*buffers)[(*offset)++]; - - - EXPECT_EQ(buffer->timestamp().InMilliseconds(), block_info[i].timestamp); - - if (!block_info[i].use_simple_block) - EXPECT_NE(buffer->duration(), kNoTimestamp()); - - if (buffer->duration() != kNoTimestamp()) - EXPECT_EQ(buffer->duration().InMilliseconds(), block_info[i].duration); - } - - return true; -} - -static bool VerifyBuffers(const scoped_ptr& parser, - const BlockInfo* block_info, - int block_count) { - typedef WebMClusterParser::TextTrackIterator TextTrackIterator; - TextTrackIterator text_it = parser->CreateTextTrackIterator(); - - int text_track_num; - const WebMClusterParser::BufferQueue* text_buffers; - - while (text_it(&text_track_num, &text_buffers)) - break; - - const WebMClusterParser::BufferQueue no_text_buffers; - - if (text_buffers == NULL) - text_buffers = &no_text_buffers; - - return VerifyBuffers(parser->audio_buffers(), - parser->video_buffers(), - *text_buffers, - block_info, - block_count); -} - -static bool VerifyTextBuffers( - const scoped_ptr& 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 buffer = *buffer_iter++; - EXPECT_EQ(buffer->timestamp().InMilliseconds(), block_info.timestamp); - EXPECT_EQ(buffer->duration().InMilliseconds(), block_info.duration); - } - - EXPECT_TRUE(buffer_iter == buffer_end); - return true; -} - -static bool VerifyEncryptedBuffer( - scoped_refptr buffer) { - EXPECT_TRUE(buffer->decrypt_config()); - EXPECT_EQ(static_cast(DecryptConfig::kDecryptionKeySize), - buffer->decrypt_config()->iv().length()); - const uint8* data = buffer->data(); - return data[0] & kWebMFlagEncryptedFrame; -} - -static void AppendToEnd(const WebMClusterParser::BufferQueue& src, - WebMClusterParser::BufferQueue* dest) { - for (WebMClusterParser::BufferQueue::const_iterator itr = src.begin(); - itr != src.end(); ++itr) { - dest->push_back(*itr); - } -} - -class WebMClusterParserTest : public testing::Test { - public: - WebMClusterParserTest() - : parser_(new WebMClusterParser(kTimecodeScale, - kAudioTrackNum, - kVideoTrackNum, - WebMTracksParser::TextTracks(), - std::set(), - std::string(), - std::string(), - LogCB())) {} - - protected: - scoped_ptr parser_; -}; - -TEST_F(WebMClusterParserTest, Reset) { - InSequence s; - - int block_count = arraysize(kDefaultBlockInfo); - scoped_ptr 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(result, cluster->size()); - ASSERT_TRUE(VerifyBuffers(parser_, kDefaultBlockInfo, block_count)); -} - -TEST_F(WebMClusterParserTest, ParseClusterWithSingleCall) { - int block_count = arraysize(kDefaultBlockInfo); - scoped_ptr 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(CreateCluster(0, kDefaultBlockInfo, block_count)); - - WebMClusterParser::BufferQueue audio_buffers; - WebMClusterParser::BufferQueue video_buffers; - const WebMClusterParser::BufferQueue no_text_buffers; - - const uint8* data = cluster->data(); - int size = cluster->size(); - int default_parse_size = 3; - int parse_size = std::min(default_parse_size, size); - - 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; - } - - AppendToEnd(parser_->audio_buffers(), &audio_buffers); - AppendToEnd(parser_->video_buffers(), &video_buffers); - - parse_size = default_parse_size; - - data += result; - size -= result; - } - ASSERT_TRUE(VerifyBuffers(audio_buffers, video_buffers, - no_text_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 }, - { kVideoTrackNum, 33, 34, false }, - }; - int block_count = arraysize(kBlockInfo); - - const uint8 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(result, kClusterSize); - ASSERT_TRUE(VerifyBuffers(parser_, kBlockInfo, block_count)); -} - -TEST_F(WebMClusterParserTest, ParseSimpleBlockAndBlockGroupMixture) { - const BlockInfo kBlockInfo[] = { - { kAudioTrackNum, 0, 23, true }, - { kAudioTrackNum, 23, 23, false }, - { kVideoTrackNum, 33, 34, true }, - { kAudioTrackNum, 46, 23, false }, - { kVideoTrackNum, 67, 33, false }, - }; - int block_count = arraysize(kBlockInfo); - scoped_ptr 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 ignored_tracks; - ignored_tracks.insert(kTextTrackNum); - - parser_.reset(new WebMClusterParser(kTimecodeScale, - kAudioTrackNum, - kVideoTrackNum, - WebMTracksParser::TextTracks(), - ignored_tracks, - std::string(), - std::string(), - LogCB())); - - const BlockInfo kInputBlockInfo[] = { - { kAudioTrackNum, 0, 23, true }, - { kAudioTrackNum, 23, 23, true }, - { kVideoTrackNum, 33, 33, true }, - { kTextTrackNum, 33, 99, true }, - { kAudioTrackNum, 46, 23, true }, - { kVideoTrackNum, 67, 33, true }, - }; - int input_block_count = arraysize(kInputBlockInfo); - - const BlockInfo kOutputBlockInfo[] = { - { kAudioTrackNum, 0, 23, true }, - { kAudioTrackNum, 23, 23, true }, - { kVideoTrackNum, 33, 33, true }, - { kAudioTrackNum, 46, 23, true }, - { kVideoTrackNum, 67, 33, true }, - }; - int output_block_count = arraysize(kOutputBlockInfo); - - scoped_ptr cluster( - CreateCluster(0, kInputBlockInfo, input_block_count)); - - 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) { - typedef WebMTracksParser::TextTracks TextTracks; - TextTracks text_tracks; - WebMTracksParser::TextTrackInfo text_track_info; - - text_track_info.kind = kTextSubtitles; - text_tracks.insert(std::make_pair(TextTracks::key_type(kTextTrackNum), - text_track_info)); - - parser_.reset(new WebMClusterParser(kTimecodeScale, - kAudioTrackNum, - kVideoTrackNum, - text_tracks, - std::set(), - std::string(), - std::string(), - LogCB())); - - const BlockInfo kInputBlockInfo[] = { - { kAudioTrackNum, 0, 23, true }, - { kAudioTrackNum, 23, 23, true }, - { kVideoTrackNum, 33, 33, true }, - { kTextTrackNum, 33, 42, false }, - { kAudioTrackNum, 46, 23, true }, - { kTextTrackNum, 55, 44, false }, - { kVideoTrackNum, 67, 33, true }, - }; - int input_block_count = arraysize(kInputBlockInfo); - - scoped_ptr cluster( - CreateCluster(0, kInputBlockInfo, input_block_count)); - - 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) { - typedef WebMTracksParser::TextTracks TextTracks; - TextTracks text_tracks; - WebMTracksParser::TextTrackInfo text_track_info; - - text_track_info.kind = kTextSubtitles; - text_tracks.insert(std::make_pair(TextTracks::key_type(kTextTrackNum), - text_track_info)); - - parser_.reset(new WebMClusterParser(kTimecodeScale, - kAudioTrackNum, - kVideoTrackNum, - text_tracks, - std::set(), - std::string(), - std::string(), - LogCB())); - - const BlockInfo kInputBlockInfo[] = { - { kTextTrackNum, 33, 42, true }, - }; - int input_block_count = arraysize(kInputBlockInfo); - - scoped_ptr cluster( - CreateCluster(0, kInputBlockInfo, input_block_count)); - - int result = parser_->Parse(cluster->data(), cluster->size()); - EXPECT_LT(result, 0); -} - -TEST_F(WebMClusterParserTest, ParseMultipleTextTracks) { - typedef WebMTracksParser::TextTracks TextTracks; - TextTracks text_tracks; - WebMTracksParser::TextTrackInfo text_track_info; - - const int kSubtitleTextTrackNum = kTextTrackNum; - const int kCaptionTextTrackNum = kTextTrackNum + 1; - - text_track_info.kind = kTextSubtitles; - text_tracks.insert(std::make_pair(TextTracks::key_type(kSubtitleTextTrackNum), - text_track_info)); - - text_track_info.kind = kTextCaptions; - text_tracks.insert(std::make_pair(TextTracks::key_type(kCaptionTextTrackNum), - text_track_info)); - - parser_.reset(new WebMClusterParser(kTimecodeScale, - kAudioTrackNum, - kVideoTrackNum, - text_tracks, - std::set(), - std::string(), - std::string(), - LogCB())); - - const BlockInfo kInputBlockInfo[] = { - { kAudioTrackNum, 0, 23, true }, - { kAudioTrackNum, 23, 23, true }, - { kVideoTrackNum, 33, 33, true }, - { kSubtitleTextTrackNum, 33, 42, false }, - { kAudioTrackNum, 46, 23, true }, - { kCaptionTextTrackNum, 55, 44, false }, - { kVideoTrackNum, 67, 33, true }, - { kSubtitleTextTrackNum, 67, 33, false }, - }; - int input_block_count = arraysize(kInputBlockInfo); - - scoped_ptr cluster( - CreateCluster(0, kInputBlockInfo, input_block_count)); - - int result = parser_->Parse(cluster->data(), cluster->size()); - EXPECT_EQ(cluster->size(), result); - - WebMClusterParser::TextTrackIterator text_it = - parser_->CreateTextTrackIterator(); - - int text_track_num; - const WebMClusterParser::BufferQueue* text_buffers; - - while (text_it(&text_track_num, &text_buffers)) { - const WebMTracksParser::TextTracks::const_iterator find_result = - text_tracks.find(text_track_num); - ASSERT_TRUE(find_result != text_tracks.end()); - ASSERT_TRUE(VerifyTextBuffers(parser_, kInputBlockInfo, input_block_count, - text_track_num, *text_buffers)); - } -} - -TEST_F(WebMClusterParserTest, ParseEncryptedBlock) { - scoped_ptr cluster(CreateEncryptedCluster(sizeof(kEncryptedFrame))); - - parser_.reset(new WebMClusterParser(kTimecodeScale, - kAudioTrackNum, - kVideoTrackNum, - WebMTracksParser::TextTracks(), - std::set(), - std::string(), - "video_key_id", - LogCB())); - int result = parser_->Parse(cluster->data(), cluster->size()); - EXPECT_EQ(cluster->size(), result); - ASSERT_EQ(1UL, parser_->video_buffers().size()); - scoped_refptr buffer = parser_->video_buffers()[0]; - EXPECT_TRUE(VerifyEncryptedBuffer(buffer)); -} - -TEST_F(WebMClusterParserTest, ParseBadEncryptedBlock) { - scoped_ptr cluster( - CreateEncryptedCluster(sizeof(kEncryptedFrame) - 1)); - - parser_.reset(new WebMClusterParser(kTimecodeScale, - kAudioTrackNum, - kVideoTrackNum, - WebMTracksParser::TextTracks(), - std::set(), - std::string(), - "video_key_id", - LogCB())); - int result = parser_->Parse(cluster->data(), cluster->size()); - EXPECT_EQ(-1, result); -} - -} // namespace media diff --git a/media/webm/webm_constants.cc b/media/webm/webm_constants.cc deleted file mode 100644 index 13ae086eca..0000000000 --- a/media/webm/webm_constants.cc +++ /dev/null @@ -1,14 +0,0 @@ -// Copyright (c) 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 "media/webm/webm_constants.h" - -namespace media { - -const char kWebMCodecSubtitles[] = "D_WEBVTT/SUBTITLES"; -const char kWebMCodecCaptions[] = "D_WEBVTT/CAPTIONS"; -const char kWebMCodecDescriptions[] = "D_WEBVTT/DESCRIPTIONS"; -const char kWebMCodecMetadata[] = "D_WEBVTT/METADATA"; - -} // namespace media diff --git a/media/webm/webm_constants.h b/media/webm/webm_constants.h deleted file mode 100644 index cda45e00d4..0000000000 --- a/media/webm/webm_constants.h +++ /dev/null @@ -1,225 +0,0 @@ -// Copyright (c) 2012 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. - -#ifndef MEDIA_WEBM_WEBM_CONSTANTS_H_ -#define MEDIA_WEBM_WEBM_CONSTANTS_H_ - -#include "base/basictypes.h" -#include "media/base/media_export.h" - -namespace media { - -// WebM element IDs. -// This is a subset of the IDs in the Matroska spec. -// http://www.matroska.org/technical/specs/index.html -const int kWebMIdAESSettingsCipherMode = 0x47E8; -const int kWebMIdAlphaMode = 0x53C0; -const int kWebMIdAspectRatioType = 0x54B3; -const int kWebMIdAttachedFile = 0x61A7; -const int kWebMIdAttachmentLink = 0x7446; -const int kWebMIdAttachments = 0x1941A469; -const int kWebMIdAudio = 0xE1; -const int kWebMIdBitDepth = 0x6264; -const int kWebMIdBlock = 0xA1; -const int kWebMIdBlockAddID = 0xEE; -const int kWebMIdBlockAdditions = 0x75A1; -const int kWebMIdBlockAdditional = 0xA5; -const int kWebMIdBlockDuration = 0x9B; -const int kWebMIdBlockGroup = 0xA0; -const int kWebMIdBlockMore = 0xA6; -const int kWebMIdChannels = 0x9F; -const int kWebMIdChapCountry = 0x437E; -const int kWebMIdChapLanguage = 0x437C; -const int kWebMIdChapProcess = 0x6944; -const int kWebMIdChapProcessCodecID = 0x6955; -const int kWebMIdChapProcessCommand = 0x6911; -const int kWebMIdChapProcessData = 0x6933; -const int kWebMIdChapProcessPrivate = 0x450D; -const int kWebMIdChapProcessTime = 0x6922; -const int kWebMIdChapString = 0x85; -const int kWebMIdChapterAtom = 0xB6; -const int kWebMIdChapterDisplay = 0x80; -const int kWebMIdChapterFlagEnabled = 0x4598; -const int kWebMIdChapterFlagHidden = 0x98; -const int kWebMIdChapterPhysicalEquiv = 0x63C3; -const int kWebMIdChapters = 0x1043A770; -const int kWebMIdChapterSegmentEditionUID = 0x6EBC; -const int kWebMIdChapterSegmentUID = 0x6E67; -const int kWebMIdChapterTimeEnd = 0x92; -const int kWebMIdChapterTimeStart = 0x91; -const int kWebMIdChapterTrack = 0x8F; -const int kWebMIdChapterTrackNumber = 0x89; -const int kWebMIdChapterTranslate = 0x6924; -const int kWebMIdChapterTranslateCodec = 0x69BF; -const int kWebMIdChapterTranslateEditionUID = 0x69FC; -const int kWebMIdChapterTranslateID = 0x69A5; -const int kWebMIdChapterUID = 0x73C4; -const int kWebMIdCluster = 0x1F43B675; -const int kWebMIdCodecDecodeAll = 0xAA; -const int kWebMIdCodecID = 0x86; -const int kWebMIdCodecName = 0x258688; -const int kWebMIdCodecPrivate = 0x63A2; -const int kWebMIdCodecState = 0xA4; -const int kWebMIdColorSpace = 0x2EB524; -const int kWebMIdContentCompAlgo = 0x4254; -const int kWebMIdContentCompression = 0x5034; -const int kWebMIdContentCompSettings = 0x4255; -const int kWebMIdContentEncAESSettings = 0x47E7; -const int kWebMIdContentEncAlgo = 0x47E1; -const int kWebMIdContentEncKeyID = 0x47E2; -const int kWebMIdContentEncoding = 0x6240; -const int kWebMIdContentEncodingOrder = 0x5031; -const int kWebMIdContentEncodings = 0x6D80; -const int kWebMIdContentEncodingScope = 0x5032; -const int kWebMIdContentEncodingType = 0x5033; -const int kWebMIdContentEncryption = 0x5035; -const int kWebMIdContentSigAlgo = 0x47E5; -const int kWebMIdContentSigHashAlgo = 0x47E6; -const int kWebMIdContentSigKeyID = 0x47E4; -const int kWebMIdContentSignature = 0x47E3; -const int kWebMIdCRC32 = 0xBF; -const int kWebMIdCueBlockNumber = 0x5378; -const int kWebMIdCueClusterPosition = 0xF1; -const int kWebMIdCueCodecState = 0xEA; -const int kWebMIdCuePoint = 0xBB; -const int kWebMIdCueReference = 0xDB; -const int kWebMIdCueRefTime = 0x96; -const int kWebMIdCues = 0x1C53BB6B; -const int kWebMIdCueTime = 0xB3; -const int kWebMIdCueTrack = 0xF7; -const int kWebMIdCueTrackPositions = 0xB7; -const int kWebMIdDateUTC = 0x4461; -const int kWebMIdDefaultDuration = 0x23E383; -const int kWebMIdDisplayHeight = 0x54BA; -const int kWebMIdDisplayUnit = 0x54B2; -const int kWebMIdDisplayWidth = 0x54B0; -const int kWebMIdDocType = 0x4282; -const int kWebMIdDocTypeReadVersion = 0x4285; -const int kWebMIdDocTypeVersion = 0x4287; -const int kWebMIdDuration = 0x4489; -const int kWebMIdEBMLHeader = 0x1A45DFA3; -const int kWebMIdEBMLMaxIDLength = 0x42F2; -const int kWebMIdEBMLMaxSizeLength = 0x42F3; -const int kWebMIdEBMLReadVersion = 0x42F7; -const int kWebMIdEBMLVersion = 0x4286; -const int kWebMIdEditionEntry = 0x45B9; -const int kWebMIdEditionFlagDefault = 0x45DB; -const int kWebMIdEditionFlagHidden = 0x45BD; -const int kWebMIdEditionFlagOrdered = 0x45DD; -const int kWebMIdEditionUID = 0x45BC; -const int kWebMIdFileData = 0x465C; -const int kWebMIdFileDescription = 0x467E; -const int kWebMIdFileMimeType = 0x4660; -const int kWebMIdFileName = 0x466E; -const int kWebMIdFileUID = 0x46AE; -const int kWebMIdFlagDefault = 0x88; -const int kWebMIdFlagEnabled = 0xB9; -const int kWebMIdFlagForced = 0x55AA; -const int kWebMIdFlagInterlaced = 0x9A; -const int kWebMIdFlagLacing = 0x9C; -const int kWebMIdInfo = 0x1549A966; -const int kWebMIdJoinBlocks = 0xE9; -const int kWebMIdLaceNumber = 0xCC; -const int kWebMIdLanguage = 0x22B59C; -const int kWebMIdMaxBlockAdditionId = 0x55EE; -const int kWebMIdMaxCache = 0x6DF8; -const int kWebMIdMinCache = 0x6DE7; -const int kWebMIdMuxingApp = 0x4D80; -const int kWebMIdName = 0x536E; -const int kWebMIdNextFilename = 0x3E83BB; -const int kWebMIdNextUID = 0x3EB923; -const int kWebMIdOutputSamplingFrequency = 0x78B5; -const int kWebMIdPixelCropBottom = 0x54AA; -const int kWebMIdPixelCropLeft = 0x54CC; -const int kWebMIdPixelCropRight = 0x54DD; -const int kWebMIdPixelCropTop = 0x54BB; -const int kWebMIdPixelHeight = 0xBA; -const int kWebMIdPixelWidth = 0xB0; -const int kWebMIdPosition = 0xA7; -const int kWebMIdPrevFilename = 0x3C83AB; -const int kWebMIdPrevSize = 0xAB; -const int kWebMIdPrevUID = 0x3CB923; -const int kWebMIdReferenceBlock = 0xFB; -const int kWebMIdReferencePriority = 0xFA; -const int kWebMIdSamplingFrequency = 0xB5; -const int kWebMIdSeek = 0x4DBB; -const int kWebMIdSeekHead = 0x114D9B74; -const int kWebMIdSeekID = 0x53AB; -const int kWebMIdSeekPosition = 0x53AC; -const int kWebMIdSegment = 0x18538067; -const int kWebMIdSegmentFamily = 0x4444; -const int kWebMIdSegmentFilename = 0x7384; -const int kWebMIdSegmentUID = 0x73A4; -const int kWebMIdSilentTrackNumber = 0x58D7; -const int kWebMIdSilentTracks = 0x5854; -const int kWebMIdSimpleBlock = 0xA3; -const int kWebMIdSimpleTag = 0x67C8; -const int kWebMIdSlices = 0x8E; -const int kWebMIdStereoMode = 0x53B8; -const int kWebMIdTag = 0x7373; -const int kWebMIdTagAttachmentUID = 0x63C6; -const int kWebMIdTagBinary = 0x4485; -const int kWebMIdTagChapterUID = 0x63C4; -const int kWebMIdTagDefault = 0x4484; -const int kWebMIdTagEditionUID = 0x63C9; -const int kWebMIdTagLanguage = 0x447A; -const int kWebMIdTagName = 0x45A3; -const int kWebMIdTags = 0x1254C367; -const int kWebMIdTagString = 0x4487; -const int kWebMIdTagTrackUID = 0x63C5; -const int kWebMIdTargets = 0x63C0; -const int kWebMIdTargetType = 0x63CA; -const int kWebMIdTargetTypeValue = 0x68CA; -const int kWebMIdTimecode = 0xE7; -const int kWebMIdTimecodeScale = 0x2AD7B1; -const int kWebMIdTimeSlice = 0xE8; -const int kWebMIdTitle = 0x7BA9; -const int kWebMIdTrackCombinePlanes = 0xE3; -const int kWebMIdTrackEntry = 0xAE; -const int kWebMIdTrackJoinUID = 0xED; -const int kWebMIdTrackNumber = 0xD7; -const int kWebMIdTrackOperation = 0xE2; -const int kWebMIdTrackOverlay = 0x6FAB; -const int kWebMIdTrackPlane = 0xE4; -const int kWebMIdTrackPlaneType = 0xE6; -const int kWebMIdTrackPlaneUID = 0xE5; -const int kWebMIdTracks = 0x1654AE6B; -const int kWebMIdTrackTimecodeScale = 0x23314F; -const int kWebMIdTrackTranslate = 0x6624; -const int kWebMIdTrackTranslateCodec = 0x66BF; -const int kWebMIdTrackTranslateEditionUID = 0x66FC; -const int kWebMIdTrackTranslateTrackID = 0x66A5; -const int kWebMIdTrackType = 0x83; -const int kWebMIdTrackUID = 0x73C5; -const int kWebMIdVideo = 0xE0; -const int kWebMIdVoid = 0xEC; -const int kWebMIdWritingApp = 0x5741; - -const int64 kWebMReservedId = 0x1FFFFFFF; -const int64 kWebMUnknownSize = GG_LONGLONG(0x00FFFFFFFFFFFFFF); - -const uint8 kWebMFlagKeyframe = 0x80; - -// Current encrypted WebM request for comments specification is here -// http://wiki.webmproject.org/encryption/webm-encryption-rfc -const uint8 kWebMFlagEncryptedFrame = 0x1; -const int kWebMIvSize = 8; -const int kWebMSignalByteSize = 1; - -// Current specification for WebVTT embedded in WebM -// http://wiki.webmproject.org/webm-metadata/temporal-metadata/webvtt-in-webm - -const int kWebMTrackTypeVideo = 1; -const int kWebMTrackTypeAudio = 2; -const int kWebMTrackTypeSubtitlesOrCaptions = 0x11; -const int kWebMTrackTypeDescriptionsOrMetadata = 0x21; - -MEDIA_EXPORT extern const char kWebMCodecSubtitles[]; -MEDIA_EXPORT extern const char kWebMCodecCaptions[]; -MEDIA_EXPORT extern const char kWebMCodecDescriptions[]; -MEDIA_EXPORT extern const char kWebMCodecMetadata[]; - -} // namespace media - -#endif // MEDIA_WEBM_WEBM_CONSTANTS_H_ diff --git a/media/webm/webm_content_encodings.cc b/media/webm/webm_content_encodings.cc deleted file mode 100644 index 9789c0f302..0000000000 --- a/media/webm/webm_content_encodings.cc +++ /dev/null @@ -1,28 +0,0 @@ -// Copyright (c) 2012 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/logging.h" -#include "media/webm/webm_content_encodings.h" - -namespace media { - -ContentEncoding::ContentEncoding() - : order_(kOrderInvalid), - scope_(kScopeInvalid), - type_(kTypeInvalid), - encryption_algo_(kEncAlgoInvalid), - cipher_mode_(kCipherModeInvalid) { -} - -ContentEncoding::~ContentEncoding() {} - -void ContentEncoding::SetEncryptionKeyId(const uint8* encryption_key_id, - int size) { - DCHECK(encryption_key_id); - DCHECK_GT(size, 0); - encryption_key_id_.assign(reinterpret_cast(encryption_key_id), - size); -} - -} // namespace media diff --git a/media/webm/webm_content_encodings.h b/media/webm/webm_content_encodings.h deleted file mode 100644 index 2866f253f0..0000000000 --- a/media/webm/webm_content_encodings.h +++ /dev/null @@ -1,88 +0,0 @@ -// Copyright (c) 2012 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. - -#ifndef MEDIA_WEBM_WEBM_CONTENT_ENCODINGS_H_ -#define MEDIA_WEBM_WEBM_CONTENT_ENCODINGS_H_ - -#include - -#include "base/basictypes.h" -#include "base/memory/scoped_ptr.h" -#include "media/base/media_export.h" - -namespace media { - -class MEDIA_EXPORT ContentEncoding { - public: - // The following enum definitions are based on the ContentEncoding element - // specified in the Matroska spec. - - static const int kOrderInvalid = -1; - - enum Scope { - kScopeInvalid = 0, - kScopeAllFrameContents = 1, - kScopeTrackPrivateData = 2, - kScopeNextContentEncodingData = 4, - kScopeMax = 7, - }; - - enum Type { - kTypeInvalid = -1, - kTypeCompression = 0, - kTypeEncryption = 1, - }; - - enum EncryptionAlgo { - kEncAlgoInvalid = -1, - kEncAlgoNotEncrypted = 0, - kEncAlgoDes = 1, - kEncAlgo3des = 2, - kEncAlgoTwofish = 3, - kEncAlgoBlowfish = 4, - kEncAlgoAes = 5, - }; - - enum CipherMode { - kCipherModeInvalid = 0, - kCipherModeCtr = 1, - }; - - ContentEncoding(); - ~ContentEncoding(); - - int64 order() const { return order_; } - void set_order(int64 order) { order_ = order; } - - Scope scope() const { return scope_; } - void set_scope(Scope scope) { scope_ = scope; } - - Type type() const { return type_; } - void set_type(Type type) { type_ = type; } - - EncryptionAlgo encryption_algo() const { return encryption_algo_; } - void set_encryption_algo(EncryptionAlgo encryption_algo) { - encryption_algo_ = encryption_algo; - } - - const std::string& encryption_key_id() const { return encryption_key_id_; } - void SetEncryptionKeyId(const uint8* encryption_key_id, int size); - - CipherMode cipher_mode() const { return cipher_mode_; } - void set_cipher_mode(CipherMode mode) { cipher_mode_ = mode; } - - private: - int64 order_; - Scope scope_; - Type type_; - EncryptionAlgo encryption_algo_; - std::string encryption_key_id_; - CipherMode cipher_mode_; - - DISALLOW_COPY_AND_ASSIGN(ContentEncoding); -}; - -} // namespace media - -#endif // MEDIA_WEBM_WEBM_CONTENT_ENCODINGS_H_ diff --git a/media/webm/webm_content_encodings_client.cc b/media/webm/webm_content_encodings_client.cc deleted file mode 100644 index bcf964ed31..0000000000 --- a/media/webm/webm_content_encodings_client.cc +++ /dev/null @@ -1,265 +0,0 @@ -// Copyright (c) 2012 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 "media/webm/webm_content_encodings_client.h" - -#include "base/logging.h" -#include "base/stl_util.h" -#include "media/webm/webm_constants.h" - -namespace media { - -WebMContentEncodingsClient::WebMContentEncodingsClient(const LogCB& log_cb) - : log_cb_(log_cb), - content_encryption_encountered_(false), - content_encodings_ready_(false) { -} - -WebMContentEncodingsClient::~WebMContentEncodingsClient() { - STLDeleteElements(&content_encodings_); -} - -const ContentEncodings& WebMContentEncodingsClient::content_encodings() const { - DCHECK(content_encodings_ready_); - return content_encodings_; -} - -WebMParserClient* WebMContentEncodingsClient::OnListStart(int id) { - if (id == kWebMIdContentEncodings) { - DCHECK(!cur_content_encoding_.get()); - DCHECK(!content_encryption_encountered_); - STLDeleteElements(&content_encodings_); - content_encodings_ready_ = false; - return this; - } - - if (id == kWebMIdContentEncoding) { - DCHECK(!cur_content_encoding_.get()); - DCHECK(!content_encryption_encountered_); - cur_content_encoding_.reset(new ContentEncoding()); - return this; - } - - if (id == kWebMIdContentEncryption) { - DCHECK(cur_content_encoding_.get()); - if (content_encryption_encountered_) { - MEDIA_LOG(log_cb_) << "Unexpected multiple ContentEncryption."; - return NULL; - } - content_encryption_encountered_ = true; - return this; - } - - if (id == kWebMIdContentEncAESSettings) { - DCHECK(cur_content_encoding_.get()); - return this; - } - - // This should not happen if WebMListParser is working properly. - DCHECK(false); - return NULL; -} - -// Mandatory occurrence restriction is checked in this function. Multiple -// occurrence restriction is checked in OnUInt and OnBinary. -bool WebMContentEncodingsClient::OnListEnd(int id) { - if (id == kWebMIdContentEncodings) { - // ContentEncoding element is mandatory. Check this! - if (content_encodings_.empty()) { - MEDIA_LOG(log_cb_) << "Missing ContentEncoding."; - return false; - } - content_encodings_ready_ = true; - return true; - } - - if (id == kWebMIdContentEncoding) { - DCHECK(cur_content_encoding_.get()); - - // - // Specify default values to missing mandatory elements. - // - - if (cur_content_encoding_->order() == ContentEncoding::kOrderInvalid) { - // Default value of encoding order is 0, which should only be used on the - // first ContentEncoding. - if (!content_encodings_.empty()) { - MEDIA_LOG(log_cb_) << "Missing ContentEncodingOrder."; - return false; - } - cur_content_encoding_->set_order(0); - } - - if (cur_content_encoding_->scope() == ContentEncoding::kScopeInvalid) - cur_content_encoding_->set_scope(ContentEncoding::kScopeAllFrameContents); - - if (cur_content_encoding_->type() == ContentEncoding::kTypeInvalid) - cur_content_encoding_->set_type(ContentEncoding::kTypeCompression); - - // Check for elements valid in spec but not supported for now. - if (cur_content_encoding_->type() == ContentEncoding::kTypeCompression) { - MEDIA_LOG(log_cb_) << "ContentCompression not supported."; - return false; - } - - // Enforce mandatory elements without default values. - DCHECK(cur_content_encoding_->type() == ContentEncoding::kTypeEncryption); - if (!content_encryption_encountered_) { - MEDIA_LOG(log_cb_) << "ContentEncodingType is encryption but" - << " ContentEncryption is missing."; - return false; - } - - content_encodings_.push_back(cur_content_encoding_.release()); - content_encryption_encountered_ = false; - return true; - } - - if (id == kWebMIdContentEncryption) { - DCHECK(cur_content_encoding_.get()); - // Specify default value for elements that are not present. - if (cur_content_encoding_->encryption_algo() == - ContentEncoding::kEncAlgoInvalid) { - cur_content_encoding_->set_encryption_algo( - ContentEncoding::kEncAlgoNotEncrypted); - } - return true; - } - - if (id == kWebMIdContentEncAESSettings) { - if (cur_content_encoding_->cipher_mode() == - ContentEncoding::kCipherModeInvalid) - cur_content_encoding_->set_cipher_mode(ContentEncoding::kCipherModeCtr); - return true; - } - - // This should not happen if WebMListParser is working properly. - DCHECK(false); - return false; -} - -// Multiple occurrence restriction and range are checked in this function. -// Mandatory occurrence restriction is checked in OnListEnd. -bool WebMContentEncodingsClient::OnUInt(int id, int64 val) { - DCHECK(cur_content_encoding_.get()); - - if (id == kWebMIdContentEncodingOrder) { - if (cur_content_encoding_->order() != ContentEncoding::kOrderInvalid) { - MEDIA_LOG(log_cb_) << "Unexpected multiple ContentEncodingOrder."; - return false; - } - - if (val != static_cast(content_encodings_.size())) { - // According to the spec, encoding order starts with 0 and counts upwards. - MEDIA_LOG(log_cb_) << "Unexpected ContentEncodingOrder."; - return false; - } - - cur_content_encoding_->set_order(val); - return true; - } - - if (id == kWebMIdContentEncodingScope) { - if (cur_content_encoding_->scope() != ContentEncoding::kScopeInvalid) { - MEDIA_LOG(log_cb_) << "Unexpected multiple ContentEncodingScope."; - return false; - } - - if (val == ContentEncoding::kScopeInvalid || - val > ContentEncoding::kScopeMax) { - MEDIA_LOG(log_cb_) << "Unexpected ContentEncodingScope."; - return false; - } - - if (val & ContentEncoding::kScopeNextContentEncodingData) { - MEDIA_LOG(log_cb_) << "Encoded next ContentEncoding is not supported."; - return false; - } - - cur_content_encoding_->set_scope(static_cast(val)); - return true; - } - - if (id == kWebMIdContentEncodingType) { - if (cur_content_encoding_->type() != ContentEncoding::kTypeInvalid) { - MEDIA_LOG(log_cb_) << "Unexpected multiple ContentEncodingType."; - return false; - } - - if (val == ContentEncoding::kTypeCompression) { - MEDIA_LOG(log_cb_) << "ContentCompression not supported."; - return false; - } - - if (val != ContentEncoding::kTypeEncryption) { - MEDIA_LOG(log_cb_) << "Unexpected ContentEncodingType " << val << "."; - return false; - } - - cur_content_encoding_->set_type(static_cast(val)); - return true; - } - - if (id == kWebMIdContentEncAlgo) { - if (cur_content_encoding_->encryption_algo() != - ContentEncoding::kEncAlgoInvalid) { - MEDIA_LOG(log_cb_) << "Unexpected multiple ContentEncAlgo."; - return false; - } - - if (val < ContentEncoding::kEncAlgoNotEncrypted || - val > ContentEncoding::kEncAlgoAes) { - MEDIA_LOG(log_cb_) << "Unexpected ContentEncAlgo " << val << "."; - return false; - } - - cur_content_encoding_->set_encryption_algo( - static_cast(val)); - return true; - } - - if (id == kWebMIdAESSettingsCipherMode) { - if (cur_content_encoding_->cipher_mode() != - ContentEncoding::kCipherModeInvalid) { - MEDIA_LOG(log_cb_) << "Unexpected multiple AESSettingsCipherMode."; - return false; - } - - if (val != ContentEncoding::kCipherModeCtr) { - MEDIA_LOG(log_cb_) << "Unexpected AESSettingsCipherMode " << val << "."; - return false; - } - - cur_content_encoding_->set_cipher_mode( - static_cast(val)); - return true; - } - - // This should not happen if WebMListParser is working properly. - DCHECK(false); - return false; -} - -// Multiple occurrence restriction is checked in this function. Mandatory -// restriction is checked in OnListEnd. -bool WebMContentEncodingsClient::OnBinary(int id, const uint8* data, int size) { - DCHECK(cur_content_encoding_.get()); - DCHECK(data); - DCHECK_GT(size, 0); - - if (id == kWebMIdContentEncKeyID) { - if (!cur_content_encoding_->encryption_key_id().empty()) { - MEDIA_LOG(log_cb_) << "Unexpected multiple ContentEncKeyID"; - return false; - } - cur_content_encoding_->SetEncryptionKeyId(data, size); - return true; - } - - // This should not happen if WebMListParser is working properly. - DCHECK(false); - return false; -} - -} // namespace media diff --git a/media/webm/webm_content_encodings_client.h b/media/webm/webm_content_encodings_client.h deleted file mode 100644 index e477fcf380..0000000000 --- a/media/webm/webm_content_encodings_client.h +++ /dev/null @@ -1,50 +0,0 @@ -// Copyright (c) 2012 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. - -#ifndef MEDIA_WEBM_WEBM_CONTENT_ENCODINGS_CLIENT_H_ -#define MEDIA_WEBM_WEBM_CONTENT_ENCODINGS_CLIENT_H_ - -#include - -#include "base/callback.h" -#include "base/compiler_specific.h" -#include "base/memory/scoped_ptr.h" -#include "media/base/media_export.h" -#include "media/base/media_log.h" -#include "media/webm/webm_content_encodings.h" -#include "media/webm/webm_parser.h" - -namespace media { - -typedef std::vector ContentEncodings; - -// Parser for WebM ContentEncodings element. -class MEDIA_EXPORT WebMContentEncodingsClient : public WebMParserClient { - public: - explicit WebMContentEncodingsClient(const LogCB& log_cb); - virtual ~WebMContentEncodingsClient(); - - const ContentEncodings& content_encodings() const; - - // WebMParserClient methods - virtual WebMParserClient* OnListStart(int id) OVERRIDE; - virtual bool OnListEnd(int id) OVERRIDE; - virtual bool OnUInt(int id, int64 val) OVERRIDE; - virtual bool OnBinary(int id, const uint8* data, int size) OVERRIDE; - - private: - LogCB log_cb_; - scoped_ptr cur_content_encoding_; - bool content_encryption_encountered_; - ContentEncodings content_encodings_; - - // |content_encodings_| is ready. For debugging purpose. - bool content_encodings_ready_; - - DISALLOW_COPY_AND_ASSIGN(WebMContentEncodingsClient); -}; - -} // namespace media - -#endif // MEDIA_WEBM_WEBM_CONTENT_ENCODINGS_CLIENT_H_ diff --git a/media/webm/webm_content_encodings_client_unittest.cc b/media/webm/webm_content_encodings_client_unittest.cc deleted file mode 100644 index bb9e694312..0000000000 --- a/media/webm/webm_content_encodings_client_unittest.cc +++ /dev/null @@ -1,238 +0,0 @@ -// Copyright (c) 2012 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/bind.h" -#include "media/webm/webm_constants.h" -#include "media/webm/webm_content_encodings_client.h" -#include "media/webm/webm_parser.h" -#include "testing/gtest/include/gtest/gtest.h" - -namespace media { - -class WebMContentEncodingsClientTest : public testing::Test { - public: - WebMContentEncodingsClientTest() - : client_(LogCB()), - parser_(kWebMIdContentEncodings, &client_) {} - - void ParseAndExpectToFail(const uint8* buf, int size) { - int result = parser_.Parse(buf, size); - EXPECT_EQ(-1, result); - } - - protected: - WebMContentEncodingsClient client_; - WebMListParser parser_; -}; - -TEST_F(WebMContentEncodingsClientTest, EmptyContentEncodings) { - const uint8 kContentEncodings[] = { - 0x6D, 0x80, 0x80, // ContentEncodings (size = 0) - }; - int size = sizeof(kContentEncodings); - ParseAndExpectToFail(kContentEncodings, size); -} - -TEST_F(WebMContentEncodingsClientTest, EmptyContentEncoding) { - const uint8 kContentEncodings[] = { - 0x6D, 0x80, 0x83, // ContentEncodings (size = 3) - 0x63, 0x40, 0x80, // ContentEncoding (size = 0) - }; - int size = sizeof(kContentEncodings); - ParseAndExpectToFail(kContentEncodings, size); -} - -TEST_F(WebMContentEncodingsClientTest, SingleContentEncoding) { - const uint8 kContentEncodings[] = { - 0x6D, 0x80, 0xA1, // ContentEncodings (size = 33) - 0x62, 0x40, 0x9e, // ContentEncoding (size = 30) - 0x50, 0x31, 0x81, 0x00, // ContentEncodingOrder (size = 1) - 0x50, 0x32, 0x81, 0x01, // ContentEncodingScope (size = 1) - 0x50, 0x33, 0x81, 0x01, // ContentEncodingType (size = 1) - 0x50, 0x35, 0x8F, // ContentEncryption (size = 15) - 0x47, 0xE1, 0x81, 0x05, // ContentEncAlgo (size = 1) - 0x47, 0xE2, 0x88, // ContentEncKeyID (size = 8) - 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, - }; - int size = sizeof(kContentEncodings); - - int result = parser_.Parse(kContentEncodings, size); - ASSERT_EQ(size, result); - const ContentEncodings& content_encodings = client_.content_encodings(); - - ASSERT_EQ(1u, content_encodings.size()); - ASSERT_TRUE(content_encodings[0]); - EXPECT_EQ(0, content_encodings[0]->order()); - EXPECT_EQ(ContentEncoding::kScopeAllFrameContents, - content_encodings[0]->scope()); - EXPECT_EQ(ContentEncoding::kTypeEncryption, content_encodings[0]->type()); - EXPECT_EQ(ContentEncoding::kEncAlgoAes, - content_encodings[0]->encryption_algo()); - EXPECT_EQ(8u, content_encodings[0]->encryption_key_id().size()); -} - -TEST_F(WebMContentEncodingsClientTest, MultipleContentEncoding) { - const uint8 kContentEncodings[] = { - 0x6D, 0x80, 0xC2, // ContentEncodings (size = 66) - 0x62, 0x40, 0x9e, // ContentEncoding (size = 30) - 0x50, 0x31, 0x81, 0x00, // ContentEncodingOrder (size = 1) - 0x50, 0x32, 0x81, 0x03, // ContentEncodingScope (size = 1) - 0x50, 0x33, 0x81, 0x01, // ContentEncodingType (size = 1) - 0x50, 0x35, 0x8F, // ContentEncryption (size = 15) - 0x47, 0xE1, 0x81, 0x05, // ContentEncAlgo (size = 1) - 0x47, 0xE2, 0x88, // ContentEncKeyID (size = 8) - 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, - 0x62, 0x40, 0x9e, // ContentEncoding (size = 30) - 0x50, 0x31, 0x81, 0x01, // ContentEncodingOrder (size = 1) - 0x50, 0x32, 0x81, 0x03, // ContentEncodingScope (size = 1) - 0x50, 0x33, 0x81, 0x01, // ContentEncodingType (size = 1) - 0x50, 0x35, 0x8F, // ContentEncryption (size = 15) - 0x47, 0xE1, 0x81, 0x01, // ContentEncAlgo (size = 1) - 0x47, 0xE2, 0x88, // ContentEncKeyID (size = 8) - 0xBB, 0xBB, 0xBB, 0xBB, 0xBB, 0xBB, 0xBB, 0xBB, - }; - int size = sizeof(kContentEncodings); - - int result = parser_.Parse(kContentEncodings, size); - ASSERT_EQ(size, result); - const ContentEncodings& content_encodings = client_.content_encodings(); - ASSERT_EQ(2u, content_encodings.size()); - - for (int i = 0; i < 2; ++i) { - ASSERT_TRUE(content_encodings[i]); - EXPECT_EQ(i, content_encodings[i]->order()); - EXPECT_EQ(ContentEncoding::kScopeAllFrameContents | - ContentEncoding::kScopeTrackPrivateData, - content_encodings[i]->scope()); - EXPECT_EQ(ContentEncoding::kTypeEncryption, content_encodings[i]->type()); - EXPECT_EQ(!i ? ContentEncoding::kEncAlgoAes : ContentEncoding::kEncAlgoDes, - content_encodings[i]->encryption_algo()); - EXPECT_EQ(8u, content_encodings[i]->encryption_key_id().size()); - } -} - -TEST_F(WebMContentEncodingsClientTest, DefaultValues) { - const uint8 kContentEncodings[] = { - 0x6D, 0x80, 0x8A, // ContentEncodings (size = 10) - 0x62, 0x40, 0x87, // ContentEncoding (size = 7) - // ContentEncodingOrder missing - // ContentEncodingScope missing - 0x50, 0x33, 0x81, 0x01, // ContentEncodingType (size = 1) - 0x50, 0x35, 0x80, // ContentEncryption (size = 0) - // ContentEncAlgo missing - }; - int size = sizeof(kContentEncodings); - - int result = parser_.Parse(kContentEncodings, size); - ASSERT_EQ(size, result); - const ContentEncodings& content_encodings = client_.content_encodings(); - - ASSERT_EQ(1u, content_encodings.size()); - ASSERT_TRUE(content_encodings[0]); - EXPECT_EQ(0, content_encodings[0]->order()); - EXPECT_EQ(ContentEncoding::kScopeAllFrameContents, - content_encodings[0]->scope()); - EXPECT_EQ(ContentEncoding::kTypeEncryption, content_encodings[0]->type()); - EXPECT_EQ(ContentEncoding::kEncAlgoNotEncrypted, - content_encodings[0]->encryption_algo()); - EXPECT_TRUE(content_encodings[0]->encryption_key_id().empty()); -} - -TEST_F(WebMContentEncodingsClientTest, ContentEncodingsClientReuse) { - const uint8 kContentEncodings[] = { - 0x6D, 0x80, 0xA1, // ContentEncodings (size = 33) - 0x62, 0x40, 0x9e, // ContentEncoding (size = 30) - 0x50, 0x31, 0x81, 0x00, // ContentEncodingOrder (size = 1) - 0x50, 0x32, 0x81, 0x01, // ContentEncodingScope (size = 1) - 0x50, 0x33, 0x81, 0x01, // ContentEncodingType (size = 1) - 0x50, 0x35, 0x8F, // ContentEncryption (size = 15) - 0x47, 0xE1, 0x81, 0x05, // ContentEncAlgo (size = 1) - 0x47, 0xE2, 0x88, // ContentEncKeyID (size = 8) - 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, - }; - int size = sizeof(kContentEncodings); - - // Parse for the first time. - int result = parser_.Parse(kContentEncodings, size); - ASSERT_EQ(size, result); - - // Parse again. - parser_.Reset(); - result = parser_.Parse(kContentEncodings, size); - ASSERT_EQ(size, result); - const ContentEncodings& content_encodings = client_.content_encodings(); - - ASSERT_EQ(1u, content_encodings.size()); - ASSERT_TRUE(content_encodings[0]); - EXPECT_EQ(0, content_encodings[0]->order()); - EXPECT_EQ(ContentEncoding::kScopeAllFrameContents, - content_encodings[0]->scope()); - EXPECT_EQ(ContentEncoding::kTypeEncryption, content_encodings[0]->type()); - EXPECT_EQ(ContentEncoding::kEncAlgoAes, - content_encodings[0]->encryption_algo()); - EXPECT_EQ(8u, content_encodings[0]->encryption_key_id().size()); -} - -TEST_F(WebMContentEncodingsClientTest, InvalidContentEncodingOrder) { - const uint8 kContentEncodings[] = { - 0x6D, 0x80, 0x8E, // ContentEncodings (size = 14) - 0x62, 0x40, 0x8B, // ContentEncoding (size = 11) - 0x50, 0x31, 0x81, 0xEE, // ContentEncodingOrder (size = 1), invalid - 0x50, 0x33, 0x81, 0x01, // ContentEncodingType (size = 1) - 0x50, 0x35, 0x80, // ContentEncryption (size = 0) - }; - int size = sizeof(kContentEncodings); - ParseAndExpectToFail(kContentEncodings, size); -} - -TEST_F(WebMContentEncodingsClientTest, InvalidContentEncodingScope) { - const uint8 kContentEncodings[] = { - 0x6D, 0x80, 0x8E, // ContentEncodings (size = 14) - 0x62, 0x40, 0x8B, // ContentEncoding (size = 11) - 0x50, 0x32, 0x81, 0xEE, // ContentEncodingScope (size = 1), invalid - 0x50, 0x33, 0x81, 0x01, // ContentEncodingType (size = 1) - 0x50, 0x35, 0x80, // ContentEncryption (size = 0) - }; - int size = sizeof(kContentEncodings); - ParseAndExpectToFail(kContentEncodings, size); -} - -TEST_F(WebMContentEncodingsClientTest, InvalidContentEncodingType) { - const uint8 kContentEncodings[] = { - 0x6D, 0x80, 0x8E, // ContentEncodings (size = 14) - 0x62, 0x40, 0x8B, // ContentEncoding (size = 11) - 0x50, 0x33, 0x81, 0x00, // ContentEncodingType (size = 1), invalid - 0x50, 0x35, 0x80, // ContentEncryption (size = 0) - }; - int size = sizeof(kContentEncodings); - ParseAndExpectToFail(kContentEncodings, size); -} - -// ContentEncodingType is encryption but no ContentEncryption present. -TEST_F(WebMContentEncodingsClientTest, MissingContentEncryption) { - const uint8 kContentEncodings[] = { - 0x6D, 0x80, 0x87, // ContentEncodings (size = 7) - 0x62, 0x40, 0x84, // ContentEncoding (size = 4) - 0x50, 0x33, 0x81, 0x01, // ContentEncodingType (size = 1) - // ContentEncryption missing - }; - int size = sizeof(kContentEncodings); - ParseAndExpectToFail(kContentEncodings, size); -} - -TEST_F(WebMContentEncodingsClientTest, InvalidContentEncAlgo) { - const uint8 kContentEncodings[] = { - 0x6D, 0x80, 0x99, // ContentEncodings (size = 25) - 0x62, 0x40, 0x96, // ContentEncoding (size = 22) - 0x50, 0x33, 0x81, 0x01, // ContentEncodingType (size = 1) - 0x50, 0x35, 0x8F, // ContentEncryption (size = 15) - 0x47, 0xE1, 0x81, 0xEE, // ContentEncAlgo (size = 1), invalid - 0x47, 0xE2, 0x88, // ContentEncKeyID (size = 8) - 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, - }; - int size = sizeof(kContentEncodings); - ParseAndExpectToFail(kContentEncodings, size); -} - -} // namespace media diff --git a/media/webm/webm_crypto_helpers.cc b/media/webm/webm_crypto_helpers.cc deleted file mode 100644 index a663f3cd6a..0000000000 --- a/media/webm/webm_crypto_helpers.cc +++ /dev/null @@ -1,60 +0,0 @@ -// Copyright (c) 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 "media/webm/webm_crypto_helpers.h" - -#include "base/logging.h" -#include "base/sys_byteorder.h" -#include "media/base/decrypt_config.h" -#include "media/webm/webm_constants.h" - -namespace media { -namespace { - -// Generates a 16 byte CTR counter block. The CTR counter block format is a -// CTR IV appended with a CTR block counter. |iv| is an 8 byte CTR IV. -// |iv_size| is the size of |iv| in btyes. Returns a string of -// kDecryptionKeySize bytes. -std::string GenerateWebMCounterBlock(const uint8* iv, int iv_size) { - std::string counter_block(reinterpret_cast(iv), iv_size); - counter_block.append(DecryptConfig::kDecryptionKeySize - iv_size, 0); - return counter_block; -} - -} // namespace anonymous - -scoped_ptr WebMCreateDecryptConfig( - const uint8* data, int data_size, - const uint8* key_id, int key_id_size) { - if (data_size < kWebMSignalByteSize) { - DVLOG(1) << "Got a block from an encrypted stream with no data."; - return scoped_ptr(); - } - - uint8 signal_byte = data[0]; - int frame_offset = sizeof(signal_byte); - - // Setting the DecryptConfig object of the buffer while leaving the - // initialization vector empty will tell the decryptor that the frame is - // unencrypted. - std::string counter_block; - - if (signal_byte & kWebMFlagEncryptedFrame) { - if (data_size < kWebMSignalByteSize + kWebMIvSize) { - DVLOG(1) << "Got an encrypted block with not enough data " << data_size; - return scoped_ptr(); - } - counter_block = GenerateWebMCounterBlock(data + frame_offset, kWebMIvSize); - frame_offset += kWebMIvSize; - } - - scoped_ptr config(new DecryptConfig( - std::string(reinterpret_cast(key_id), key_id_size), - counter_block, - frame_offset, - std::vector())); - return config.Pass(); -} - -} // namespace media diff --git a/media/webm/webm_crypto_helpers.h b/media/webm/webm_crypto_helpers.h deleted file mode 100644 index c5f1f15eca..0000000000 --- a/media/webm/webm_crypto_helpers.h +++ /dev/null @@ -1,32 +0,0 @@ -// Copyright (c) 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. - -#ifndef MEDIA_WEBM_WEBM_CRYPTO_HELPERS_H_ -#define MEDIA_WEBM_WEBM_CRYPTO_HELPERS_H_ - -#include "base/basictypes.h" -#include "base/memory/scoped_ptr.h" -#include "media/base/decoder_buffer.h" - -namespace media { - -// TODO(xhwang): Figure out the init data type appropriately once it's spec'ed. -// See https://www.w3.org/Bugs/Public/show_bug.cgi?id=19096 for more -// information. -const char kWebMEncryptInitDataType[] = "video/webm"; - -// Returns an initialized DecryptConfig, which can be sent to the Decryptor if -// the stream has potentially encrypted frames. Every encrypted Block has a -// signal byte, and if the frame is encrypted, an initialization vector -// prepended to the frame. Leaving the IV empty will tell the decryptor that the -// frame is unencrypted. Returns NULL if |data| is invalid. Current encrypted -// WebM request for comments specification is here -// http://wiki.webmproject.org/encryption/webm-encryption-rfc -scoped_ptr WebMCreateDecryptConfig( - const uint8* data, int data_size, - const uint8* key_id, int key_id_size); - -} // namespace media - -#endif // MEDIA_WEBM_WEBM_CRYPT_HELPERS_H_ diff --git a/media/webm/webm_info_parser.cc b/media/webm/webm_info_parser.cc deleted file mode 100644 index 6df1690bf8..0000000000 --- a/media/webm/webm_info_parser.cc +++ /dev/null @@ -1,84 +0,0 @@ -// Copyright (c) 2011 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 "media/webm/webm_info_parser.h" - -#include "base/logging.h" -#include "media/webm/webm_constants.h" - -namespace media { - -// Default timecode scale if the TimecodeScale element is -// not specified in the INFO element. -static const int kWebMDefaultTimecodeScale = 1000000; - -WebMInfoParser::WebMInfoParser() - : timecode_scale_(-1), - duration_(-1) { -} - -WebMInfoParser::~WebMInfoParser() {} - -int WebMInfoParser::Parse(const uint8* buf, int size) { - timecode_scale_ = -1; - duration_ = -1; - - WebMListParser parser(kWebMIdInfo, this); - int result = parser.Parse(buf, size); - - if (result <= 0) - return result; - - // For now we do all or nothing parsing. - return parser.IsParsingComplete() ? result : 0; -} - -WebMParserClient* WebMInfoParser::OnListStart(int id) { return this; } - -bool WebMInfoParser::OnListEnd(int id) { - if (id == kWebMIdInfo && timecode_scale_ == -1) { - // Set timecode scale to default value if it isn't present in - // the Info element. - timecode_scale_ = kWebMDefaultTimecodeScale; - } - return true; -} - -bool WebMInfoParser::OnUInt(int id, int64 val) { - if (id != kWebMIdTimecodeScale) - return true; - - if (timecode_scale_ != -1) { - DVLOG(1) << "Multiple values for id " << std::hex << id << " specified"; - return false; - } - - timecode_scale_ = val; - return true; -} - -bool WebMInfoParser::OnFloat(int id, double val) { - if (id != kWebMIdDuration) { - DVLOG(1) << "Unexpected float for id" << std::hex << id; - return false; - } - - if (duration_ != -1) { - DVLOG(1) << "Multiple values for duration."; - return false; - } - - duration_ = val; - return true; -} - -bool WebMInfoParser::OnBinary(int id, const uint8* data, int size) { - return true; -} - -bool WebMInfoParser::OnString(int id, const std::string& str) { - return true; -} - -} // namespace media diff --git a/media/webm/webm_info_parser.h b/media/webm/webm_info_parser.h deleted file mode 100644 index ab5de43b1d..0000000000 --- a/media/webm/webm_info_parser.h +++ /dev/null @@ -1,47 +0,0 @@ -// Copyright (c) 2012 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. - -#ifndef MEDIA_WEBM_WEBM_INFO_PARSER_H_ -#define MEDIA_WEBM_WEBM_INFO_PARSER_H_ - -#include "base/compiler_specific.h" -#include "media/base/media_export.h" -#include "media/webm/webm_parser.h" - -namespace media { - -// Parser for WebM Info element. -class MEDIA_EXPORT WebMInfoParser : public WebMParserClient { - public: - WebMInfoParser(); - virtual ~WebMInfoParser(); - - // Parses a WebM Info element in |buf|. - // - // Returns -1 if the parse fails. - // Returns 0 if more data is needed. - // Returns the number of bytes parsed on success. - int Parse(const uint8* buf, int size); - - int64 timecode_scale() const { return timecode_scale_; } - double duration() const { return duration_; } - - private: - // WebMParserClient methods - virtual WebMParserClient* OnListStart(int id) OVERRIDE; - virtual bool OnListEnd(int id) OVERRIDE; - virtual bool OnUInt(int id, int64 val) OVERRIDE; - virtual bool OnFloat(int id, double val) OVERRIDE; - virtual bool OnBinary(int id, const uint8* data, int size) OVERRIDE; - virtual bool OnString(int id, const std::string& str) OVERRIDE; - - int64 timecode_scale_; - double duration_; - - DISALLOW_COPY_AND_ASSIGN(WebMInfoParser); -}; - -} // namespace media - -#endif // MEDIA_WEBM_WEBM_INFO_PARSER_H_ diff --git a/media/webm/webm_parser.cc b/media/webm/webm_parser.cc deleted file mode 100644 index 30e5c1b5e5..0000000000 --- a/media/webm/webm_parser.cc +++ /dev/null @@ -1,943 +0,0 @@ -// Copyright (c) 2012 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 "media/webm/webm_parser.h" - -// This file contains code to parse WebM file elements. It was created -// from information in the Matroska spec. -// http://www.matroska.org/technical/specs/index.html -// This file contains code for encrypted WebM. Current WebM -// encrypted request for comments specification is here -// http://wiki.webmproject.org/encryption/webm-encryption-rfc - -#include - -#include "base/logging.h" -#include "media/webm/webm_constants.h" - -namespace media { - -enum ElementType { - UNKNOWN, - LIST, // Referred to as Master Element in the Matroska spec. - UINT, - FLOAT, - BINARY, - STRING, - SKIP, -}; - -struct ElementIdInfo { - ElementType type_; - int id_; -}; - -struct ListElementInfo { - int id_; - int level_; - const ElementIdInfo* id_info_; - int id_info_count_; -}; - -// The following are tables indicating what IDs are valid sub-elements -// of particular elements. If an element is encountered that doesn't -// appear in the list, a parsing error is signalled. Some elements are -// marked as SKIP because they are valid, but we don't care about them -// right now. -static const ElementIdInfo kEBMLHeaderIds[] = { - {UINT, kWebMIdEBMLVersion}, - {UINT, kWebMIdEBMLReadVersion}, - {UINT, kWebMIdEBMLMaxIDLength}, - {UINT, kWebMIdEBMLMaxSizeLength}, - {STRING, kWebMIdDocType}, - {UINT, kWebMIdDocTypeVersion}, - {UINT, kWebMIdDocTypeReadVersion}, -}; - -static const ElementIdInfo kSegmentIds[] = { - {LIST, kWebMIdSeekHead}, - {LIST, kWebMIdInfo}, - {LIST, kWebMIdCluster}, - {LIST, kWebMIdTracks}, - {LIST, kWebMIdCues}, - {LIST, kWebMIdAttachments}, - {LIST, kWebMIdChapters}, - {LIST, kWebMIdTags}, -}; - -static const ElementIdInfo kSeekHeadIds[] = { - {LIST, kWebMIdSeek}, -}; - -static const ElementIdInfo kSeekIds[] = { - {BINARY, kWebMIdSeekID}, - {UINT, kWebMIdSeekPosition}, -}; - -static const ElementIdInfo kInfoIds[] = { - {BINARY, kWebMIdSegmentUID}, - {STRING, kWebMIdSegmentFilename}, - {BINARY, kWebMIdPrevUID}, - {STRING, kWebMIdPrevFilename}, - {BINARY, kWebMIdNextUID}, - {STRING, kWebMIdNextFilename}, - {BINARY, kWebMIdSegmentFamily}, - {LIST, kWebMIdChapterTranslate}, - {UINT, kWebMIdTimecodeScale}, - {FLOAT, kWebMIdDuration}, - {BINARY, kWebMIdDateUTC}, - {STRING, kWebMIdTitle}, - {STRING, kWebMIdMuxingApp}, - {STRING, kWebMIdWritingApp}, -}; - -static const ElementIdInfo kChapterTranslateIds[] = { - {UINT, kWebMIdChapterTranslateEditionUID}, - {UINT, kWebMIdChapterTranslateCodec}, - {BINARY, kWebMIdChapterTranslateID}, -}; - -static const ElementIdInfo kClusterIds[] = { - {BINARY, kWebMIdSimpleBlock}, - {UINT, kWebMIdTimecode}, - {LIST, kWebMIdSilentTracks}, - {UINT, kWebMIdPosition}, - {UINT, kWebMIdPrevSize}, - {LIST, kWebMIdBlockGroup}, -}; - -static const ElementIdInfo kSilentTracksIds[] = { - {UINT, kWebMIdSilentTrackNumber}, -}; - -static const ElementIdInfo kBlockGroupIds[] = { - {BINARY, kWebMIdBlock}, - {LIST, kWebMIdBlockAdditions}, - {UINT, kWebMIdBlockDuration}, - {UINT, kWebMIdReferencePriority}, - {BINARY, kWebMIdReferenceBlock}, - {BINARY, kWebMIdCodecState}, - {LIST, kWebMIdSlices}, -}; - -static const ElementIdInfo kBlockAdditionsIds[] = { - {LIST, kWebMIdBlockMore}, -}; - -static const ElementIdInfo kBlockMoreIds[] = { - {UINT, kWebMIdBlockAddID}, - {BINARY, kWebMIdBlockAdditional}, -}; - -static const ElementIdInfo kSlicesIds[] = { - {LIST, kWebMIdTimeSlice}, -}; - -static const ElementIdInfo kTimeSliceIds[] = { - {UINT, kWebMIdLaceNumber}, -}; - -static const ElementIdInfo kTracksIds[] = { - {LIST, kWebMIdTrackEntry}, -}; - -static const ElementIdInfo kTrackEntryIds[] = { - {UINT, kWebMIdTrackNumber}, - {UINT, kWebMIdTrackUID}, - {UINT, kWebMIdTrackType}, - {UINT, kWebMIdFlagEnabled}, - {UINT, kWebMIdFlagDefault}, - {UINT, kWebMIdFlagForced}, - {UINT, kWebMIdFlagLacing}, - {UINT, kWebMIdMinCache}, - {UINT, kWebMIdMaxCache}, - {UINT, kWebMIdDefaultDuration}, - {FLOAT, kWebMIdTrackTimecodeScale}, - {UINT, kWebMIdMaxBlockAdditionId}, - {STRING, kWebMIdName}, - {STRING, kWebMIdLanguage}, - {STRING, kWebMIdCodecID}, - {BINARY, kWebMIdCodecPrivate}, - {STRING, kWebMIdCodecName}, - {UINT, kWebMIdAttachmentLink}, - {UINT, kWebMIdCodecDecodeAll}, - {UINT, kWebMIdTrackOverlay}, - {LIST, kWebMIdTrackTranslate}, - {LIST, kWebMIdVideo}, - {LIST, kWebMIdAudio}, - {LIST, kWebMIdTrackOperation}, - {LIST, kWebMIdContentEncodings}, -}; - -static const ElementIdInfo kTrackTranslateIds[] = { - {UINT, kWebMIdTrackTranslateEditionUID}, - {UINT, kWebMIdTrackTranslateCodec}, - {BINARY, kWebMIdTrackTranslateTrackID}, -}; - -static const ElementIdInfo kVideoIds[] = { - {UINT, kWebMIdFlagInterlaced}, - {UINT, kWebMIdStereoMode}, - {UINT, kWebMIdAlphaMode}, - {UINT, kWebMIdPixelWidth}, - {UINT, kWebMIdPixelHeight}, - {UINT, kWebMIdPixelCropBottom}, - {UINT, kWebMIdPixelCropTop}, - {UINT, kWebMIdPixelCropLeft}, - {UINT, kWebMIdPixelCropRight}, - {UINT, kWebMIdDisplayWidth}, - {UINT, kWebMIdDisplayHeight}, - {UINT, kWebMIdDisplayUnit}, - {UINT, kWebMIdAspectRatioType}, - {BINARY, kWebMIdColorSpace}, -}; - -static const ElementIdInfo kAudioIds[] = { - {FLOAT, kWebMIdSamplingFrequency}, - {FLOAT, kWebMIdOutputSamplingFrequency}, - {UINT, kWebMIdChannels}, - {UINT, kWebMIdBitDepth}, -}; - -static const ElementIdInfo kTrackOperationIds[] = { - {LIST, kWebMIdTrackCombinePlanes}, - {LIST, kWebMIdJoinBlocks}, -}; - -static const ElementIdInfo kTrackCombinePlanesIds[] = { - {LIST, kWebMIdTrackPlane}, -}; - -static const ElementIdInfo kTrackPlaneIds[] = { - {UINT, kWebMIdTrackPlaneUID}, - {UINT, kWebMIdTrackPlaneType}, -}; - -static const ElementIdInfo kJoinBlocksIds[] = { - {UINT, kWebMIdTrackJoinUID}, -}; - -static const ElementIdInfo kContentEncodingsIds[] = { - {LIST, kWebMIdContentEncoding}, -}; - -static const ElementIdInfo kContentEncodingIds[] = { - {UINT, kWebMIdContentEncodingOrder}, - {UINT, kWebMIdContentEncodingScope}, - {UINT, kWebMIdContentEncodingType}, - {LIST, kWebMIdContentCompression}, - {LIST, kWebMIdContentEncryption}, -}; - -static const ElementIdInfo kContentCompressionIds[] = { - {UINT, kWebMIdContentCompAlgo}, - {BINARY, kWebMIdContentCompSettings}, -}; - -static const ElementIdInfo kContentEncryptionIds[] = { - {LIST, kWebMIdContentEncAESSettings}, - {UINT, kWebMIdContentEncAlgo}, - {BINARY, kWebMIdContentEncKeyID}, - {BINARY, kWebMIdContentSignature}, - {BINARY, kWebMIdContentSigKeyID}, - {UINT, kWebMIdContentSigAlgo}, - {UINT, kWebMIdContentSigHashAlgo}, -}; - -static const ElementIdInfo kContentEncAESSettingsIds[] = { - {UINT, kWebMIdAESSettingsCipherMode}, -}; - -static const ElementIdInfo kCuesIds[] = { - {LIST, kWebMIdCuePoint}, -}; - -static const ElementIdInfo kCuePointIds[] = { - {UINT, kWebMIdCueTime}, - {LIST, kWebMIdCueTrackPositions}, -}; - -static const ElementIdInfo kCueTrackPositionsIds[] = { - {UINT, kWebMIdCueTrack}, - {UINT, kWebMIdCueClusterPosition}, - {UINT, kWebMIdCueBlockNumber}, - {UINT, kWebMIdCueCodecState}, - {LIST, kWebMIdCueReference}, -}; - -static const ElementIdInfo kCueReferenceIds[] = { - {UINT, kWebMIdCueRefTime}, -}; - -static const ElementIdInfo kAttachmentsIds[] = { - {LIST, kWebMIdAttachedFile}, -}; - -static const ElementIdInfo kAttachedFileIds[] = { - {STRING, kWebMIdFileDescription}, - {STRING, kWebMIdFileName}, - {STRING, kWebMIdFileMimeType}, - {BINARY, kWebMIdFileData}, - {UINT, kWebMIdFileUID}, -}; - -static const ElementIdInfo kChaptersIds[] = { - {LIST, kWebMIdEditionEntry}, -}; - -static const ElementIdInfo kEditionEntryIds[] = { - {UINT, kWebMIdEditionUID}, - {UINT, kWebMIdEditionFlagHidden}, - {UINT, kWebMIdEditionFlagDefault}, - {UINT, kWebMIdEditionFlagOrdered}, - {LIST, kWebMIdChapterAtom}, -}; - -static const ElementIdInfo kChapterAtomIds[] = { - {UINT, kWebMIdChapterUID}, - {UINT, kWebMIdChapterTimeStart}, - {UINT, kWebMIdChapterTimeEnd}, - {UINT, kWebMIdChapterFlagHidden}, - {UINT, kWebMIdChapterFlagEnabled}, - {BINARY, kWebMIdChapterSegmentUID}, - {UINT, kWebMIdChapterSegmentEditionUID}, - {UINT, kWebMIdChapterPhysicalEquiv}, - {LIST, kWebMIdChapterTrack}, - {LIST, kWebMIdChapterDisplay}, - {LIST, kWebMIdChapProcess}, -}; - -static const ElementIdInfo kChapterTrackIds[] = { - {UINT, kWebMIdChapterTrackNumber}, -}; - -static const ElementIdInfo kChapterDisplayIds[] = { - {STRING, kWebMIdChapString}, - {STRING, kWebMIdChapLanguage}, - {STRING, kWebMIdChapCountry}, -}; - -static const ElementIdInfo kChapProcessIds[] = { - {UINT, kWebMIdChapProcessCodecID}, - {BINARY, kWebMIdChapProcessPrivate}, - {LIST, kWebMIdChapProcessCommand}, -}; - -static const ElementIdInfo kChapProcessCommandIds[] = { - {UINT, kWebMIdChapProcessTime}, - {BINARY, kWebMIdChapProcessData}, -}; - -static const ElementIdInfo kTagsIds[] = { - {LIST, kWebMIdTag}, -}; - -static const ElementIdInfo kTagIds[] = { - {LIST, kWebMIdTargets}, - {LIST, kWebMIdSimpleTag}, -}; - -static const ElementIdInfo kTargetsIds[] = { - {UINT, kWebMIdTargetTypeValue}, - {STRING, kWebMIdTargetType}, - {UINT, kWebMIdTagTrackUID}, - {UINT, kWebMIdTagEditionUID}, - {UINT, kWebMIdTagChapterUID}, - {UINT, kWebMIdTagAttachmentUID}, -}; - -static const ElementIdInfo kSimpleTagIds[] = { - {STRING, kWebMIdTagName}, - {STRING, kWebMIdTagLanguage}, - {UINT, kWebMIdTagDefault}, - {STRING, kWebMIdTagString}, - {BINARY, kWebMIdTagBinary}, -}; - -#define LIST_ELEMENT_INFO(id, level, id_info) \ - { (id), (level), (id_info), arraysize(id_info) } - -static const ListElementInfo kListElementInfo[] = { - LIST_ELEMENT_INFO(kWebMIdCluster, 1, kClusterIds), - LIST_ELEMENT_INFO(kWebMIdEBMLHeader, 0, kEBMLHeaderIds), - LIST_ELEMENT_INFO(kWebMIdSegment, 0, kSegmentIds), - LIST_ELEMENT_INFO(kWebMIdSeekHead, 1, kSeekHeadIds), - LIST_ELEMENT_INFO(kWebMIdSeek, 2, kSeekIds), - LIST_ELEMENT_INFO(kWebMIdInfo, 1, kInfoIds), - LIST_ELEMENT_INFO(kWebMIdChapterTranslate, 2, kChapterTranslateIds), - LIST_ELEMENT_INFO(kWebMIdSilentTracks, 2, kSilentTracksIds), - LIST_ELEMENT_INFO(kWebMIdBlockGroup, 2, kBlockGroupIds), - LIST_ELEMENT_INFO(kWebMIdBlockAdditions, 3, kBlockAdditionsIds), - LIST_ELEMENT_INFO(kWebMIdBlockMore, 4, kBlockMoreIds), - LIST_ELEMENT_INFO(kWebMIdSlices, 3, kSlicesIds), - LIST_ELEMENT_INFO(kWebMIdTimeSlice, 4, kTimeSliceIds), - LIST_ELEMENT_INFO(kWebMIdTracks, 1, kTracksIds), - LIST_ELEMENT_INFO(kWebMIdTrackEntry, 2, kTrackEntryIds), - LIST_ELEMENT_INFO(kWebMIdTrackTranslate, 3, kTrackTranslateIds), - LIST_ELEMENT_INFO(kWebMIdVideo, 3, kVideoIds), - LIST_ELEMENT_INFO(kWebMIdAudio, 3, kAudioIds), - LIST_ELEMENT_INFO(kWebMIdTrackOperation, 3, kTrackOperationIds), - LIST_ELEMENT_INFO(kWebMIdTrackCombinePlanes, 4, kTrackCombinePlanesIds), - LIST_ELEMENT_INFO(kWebMIdTrackPlane, 5, kTrackPlaneIds), - LIST_ELEMENT_INFO(kWebMIdJoinBlocks, 4, kJoinBlocksIds), - LIST_ELEMENT_INFO(kWebMIdContentEncodings, 3, kContentEncodingsIds), - LIST_ELEMENT_INFO(kWebMIdContentEncoding, 4, kContentEncodingIds), - LIST_ELEMENT_INFO(kWebMIdContentCompression, 5, kContentCompressionIds), - LIST_ELEMENT_INFO(kWebMIdContentEncryption, 5, kContentEncryptionIds), - LIST_ELEMENT_INFO(kWebMIdContentEncAESSettings, 6, kContentEncAESSettingsIds), - LIST_ELEMENT_INFO(kWebMIdCues, 1, kCuesIds), - LIST_ELEMENT_INFO(kWebMIdCuePoint, 2, kCuePointIds), - LIST_ELEMENT_INFO(kWebMIdCueTrackPositions, 3, kCueTrackPositionsIds), - LIST_ELEMENT_INFO(kWebMIdCueReference, 4, kCueReferenceIds), - LIST_ELEMENT_INFO(kWebMIdAttachments, 1, kAttachmentsIds), - LIST_ELEMENT_INFO(kWebMIdAttachedFile, 2, kAttachedFileIds), - LIST_ELEMENT_INFO(kWebMIdChapters, 1, kChaptersIds), - LIST_ELEMENT_INFO(kWebMIdEditionEntry, 2, kEditionEntryIds), - LIST_ELEMENT_INFO(kWebMIdChapterAtom, 3, kChapterAtomIds), - LIST_ELEMENT_INFO(kWebMIdChapterTrack, 4, kChapterTrackIds), - LIST_ELEMENT_INFO(kWebMIdChapterDisplay, 4, kChapterDisplayIds), - LIST_ELEMENT_INFO(kWebMIdChapProcess, 4, kChapProcessIds), - LIST_ELEMENT_INFO(kWebMIdChapProcessCommand, 5, kChapProcessCommandIds), - LIST_ELEMENT_INFO(kWebMIdTags, 1, kTagsIds), - LIST_ELEMENT_INFO(kWebMIdTag, 2, kTagIds), - LIST_ELEMENT_INFO(kWebMIdTargets, 3, kTargetsIds), - LIST_ELEMENT_INFO(kWebMIdSimpleTag, 3, kSimpleTagIds), -}; - -// Parses an element header id or size field. These fields are variable length -// encoded. The first byte indicates how many bytes the field occupies. -// |buf| - The buffer to parse. -// |size| - The number of bytes in |buf| -// |max_bytes| - The maximum number of bytes the field can be. ID fields -// set this to 4 & element size fields set this to 8. If the -// first byte indicates a larger field size than this it is a -// parser error. -// |mask_first_byte| - For element size fields the field length encoding bits -// need to be masked off. This parameter is true for -// element size fields and is false for ID field values. -// -// Returns: The number of bytes parsed on success. -1 on error. -static int ParseWebMElementHeaderField(const uint8* buf, int size, - int max_bytes, bool mask_first_byte, - int64* num) { - DCHECK(buf); - DCHECK(num); - - if (size < 0) - return -1; - - if (size == 0) - return 0; - - int mask = 0x80; - uint8 ch = buf[0]; - int extra_bytes = -1; - bool all_ones = false; - for (int i = 0; i < max_bytes; ++i) { - if ((ch & mask) != 0) { - mask = ~mask & 0xff; - *num = mask_first_byte ? ch & mask : ch; - all_ones = (ch & mask) == mask; - extra_bytes = i; - break; - } - mask = 0x80 | mask >> 1; - } - - if (extra_bytes == -1) - return -1; - - // Return 0 if we need more data. - if ((1 + extra_bytes) > size) - return 0; - - int bytes_used = 1; - - for (int i = 0; i < extra_bytes; ++i) { - ch = buf[bytes_used++]; - all_ones &= (ch == 0xff); - *num = (*num << 8) | ch; - } - - if (all_ones) - *num = kint64max; - - return bytes_used; -} - -int WebMParseElementHeader(const uint8* buf, int size, - int* id, int64* element_size) { - DCHECK(buf); - DCHECK_GE(size, 0); - DCHECK(id); - DCHECK(element_size); - - if (size == 0) - return 0; - - int64 tmp = 0; - int num_id_bytes = ParseWebMElementHeaderField(buf, size, 4, false, &tmp); - - if (num_id_bytes <= 0) - return num_id_bytes; - - if (tmp == kint64max) - tmp = kWebMReservedId; - - *id = static_cast(tmp); - - int num_size_bytes = ParseWebMElementHeaderField(buf + num_id_bytes, - size - num_id_bytes, - 8, true, &tmp); - - if (num_size_bytes <= 0) - return num_size_bytes; - - if (tmp == kint64max) - tmp = kWebMUnknownSize; - - *element_size = tmp; - DVLOG(3) << "WebMParseElementHeader() : id " << std::hex << *id << std::dec - << " size " << *element_size; - return num_id_bytes + num_size_bytes; -} - -// Finds ElementType for a specific ID. -static ElementType FindIdType(int id, - const ElementIdInfo* id_info, - int id_info_count) { - - // Check for global element IDs that can be anywhere. - if (id == kWebMIdVoid || id == kWebMIdCRC32) - return SKIP; - - for (int i = 0; i < id_info_count; ++i) { - if (id == id_info[i].id_) - return id_info[i].type_; - } - - return UNKNOWN; -} - -// Finds ListElementInfo for a specific ID. -static const ListElementInfo* FindListInfo(int id) { - for (size_t i = 0; i < arraysize(kListElementInfo); ++i) { - if (id == kListElementInfo[i].id_) - return &kListElementInfo[i]; - } - - return NULL; -} - -static int FindListLevel(int id) { - const ListElementInfo* list_info = FindListInfo(id); - if (list_info) - return list_info->level_; - - return -1; -} - -static int ParseUInt(const uint8* buf, int size, int id, - WebMParserClient* client) { - if ((size <= 0) || (size > 8)) - return -1; - - // Read in the big-endian integer. - int64 value = 0; - for (int i = 0; i < size; ++i) - value = (value << 8) | buf[i]; - - if (!client->OnUInt(id, value)) - return -1; - - return size; -} - -static int ParseFloat(const uint8* buf, int size, int id, - WebMParserClient* client) { - - if ((size != 4) && (size != 8)) - return -1; - - double value = -1; - - // Read the bytes from big-endian form into a native endian integer. - int64 tmp = 0; - for (int i = 0; i < size; ++i) - tmp = (tmp << 8) | buf[i]; - - // Use a union to convert the integer bit pattern into a floating point - // number. - if (size == 4) { - union { - int32 src; - float dst; - } tmp2; - tmp2.src = static_cast(tmp); - value = tmp2.dst; - } else if (size == 8) { - union { - int64 src; - double dst; - } tmp2; - tmp2.src = tmp; - value = tmp2.dst; - } else { - return -1; - } - - if (!client->OnFloat(id, value)) - return -1; - - return size; -} - -static int ParseBinary(const uint8* buf, int size, int id, - WebMParserClient* client) { - return client->OnBinary(id, buf, size) ? size : -1; -} - -static int ParseString(const uint8* buf, int size, int id, - WebMParserClient* client) { - const uint8* end = static_cast(memchr(buf, '\0', size)); - int length = (end != NULL) ? static_cast(end - buf) : size; - std::string str(reinterpret_cast(buf), length); - return client->OnString(id, str) ? size : -1; -} - -static int ParseNonListElement(ElementType type, int id, int64 element_size, - const uint8* buf, int size, - WebMParserClient* client) { - DCHECK_GE(size, element_size); - - int result = -1; - switch(type) { - case LIST: - NOTIMPLEMENTED(); - result = -1; - break; - case UINT: - result = ParseUInt(buf, element_size, id, client); - break; - case FLOAT: - result = ParseFloat(buf, element_size, id, client); - break; - case BINARY: - result = ParseBinary(buf, element_size, id, client); - break; - case STRING: - result = ParseString(buf, element_size, id, client); - break; - case SKIP: - result = element_size; - break; - default: - DVLOG(1) << "Unhandled ID type " << type; - return -1; - }; - - DCHECK_LE(result, size); - return result; -} - -WebMParserClient::WebMParserClient() {} -WebMParserClient::~WebMParserClient() {} - -WebMParserClient* WebMParserClient::OnListStart(int id) { - DVLOG(1) << "Unexpected list element start with ID " << std::hex << id; - return NULL; -} - -bool WebMParserClient::OnListEnd(int id) { - DVLOG(1) << "Unexpected list element end with ID " << std::hex << id; - return false; -} - -bool WebMParserClient::OnUInt(int id, int64 val) { - DVLOG(1) << "Unexpected unsigned integer element with ID " << std::hex << id; - return false; -} - -bool WebMParserClient::OnFloat(int id, double val) { - DVLOG(1) << "Unexpected float element with ID " << std::hex << id; - return false; -} - -bool WebMParserClient::OnBinary(int id, const uint8* data, int size) { - DVLOG(1) << "Unexpected binary element with ID " << std::hex << id; - return false; -} - -bool WebMParserClient::OnString(int id, const std::string& str) { - DVLOG(1) << "Unexpected string element with ID " << std::hex << id; - return false; -} - -WebMListParser::WebMListParser(int id, WebMParserClient* client) - : state_(NEED_LIST_HEADER), - root_id_(id), - root_level_(FindListLevel(id)), - root_client_(client) { - DCHECK_GE(root_level_, 0); - DCHECK(client); -} - -WebMListParser::~WebMListParser() {} - -void WebMListParser::Reset() { - ChangeState(NEED_LIST_HEADER); - list_state_stack_.clear(); -} - -int WebMListParser::Parse(const uint8* buf, int size) { - DCHECK(buf); - - if (size < 0 || state_ == PARSE_ERROR || state_ == DONE_PARSING_LIST) - return -1; - - if (size == 0) - return 0; - - const uint8* cur = buf; - int cur_size = size; - int bytes_parsed = 0; - - while (cur_size > 0 && state_ != PARSE_ERROR && state_ != DONE_PARSING_LIST) { - int element_id = 0; - int64 element_size = 0; - int result = WebMParseElementHeader(cur, cur_size, &element_id, - &element_size); - - if (result < 0) - return result; - - if (result == 0) - return bytes_parsed; - - switch(state_) { - case NEED_LIST_HEADER: { - if (element_id != root_id_) { - ChangeState(PARSE_ERROR); - return -1; - } - - // Only allow Segment & Cluster to have an unknown size. - if (element_size == kWebMUnknownSize && - (element_id != kWebMIdSegment) && - (element_id != kWebMIdCluster)) { - ChangeState(PARSE_ERROR); - return -1; - } - - ChangeState(INSIDE_LIST); - if (!OnListStart(root_id_, element_size)) - return -1; - - break; - } - - case INSIDE_LIST: { - int header_size = result; - const uint8* element_data = cur + header_size; - int element_data_size = cur_size - header_size; - - if (element_size < element_data_size) - element_data_size = element_size; - - result = ParseListElement(header_size, element_id, element_size, - element_data, element_data_size); - - DCHECK_LE(result, header_size + element_data_size); - if (result < 0) { - ChangeState(PARSE_ERROR); - return -1; - } - - if (result == 0) - return bytes_parsed; - - break; - } - case DONE_PARSING_LIST: - case PARSE_ERROR: - // Shouldn't be able to get here. - NOTIMPLEMENTED(); - break; - } - - cur += result; - cur_size -= result; - bytes_parsed += result; - } - - return (state_ == PARSE_ERROR) ? -1 : bytes_parsed; -} - -bool WebMListParser::IsParsingComplete() const { - return state_ == DONE_PARSING_LIST; -} - -void WebMListParser::ChangeState(State new_state) { - state_ = new_state; -} - -int WebMListParser::ParseListElement(int header_size, - int id, int64 element_size, - const uint8* data, int size) { - DCHECK_GT(list_state_stack_.size(), 0u); - - ListState& list_state = list_state_stack_.back(); - DCHECK(list_state.element_info_); - - const ListElementInfo* element_info = list_state.element_info_; - ElementType id_type = - FindIdType(id, element_info->id_info_, element_info->id_info_count_); - - // Unexpected ID. - if (id_type == UNKNOWN) { - if (list_state.size_ != kWebMUnknownSize || - !IsSiblingOrAncestor(list_state.id_, id)) { - DVLOG(1) << "No ElementType info for ID 0x" << std::hex << id; - return -1; - } - - // We've reached the end of a list of unknown size. Update the size now that - // we know it and dispatch the end of list calls. - list_state.size_ = list_state.bytes_parsed_; - - if (!OnListEnd()) - return -1; - - // Check to see if all open lists have ended. - if (list_state_stack_.size() == 0) - return 0; - - list_state = list_state_stack_.back(); - } - - // Make sure the whole element can fit inside the current list. - int64 total_element_size = header_size + element_size; - if (list_state.size_ != kWebMUnknownSize && - list_state.size_ < list_state.bytes_parsed_ + total_element_size) { - return -1; - } - - if (id_type == LIST) { - list_state.bytes_parsed_ += header_size; - - if (!OnListStart(id, element_size)) - return -1; - return header_size; - } - - // Make sure we have the entire element before trying to parse a non-list - // element. - if (size < element_size) - return 0; - - int bytes_parsed = ParseNonListElement(id_type, id, element_size, - data, size, list_state.client_); - DCHECK_LE(bytes_parsed, size); - - // Return if an error occurred or we need more data. - // Note: bytes_parsed is 0 for a successful parse of a size 0 element. We - // need to check the element_size to disambiguate the "need more data" case - // from a successful parse. - if (bytes_parsed < 0 || (bytes_parsed == 0 && element_size != 0)) - return bytes_parsed; - - int result = header_size + bytes_parsed; - list_state.bytes_parsed_ += result; - - // See if we have reached the end of the current list. - if (list_state.bytes_parsed_ == list_state.size_) { - if (!OnListEnd()) - return -1; - } - - return result; -} - -bool WebMListParser::OnListStart(int id, int64 size) { - const ListElementInfo* element_info = FindListInfo(id); - if (!element_info) - return false; - - int current_level = root_level_ + list_state_stack_.size() - 1; - if (current_level + 1 != element_info->level_) - return false; - - WebMParserClient* current_list_client = NULL; - if (!list_state_stack_.empty()) { - // Make sure the new list doesn't go past the end of the current list. - ListState current_list_state = list_state_stack_.back(); - if (current_list_state.size_ != kWebMUnknownSize && - current_list_state.size_ < current_list_state.bytes_parsed_ + size) - return false; - current_list_client = current_list_state.client_; - } else { - current_list_client = root_client_; - } - - WebMParserClient* new_list_client = current_list_client->OnListStart(id); - if (!new_list_client) - return false; - - ListState new_list_state = { id, size, 0, element_info, new_list_client }; - list_state_stack_.push_back(new_list_state); - - if (size == 0) - return OnListEnd(); - - return true; -} - -bool WebMListParser::OnListEnd() { - int lists_ended = 0; - for (; !list_state_stack_.empty(); ++lists_ended) { - const ListState& list_state = list_state_stack_.back(); - - if (list_state.bytes_parsed_ != list_state.size_) - break; - - list_state_stack_.pop_back(); - - int64 bytes_parsed = list_state.bytes_parsed_; - WebMParserClient* client = NULL; - if (!list_state_stack_.empty()) { - // Update the bytes_parsed_ for the parent element. - list_state_stack_.back().bytes_parsed_ += bytes_parsed; - client = list_state_stack_.back().client_; - } else { - client = root_client_; - } - - if (!client->OnListEnd(list_state.id_)) - return false; - } - - DCHECK_GE(lists_ended, 1); - - if (list_state_stack_.empty()) - ChangeState(DONE_PARSING_LIST); - - return true; -} - -bool WebMListParser::IsSiblingOrAncestor(int id_a, int id_b) const { - DCHECK((id_a == kWebMIdSegment) || (id_a == kWebMIdCluster)); - - if (id_a == kWebMIdCluster) { - // kWebMIdCluster siblings. - for (size_t i = 0; i < arraysize(kSegmentIds); i++) { - if (kSegmentIds[i].id_ == id_b) - return true; - } - } - - // kWebMIdSegment siblings. - return ((id_b == kWebMIdSegment) || (id_b == kWebMIdEBMLHeader)); -} - -} // namespace media diff --git a/media/webm/webm_parser.h b/media/webm/webm_parser.h deleted file mode 100644 index 68611a85bd..0000000000 --- a/media/webm/webm_parser.h +++ /dev/null @@ -1,158 +0,0 @@ -// Copyright (c) 2012 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. - -#ifndef MEDIA_WEBM_WEBM_PARSER_H_ -#define MEDIA_WEBM_WEBM_PARSER_H_ - -#include -#include - -#include "base/basictypes.h" -#include "media/base/media_export.h" - -namespace media { - -// Interface for receiving WebM parser events. -// -// Each method is called when an element of the specified type is parsed. -// The ID of the element that was parsed is given along with the value -// stored in the element. List elements generate calls at the start and -// end of the list. Any pointers passed to these methods are only guaranteed -// to be valid for the life of that call. Each method (except for OnListStart) -// returns a bool that indicates whether the parsed data is valid. OnListStart -// returns a pointer to a WebMParserClient object, which should be used to -// handle elements parsed out of the list being started. If false (or NULL by -// OnListStart) is returned then the parse is immediately terminated and an -// error is reported by the parser. -class MEDIA_EXPORT WebMParserClient { - public: - virtual ~WebMParserClient(); - - virtual WebMParserClient* OnListStart(int id); - virtual bool OnListEnd(int id); - virtual bool OnUInt(int id, int64 val); - virtual bool OnFloat(int id, double val); - virtual bool OnBinary(int id, const uint8* data, int size); - virtual bool OnString(int id, const std::string& str); - - protected: - WebMParserClient(); - - DISALLOW_COPY_AND_ASSIGN(WebMParserClient); -}; - -struct ListElementInfo; - -// Parses a WebM list element and all of its children. This -// class supports incremental parsing of the list so Parse() -// can be called multiple times with pieces of the list. -// IsParsingComplete() will return true once the entire list has -// been parsed. -class MEDIA_EXPORT WebMListParser { - public: - // |id| - Element ID of the list we intend to parse. - // |client| - Called as different elements in the list are parsed. - WebMListParser(int id, WebMParserClient* client); - ~WebMListParser(); - - // Resets the state of the parser so it can start parsing a new list. - void Reset(); - - // Parses list data contained in |buf|. - // - // Returns < 0 if the parse fails. - // Returns 0 if more data is needed. - // Returning > 0 indicates success & the number of bytes parsed. - int Parse(const uint8* buf, int size); - - // Returns true if the entire list has been parsed. - bool IsParsingComplete() const; - - private: - enum State { - NEED_LIST_HEADER, - INSIDE_LIST, - DONE_PARSING_LIST, - PARSE_ERROR, - }; - - struct ListState { - int id_; - int64 size_; - int64 bytes_parsed_; - const ListElementInfo* element_info_; - WebMParserClient* client_; - }; - - void ChangeState(State new_state); - - // Parses a single element in the current list. - // - // |header_size| - The size of the element header - // |id| - The ID of the element being parsed. - // |element_size| - The size of the element body. - // |data| - Pointer to the element contents. - // |size| - Number of bytes in |data| - // |client| - Client to pass the parsed data to. - // - // Returns < 0 if the parse fails. - // Returns 0 if more data is needed. - // Returning > 0 indicates success & the number of bytes parsed. - int ParseListElement(int header_size, - int id, int64 element_size, - const uint8* data, int size); - - // Called when starting to parse a new list. - // - // |id| - The ID of the new list. - // |size| - The size of the new list. - // |client| - The client object to notify that a new list is being parsed. - // - // Returns true if this list can be started in the current context. False - // if starting this list causes some sort of parse error. - bool OnListStart(int id, int64 size); - - // Called when the end of the current list has been reached. This may also - // signal the end of the current list's ancestors if the current list happens - // to be at the end of its parent. - // - // Returns true if no errors occurred while ending this list(s). - bool OnListEnd(); - - // Checks to see if |id_b| is a sibling or ancestor of |id_a|. - bool IsSiblingOrAncestor(int id_a, int id_b) const; - - State state_; - - // Element ID passed to the constructor. - const int root_id_; - - // Element level for |root_id_|. Used to verify that elements appear at - // the correct level. - const int root_level_; - - // WebMParserClient to handle the root list. - WebMParserClient* const root_client_; - - // Stack of state for all the lists currently being parsed. Lists are - // added and removed from this stack as they are parsed. - std::vector list_state_stack_; - - DISALLOW_COPY_AND_ASSIGN(WebMListParser); -}; - -// Parses an element header & returns the ID and element size. -// -// Returns < 0 if the parse fails. -// Returns 0 if more data is needed. -// Returning > 0 indicates success & the number of bytes parsed. -// |*id| contains the element ID on success and is undefined otherwise. -// |*element_size| contains the element size on success and is undefined -// otherwise. -int MEDIA_EXPORT WebMParseElementHeader(const uint8* buf, int size, - int* id, int64* element_size); - -} // namespace media - -#endif // MEDIA_WEBM_WEBM_PARSER_H_ diff --git a/media/webm/webm_parser_unittest.cc b/media/webm/webm_parser_unittest.cc deleted file mode 100644 index cb71fe98bd..0000000000 --- a/media/webm/webm_parser_unittest.cc +++ /dev/null @@ -1,395 +0,0 @@ -// Copyright (c) 2012 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 "media/webm/cluster_builder.h" -#include "media/webm/webm_constants.h" -#include "media/webm/webm_parser.h" -#include "testing/gmock/include/gmock/gmock.h" -#include "testing/gtest/include/gtest/gtest.h" - -using ::testing::InSequence; -using ::testing::Return; -using ::testing::ReturnNull; -using ::testing::StrictMock; -using ::testing::_; - -namespace media { - -enum { kBlockCount = 5 }; - -class MockWebMParserClient : public WebMParserClient { - public: - virtual ~MockWebMParserClient() {} - - // WebMParserClient methods. - MOCK_METHOD1(OnListStart, WebMParserClient*(int)); - MOCK_METHOD1(OnListEnd, bool(int)); - MOCK_METHOD2(OnUInt, bool(int, int64)); - MOCK_METHOD2(OnFloat, bool(int, double)); - MOCK_METHOD3(OnBinary, bool(int, const uint8*, int)); - MOCK_METHOD2(OnString, bool(int, const std::string&)); -}; - -class WebMParserTest : public testing::Test { - protected: - StrictMock client_; -}; - -static scoped_ptr CreateCluster(int block_count) { - ClusterBuilder cb; - cb.SetClusterTimecode(0); - - for (int i = 0; i < block_count; i++) { - uint8 data[] = { 0x00 }; - cb.AddSimpleBlock(0, i, 0, data, sizeof(data)); - } - - return cb.Finish(); -} - -static void CreateClusterExpectations(int block_count, - bool is_complete_cluster, - MockWebMParserClient* client) { - - InSequence s; - EXPECT_CALL(*client, OnListStart(kWebMIdCluster)).WillOnce(Return(client)); - EXPECT_CALL(*client, OnUInt(kWebMIdTimecode, 0)) - .WillOnce(Return(true)); - - for (int i = 0; i < block_count; i++) { - EXPECT_CALL(*client, OnBinary(kWebMIdSimpleBlock, _, _)) - .WillOnce(Return(true)); - } - - if (is_complete_cluster) - EXPECT_CALL(*client, OnListEnd(kWebMIdCluster)).WillOnce(Return(true)); -} - -TEST_F(WebMParserTest, EmptyCluster) { - const uint8 kEmptyCluster[] = { - 0x1F, 0x43, 0xB6, 0x75, 0x80 // CLUSTER (size = 0) - }; - int size = sizeof(kEmptyCluster); - - InSequence s; - EXPECT_CALL(client_, OnListStart(kWebMIdCluster)).WillOnce(Return(&client_)); - EXPECT_CALL(client_, OnListEnd(kWebMIdCluster)).WillOnce(Return(true)); - - WebMListParser parser(kWebMIdCluster, &client_); - int result = parser.Parse(kEmptyCluster, size); - EXPECT_EQ(size, result); - EXPECT_TRUE(parser.IsParsingComplete()); -} - -TEST_F(WebMParserTest, EmptyClusterInSegment) { - const uint8 kBuffer[] = { - 0x18, 0x53, 0x80, 0x67, 0x85, // SEGMENT (size = 5) - 0x1F, 0x43, 0xB6, 0x75, 0x80, // CLUSTER (size = 0) - }; - int size = sizeof(kBuffer); - - InSequence s; - EXPECT_CALL(client_, OnListStart(kWebMIdSegment)).WillOnce(Return(&client_)); - EXPECT_CALL(client_, OnListStart(kWebMIdCluster)).WillOnce(Return(&client_)); - EXPECT_CALL(client_, OnListEnd(kWebMIdCluster)).WillOnce(Return(true)); - EXPECT_CALL(client_, OnListEnd(kWebMIdSegment)).WillOnce(Return(true)); - - WebMListParser parser(kWebMIdSegment, &client_); - int result = parser.Parse(kBuffer, size); - EXPECT_EQ(size, result); - EXPECT_TRUE(parser.IsParsingComplete()); -} - -// Test the case where a non-list child element has a size -// that is beyond the end of the parent. -TEST_F(WebMParserTest, ChildNonListLargerThanParent) { - const uint8 kBuffer[] = { - 0x1F, 0x43, 0xB6, 0x75, 0x81, // CLUSTER (size = 1) - 0xE7, 0x81, 0x01, // Timecode (size=1, value=1) - }; - int size = sizeof(kBuffer); - - InSequence s; - EXPECT_CALL(client_, OnListStart(kWebMIdCluster)).WillOnce(Return(&client_)); - - WebMListParser parser(kWebMIdCluster, &client_); - int result = parser.Parse(kBuffer, size); - EXPECT_EQ(-1, result); - EXPECT_FALSE(parser.IsParsingComplete()); -} - -// Test the case where a list child element has a size -// that is beyond the end of the parent. -TEST_F(WebMParserTest, ChildListLargerThanParent) { - const uint8 kBuffer[] = { - 0x18, 0x53, 0x80, 0x67, 0x85, // SEGMENT (size = 5) - 0x1F, 0x43, 0xB6, 0x75, 0x81, 0x11 // CLUSTER (size = 1) - }; - int size = sizeof(kBuffer); - - InSequence s; - EXPECT_CALL(client_, OnListStart(kWebMIdSegment)).WillOnce(Return(&client_)); - - WebMListParser parser(kWebMIdSegment, &client_); - int result = parser.Parse(kBuffer, size); - EXPECT_EQ(-1, result); - EXPECT_FALSE(parser.IsParsingComplete()); -} - -// Expecting to parse a Cluster, but get a Segment. -TEST_F(WebMParserTest, ListIdDoesNotMatch) { - const uint8 kBuffer[] = { - 0x18, 0x53, 0x80, 0x67, 0x80, // SEGMENT (size = 0) - }; - int size = sizeof(kBuffer); - - WebMListParser parser(kWebMIdCluster, &client_); - int result = parser.Parse(kBuffer, size); - EXPECT_EQ(-1, result); - EXPECT_FALSE(parser.IsParsingComplete()); -} - -TEST_F(WebMParserTest, InvalidElementInList) { - const uint8 kBuffer[] = { - 0x18, 0x53, 0x80, 0x67, 0x82, // SEGMENT (size = 2) - 0xAE, 0x80, // TrackEntry (size = 0) - }; - int size = sizeof(kBuffer); - - InSequence s; - EXPECT_CALL(client_, OnListStart(kWebMIdSegment)).WillOnce(Return(&client_)); - - WebMListParser parser(kWebMIdSegment, &client_); - int result = parser.Parse(kBuffer, size); - EXPECT_EQ(-1, result); - EXPECT_FALSE(parser.IsParsingComplete()); -} - -TEST_F(WebMParserTest, VoidAndCRC32InList) { - const uint8 kBuffer[] = { - 0x18, 0x53, 0x80, 0x67, 0x99, // SEGMENT (size = 25) - 0xEC, 0x83, 0x00, 0x00, 0x00, // Void (size = 3) - 0xBF, 0x83, 0x00, 0x00, 0x00, // CRC32 (size = 3) - 0x1F, 0x43, 0xB6, 0x75, 0x8A, // CLUSTER (size = 10) - 0xEC, 0x83, 0x00, 0x00, 0x00, // Void (size = 3) - 0xBF, 0x83, 0x00, 0x00, 0x00, // CRC32 (size = 3) - }; - int size = sizeof(kBuffer); - - InSequence s; - EXPECT_CALL(client_, OnListStart(kWebMIdSegment)).WillOnce(Return(&client_)); - EXPECT_CALL(client_, OnListStart(kWebMIdCluster)).WillOnce(Return(&client_)); - EXPECT_CALL(client_, OnListEnd(kWebMIdCluster)).WillOnce(Return(true)); - EXPECT_CALL(client_, OnListEnd(kWebMIdSegment)).WillOnce(Return(true)); - - WebMListParser parser(kWebMIdSegment, &client_); - int result = parser.Parse(kBuffer, size); - EXPECT_EQ(size, result); - EXPECT_TRUE(parser.IsParsingComplete()); -} - - -TEST_F(WebMParserTest, ParseListElementWithSingleCall) { - scoped_ptr cluster(CreateCluster(kBlockCount)); - CreateClusterExpectations(kBlockCount, true, &client_); - - WebMListParser parser(kWebMIdCluster, &client_); - int result = parser.Parse(cluster->data(), cluster->size()); - EXPECT_EQ(cluster->size(), result); - EXPECT_TRUE(parser.IsParsingComplete()); -} - -TEST_F(WebMParserTest, ParseListElementWithMultipleCalls) { - scoped_ptr cluster(CreateCluster(kBlockCount)); - CreateClusterExpectations(kBlockCount, true, &client_); - - const uint8* data = cluster->data(); - int size = cluster->size(); - int default_parse_size = 3; - WebMListParser parser(kWebMIdCluster, &client_); - int parse_size = std::min(default_parse_size, size); - - 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. - EXPECT_FALSE(parser.IsParsingComplete()); - parse_size += default_parse_size; - parse_size = std::min(parse_size, size); - continue; - } - - parse_size = default_parse_size; - - data += result; - size -= result; - - EXPECT_EQ((size == 0), parser.IsParsingComplete()); - } - EXPECT_TRUE(parser.IsParsingComplete()); -} - -TEST_F(WebMParserTest, Reset) { - InSequence s; - scoped_ptr cluster(CreateCluster(kBlockCount)); - - // First expect all but the last block. - CreateClusterExpectations(kBlockCount - 1, false, &client_); - - // Now expect all blocks. - CreateClusterExpectations(kBlockCount, true, &client_); - - WebMListParser parser(kWebMIdCluster, &client_); - - // 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()); - EXPECT_FALSE(parser.IsParsingComplete()); - - 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(result, cluster->size()); - EXPECT_TRUE(parser.IsParsingComplete()); -} - -// Test the case where multiple clients are used for different lists. -TEST_F(WebMParserTest, MultipleClients) { - const uint8 kBuffer[] = { - 0x18, 0x53, 0x80, 0x67, 0x94, // SEGMENT (size = 20) - 0x16, 0x54, 0xAE, 0x6B, 0x85, // TRACKS (size = 5) - 0xAE, 0x83, // TRACKENTRY (size = 3) - 0xD7, 0x81, 0x01, // TRACKNUMBER (size = 1) - 0x1F, 0x43, 0xB6, 0x75, 0x85, // CLUSTER (size = 5) - 0xEC, 0x83, 0x00, 0x00, 0x00, // Void (size = 3) - }; - int size = sizeof(kBuffer); - - StrictMock c1_; - StrictMock c2_; - StrictMock c3_; - - InSequence s; - EXPECT_CALL(client_, OnListStart(kWebMIdSegment)).WillOnce(Return(&c1_)); - EXPECT_CALL(c1_, OnListStart(kWebMIdTracks)).WillOnce(Return(&c2_)); - EXPECT_CALL(c2_, OnListStart(kWebMIdTrackEntry)).WillOnce(Return(&c3_)); - EXPECT_CALL(c3_, OnUInt(kWebMIdTrackNumber, 1)).WillOnce(Return(true)); - EXPECT_CALL(c2_, OnListEnd(kWebMIdTrackEntry)).WillOnce(Return(true)); - EXPECT_CALL(c1_, OnListEnd(kWebMIdTracks)).WillOnce(Return(true)); - EXPECT_CALL(c1_, OnListStart(kWebMIdCluster)).WillOnce(Return(&c2_)); - EXPECT_CALL(c1_, OnListEnd(kWebMIdCluster)).WillOnce(Return(true)); - EXPECT_CALL(client_, OnListEnd(kWebMIdSegment)).WillOnce(Return(true)); - - WebMListParser parser(kWebMIdSegment, &client_); - int result = parser.Parse(kBuffer, size); - EXPECT_EQ(size, result); - EXPECT_TRUE(parser.IsParsingComplete()); -} - -// Test the case where multiple clients are used for different lists. -TEST_F(WebMParserTest, InvalidClient) { - const uint8 kBuffer[] = { - 0x18, 0x53, 0x80, 0x67, 0x85, // SEGMENT (size = 20) - 0x16, 0x54, 0xAE, 0x6B, 0x80, // TRACKS (size = 5) - }; - int size = sizeof(kBuffer); - - InSequence s; - EXPECT_CALL(client_, OnListStart(kWebMIdSegment)).WillOnce(ReturnNull()); - - WebMListParser parser(kWebMIdSegment, &client_); - int result = parser.Parse(kBuffer, size); - EXPECT_EQ(-1, result); - EXPECT_FALSE(parser.IsParsingComplete()); -} - -TEST_F(WebMParserTest, ReservedIds) { - const uint8 k1ByteReservedId[] = { 0xFF, 0x81 }; - const uint8 k2ByteReservedId[] = { 0x7F, 0xFF, 0x81 }; - const uint8 k3ByteReservedId[] = { 0x3F, 0xFF, 0xFF, 0x81 }; - const uint8 k4ByteReservedId[] = { 0x1F, 0xFF, 0xFF, 0xFF, 0x81 }; - const uint8* kBuffers[] = { - k1ByteReservedId, - k2ByteReservedId, - k3ByteReservedId, - k4ByteReservedId - }; - - for (size_t i = 0; i < arraysize(kBuffers); i++) { - int id; - int64 element_size; - int buffer_size = 2 + i; - EXPECT_EQ(buffer_size, WebMParseElementHeader(kBuffers[i], buffer_size, - &id, &element_size)); - EXPECT_EQ(id, kWebMReservedId); - EXPECT_EQ(element_size, 1); - } -} - -TEST_F(WebMParserTest, ReservedSizes) { - const uint8 k1ByteReservedSize[] = { 0xA3, 0xFF }; - const uint8 k2ByteReservedSize[] = { 0xA3, 0x7F, 0xFF }; - const uint8 k3ByteReservedSize[] = { 0xA3, 0x3F, 0xFF, 0xFF }; - const uint8 k4ByteReservedSize[] = { 0xA3, 0x1F, 0xFF, 0xFF, 0xFF }; - const uint8 k5ByteReservedSize[] = { 0xA3, 0x0F, 0xFF, 0xFF, 0xFF, 0xFF }; - const uint8 k6ByteReservedSize[] = { 0xA3, 0x07, 0xFF, 0xFF, 0xFF, 0xFF, - 0xFF }; - const uint8 k7ByteReservedSize[] = { 0xA3, 0x03, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, - 0xFF }; - const uint8 k8ByteReservedSize[] = { 0xA3, 0x01, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, - 0xFF, 0xFF }; - const uint8* kBuffers[] = { - k1ByteReservedSize, - k2ByteReservedSize, - k3ByteReservedSize, - k4ByteReservedSize, - k5ByteReservedSize, - k6ByteReservedSize, - k7ByteReservedSize, - k8ByteReservedSize - }; - - for (size_t i = 0; i < arraysize(kBuffers); i++) { - int id; - int64 element_size; - int buffer_size = 2 + i; - EXPECT_EQ(buffer_size, WebMParseElementHeader(kBuffers[i], buffer_size, - &id, &element_size)); - EXPECT_EQ(id, 0xA3); - EXPECT_EQ(element_size, kWebMUnknownSize); - } -} - -TEST_F(WebMParserTest, ZeroPaddedStrings) { - const uint8 kBuffer[] = { - 0x1A, 0x45, 0xDF, 0xA3, 0x91, // EBMLHEADER (size = 17) - 0x42, 0x82, 0x80, // DocType (size = 0) - 0x42, 0x82, 0x81, 0x00, // DocType (size = 1) "" - 0x42, 0x82, 0x81, 'a', // DocType (size = 1) "a" - 0x42, 0x82, 0x83, 'a', 0x00, 0x00 // DocType (size = 3) "a" - }; - int size = sizeof(kBuffer); - - InSequence s; - EXPECT_CALL(client_, OnListStart(kWebMIdEBMLHeader)) - .WillOnce(Return(&client_)); - EXPECT_CALL(client_, OnString(kWebMIdDocType, "")).WillOnce(Return(true)); - EXPECT_CALL(client_, OnString(kWebMIdDocType, "")).WillOnce(Return(true)); - EXPECT_CALL(client_, OnString(kWebMIdDocType, "a")).WillOnce(Return(true)); - EXPECT_CALL(client_, OnString(kWebMIdDocType, "a")).WillOnce(Return(true)); - EXPECT_CALL(client_, OnListEnd(kWebMIdEBMLHeader)).WillOnce(Return(true)); - - WebMListParser parser(kWebMIdEBMLHeader, &client_); - int result = parser.Parse(kBuffer, size); - EXPECT_EQ(size, result); - EXPECT_TRUE(parser.IsParsingComplete()); -} - -} // namespace media diff --git a/media/webm/webm_stream_parser.cc b/media/webm/webm_stream_parser.cc deleted file mode 100644 index 796a1b3b09..0000000000 --- a/media/webm/webm_stream_parser.cc +++ /dev/null @@ -1,329 +0,0 @@ -// Copyright (c) 2012 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 "media/webm/webm_stream_parser.h" - -#include - -#include "base/callback.h" -#include "base/logging.h" -#include "base/stl_util.h" -#include "media/webm/webm_cluster_parser.h" -#include "media/webm/webm_constants.h" -#include "media/webm/webm_content_encodings.h" -#include "media/webm/webm_crypto_helpers.h" -#include "media/webm/webm_info_parser.h" -#include "media/webm/webm_tracks_parser.h" - -namespace media { - -WebMStreamParser::WebMStreamParser() - : state_(kWaitingForInit), - waiting_for_buffers_(false) { -} - -WebMStreamParser::~WebMStreamParser() { - STLDeleteValues(&text_track_map_); -} - -void WebMStreamParser::Init(const InitCB& init_cb, - const NewConfigCB& config_cb, - const NewBuffersCB& new_buffers_cb, - const NewTextBuffersCB& text_cb, - const NeedKeyCB& need_key_cb, - const AddTextTrackCB& add_text_track_cb, - const NewMediaSegmentCB& new_segment_cb, - const base::Closure& end_of_segment_cb, - const LogCB& log_cb) { - DCHECK_EQ(state_, kWaitingForInit); - DCHECK(init_cb_.is_null()); - DCHECK(!init_cb.is_null()); - DCHECK(!config_cb.is_null()); - DCHECK(!new_buffers_cb.is_null()); - DCHECK(!text_cb.is_null()); - DCHECK(!need_key_cb.is_null()); - DCHECK(!new_segment_cb.is_null()); - DCHECK(!end_of_segment_cb.is_null()); - - ChangeState(kParsingHeaders); - init_cb_ = init_cb; - config_cb_ = config_cb; - new_buffers_cb_ = new_buffers_cb; - text_cb_ = text_cb; - need_key_cb_ = need_key_cb; - add_text_track_cb_ = add_text_track_cb; - new_segment_cb_ = new_segment_cb; - end_of_segment_cb_ = end_of_segment_cb; - log_cb_ = log_cb; -} - -void WebMStreamParser::Flush() { - DCHECK_NE(state_, kWaitingForInit); - - byte_queue_.Reset(); - - if (state_ != kParsingClusters) - return; - - cluster_parser_->Reset(); -} - -bool WebMStreamParser::Parse(const uint8* buf, int size) { - DCHECK_NE(state_, kWaitingForInit); - - if (state_ == kError) - return false; - - byte_queue_.Push(buf, size); - - int result = 0; - int bytes_parsed = 0; - const uint8* cur = NULL; - int cur_size = 0; - - byte_queue_.Peek(&cur, &cur_size); - while (cur_size > 0) { - State oldState = state_; - switch (state_) { - case kParsingHeaders: - result = ParseInfoAndTracks(cur, cur_size); - break; - - case kParsingClusters: - result = ParseCluster(cur, cur_size); - break; - - case kWaitingForInit: - case kError: - return false; - } - - if (result < 0) { - ChangeState(kError); - return false; - } - - if (state_ == oldState && result == 0) - break; - - DCHECK_GE(result, 0); - cur += result; - cur_size -= result; - bytes_parsed += result; - } - - byte_queue_.Pop(bytes_parsed); - return true; -} - -void WebMStreamParser::ChangeState(State new_state) { - DVLOG(1) << "ChangeState() : " << state_ << " -> " << new_state; - state_ = new_state; -} - -int WebMStreamParser::ParseInfoAndTracks(const uint8* data, int size) { - DVLOG(2) << "ParseInfoAndTracks()"; - DCHECK(data); - DCHECK_GT(size, 0); - - const uint8* cur = data; - int cur_size = size; - int bytes_parsed = 0; - - int id; - int64 element_size; - int result = WebMParseElementHeader(cur, cur_size, &id, &element_size); - - if (result <= 0) - return result; - - switch (id) { - case kWebMIdEBMLHeader: - case kWebMIdSeekHead: - case kWebMIdVoid: - case kWebMIdCRC32: - case kWebMIdCues: - case kWebMIdChapters: - if (cur_size < (result + element_size)) { - // We don't have the whole element yet. Signal we need more data. - return 0; - } - // Skip the element. - return result + element_size; - break; - case kWebMIdSegment: - // Just consume the segment header. - return result; - break; - case kWebMIdInfo: - // We've found the element we are looking for. - break; - default: { - MEDIA_LOG(log_cb_) << "Unexpected element ID 0x" << std::hex << id; - return -1; - } - } - - WebMInfoParser info_parser; - result = info_parser.Parse(cur, cur_size); - - if (result <= 0) - return result; - - cur += result; - cur_size -= result; - bytes_parsed += result; - - WebMTracksParser tracks_parser(log_cb_, add_text_track_cb_.is_null()); - result = tracks_parser.Parse(cur, cur_size); - - if (result <= 0) - return result; - - bytes_parsed += result; - - base::TimeDelta duration = kInfiniteDuration(); - - if (info_parser.duration() > 0) { - double mult = info_parser.timecode_scale() / 1000.0; - int64 duration_in_us = info_parser.duration() * mult; - duration = base::TimeDelta::FromMicroseconds(duration_in_us); - } - - const AudioDecoderConfig& audio_config = tracks_parser.audio_decoder_config(); - if (audio_config.is_encrypted()) - FireNeedKey(tracks_parser.audio_encryption_key_id()); - - const VideoDecoderConfig& video_config = tracks_parser.video_decoder_config(); - if (video_config.is_encrypted()) - FireNeedKey(tracks_parser.video_encryption_key_id()); - - if (!config_cb_.Run(audio_config, video_config)) { - DVLOG(1) << "New config data isn't allowed."; - return -1; - } - - typedef WebMTracksParser::TextTracks TextTracks; - const TextTracks& text_tracks = tracks_parser.text_tracks(); - - for (TextTracks::const_iterator itr = text_tracks.begin(); - itr != text_tracks.end(); ++itr) { - const WebMTracksParser::TextTrackInfo& text_track_info = itr->second; - - // TODO(matthewjheaney): verify that WebVTT uses ISO 639-2 for lang - scoped_ptr text_track = - add_text_track_cb_.Run(text_track_info.kind, - text_track_info.name, - text_track_info.language); - - // Assume ownership of pointer, and cache the text track object, for use - // later when we have text track buffers. (The text track objects are - // deallocated in the dtor for this class.) - - if (text_track) - text_track_map_.insert(std::make_pair(itr->first, text_track.release())); - } - - cluster_parser_.reset(new WebMClusterParser( - info_parser.timecode_scale(), - tracks_parser.audio_track_num(), - tracks_parser.video_track_num(), - text_tracks, - tracks_parser.ignored_tracks(), - tracks_parser.audio_encryption_key_id(), - tracks_parser.video_encryption_key_id(), - log_cb_)); - - ChangeState(kParsingClusters); - - if (!init_cb_.is_null()) { - init_cb_.Run(true, duration); - init_cb_.Reset(); - } - - return bytes_parsed; -} - -int WebMStreamParser::ParseCluster(const uint8* data, int size) { - if (!cluster_parser_) - return -1; - - int id; - int64 element_size; - int result = WebMParseElementHeader(data, size, &id, &element_size); - - if (result <= 0) - return result; - - if (id == kWebMIdCluster) - waiting_for_buffers_ = true; - - // TODO(matthewjheaney): implement support for chapters - if (id == kWebMIdCues || id == kWebMIdChapters) { - if (size < (result + element_size)) { - // We don't have the whole element yet. Signal we need more data. - return 0; - } - // Skip the element. - return result + element_size; - } - - if (id == kWebMIdEBMLHeader) { - ChangeState(kParsingHeaders); - return 0; - } - - int bytes_parsed = cluster_parser_->Parse(data, size); - - if (bytes_parsed <= 0) - return bytes_parsed; - - const BufferQueue& audio_buffers = cluster_parser_->audio_buffers(); - const BufferQueue& video_buffers = cluster_parser_->video_buffers(); - bool cluster_ended = cluster_parser_->cluster_ended(); - - if (waiting_for_buffers_ && - cluster_parser_->cluster_start_time() != kNoTimestamp()) { - new_segment_cb_.Run(); - waiting_for_buffers_ = false; - } - - if ((!audio_buffers.empty() || !video_buffers.empty()) && - !new_buffers_cb_.Run(audio_buffers, video_buffers)) { - return -1; - } - - WebMClusterParser::TextTrackIterator text_track_iter = - cluster_parser_->CreateTextTrackIterator(); - - int text_track_num; - const BufferQueue* text_buffers; - - while (text_track_iter(&text_track_num, &text_buffers)) { - TextTrackMap::iterator find_result = text_track_map_.find(text_track_num); - - if (find_result == text_track_map_.end()) - continue; - - TextTrack* const text_track = find_result->second; - - if (!text_buffers->empty() && !text_cb_.Run(text_track, *text_buffers)) - return -1; - } - - if (cluster_ended) - end_of_segment_cb_.Run(); - - return bytes_parsed; -} - -void WebMStreamParser::FireNeedKey(const std::string& key_id) { - int key_id_size = key_id.size(); - DCHECK_GT(key_id_size, 0); - scoped_ptr key_id_array(new uint8[key_id_size]); - memcpy(key_id_array.get(), key_id.data(), key_id_size); - need_key_cb_.Run(kWebMEncryptInitDataType, key_id_array.Pass(), key_id_size); -} - -} // namespace media diff --git a/media/webm/webm_stream_parser.h b/media/webm/webm_stream_parser.h deleted file mode 100644 index 9c3a6d544f..0000000000 --- a/media/webm/webm_stream_parser.h +++ /dev/null @@ -1,98 +0,0 @@ -// Copyright (c) 2012 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. - -#ifndef MEDIA_WEBM_WEBM_STREAM_PARSER_H_ -#define MEDIA_WEBM_WEBM_STREAM_PARSER_H_ - -#include - -#include "base/callback_forward.h" -#include "base/memory/ref_counted.h" -#include "media/base/audio_decoder_config.h" -#include "media/base/buffers.h" -#include "media/base/byte_queue.h" -#include "media/base/stream_parser.h" -#include "media/base/video_decoder_config.h" - -namespace media { - -class WebMClusterParser; - -class WebMStreamParser : public StreamParser { - public: - WebMStreamParser(); - virtual ~WebMStreamParser(); - - // StreamParser implementation. - virtual void Init(const InitCB& init_cb, const NewConfigCB& config_cb, - const NewBuffersCB& new_buffers_cb, - const NewTextBuffersCB& text_cb, - const NeedKeyCB& need_key_cb, - const AddTextTrackCB& add_text_track_cb, - const NewMediaSegmentCB& new_segment_cb, - const base::Closure& end_of_segment_cb, - const LogCB& log_cb) OVERRIDE; - virtual void Flush() OVERRIDE; - virtual bool Parse(const uint8* buf, int size) OVERRIDE; - - private: - enum State { - kWaitingForInit, - kParsingHeaders, - kParsingClusters, - kError - }; - - void ChangeState(State new_state); - - // Parses WebM Header, Info, Tracks elements. It also skips other level 1 - // elements that are not used right now. Once the Info & Tracks elements have - // been parsed, this method will transition the parser from PARSING_HEADERS to - // PARSING_CLUSTERS. - // - // Returns < 0 if the parse fails. - // Returns 0 if more data is needed. - // Returning > 0 indicates success & the number of bytes parsed. - int ParseInfoAndTracks(const uint8* data, int size); - - // Incrementally parses WebM cluster elements. This method also skips - // CUES elements if they are encountered since we currently don't use the - // data in these elements. - // - // Returns < 0 if the parse fails. - // Returns 0 if more data is needed. - // Returning > 0 indicates success & the number of bytes parsed. - int ParseCluster(const uint8* data, int size); - - // Fire needkey event through the |need_key_cb_|. - void FireNeedKey(const std::string& key_id); - - State state_; - InitCB init_cb_; - NewConfigCB config_cb_; - NewBuffersCB new_buffers_cb_; - NewTextBuffersCB text_cb_; - NeedKeyCB need_key_cb_; - AddTextTrackCB add_text_track_cb_; - - typedef std::map TextTrackMap; - TextTrackMap text_track_map_; - - NewMediaSegmentCB new_segment_cb_; - base::Closure end_of_segment_cb_; - LogCB log_cb_; - - // True if a new cluster id has been seen, but no audio or video buffers have - // been parsed yet. - bool waiting_for_buffers_; - - scoped_ptr cluster_parser_; - ByteQueue byte_queue_; - - DISALLOW_COPY_AND_ASSIGN(WebMStreamParser); -}; - -} // namespace media - -#endif // MEDIA_WEBM_WEBM_STREAM_PARSER_H_ diff --git a/media/webm/webm_tracks_parser.cc b/media/webm/webm_tracks_parser.cc deleted file mode 100644 index 67bac044e4..0000000000 --- a/media/webm/webm_tracks_parser.cc +++ /dev/null @@ -1,284 +0,0 @@ -// Copyright (c) 2012 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 "media/webm/webm_tracks_parser.h" - -#include "base/logging.h" -#include "base/strings/string_util.h" -#include "media/base/buffers.h" -#include "media/webm/webm_constants.h" -#include "media/webm/webm_content_encodings.h" - -namespace media { - -static TextKind CodecIdToTextKind(const std::string& codec_id) { - if (codec_id == kWebMCodecSubtitles) - return kTextSubtitles; - - if (codec_id == kWebMCodecCaptions) - return kTextCaptions; - - if (codec_id == kWebMCodecDescriptions) - return kTextDescriptions; - - if (codec_id == kWebMCodecMetadata) - return kTextMetadata; - - return kTextNone; -} - -WebMTracksParser::WebMTracksParser(const LogCB& log_cb, bool ignore_text_tracks) - : track_type_(-1), - track_num_(-1), - audio_track_num_(-1), - video_track_num_(-1), - ignore_text_tracks_(ignore_text_tracks), - log_cb_(log_cb), - audio_client_(log_cb), - video_client_(log_cb) { -} - -WebMTracksParser::~WebMTracksParser() {} - -int WebMTracksParser::Parse(const uint8* buf, int size) { - track_type_ =-1; - track_num_ = -1; - track_name_.clear(); - track_language_.clear(); - audio_track_num_ = -1; - audio_decoder_config_ = AudioDecoderConfig(); - video_track_num_ = -1; - video_decoder_config_ = VideoDecoderConfig(); - text_tracks_.clear(); - ignored_tracks_.clear(); - - WebMListParser parser(kWebMIdTracks, this); - int result = parser.Parse(buf, size); - - if (result <= 0) - return result; - - // For now we do all or nothing parsing. - return parser.IsParsingComplete() ? result : 0; -} - -WebMParserClient* WebMTracksParser::OnListStart(int id) { - if (id == kWebMIdContentEncodings) { - DCHECK(!track_content_encodings_client_.get()); - track_content_encodings_client_.reset( - new WebMContentEncodingsClient(log_cb_)); - return track_content_encodings_client_->OnListStart(id); - } - - if (id == kWebMIdTrackEntry) { - track_type_ = -1; - track_num_ = -1; - track_name_.clear(); - track_language_.clear(); - codec_id_ = ""; - codec_private_.clear(); - audio_client_.Reset(); - video_client_.Reset(); - return this; - } - - if (id == kWebMIdAudio) - return &audio_client_; - - if (id == kWebMIdVideo) - return &video_client_; - - return this; -} - -bool WebMTracksParser::OnListEnd(int id) { - if (id == kWebMIdContentEncodings) { - DCHECK(track_content_encodings_client_.get()); - return track_content_encodings_client_->OnListEnd(id); - } - - if (id == kWebMIdTrackEntry) { - if (track_type_ == -1 || track_num_ == -1) { - MEDIA_LOG(log_cb_) << "Missing TrackEntry data for " - << " TrackType " << track_type_ - << " TrackNum " << track_num_; - return false; - } - - if (track_type_ != kWebMTrackTypeAudio && - track_type_ != kWebMTrackTypeVideo && - track_type_ != kWebMTrackTypeSubtitlesOrCaptions && - track_type_ != kWebMTrackTypeDescriptionsOrMetadata) { - MEDIA_LOG(log_cb_) << "Unexpected TrackType " << track_type_; - return false; - } - - TextKind text_track_kind = kTextNone; - if (track_type_ == kWebMTrackTypeSubtitlesOrCaptions) { - text_track_kind = CodecIdToTextKind(codec_id_); - if (text_track_kind == kTextNone) { - MEDIA_LOG(log_cb_) << "Missing TrackEntry CodecID" - << " TrackNum " << track_num_; - return false; - } - - if (text_track_kind != kTextSubtitles && - text_track_kind != kTextCaptions) { - MEDIA_LOG(log_cb_) << "Wrong TrackEntry CodecID" - << " TrackNum " << track_num_; - return false; - } - } else if (track_type_ == kWebMTrackTypeDescriptionsOrMetadata) { - text_track_kind = CodecIdToTextKind(codec_id_); - if (text_track_kind == kTextNone) { - MEDIA_LOG(log_cb_) << "Missing TrackEntry CodecID" - << " TrackNum " << track_num_; - return false; - } - - if (text_track_kind != kTextDescriptions && - text_track_kind != kTextMetadata) { - MEDIA_LOG(log_cb_) << "Wrong TrackEntry CodecID" - << " TrackNum " << track_num_; - return false; - } - } - - std::string encryption_key_id; - if (track_content_encodings_client_) { - DCHECK(!track_content_encodings_client_->content_encodings().empty()); - // If we have multiple ContentEncoding in one track. Always choose the - // key id in the first ContentEncoding as the key id of the track. - encryption_key_id = track_content_encodings_client_-> - content_encodings()[0]->encryption_key_id(); - } - - if (track_type_ == kWebMTrackTypeAudio) { - if (audio_track_num_ == -1) { - audio_track_num_ = track_num_; - audio_encryption_key_id_ = encryption_key_id; - - DCHECK(!audio_decoder_config_.IsValidConfig()); - if (!audio_client_.InitializeConfig( - codec_id_, codec_private_, !audio_encryption_key_id_.empty(), - &audio_decoder_config_)) { - return false; - } - } else { - MEDIA_LOG(log_cb_) << "Ignoring audio track " << track_num_; - ignored_tracks_.insert(track_num_); - } - } else if (track_type_ == kWebMTrackTypeVideo) { - if (video_track_num_ == -1) { - video_track_num_ = track_num_; - video_encryption_key_id_ = encryption_key_id; - - DCHECK(!video_decoder_config_.IsValidConfig()); - if (!video_client_.InitializeConfig( - codec_id_, codec_private_, !video_encryption_key_id_.empty(), - &video_decoder_config_)) { - return false; - } - } else { - MEDIA_LOG(log_cb_) << "Ignoring video track " << track_num_; - ignored_tracks_.insert(track_num_); - } - } else if (track_type_ == kWebMTrackTypeSubtitlesOrCaptions || - track_type_ == kWebMTrackTypeDescriptionsOrMetadata) { - if (ignore_text_tracks_) { - MEDIA_LOG(log_cb_) << "Ignoring text track " << track_num_; - ignored_tracks_.insert(track_num_); - } else { - TextTrackInfo& text_track_info = text_tracks_[track_num_]; - text_track_info.kind = text_track_kind; - text_track_info.name = track_name_; - text_track_info.language = track_language_; - } - } else { - MEDIA_LOG(log_cb_) << "Unexpected TrackType " << track_type_; - return false; - } - - track_type_ = -1; - track_num_ = -1; - track_name_.clear(); - track_language_.clear(); - codec_id_ = ""; - codec_private_.clear(); - track_content_encodings_client_.reset(); - - audio_client_.Reset(); - video_client_.Reset(); - return true; - } - - return true; -} - -bool WebMTracksParser::OnUInt(int id, int64 val) { - int64* dst = NULL; - - switch (id) { - case kWebMIdTrackNumber: - dst = &track_num_; - break; - case kWebMIdTrackType: - dst = &track_type_; - break; - default: - return true; - } - - if (*dst != -1) { - MEDIA_LOG(log_cb_) << "Multiple values for id " << std::hex << id - << " specified"; - return false; - } - - *dst = val; - return true; -} - -bool WebMTracksParser::OnFloat(int id, double val) { - return true; -} - -bool WebMTracksParser::OnBinary(int id, const uint8* data, int size) { - if (id == kWebMIdCodecPrivate) { - if (!codec_private_.empty()) { - MEDIA_LOG(log_cb_) << "Multiple CodecPrivate fields in a track."; - return false; - } - - codec_private_.assign(data, data + size); - return true; - } - return true; -} - -bool WebMTracksParser::OnString(int id, const std::string& str) { - if (id == kWebMIdCodecID) { - if (!codec_id_.empty()) { - MEDIA_LOG(log_cb_) << "Multiple CodecID fields in a track"; - return false; - } - - codec_id_ = str; - return true; - } - - if (id == kWebMIdName) { - track_name_ = str; - return true; - } - - if (id == kWebMIdLanguage) { - track_language_ = str; - return true; - } - - return true; -} - -} // namespace media diff --git a/media/webm/webm_tracks_parser.h b/media/webm/webm_tracks_parser.h deleted file mode 100644 index 81588e4b51..0000000000 --- a/media/webm/webm_tracks_parser.h +++ /dev/null @@ -1,108 +0,0 @@ -// Copyright (c) 2012 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. - -#ifndef MEDIA_WEBM_WEBM_TRACKS_PARSER_H_ -#define MEDIA_WEBM_WEBM_TRACKS_PARSER_H_ - -#include -#include -#include -#include - -#include "base/compiler_specific.h" -#include "base/memory/scoped_ptr.h" -#include "media/base/audio_decoder_config.h" -#include "media/base/media_log.h" -#include "media/base/text_track.h" -#include "media/base/video_decoder_config.h" -#include "media/webm/webm_audio_client.h" -#include "media/webm/webm_content_encodings_client.h" -#include "media/webm/webm_parser.h" -#include "media/webm/webm_video_client.h" - -namespace media { - -// Parser for WebM Tracks element. -class MEDIA_EXPORT WebMTracksParser : public WebMParserClient { - public: - explicit WebMTracksParser(const LogCB& log_cb, bool ignore_text_tracks); - virtual ~WebMTracksParser(); - - // Parses a WebM Tracks element in |buf|. - // - // Returns -1 if the parse fails. - // Returns 0 if more data is needed. - // Returns the number of bytes parsed on success. - int Parse(const uint8* buf, int size); - - int64 audio_track_num() const { return audio_track_num_; } - int64 video_track_num() const { return video_track_num_; } - const std::set& ignored_tracks() const { return ignored_tracks_; } - - const std::string& audio_encryption_key_id() const { - return audio_encryption_key_id_; - } - - const AudioDecoderConfig& audio_decoder_config() { - return audio_decoder_config_; - } - - const std::string& video_encryption_key_id() const { - return video_encryption_key_id_; - } - - const VideoDecoderConfig& video_decoder_config() { - return video_decoder_config_; - } - - struct TextTrackInfo { - TextKind kind; - std::string name; - std::string language; - }; - - typedef std::map TextTracks; - - const TextTracks& text_tracks() const { - return text_tracks_; - } - - private: - // WebMParserClient implementation. - virtual WebMParserClient* OnListStart(int id) OVERRIDE; - virtual bool OnListEnd(int id) OVERRIDE; - virtual bool OnUInt(int id, int64 val) OVERRIDE; - virtual bool OnFloat(int id, double val) OVERRIDE; - virtual bool OnBinary(int id, const uint8* data, int size) OVERRIDE; - virtual bool OnString(int id, const std::string& str) OVERRIDE; - - int64 track_type_; - int64 track_num_; - std::string track_name_; - std::string track_language_; - std::string codec_id_; - std::vector codec_private_; - scoped_ptr track_content_encodings_client_; - - int64 audio_track_num_; - int64 video_track_num_; - bool ignore_text_tracks_; - TextTracks text_tracks_; - std::set ignored_tracks_; - std::string audio_encryption_key_id_; - std::string video_encryption_key_id_; - LogCB log_cb_; - - WebMAudioClient audio_client_; - AudioDecoderConfig audio_decoder_config_; - - WebMVideoClient video_client_; - VideoDecoderConfig video_decoder_config_; - - DISALLOW_COPY_AND_ASSIGN(WebMTracksParser); -}; - -} // namespace media - -#endif // MEDIA_WEBM_WEBM_TRACKS_PARSER_H_ diff --git a/media/webm/webm_tracks_parser_unittest.cc b/media/webm/webm_tracks_parser_unittest.cc deleted file mode 100644 index 1ba3111789..0000000000 --- a/media/webm/webm_tracks_parser_unittest.cc +++ /dev/null @@ -1,125 +0,0 @@ -// Copyright (c) 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/logging.h" -#include "media/webm/tracks_builder.h" -#include "media/webm/webm_constants.h" -#include "media/webm/webm_tracks_parser.h" -#include "testing/gmock/include/gmock/gmock.h" -#include "testing/gtest/include/gtest/gtest.h" - -using ::testing::InSequence; -using ::testing::Return; -using ::testing::_; - -namespace media { - -static const int kTypeSubtitlesOrCaptions = 0x11; -static const int kTypeDescriptionsOrMetadata = 0x21; - -class WebMTracksParserTest : public testing::Test { - public: - WebMTracksParserTest() {} -}; - -static void VerifyTextTrackInfo(const uint8* buffer, - int buffer_size, - TextKind text_kind, - const std::string& name, - const std::string& language) { - scoped_ptr parser(new WebMTracksParser(LogCB(), false)); - - int result = parser->Parse(buffer, buffer_size); - EXPECT_GT(result, 0); - EXPECT_EQ(result, buffer_size); - - const WebMTracksParser::TextTracks& text_tracks = parser->text_tracks(); - EXPECT_EQ(text_tracks.size(), WebMTracksParser::TextTracks::size_type(1)); - - const WebMTracksParser::TextTracks::const_iterator itr = text_tracks.begin(); - EXPECT_EQ(itr->first, 1); // track num - - const WebMTracksParser::TextTrackInfo& info = itr->second; - EXPECT_EQ(info.kind, text_kind); - EXPECT_TRUE(info.name == name); - EXPECT_TRUE(info.language == language); -} - -TEST_F(WebMTracksParserTest, SubtitleNoNameNoLang) { - InSequence s; - - TracksBuilder tb; - tb.AddTrack(1, kWebMTrackTypeSubtitlesOrCaptions, - kWebMCodecSubtitles, "", ""); - - const std::vector buf = tb.Finish(); - VerifyTextTrackInfo(&buf[0], buf.size(), kTextSubtitles, "", ""); -} - -TEST_F(WebMTracksParserTest, SubtitleYesNameNoLang) { - InSequence s; - - TracksBuilder tb; - tb.AddTrack(1, kWebMTrackTypeSubtitlesOrCaptions, - kWebMCodecSubtitles, "Spock", ""); - - const std::vector buf = tb.Finish(); - VerifyTextTrackInfo(&buf[0], buf.size(), kTextSubtitles, "Spock", ""); -} - -TEST_F(WebMTracksParserTest, SubtitleNoNameYesLang) { - InSequence s; - - TracksBuilder tb; - tb.AddTrack(1, kWebMTrackTypeSubtitlesOrCaptions, - kWebMCodecSubtitles, "", "eng"); - - const std::vector buf = tb.Finish(); - VerifyTextTrackInfo(&buf[0], buf.size(), kTextSubtitles, "", "eng"); -} - -TEST_F(WebMTracksParserTest, SubtitleYesNameYesLang) { - InSequence s; - - TracksBuilder tb; - tb.AddTrack(1, kWebMTrackTypeSubtitlesOrCaptions, - kWebMCodecSubtitles, "Picard", "fre"); - - const std::vector buf = tb.Finish(); - VerifyTextTrackInfo(&buf[0], buf.size(), kTextSubtitles, "Picard", "fre"); -} - -TEST_F(WebMTracksParserTest, IgnoringTextTracks) { - InSequence s; - - TracksBuilder tb; - tb.AddTrack(1, kWebMTrackTypeSubtitlesOrCaptions, - kWebMCodecSubtitles, "Subtitles", "fre"); - tb.AddTrack(2, kWebMTrackTypeSubtitlesOrCaptions, - kWebMCodecSubtitles, "Commentary", "fre"); - - const std::vector buf = tb.Finish(); - scoped_ptr parser(new WebMTracksParser(LogCB(), true)); - - int result = parser->Parse(&buf[0], buf.size()); - EXPECT_GT(result, 0); - EXPECT_EQ(result, static_cast(buf.size())); - - EXPECT_EQ(parser->text_tracks().size(), 0u); - - const std::set& ignored_tracks = parser->ignored_tracks(); - EXPECT_TRUE(ignored_tracks.find(1) != ignored_tracks.end()); - EXPECT_TRUE(ignored_tracks.find(2) != ignored_tracks.end()); - - // Test again w/o ignoring the test tracks. - parser.reset(new WebMTracksParser(LogCB(), false)); - - result = parser->Parse(&buf[0], buf.size()); - EXPECT_GT(result, 0); - - EXPECT_EQ(parser->ignored_tracks().size(), 0u); - EXPECT_EQ(parser->text_tracks().size(), 2u); -} - -} // namespace media diff --git a/media/webm/webm_video_client.cc b/media/webm/webm_video_client.cc deleted file mode 100644 index 1d0cbcb2ac..0000000000 --- a/media/webm/webm_video_client.cc +++ /dev/null @@ -1,163 +0,0 @@ -// Copyright (c) 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 "media/webm/webm_video_client.h" - -#include "media/base/video_decoder_config.h" -#include "media/webm/webm_constants.h" - -namespace media { - -WebMVideoClient::WebMVideoClient(const LogCB& log_cb) - : log_cb_(log_cb) { - Reset(); -} - -WebMVideoClient::~WebMVideoClient() { -} - -void WebMVideoClient::Reset() { - pixel_width_ = -1; - pixel_height_ = -1; - crop_bottom_ = -1; - crop_top_ = -1; - crop_left_ = -1; - crop_right_ = -1; - display_width_ = -1; - display_height_ = -1; - display_unit_ = -1; - alpha_mode_ = -1; -} - -bool WebMVideoClient::InitializeConfig( - const std::string& codec_id, const std::vector& codec_private, - bool is_encrypted, VideoDecoderConfig* config) { - DCHECK(config); - - VideoCodec video_codec = kUnknownVideoCodec; - VideoCodecProfile profile = VIDEO_CODEC_PROFILE_UNKNOWN; - if (codec_id == "V_VP8") { - video_codec = kCodecVP8; - profile = VP8PROFILE_MAIN; - } else if (codec_id == "V_VP9") { - video_codec = kCodecVP9; - profile = VP9PROFILE_MAIN; - } else { - MEDIA_LOG(log_cb_) << "Unsupported video codec_id " << codec_id; - return false; - } - - VideoFrame::Format format = - (alpha_mode_ == 1) ? VideoFrame::YV12A : VideoFrame::YV12; - - if (pixel_width_ <= 0 || pixel_height_ <= 0) - return false; - - // Set crop and display unit defaults if these elements are not present. - if (crop_bottom_ == -1) - crop_bottom_ = 0; - - if (crop_top_ == -1) - crop_top_ = 0; - - if (crop_left_ == -1) - crop_left_ = 0; - - if (crop_right_ == -1) - crop_right_ = 0; - - if (display_unit_ == -1) - display_unit_ = 0; - - gfx::Size coded_size(pixel_width_, pixel_height_); - gfx::Rect visible_rect(crop_top_, crop_left_, - pixel_width_ - (crop_left_ + crop_right_), - pixel_height_ - (crop_top_ + crop_bottom_)); - gfx::Size natural_size = coded_size; - if (display_unit_ == 0) { - if (display_width_ <= 0) - display_width_ = pixel_width_; - if (display_height_ <= 0) - display_height_ = pixel_height_; - natural_size = gfx::Size(display_width_, display_height_); - } else if (display_unit_ == 3) { - if (display_width_ <= 0 || display_height_ <= 0) - return false; - natural_size = gfx::Size(display_width_, display_height_); - } else { - MEDIA_LOG(log_cb_) << "Unsupported display unit type " << display_unit_; - return false; - } - const uint8* extra_data = NULL; - size_t extra_data_size = 0; - if (codec_private.size() > 0) { - extra_data = &codec_private[0]; - extra_data_size = codec_private.size(); - } - - config->Initialize( - video_codec, profile, format, coded_size, visible_rect, natural_size, - extra_data, extra_data_size, is_encrypted, true); - return config->IsValidConfig(); -} - -bool WebMVideoClient::OnUInt(int id, int64 val) { - int64* dst = NULL; - - switch (id) { - case kWebMIdPixelWidth: - dst = &pixel_width_; - break; - case kWebMIdPixelHeight: - dst = &pixel_height_; - break; - case kWebMIdPixelCropTop: - dst = &crop_top_; - break; - case kWebMIdPixelCropBottom: - dst = &crop_bottom_; - break; - case kWebMIdPixelCropLeft: - dst = &crop_left_; - break; - case kWebMIdPixelCropRight: - dst = &crop_right_; - break; - case kWebMIdDisplayWidth: - dst = &display_width_; - break; - case kWebMIdDisplayHeight: - dst = &display_height_; - break; - case kWebMIdDisplayUnit: - dst = &display_unit_; - break; - case kWebMIdAlphaMode: - dst = &alpha_mode_; - break; - default: - return true; - } - - if (*dst != -1) { - MEDIA_LOG(log_cb_) << "Multiple values for id " << std::hex << id - << " specified (" << *dst << " and " << val << ")"; - return false; - } - - *dst = val; - return true; -} - -bool WebMVideoClient::OnBinary(int id, const uint8* data, int size) { - // Accept binary fields we don't care about for now. - return true; -} - -bool WebMVideoClient::OnFloat(int id, double val) { - // Accept float fields we don't care about for now. - return true; -} - -} // namespace media diff --git a/media/webm/webm_video_client.h b/media/webm/webm_video_client.h deleted file mode 100644 index d1872baebb..0000000000 --- a/media/webm/webm_video_client.h +++ /dev/null @@ -1,61 +0,0 @@ -// Copyright (c) 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. - -#ifndef MEDIA_WEBM_WEBM_VIDEO_CLIENT_H_ -#define MEDIA_WEBM_WEBM_VIDEO_CLIENT_H_ - -#include -#include - -#include "media/base/media_log.h" -#include "media/webm/webm_parser.h" - -namespace media { -class VideoDecoderConfig; - -// Helper class used to parse a Video element inside a TrackEntry element. -class WebMVideoClient : public WebMParserClient { - public: - explicit WebMVideoClient(const LogCB& log_cb); - virtual ~WebMVideoClient(); - - // Reset this object's state so it can process a new video track element. - void Reset(); - - // Initialize |config| with the data in |codec_id|, |codec_private|, - // |is_encrypted| and the fields parsed from the last video track element this - // object was used to parse. - // Returns true if |config| was successfully initialized. - // Returns false if there was unexpected values in the provided parameters or - // video track element fields. The contents of |config| are undefined in this - // case and should not be relied upon. - bool InitializeConfig(const std::string& codec_id, - const std::vector& codec_private, - bool is_encrypted, - VideoDecoderConfig* config); - - private: - // WebMParserClient implementation. - virtual bool OnUInt(int id, int64 val) OVERRIDE; - virtual bool OnBinary(int id, const uint8* data, int size) OVERRIDE; - virtual bool OnFloat(int id, double val) OVERRIDE; - - LogCB log_cb_; - int64 pixel_width_; - int64 pixel_height_; - int64 crop_bottom_; - int64 crop_top_; - int64 crop_left_; - int64 crop_right_; - int64 display_width_; - int64 display_height_; - int64 display_unit_; - int64 alpha_mode_; - - DISALLOW_COPY_AND_ASSIGN(WebMVideoClient); -}; - -} // namespace media - -#endif // MEDIA_WEBM_WEBM_VIDEO_CLIENT_H_ diff --git a/media/webm/webm_webvtt_parser.cc b/media/webm/webm_webvtt_parser.cc deleted file mode 100644 index d77bfbcfd8..0000000000 --- a/media/webm/webm_webvtt_parser.cc +++ /dev/null @@ -1,78 +0,0 @@ -// Copyright (c) 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 "media/webm/webm_webvtt_parser.h" - -namespace media { - -void WebMWebVTTParser::Parse(const uint8* payload, int payload_size, - std::string* id, - std::string* settings, - std::string* content) { - WebMWebVTTParser parser(payload, payload_size); - parser.Parse(id, settings, content); -} - -WebMWebVTTParser::WebMWebVTTParser(const uint8* payload, int payload_size) - : ptr_(payload), - ptr_end_(payload + payload_size) { -} - -void WebMWebVTTParser::Parse(std::string* id, - std::string* settings, - std::string* content) { - ParseLine(id); - ParseLine(settings); - content->assign(ptr_, ptr_end_); -} - -bool WebMWebVTTParser::GetByte(uint8* byte) { - if (ptr_ >= ptr_end_) - return false; // indicates end-of-stream - - *byte = *ptr_++; - return true; -} - -void WebMWebVTTParser::UngetByte() { - --ptr_; -} - -void WebMWebVTTParser::ParseLine(std::string* line) { - line->clear(); - - // Consume characters from the stream, until we reach end-of-line. - - // The WebVTT spec states that lines may be terminated in any of the following - // three ways: - // LF - // CR - // CR LF - - // The spec is here: - // http://wiki.webmproject.org/webm-metadata/temporal-metadata/webvtt-in-webm - - enum { - kLF = '\x0A', - kCR = '\x0D' - }; - - for (;;) { - uint8 byte; - - if (!GetByte(&byte) || byte == kLF) - return; - - if (byte == kCR) { - if (GetByte(&byte) && byte != kLF) - UngetByte(); - - return; - } - - line->push_back(byte); - } -} - -} // namespace media diff --git a/media/webm/webm_webvtt_parser.h b/media/webm/webm_webvtt_parser.h deleted file mode 100644 index a6aa316d5e..0000000000 --- a/media/webm/webm_webvtt_parser.h +++ /dev/null @@ -1,49 +0,0 @@ -// Copyright (c) 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. - -#ifndef MEDIA_WEBM_WEBM_WEBVTT_PARSER_H_ -#define MEDIA_WEBM_WEBM_WEBVTT_PARSER_H_ - -#include - -#include "base/basictypes.h" -#include "media/base/media_export.h" - -namespace media { - -class MEDIA_EXPORT WebMWebVTTParser { - public: - // Utility function to parse the WebVTT cue from a byte stream. - static void Parse(const uint8* payload, int payload_size, - std::string* id, - std::string* settings, - std::string* content); - - private: - // The payload is the embedded WebVTT cue, stored in a WebM block. - // The parser treats this as a UTF-8 byte stream. - WebMWebVTTParser(const uint8* payload, int payload_size); - - // Parse the cue identifier, settings, and content from the stream. - void Parse(std::string* id, std::string* settings, std::string* content); - // Remove a byte from the stream, advancing the stream pointer. - // Returns true if a character was returned; false means "end of stream". - bool GetByte(uint8* byte); - - // Backup the stream pointer. - void UngetByte(); - - // Parse a line of text from the stream. - void ParseLine(std::string* line); - - // Represents the portion of the stream that has not been consumed yet. - const uint8* ptr_; - const uint8* const ptr_end_; - - DISALLOW_COPY_AND_ASSIGN(WebMWebVTTParser); -}; - -} // namespace media - -#endif // MEDIA_WEBM_WEBM_WEBVTT_PARSER_H_ diff --git a/media/webm/webm_webvtt_parser_unittest.cc b/media/webm/webm_webvtt_parser_unittest.cc deleted file mode 100644 index db514a1247..0000000000 --- a/media/webm/webm_webvtt_parser_unittest.cc +++ /dev/null @@ -1,105 +0,0 @@ -// Copyright (c) 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 "media/webm/webm_webvtt_parser.h" -#include "testing/gmock/include/gmock/gmock.h" -#include "testing/gtest/include/gtest/gtest.h" - -using ::testing::InSequence; - -namespace media { - -typedef std::vector Cue; - -static Cue EncodeCue(const std::string& id, - const std::string& settings, - const std::string& content) { - const std::string result = id + '\n' + settings + '\n' + content; - const uint8* const buf = reinterpret_cast(result.data()); - return Cue(buf, buf + result.length()); -} - -static void DecodeCue(const Cue& cue, - std::string* id, - std::string* settings, - std::string* content) { - WebMWebVTTParser::Parse(&cue[0], static_cast(cue.size()), - id, settings, content); -} - -class WebMWebVTTParserTest : public testing::Test { - public: - WebMWebVTTParserTest() {} -}; - -TEST_F(WebMWebVTTParserTest, Blank) { - InSequence s; - - const Cue cue = EncodeCue("", "", "Subtitle"); - std::string id, settings, content; - - DecodeCue(cue, &id, &settings, &content); - EXPECT_EQ(id, ""); - EXPECT_EQ(settings, ""); - EXPECT_EQ(content, "Subtitle"); -} - -TEST_F(WebMWebVTTParserTest, Id) { - InSequence s; - - for (int i = 1; i <= 9; ++i) { - const std::string idsrc(1, '0'+i); - const Cue cue = EncodeCue(idsrc, "", "Subtitle"); - std::string id, settings, content; - - DecodeCue(cue, &id, &settings, &content); - EXPECT_EQ(id, idsrc); - EXPECT_EQ(settings, ""); - EXPECT_EQ(content, "Subtitle"); - } -} - -TEST_F(WebMWebVTTParserTest, Settings) { - InSequence s; - - enum { kSettingsCount = 4 }; - const char* const settings_str[kSettingsCount] = { - "vertical:lr", - "line:50%", - "position:42%", - "vertical:rl line:42% position:100%" }; - - for (int i = 0; i < kSettingsCount; ++i) { - const Cue cue = EncodeCue("", settings_str[i], "Subtitle"); - std::string id, settings, content; - - DecodeCue(cue, &id, &settings, &content); - EXPECT_EQ(id, ""); - EXPECT_EQ(settings, settings_str[i]); - EXPECT_EQ(content, "Subtitle"); - } -} - -TEST_F(WebMWebVTTParserTest, Content) { - InSequence s; - - enum { kContentCount = 4 }; - const char* const content_str[kContentCount] = { - "Subtitle", - "Another Subtitle", - "Yet Another Subtitle", - "Another Subtitle\nSplit Across Two Lines" }; - - for (int i = 0; i < kContentCount; ++i) { - const Cue cue = EncodeCue("", "", content_str[i]); - std::string id, settings, content; - - DecodeCue(cue, &id, &settings, &content); - EXPECT_EQ(id, ""); - EXPECT_EQ(settings, ""); - EXPECT_EQ(content, content_str[i]); - } -} - -} // namespace media