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 |