15821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Copyright (c) 2012 The Chromium Authors. All rights reserved. 25821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Use of this source code is governed by a BSD-style license that can be 35821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// found in the LICENSE file. 45821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 55821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "media/webm/webm_cluster_parser.h" 65821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 75821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include <vector> 85821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 95821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/logging.h" 1090dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)#include "base/sys_byteorder.h" 112a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "media/base/buffers.h" 125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "media/base/decrypt_config.h" 13f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)#include "media/filters/webvtt_util.h" 145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "media/webm/webm_constants.h" 152a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "media/webm/webm_crypto_helpers.h" 16f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)#include "media/webm/webm_webvtt_parser.h" 175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)namespace media { 195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 202a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)WebMClusterParser::TextTrackIterator::TextTrackIterator( 212a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) const TextTrackMap& text_track_map) : 222a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) iterator_(text_track_map.begin()), 232a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) iterator_end_(text_track_map.end()) { 245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 262a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)WebMClusterParser::TextTrackIterator::TextTrackIterator( 272a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) const TextTrackIterator& rhs) : 282a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) iterator_(rhs.iterator_), 292a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) iterator_end_(rhs.iterator_end_) { 302a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 312a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 322a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)WebMClusterParser::TextTrackIterator::~TextTrackIterator() { 332a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 342a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 352a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)bool WebMClusterParser::TextTrackIterator::operator()( 362a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) int* track_num, 372a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) const BufferQueue** buffers) { 382a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (iterator_ == iterator_end_) { 392a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) *track_num = 0; 402a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) *buffers = NULL; 412a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 422a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return false; 432a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 442a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 452a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) *track_num = iterator_->first; 462a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) *buffers = &iterator_->second.buffers(); 472a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 482a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) ++iterator_; 492a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return true; 502a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 512a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 522a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)WebMClusterParser::WebMClusterParser( 532a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) int64 timecode_scale, int audio_track_num, int video_track_num, 5490dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) const WebMTracksParser::TextTracks& text_tracks, 552a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) const std::set<int64>& ignored_tracks, 562a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) const std::string& audio_encryption_key_id, 572a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) const std::string& video_encryption_key_id, 582a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) const LogCB& log_cb) 595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) : timecode_multiplier_(timecode_scale / 1000.0), 602a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) ignored_tracks_(ignored_tracks), 615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) audio_encryption_key_id_(audio_encryption_key_id), 625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) video_encryption_key_id_(video_encryption_key_id), 635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) parser_(kWebMIdCluster, this), 645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) last_block_timecode_(-1), 655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) block_data_size_(-1), 665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) block_duration_(-1), 6790dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) block_add_id_(-1), 6890dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) block_additional_data_size_(-1), 6958537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) discard_padding_(-1), 705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) cluster_timecode_(-1), 715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) cluster_start_time_(kNoTimestamp()), 725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) cluster_ended_(false), 732a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) audio_(audio_track_num, false), 742a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) video_(video_track_num, true), 752a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) log_cb_(log_cb) { 7690dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) for (WebMTracksParser::TextTracks::const_iterator it = text_tracks.begin(); 772a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) it != text_tracks.end(); 782a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) ++it) { 7990dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) text_track_map_.insert(std::make_pair(it->first, Track(it->first, false))); 802a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)WebMClusterParser::~WebMClusterParser() {} 845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void WebMClusterParser::Reset() { 865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) last_block_timecode_ = -1; 875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) cluster_timecode_ = -1; 885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) cluster_start_time_ = kNoTimestamp(); 895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) cluster_ended_ = false; 905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) parser_.Reset(); 915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) audio_.Reset(); 925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) video_.Reset(); 932a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) ResetTextTracks(); 945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)int WebMClusterParser::Parse(const uint8* buf, int size) { 975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) audio_.Reset(); 985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) video_.Reset(); 992a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) ResetTextTracks(); 1005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int result = parser_.Parse(buf, size); 1025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (result < 0) { 1045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) cluster_ended_ = false; 1055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return result; 1065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 1075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) cluster_ended_ = parser_.IsParsingComplete(); 1095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (cluster_ended_) { 1105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // If there were no buffers in this cluster, set the cluster start time to 1115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // be the |cluster_timecode_|. 1125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (cluster_start_time_ == kNoTimestamp()) { 1135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DCHECK_GT(cluster_timecode_, -1); 1145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) cluster_start_time_ = base::TimeDelta::FromMicroseconds( 1155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) cluster_timecode_ * timecode_multiplier_); 1165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 1175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Reset the parser if we're done parsing so that 1195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // it is ready to accept another cluster on the next 1205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // call. 1215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) parser_.Reset(); 1225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) last_block_timecode_ = -1; 1245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) cluster_timecode_ = -1; 1255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 1265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return result; 1285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 1295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1302a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)WebMClusterParser::TextTrackIterator 1312a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)WebMClusterParser::CreateTextTrackIterator() const { 1322a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return TextTrackIterator(text_track_map_); 1332a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 1342a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 1355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)WebMParserClient* WebMClusterParser::OnListStart(int id) { 1365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (id == kWebMIdCluster) { 1375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) cluster_timecode_ = -1; 1385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) cluster_start_time_ = kNoTimestamp(); 1395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } else if (id == kWebMIdBlockGroup) { 1405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) block_data_.reset(); 1415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) block_data_size_ = -1; 1425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) block_duration_ = -1; 14358537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) discard_padding_ = -1; 14458537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) discard_padding_set_ = false; 14590dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) } else if (id == kWebMIdBlockAdditions) { 14690dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) block_add_id_ = -1; 14790dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) block_additional_data_.reset(); 14890dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) block_additional_data_size_ = -1; 1495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 1505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return this; 1525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 1535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool WebMClusterParser::OnListEnd(int id) { 1555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (id != kWebMIdBlockGroup) 1565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return true; 1575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Make sure the BlockGroup actually had a Block. 1595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (block_data_size_ == -1) { 1602a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) MEDIA_LOG(log_cb_) << "Block missing from BlockGroup."; 1615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return false; 1625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 1635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1642a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) bool result = ParseBlock(false, block_data_.get(), block_data_size_, 16590dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) block_additional_data_.get(), 16658537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) block_additional_data_size_, block_duration_, 16758537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) discard_padding_set_ ? discard_padding_ : 0); 1685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) block_data_.reset(); 1695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) block_data_size_ = -1; 1705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) block_duration_ = -1; 17190dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) block_add_id_ = -1; 17290dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) block_additional_data_.reset(); 17390dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) block_additional_data_size_ = -1; 17458537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) discard_padding_ = -1; 17558537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) discard_padding_set_ = false; 1765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return result; 1775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 1785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool WebMClusterParser::OnUInt(int id, int64 val) { 18090dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) int64* dst; 18190dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) switch (id) { 18290dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) case kWebMIdTimecode: 18390dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) dst = &cluster_timecode_; 18490dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) break; 18590dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) case kWebMIdBlockDuration: 18690dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) dst = &block_duration_; 18790dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) break; 18890dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) case kWebMIdBlockAddID: 18990dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) dst = &block_add_id_; 19090dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) break; 19158537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) case kWebMIdDiscardPadding: 19258537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) if (discard_padding_set_) 19358537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) return false; 19458537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) discard_padding_set_ = true; 19558537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) discard_padding_ = val; 19658537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) return true; 19790dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) default: 19890dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) return true; 1995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 20090dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) if (*dst != -1) 20190dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) return false; 20290dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) *dst = val; 2035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return true; 2045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 2055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2062a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)bool WebMClusterParser::ParseBlock(bool is_simple_block, const uint8* buf, 20790dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) int size, const uint8* additional, 20858537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) int additional_size, int duration, 20958537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) int64 discard_padding) { 2105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (size < 4) 2115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return false; 2125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Return an error if the trackNum > 127. We just aren't 2145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // going to support large track numbers right now. 2155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!(buf[0] & 0x80)) { 2162a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) MEDIA_LOG(log_cb_) << "TrackNumber over 127 not supported"; 2175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return false; 2185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 2195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int track_num = buf[0] & 0x7f; 2215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int timecode = buf[1] << 8 | buf[2]; 2225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int flags = buf[3] & 0xff; 2235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int lacing = (flags >> 1) & 0x3; 2245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (lacing) { 2262a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) MEDIA_LOG(log_cb_) << "Lacing " << lacing << " is not supported yet."; 2275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return false; 2285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 2295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Sign extend negative timecode offsets. 2315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (timecode & 0x8000) 2323551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) timecode |= ~0xffff; 2335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const uint8* frame_data = buf + 4; 2355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int frame_size = size - (frame_data - buf); 2362a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return OnBlock(is_simple_block, track_num, timecode, duration, flags, 23758537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) frame_data, frame_size, additional, additional_size, 23858537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) discard_padding); 2395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 2405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool WebMClusterParser::OnBinary(int id, const uint8* data, int size) { 24290dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) switch (id) { 24390dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) case kWebMIdSimpleBlock: 24458537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) return ParseBlock(true, data, size, NULL, -1, -1, 0); 24590dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) 24690dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) case kWebMIdBlock: 24790dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) if (block_data_) { 24890dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) MEDIA_LOG(log_cb_) << "More than 1 Block in a BlockGroup is not " 24990dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) "supported."; 25090dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) return false; 25190dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) } 25290dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) block_data_.reset(new uint8[size]); 25390dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) memcpy(block_data_.get(), data, size); 25490dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) block_data_size_ = size; 25590dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) return true; 25690dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) 25790dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) case kWebMIdBlockAdditional: { 25890dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) uint64 block_add_id = base::HostToNet64(block_add_id_); 25990dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) if (block_additional_data_) { 26090dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) // TODO(vigneshv): Technically, more than 1 BlockAdditional is allowed 26190dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) // as per matroska spec. But for now we don't have a use case to 26290dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) // support parsing of such files. Take a look at this again when such a 26390dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) // case arises. 26490dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) MEDIA_LOG(log_cb_) << "More than 1 BlockAdditional in a BlockGroup is " 26590dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) "not supported."; 26690dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) return false; 26790dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) } 26890dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) // First 8 bytes of side_data in DecoderBuffer is the BlockAddID 26990dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) // element's value in Big Endian format. This is done to mimic ffmpeg 27090dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) // demuxer's behavior. 27190dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) block_additional_data_size_ = size + sizeof(block_add_id); 27290dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) block_additional_data_.reset(new uint8[block_additional_data_size_]); 27390dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) memcpy(block_additional_data_.get(), &block_add_id, 27490dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) sizeof(block_add_id)); 27590dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) memcpy(block_additional_data_.get() + 8, data, size); 27690dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) return true; 27790dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) } 2785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 27990dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) default: 28090dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) return true; 2815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 2825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 2835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2842a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)bool WebMClusterParser::OnBlock(bool is_simple_block, int track_num, 2852a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) int timecode, 2865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int block_duration, 2875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int flags, 28890dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) const uint8* data, int size, 28958537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) const uint8* additional, int additional_size, 29058537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) int64 discard_padding) { 2915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DCHECK_GE(size, 0); 2925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (cluster_timecode_ == -1) { 2932a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) MEDIA_LOG(log_cb_) << "Got a block before cluster timecode."; 2945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return false; 2955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 2965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2973551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) // TODO(acolwell): Should relative negative timecode offsets be rejected? Or 2983551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) // only when the absolute timecode is negative? See http://crbug.com/271794 2995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (timecode < 0) { 3002a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) MEDIA_LOG(log_cb_) << "Got a block with negative timecode offset " 3012a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) << timecode; 3025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return false; 3035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 3045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (last_block_timecode_ != -1 && timecode < last_block_timecode_) { 3062a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) MEDIA_LOG(log_cb_) 3072a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) << "Got a block with a timecode before the previous block."; 3085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return false; 3095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 3105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) Track* track = NULL; 312f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) bool is_text = false; 3135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) std::string encryption_key_id; 3145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (track_num == audio_.track_num()) { 3155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) track = &audio_; 3165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) encryption_key_id = audio_encryption_key_id_; 3175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } else if (track_num == video_.track_num()) { 3185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) track = &video_; 3195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) encryption_key_id = video_encryption_key_id_; 3202a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } else if (ignored_tracks_.find(track_num) != ignored_tracks_.end()) { 3212a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return true; 3222a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } else if (Track* const text_track = FindTextTrack(track_num)) { 3232a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (is_simple_block) // BlockGroup is required for WebVTT cues 3242a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return false; 3252a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (block_duration < 0) // not specified 3262a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return false; 3272a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) track = text_track; 328f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) is_text = true; 3295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } else { 3302a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) MEDIA_LOG(log_cb_) << "Unexpected track number " << track_num; 3315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return false; 3325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 3335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) last_block_timecode_ = timecode; 3355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) base::TimeDelta timestamp = base::TimeDelta::FromMicroseconds( 3375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) (cluster_timecode_ + timecode) * timecode_multiplier_); 3385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3392a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // The first bit of the flags is set when a SimpleBlock contains only 3402a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // keyframes. If this is a Block, then inspection of the payload is 3412a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // necessary to determine whether it contains a keyframe or not. 3425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // http://www.matroska.org/technical/specs/index.html 3432a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) bool is_keyframe = 3442a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) is_simple_block ? (flags & 0x80) != 0 : track->IsKeyframe(data, size); 3452a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 346f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) scoped_refptr<StreamParserBuffer> buffer; 347f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) if (!is_text) { 348f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) buffer = StreamParserBuffer::CopyFrom(data, size, 349f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) additional, additional_size, 350f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) is_keyframe); 351f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) } else { 352f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) std::string id, settings, content; 353f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) WebMWebVTTParser::Parse(data, size, 354f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) &id, &settings, &content); 355f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) 356f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) std::vector<uint8> side_data; 357f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) MakeSideData(id.begin(), id.end(), 358f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) settings.begin(), settings.end(), 359f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) &side_data); 360f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) 361f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) buffer = StreamParserBuffer::CopyFrom( 362f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) reinterpret_cast<const uint8*>(content.data()), 363f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) content.length(), 364f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) &side_data[0], 365f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) side_data.size(), 366f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) is_keyframe); 367f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) } 3685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Every encrypted Block has a signal byte and IV prepended to it. Current 3705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // encrypted WebM request for comments specification is here 3715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // http://wiki.webmproject.org/encryption/webm-encryption-rfc 3725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!encryption_key_id.empty()) { 3732a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) scoped_ptr<DecryptConfig> config(WebMCreateDecryptConfig( 3742a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) data, size, 3752a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) reinterpret_cast<const uint8*>(encryption_key_id.data()), 3762a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) encryption_key_id.size())); 3772a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (!config) 3785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return false; 379ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch buffer->set_decrypt_config(config.Pass()); 3805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 3815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 382ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch buffer->set_timestamp(timestamp); 3835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (cluster_start_time_ == kNoTimestamp()) 3845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) cluster_start_time_ = timestamp; 3855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (block_duration >= 0) { 387ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch buffer->set_duration(base::TimeDelta::FromMicroseconds( 3885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) block_duration * timecode_multiplier_)); 3895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 3905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 39158537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) if (discard_padding != 0) { 39258537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) buffer->set_discard_padding(base::TimeDelta::FromMicroseconds( 39358537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) discard_padding / 1000)); 39458537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) } 39558537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) 3965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return track->AddBuffer(buffer); 3975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 3985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3992a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)WebMClusterParser::Track::Track(int track_num, bool is_video) 4002a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) : track_num_(track_num), 4012a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) is_video_(is_video) { 4025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 4035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)WebMClusterParser::Track::~Track() {} 4055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool WebMClusterParser::Track::AddBuffer( 4075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const scoped_refptr<StreamParserBuffer>& buffer) { 4085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DVLOG(2) << "AddBuffer() : " << track_num_ 409ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch << " ts " << buffer->timestamp().InSecondsF() 410ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch << " dur " << buffer->duration().InSecondsF() 4115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) << " kf " << buffer->IsKeyframe() 412ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch << " size " << buffer->data_size(); 4135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) buffers_.push_back(buffer); 4155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return true; 4165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 4175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void WebMClusterParser::Track::Reset() { 4195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) buffers_.clear(); 4205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 4215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4222a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)bool WebMClusterParser::Track::IsKeyframe(const uint8* data, int size) const { 4232a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // For now, assume that all blocks are keyframes for datatypes other than 4242a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // video. This is a valid assumption for Vorbis, WebVTT, & Opus. 4252a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (!is_video_) 4262a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return true; 4272a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 4282a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // Make sure the block is big enough for the minimal keyframe header size. 4292a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (size < 7) 4302a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return false; 4312a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 4322a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // The LSb of the first byte must be a 0 for a keyframe. 4332a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // http://tools.ietf.org/html/rfc6386 Section 19.1 4342a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if ((data[0] & 0x01) != 0) 4352a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return false; 4362a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 4372a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // Verify VP8 keyframe startcode. 4382a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // http://tools.ietf.org/html/rfc6386 Section 19.1 4392a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (data[3] != 0x9d || data[4] != 0x01 || data[5] != 0x2a) 4402a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return false; 4412a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 4422a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return true; 4432a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 4442a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 4452a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void WebMClusterParser::ResetTextTracks() { 4462a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) for (TextTrackMap::iterator it = text_track_map_.begin(); 4472a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) it != text_track_map_.end(); 4482a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) ++it) { 4492a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) it->second.Reset(); 4502a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 4512a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 4522a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 4532a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)WebMClusterParser::Track* 4542a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)WebMClusterParser::FindTextTrack(int track_num) { 4552a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) const TextTrackMap::iterator it = text_track_map_.find(track_num); 4562a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 4572a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (it == text_track_map_.end()) 4582a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return NULL; 4592a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 4602a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return &it->second; 4612a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 4622a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 4635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} // namespace media 464