diff options
author | sergeyu@chromium.org <sergeyu@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2014-06-17 03:00:07 +0000 |
---|---|---|
committer | sergeyu@chromium.org <sergeyu@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2014-06-17 03:00:07 +0000 |
commit | b6af1a2209cca61eb19ce4ece6ca22687eb3ed7e (patch) | |
tree | 1ae9d6b1218df7d2ae6df18100736fdfcca2b1e1 /media/formats/webm | |
parent | 0bb3a621c3e090c9d2bb6c5dc1c0033611924cfb (diff) | |
download | chromium_src-b6af1a2209cca61eb19ce4ece6ca22687eb3ed7e.zip chromium_src-b6af1a2209cca61eb19ce4ece6ca22687eb3ed7e.tar.gz chromium_src-b6af1a2209cca61eb19ce4ece6ca22687eb3ed7e.tar.bz2 |
Fix WebMStreamParser to continue parsing after a cluster end
Previously the parser would stop after cluster end even if there is more
data to be parsed.
BUG=382807,335676
R=acolwell@chromium.org, wolenetz@chromium.org
Review URL: https://codereview.chromium.org/328653002
git-svn-id: svn://svn.chromium.org/chrome/trunk/src@277633 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'media/formats/webm')
-rw-r--r-- | media/formats/webm/cluster_builder.cc | 11 | ||||
-rw-r--r-- | media/formats/webm/cluster_builder.h | 1 | ||||
-rw-r--r-- | media/formats/webm/webm_stream_parser.cc | 100 |
3 files changed, 67 insertions, 45 deletions
diff --git a/media/formats/webm/cluster_builder.cc b/media/formats/webm/cluster_builder.cc index bada9e2..1a3b358 100644 --- a/media/formats/webm/cluster_builder.cc +++ b/media/formats/webm/cluster_builder.cc @@ -6,6 +6,7 @@ #include "base/logging.h" #include "media/base/data_buffer.h" +#include "media/formats/webm/webm_constants.h" namespace media { @@ -180,6 +181,16 @@ scoped_ptr<Cluster> ClusterBuilder::Finish() { return ret.Pass(); } +scoped_ptr<Cluster> ClusterBuilder::FinishWithUnknownSize() { + DCHECK_NE(cluster_timecode_, -1); + + UpdateUInt64(kClusterSizeOffset, kWebMUnknownSize); + + scoped_ptr<Cluster> ret(new Cluster(buffer_.Pass(), bytes_used_)); + Reset(); + return ret.Pass(); +} + void ClusterBuilder::Reset() { buffer_size_ = kInitialBufferSize; buffer_.reset(new uint8[buffer_size_]); diff --git a/media/formats/webm/cluster_builder.h b/media/formats/webm/cluster_builder.h index ac5464a..ab5797c 100644 --- a/media/formats/webm/cluster_builder.h +++ b/media/formats/webm/cluster_builder.h @@ -40,6 +40,7 @@ class ClusterBuilder { int flags, const uint8* data, int size); scoped_ptr<Cluster> Finish(); + scoped_ptr<Cluster> FinishWithUnknownSize(); private: void AddBlockGroupInternal(int track_num, int64 timecode, diff --git a/media/formats/webm/webm_stream_parser.cc b/media/formats/webm/webm_stream_parser.cc index a90a623..3f370da 100644 --- a/media/formats/webm/webm_stream_parser.cc +++ b/media/formats/webm/webm_stream_parser.cc @@ -143,6 +143,7 @@ int WebMStreamParser::ParseInfoAndTracks(const uint8* data, int size) { case kWebMIdCRC32: case kWebMIdCues: case kWebMIdChapters: + // TODO(matthewjheaney): Implement support for chapters. if (cur_size < (result + element_size)) { // We don't have the whole element yet. Signal we need more data. return 0; @@ -242,61 +243,70 @@ 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; - - // TODO(matthewjheaney): implement support for chapters - if (id == kWebMIdCues || id == kWebMIdChapters) { - // TODO(wolenetz): Handle unknown-sized cluster parse completion correctly. - // See http://crbug.com/335676. - if (size < (result + element_size)) { - // We don't have the whole element yet. Signal we need more data. - return 0; + int result = 0; + int bytes_parsed; + bool cluster_ended; + do { + cluster_ended = false; + + // If we are not parsing a cluster then handle the case when the next + // element is not a cluster. + if (!parsing_cluster_) { + int id; + int64 element_size; + bytes_parsed = WebMParseElementHeader(data, size, &id, &element_size); + + if (bytes_parsed < 0) + return bytes_parsed; + + if (bytes_parsed == 0) + return result; + + if (id != kWebMIdCluster) { + ChangeState(kParsingHeaders); + return result; + } } - // Skip the element. - return result + element_size; - } - if (id == kWebMIdEBMLHeader) { - // TODO(wolenetz): Handle unknown-sized cluster parse completion correctly. - // See http://crbug.com/335676. - ChangeState(kParsingHeaders); - return 0; - } + bytes_parsed = cluster_parser_->Parse(data, size); - int bytes_parsed = cluster_parser_->Parse(data, size); + if (bytes_parsed < 0) + return bytes_parsed; - if (bytes_parsed <= 0) - return bytes_parsed; + // If cluster detected, immediately notify new segment if we have not + // already done this. + if (!parsing_cluster_ && bytes_parsed > 0) { + parsing_cluster_ = true; + new_segment_cb_.Run(); + } - // If cluster detected, immediately notify new segment if we have not already - // done this. - if (id == kWebMIdCluster && !parsing_cluster_) { - parsing_cluster_ = true; - new_segment_cb_.Run(); - } + const BufferQueue& audio_buffers = cluster_parser_->GetAudioBuffers(); + const BufferQueue& video_buffers = cluster_parser_->GetVideoBuffers(); + const TextBufferQueueMap& text_map = cluster_parser_->GetTextBuffers(); - const BufferQueue& audio_buffers = cluster_parser_->GetAudioBuffers(); - const BufferQueue& video_buffers = cluster_parser_->GetVideoBuffers(); - const TextBufferQueueMap& text_map = cluster_parser_->GetTextBuffers(); + cluster_ended = cluster_parser_->cluster_ended(); - bool cluster_ended = cluster_parser_->cluster_ended(); + if ((!audio_buffers.empty() || !video_buffers.empty() || + !text_map.empty()) && + !new_buffers_cb_.Run(audio_buffers, video_buffers, text_map)) { + return -1; + } - if ((!audio_buffers.empty() || !video_buffers.empty() || !text_map.empty()) && - !new_buffers_cb_.Run(audio_buffers, video_buffers, text_map)) { - return -1; - } + if (cluster_ended) { + parsing_cluster_ = false; + end_of_segment_cb_.Run(); + } - if (cluster_ended) { - parsing_cluster_ = false; - end_of_segment_cb_.Run(); - } + result += bytes_parsed; + data += bytes_parsed; + size -= bytes_parsed; - return bytes_parsed; + // WebMClusterParser returns 0 and |cluster_ended| is true if previously + // parsing an unknown-size cluster and |data| does not continue that + // cluster. Try parsing again in that case. + } while (size > 0 && (bytes_parsed > 0 || cluster_ended)); + + return result; } void WebMStreamParser::FireNeedKey(const std::string& key_id) { |