| OLD | NEW |
| 1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. |
| 2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
| 3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
| 4 // | 4 // |
| 5 // demuxer_bench is a standalone benchmarking tool for FFmpegDemuxer. It | 5 // demuxer_bench is a standalone benchmarking tool for FFmpegDemuxer. It |
| 6 // simulates the reading requirements for playback by reading from the stream | 6 // simulates the reading requirements for playback by reading from the stream |
| 7 // that has the earliest timestamp. | 7 // that has the earliest timestamp. |
| 8 | 8 |
| 9 #include <iostream> | 9 #include <iostream> |
| 10 | 10 |
| (...skipping 30 matching lines...) Expand all Loading... |
| 41 media::PipelineStatus status) { | 41 media::PipelineStatus status) { |
| 42 CHECK_EQ(status, media::PIPELINE_OK); | 42 CHECK_EQ(status, media::PIPELINE_OK); |
| 43 message_loop->PostTask(FROM_HERE, base::MessageLoop::QuitWhenIdleClosure()); | 43 message_loop->PostTask(FROM_HERE, base::MessageLoop::QuitWhenIdleClosure()); |
| 44 } | 44 } |
| 45 | 45 |
| 46 static void NeedKey(const std::string& type, scoped_ptr<uint8[]> init_data, | 46 static void NeedKey(const std::string& type, scoped_ptr<uint8[]> init_data, |
| 47 int init_data_size) { | 47 int init_data_size) { |
| 48 LOG(INFO) << "File is encrypted."; | 48 LOG(INFO) << "File is encrypted."; |
| 49 } | 49 } |
| 50 | 50 |
| 51 typedef std::vector<scoped_refptr<media::DemuxerStream> > Streams; | 51 typedef std::vector<media::DemuxerStream* > Streams; |
| 52 | 52 |
| 53 // Simulates playback reading requirements by reading from each stream | 53 // Simulates playback reading requirements by reading from each stream |
| 54 // present in |demuxer| in as-close-to-monotonically-increasing timestamp order. | 54 // present in |demuxer| in as-close-to-monotonically-increasing timestamp order. |
| 55 class StreamReader { | 55 class StreamReader { |
| 56 public: | 56 public: |
| 57 explicit StreamReader(media::Demuxer* demuxer); | 57 explicit StreamReader(media::Demuxer* demuxer); |
| 58 ~StreamReader(); | 58 ~StreamReader(); |
| 59 | 59 |
| 60 // Performs a single step read. | 60 // Performs a single step read. |
| 61 void Read(); | 61 void Read(); |
| (...skipping 15 matching lines...) Expand all Loading... |
| 77 | 77 |
| 78 Streams streams_; | 78 Streams streams_; |
| 79 std::vector<bool> end_of_stream_; | 79 std::vector<bool> end_of_stream_; |
| 80 std::vector<base::TimeDelta> last_read_timestamp_; | 80 std::vector<base::TimeDelta> last_read_timestamp_; |
| 81 std::vector<int> counts_; | 81 std::vector<int> counts_; |
| 82 | 82 |
| 83 DISALLOW_COPY_AND_ASSIGN(StreamReader); | 83 DISALLOW_COPY_AND_ASSIGN(StreamReader); |
| 84 }; | 84 }; |
| 85 | 85 |
| 86 StreamReader::StreamReader(media::Demuxer* demuxer) { | 86 StreamReader::StreamReader(media::Demuxer* demuxer) { |
| 87 scoped_refptr<media::DemuxerStream> stream; | 87 media::DemuxerStream* stream = |
| 88 stream = demuxer->GetStream(media::DemuxerStream::AUDIO); | 88 demuxer->GetStream(media::DemuxerStream::AUDIO); |
| 89 if (stream) { | 89 if (stream) { |
| 90 streams_.push_back(stream); | 90 streams_.push_back(stream); |
| 91 end_of_stream_.push_back(false); | 91 end_of_stream_.push_back(false); |
| 92 last_read_timestamp_.push_back(media::kNoTimestamp()); | 92 last_read_timestamp_.push_back(media::kNoTimestamp()); |
| 93 counts_.push_back(0); | 93 counts_.push_back(0); |
| 94 } | 94 } |
| 95 | 95 |
| 96 stream = demuxer->GetStream(media::DemuxerStream::VIDEO); | 96 stream = demuxer->GetStream(media::DemuxerStream::VIDEO); |
| 97 if (stream) { | 97 if (stream) { |
| 98 streams_.push_back(stream); | 98 streams_.push_back(stream); |
| 99 end_of_stream_.push_back(false); | 99 end_of_stream_.push_back(false); |
| 100 last_read_timestamp_.push_back(media::kNoTimestamp()); | 100 last_read_timestamp_.push_back(media::kNoTimestamp()); |
| 101 counts_.push_back(0); | 101 counts_.push_back(0); |
| 102 } | 102 } |
| 103 } | 103 } |
| 104 | 104 |
| 105 StreamReader::~StreamReader() {} | 105 StreamReader::~StreamReader() {} |
| 106 | 106 |
| 107 void StreamReader::Read() { | 107 void StreamReader::Read() { |
| 108 int index = GetNextStreamIndexToRead(); | 108 int index = GetNextStreamIndexToRead(); |
| 109 bool end_of_stream = false; | 109 bool end_of_stream = false; |
| 110 base::TimeDelta timestamp; | 110 base::TimeDelta timestamp; |
| 111 | 111 |
| 112 streams_[index]->Read(base::Bind( | 112 streams_[index]->Read(base::Bind( |
| 113 &StreamReader::OnReadDone, base::Unretained(this), | 113 &StreamReader::OnReadDone, base::Unretained(this), |
| 114 base::MessageLoop::current(), &end_of_stream, ×tamp)); | 114 base::MessageLoop::current(), &end_of_stream, ×tamp)); |
| 115 base::MessageLoop::current()->Run(); | 115 base::MessageLoop::current()->Run(); |
| 116 | 116 |
| 117 CHECK(timestamp != media::kNoTimestamp()); | 117 CHECK(end_of_stream || timestamp != media::kNoTimestamp()); |
| 118 end_of_stream_[index] = end_of_stream; | 118 end_of_stream_[index] = end_of_stream; |
| 119 last_read_timestamp_[index] = timestamp; | 119 last_read_timestamp_[index] = timestamp; |
| 120 counts_[index]++; | 120 counts_[index]++; |
| 121 } | 121 } |
| 122 | 122 |
| 123 bool StreamReader::IsDone() { | 123 bool StreamReader::IsDone() { |
| 124 for (size_t i = 0; i < end_of_stream_.size(); ++i) { | 124 for (size_t i = 0; i < end_of_stream_.size(); ++i) { |
| 125 if (!end_of_stream_[i]) | 125 if (!end_of_stream_[i]) |
| 126 return false; | 126 return false; |
| 127 } | 127 } |
| 128 return true; | 128 return true; |
| 129 } | 129 } |
| 130 | 130 |
| 131 void StreamReader::OnReadDone( | 131 void StreamReader::OnReadDone( |
| 132 base::MessageLoop* message_loop, | 132 base::MessageLoop* message_loop, |
| 133 bool* end_of_stream, | 133 bool* end_of_stream, |
| 134 base::TimeDelta* timestamp, | 134 base::TimeDelta* timestamp, |
| 135 media::DemuxerStream::Status status, | 135 media::DemuxerStream::Status status, |
| 136 const scoped_refptr<media::DecoderBuffer>& buffer) { | 136 const scoped_refptr<media::DecoderBuffer>& buffer) { |
| 137 CHECK_EQ(status, media::DemuxerStream::kOk); | 137 CHECK_EQ(status, media::DemuxerStream::kOk); |
| 138 CHECK(buffer); | 138 CHECK(buffer); |
| 139 *end_of_stream = buffer->IsEndOfStream(); | 139 *end_of_stream = buffer->IsEndOfStream(); |
| 140 *timestamp = buffer->GetTimestamp(); | 140 *timestamp = *end_of_stream ? media::kNoTimestamp() : buffer->GetTimestamp(); |
| 141 message_loop->PostTask(FROM_HERE, base::MessageLoop::QuitWhenIdleClosure()); | 141 message_loop->PostTask(FROM_HERE, base::MessageLoop::QuitWhenIdleClosure()); |
| 142 } | 142 } |
| 143 | 143 |
| 144 int StreamReader::GetNextStreamIndexToRead() { | 144 int StreamReader::GetNextStreamIndexToRead() { |
| 145 int index = -1; | 145 int index = -1; |
| 146 for (int i = 0; i < number_of_streams(); ++i) { | 146 for (int i = 0; i < number_of_streams(); ++i) { |
| 147 // Ignore streams at EOS. | 147 // Ignore streams at EOS. |
| 148 if (end_of_stream_[i]) | 148 if (end_of_stream_[i]) |
| 149 continue; | 149 continue; |
| 150 | 150 |
| (...skipping 44 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 195 // Benchmark. | 195 // Benchmark. |
| 196 base::TimeTicks start = base::TimeTicks::HighResNow(); | 196 base::TimeTicks start = base::TimeTicks::HighResNow(); |
| 197 while (!stream_reader.IsDone()) { | 197 while (!stream_reader.IsDone()) { |
| 198 stream_reader.Read(); | 198 stream_reader.Read(); |
| 199 } | 199 } |
| 200 base::TimeTicks end = base::TimeTicks::HighResNow(); | 200 base::TimeTicks end = base::TimeTicks::HighResNow(); |
| 201 | 201 |
| 202 // Results. | 202 // Results. |
| 203 std::cout << "Time: " << (end - start).InMillisecondsF() << " ms\n"; | 203 std::cout << "Time: " << (end - start).InMillisecondsF() << " ms\n"; |
| 204 for (int i = 0; i < stream_reader.number_of_streams(); ++i) { | 204 for (int i = 0; i < stream_reader.number_of_streams(); ++i) { |
| 205 scoped_refptr<media::DemuxerStream> stream = stream_reader.streams()[i]; | 205 media::DemuxerStream* stream = stream_reader.streams()[i]; |
| 206 std::cout << "Stream #" << i << ": "; | 206 std::cout << "Stream #" << i << ": "; |
| 207 | 207 |
| 208 if (stream->type() == media::DemuxerStream::AUDIO) { | 208 if (stream->type() == media::DemuxerStream::AUDIO) { |
| 209 std::cout << "audio"; | 209 std::cout << "audio"; |
| 210 } else if (stream->type() == media::DemuxerStream::VIDEO) { | 210 } else if (stream->type() == media::DemuxerStream::VIDEO) { |
| 211 std::cout << "video"; | 211 std::cout << "video"; |
| 212 } else { | 212 } else { |
| 213 std::cout << "unknown"; | 213 std::cout << "unknown"; |
| 214 } | 214 } |
| 215 | 215 |
| 216 std::cout << ", " << stream_reader.counts()[i] << " packets" << std::endl; | 216 std::cout << ", " << stream_reader.counts()[i] << " packets" << std::endl; |
| 217 } | 217 } |
| 218 | 218 |
| 219 // Teardown. | 219 // Teardown. |
| 220 demuxer->Stop(base::Bind( | 220 demuxer->Stop(base::Bind( |
| 221 &QuitLoopWithStatus, &message_loop, media::PIPELINE_OK)); | 221 &QuitLoopWithStatus, &message_loop, media::PIPELINE_OK)); |
| 222 message_loop.Run(); | 222 message_loop.Run(); |
| 223 | 223 |
| 224 return 0; | 224 return 0; |
| 225 } | 225 } |
| OLD | NEW |