| OLD | NEW |
| 1 // Copyright 2015 The Chromium Authors. All rights reserved. | 1 // Copyright 2015 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 #include "media/base/android/test_data_factory.h" | 5 #include "media/base/android/test_data_factory.h" |
| 6 | 6 |
| 7 #include <iterator> |
| 8 |
| 7 #include "base/strings/stringprintf.h" | 9 #include "base/strings/stringprintf.h" |
| 8 #include "media/base/android/demuxer_stream_player_params.h" | 10 #include "media/base/android/demuxer_stream_player_params.h" |
| 9 #include "media/base/decoder_buffer.h" | 11 #include "media/base/decoder_buffer.h" |
| 10 #include "media/base/test_data_util.h" | 12 #include "media/base/test_data_util.h" |
| 11 | 13 |
| 12 namespace media { | 14 namespace media { |
| 13 | 15 |
| 14 DemuxerConfigs TestDataFactory::CreateAudioConfigs(AudioCodec audio_codec, | 16 DemuxerConfigs TestDataFactory::CreateAudioConfigs(AudioCodec audio_codec, |
| 15 base::TimeDelta duration) { | 17 base::TimeDelta duration) { |
| 16 DemuxerConfigs configs; | 18 DemuxerConfigs configs; |
| (...skipping 36 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 53 configs.duration = duration; | 55 configs.duration = duration; |
| 54 | 56 |
| 55 return configs; | 57 return configs; |
| 56 } | 58 } |
| 57 | 59 |
| 58 TestDataFactory::TestDataFactory(const char* file_name_template, | 60 TestDataFactory::TestDataFactory(const char* file_name_template, |
| 59 base::TimeDelta duration, | 61 base::TimeDelta duration, |
| 60 base::TimeDelta frame_period) | 62 base::TimeDelta frame_period) |
| 61 : duration_(duration), | 63 : duration_(duration), |
| 62 frame_period_(frame_period), | 64 frame_period_(frame_period), |
| 65 total_chunks_(0), |
| 63 starvation_mode_(false), | 66 starvation_mode_(false), |
| 64 eos_reached_(false) { | 67 eos_reached_(false) { |
| 65 LoadPackets(file_name_template); | 68 LoadPackets(file_name_template); |
| 66 } | 69 } |
| 67 | 70 |
| 68 TestDataFactory::~TestDataFactory() {} | 71 TestDataFactory::~TestDataFactory() {} |
| 69 | 72 |
| 70 bool TestDataFactory::CreateChunk(DemuxerData* chunk, base::TimeDelta* delay) { | 73 bool TestDataFactory::CreateChunk(DemuxerData* chunk, base::TimeDelta* delay) { |
| 71 DCHECK(chunk); | 74 DCHECK(chunk); |
| 72 DCHECK(delay); | 75 DCHECK(delay); |
| 73 | 76 |
| 74 if (eos_reached_) | 77 if (eos_reached_) |
| 75 return false; | 78 return false; |
| 76 | 79 |
| 77 *delay = base::TimeDelta(); | 80 *delay = base::TimeDelta(); |
| 78 | 81 |
| 82 if (!total_chunks_ && |
| 83 HasReconfigForInterval(base::TimeDelta::FromMilliseconds(-1), |
| 84 base::TimeDelta())) { |
| 85 // Since the configs AU has to come last in the chunk the initial configs |
| 86 // preceeding any other data has to be the only unit in the chunk. |
| 87 AddConfiguration(chunk); |
| 88 ++total_chunks_; |
| 89 return true; |
| 90 } |
| 91 |
| 79 for (int i = 0; i < 4; ++i) { | 92 for (int i = 0; i < 4; ++i) { |
| 93 // Put ConfigChanged at the end of the chunk if there is a request |
| 94 // for the chunk's timeframe. |
| 95 if (i == 3 && HasReconfigForInterval(chunk->access_units[0].timestamp, |
| 96 regular_pts_)) { |
| 97 AddConfiguration(chunk); |
| 98 break; |
| 99 } |
| 100 |
| 80 chunk->access_units.push_back(AccessUnit()); | 101 chunk->access_units.push_back(AccessUnit()); |
| 81 AccessUnit& unit = chunk->access_units.back(); | 102 AccessUnit& unit = chunk->access_units.back(); |
| 82 unit.status = DemuxerStream::kOk; | 103 unit.status = DemuxerStream::kOk; |
| 83 | 104 |
| 84 unit.timestamp = regular_pts_; | 105 unit.timestamp = regular_pts_; |
| 85 regular_pts_ += frame_period_; | 106 regular_pts_ += frame_period_; |
| 86 | 107 |
| 87 if (unit.timestamp > duration_) { | 108 if (unit.timestamp > duration_) { |
| 88 if (starvation_mode_) | 109 if (starvation_mode_) |
| 89 return false; | 110 return false; |
| 90 | 111 |
| 91 unit.is_end_of_stream = true; | 112 unit.is_end_of_stream = true; |
| 92 eos_reached_ = true; | 113 eos_reached_ = true; |
| 93 break; // EOS units have no data. | 114 break; // EOS units have no data. |
| 94 } | 115 } |
| 95 | 116 |
| 96 unit.data = packet_[i]; | 117 unit.data = packet_[i]; |
| 97 | 118 |
| 98 // Allow for modification by subclasses. | 119 // Allow for modification by subclasses. |
| 99 ModifyAccessUnit(i, &unit); | 120 ModifyAccessUnit(i, &unit); |
| 100 | 121 |
| 101 // Maintain last PTS. ModifyAccessUnit() can modify unit's PTS. | 122 // Maintain last PTS. ModifyAccessUnit() can modify unit's PTS. |
| 102 if (last_pts_ < unit.timestamp) | 123 if (last_pts_ < unit.timestamp) |
| 103 last_pts_ = unit.timestamp; | 124 last_pts_ = unit.timestamp; |
| 104 } | 125 } |
| 105 | 126 |
| 127 ++total_chunks_; |
| 106 return true; | 128 return true; |
| 107 } | 129 } |
| 108 | 130 |
| 109 void TestDataFactory::SeekTo(const base::TimeDelta& seek_time) { | 131 void TestDataFactory::SeekTo(const base::TimeDelta& seek_time) { |
| 110 regular_pts_ = seek_time; | 132 regular_pts_ = seek_time; |
| 111 last_pts_ = base::TimeDelta(); | 133 last_pts_ = base::TimeDelta(); |
| 112 eos_reached_ = false; | 134 eos_reached_ = false; |
| 113 } | 135 } |
| 114 | 136 |
| 137 void TestDataFactory::RequestInitialConfigs() { |
| 138 reconfigs_.insert(base::TimeDelta::FromMilliseconds(-1)); |
| 139 } |
| 140 |
| 141 void TestDataFactory::RequestConfigChange(base::TimeDelta config_position) { |
| 142 reconfigs_.insert(config_position); |
| 143 } |
| 144 |
| 115 void TestDataFactory::LoadPackets(const char* file_name_template) { | 145 void TestDataFactory::LoadPackets(const char* file_name_template) { |
| 116 for (int i = 0; i < 4; ++i) { | 146 for (int i = 0; i < 4; ++i) { |
| 117 scoped_refptr<DecoderBuffer> buffer = | 147 scoped_refptr<DecoderBuffer> buffer = |
| 118 ReadTestDataFile(base::StringPrintf(file_name_template, i)); | 148 ReadTestDataFile(base::StringPrintf(file_name_template, i)); |
| 119 packet_[i] = std::vector<uint8>(buffer->data(), | 149 packet_[i] = std::vector<uint8>(buffer->data(), |
| 120 buffer->data() + buffer->data_size()); | 150 buffer->data() + buffer->data_size()); |
| 121 } | 151 } |
| 122 } | 152 } |
| 123 | 153 |
| 154 bool TestDataFactory::HasReconfigForInterval(base::TimeDelta left, |
| 155 base::TimeDelta right) const { |
| 156 // |first| points to an element greater or equal to |left|. |
| 157 PTSSet::const_iterator first = reconfigs_.lower_bound(left); |
| 158 |
| 159 // |last| points to an element greater or equal to |right|. |
| 160 PTSSet::const_iterator last = reconfigs_.lower_bound(right); |
| 161 |
| 162 return std::distance(first, last); |
| 163 } |
| 164 |
| 165 void TestDataFactory::AddConfiguration(DemuxerData* chunk) { |
| 166 DCHECK(chunk); |
| 167 chunk->access_units.push_back(AccessUnit()); |
| 168 AccessUnit& unit = chunk->access_units.back(); |
| 169 unit.status = DemuxerStream::kConfigChanged; |
| 170 |
| 171 DCHECK(chunk->demuxer_configs.empty()); |
| 172 chunk->demuxer_configs.push_back(GetConfigs()); |
| 173 } |
| 174 |
| 124 } // namespace media | 175 } // namespace media |
| OLD | NEW |