OLD | NEW |
1 // Copyright 2014 The Chromium Authors. All rights reserved. | 1 // Copyright 2014 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 <algorithm> | 5 #include <algorithm> |
6 #include <string> | 6 #include <string> |
7 | 7 |
8 #include "base/bind.h" | 8 #include "base/bind.h" |
9 #include "base/bind_helpers.h" | 9 #include "base/bind_helpers.h" |
10 #include "base/logging.h" | 10 #include "base/logging.h" |
11 #include "base/memory/ref_counted.h" | 11 #include "base/memory/ref_counted.h" |
12 #include "base/time/time.h" | 12 #include "base/time/time.h" |
13 #include "media/base/audio_decoder_config.h" | 13 #include "media/base/audio_decoder_config.h" |
14 #include "media/base/decoder_buffer.h" | 14 #include "media/base/decoder_buffer.h" |
| 15 #include "media/base/mock_media_log.h" |
15 #include "media/base/stream_parser_buffer.h" | 16 #include "media/base/stream_parser_buffer.h" |
16 #include "media/base/test_data_util.h" | 17 #include "media/base/test_data_util.h" |
17 #include "media/base/text_track_config.h" | 18 #include "media/base/text_track_config.h" |
18 #include "media/base/video_decoder_config.h" | 19 #include "media/base/video_decoder_config.h" |
19 #include "media/formats/mp4/es_descriptor.h" | 20 #include "media/formats/mp4/es_descriptor.h" |
20 #include "media/formats/mp4/mp4_stream_parser.h" | 21 #include "media/formats/mp4/mp4_stream_parser.h" |
| 22 #include "testing/gmock/include/gmock/gmock.h" |
21 #include "testing/gtest/include/gtest/gtest.h" | 23 #include "testing/gtest/include/gtest/gtest.h" |
22 | 24 |
| 25 using ::testing::InSequence; |
| 26 using ::testing::StrictMock; |
23 using base::TimeDelta; | 27 using base::TimeDelta; |
24 | 28 |
25 namespace media { | 29 namespace media { |
26 namespace mp4 { | 30 namespace mp4 { |
27 | 31 |
| 32 // Matchers for verifying common media log entry strings. |
| 33 MATCHER_P(VideoCodecLog, codec_string, "") { |
| 34 return CONTAINS_STRING(arg, "Video codec: " + std::string(codec_string)); |
| 35 } |
| 36 |
| 37 MATCHER_P(AudioCodecLog, codec_string, "") { |
| 38 return CONTAINS_STRING(arg, "Audio codec: " + std::string(codec_string)); |
| 39 } |
| 40 |
| 41 MATCHER(AuxInfoUnavailableLog, "") { |
| 42 return CONTAINS_STRING(arg, "Aux Info is not available."); |
| 43 } |
| 44 |
28 class MP4StreamParserTest : public testing::Test { | 45 class MP4StreamParserTest : public testing::Test { |
29 public: | 46 public: |
30 MP4StreamParserTest() | 47 MP4StreamParserTest() |
31 : configs_received_(false), | 48 : media_log_(new StrictMock<MockMediaLog>()), |
| 49 configs_received_(false), |
32 lower_bound_( | 50 lower_bound_( |
33 DecodeTimestamp::FromPresentationTime(base::TimeDelta::Max())) { | 51 DecodeTimestamp::FromPresentationTime(base::TimeDelta::Max())) { |
34 std::set<int> audio_object_types; | 52 std::set<int> audio_object_types; |
35 audio_object_types.insert(kISO_14496_3); | 53 audio_object_types.insert(kISO_14496_3); |
36 parser_.reset(new MP4StreamParser(audio_object_types, false)); | 54 parser_.reset(new MP4StreamParser(audio_object_types, false)); |
37 } | 55 } |
38 | 56 |
39 protected: | 57 protected: |
| 58 scoped_refptr<StrictMock<MockMediaLog>> media_log_; |
40 scoped_ptr<MP4StreamParser> parser_; | 59 scoped_ptr<MP4StreamParser> parser_; |
41 bool configs_received_; | 60 bool configs_received_; |
42 AudioDecoderConfig audio_decoder_config_; | 61 AudioDecoderConfig audio_decoder_config_; |
43 VideoDecoderConfig video_decoder_config_; | 62 VideoDecoderConfig video_decoder_config_; |
44 DecodeTimestamp lower_bound_; | 63 DecodeTimestamp lower_bound_; |
45 | 64 |
46 bool AppendData(const uint8* data, size_t length) { | 65 bool AppendData(const uint8* data, size_t length) { |
47 return parser_->Parse(data, length); | 66 return parser_->Parse(data, length); |
48 } | 67 } |
49 | 68 |
(...skipping 92 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
142 DemuxerStream::Liveness expected_liveness) { | 161 DemuxerStream::Liveness expected_liveness) { |
143 parser_->Init( | 162 parser_->Init( |
144 base::Bind(&MP4StreamParserTest::InitF, base::Unretained(this), | 163 base::Bind(&MP4StreamParserTest::InitF, base::Unretained(this), |
145 expected_liveness), | 164 expected_liveness), |
146 base::Bind(&MP4StreamParserTest::NewConfigF, base::Unretained(this)), | 165 base::Bind(&MP4StreamParserTest::NewConfigF, base::Unretained(this)), |
147 base::Bind(&MP4StreamParserTest::NewBuffersF, base::Unretained(this)), | 166 base::Bind(&MP4StreamParserTest::NewBuffersF, base::Unretained(this)), |
148 true, | 167 true, |
149 base::Bind(&MP4StreamParserTest::KeyNeededF, base::Unretained(this)), | 168 base::Bind(&MP4StreamParserTest::KeyNeededF, base::Unretained(this)), |
150 base::Bind(&MP4StreamParserTest::NewSegmentF, base::Unretained(this)), | 169 base::Bind(&MP4StreamParserTest::NewSegmentF, base::Unretained(this)), |
151 base::Bind(&MP4StreamParserTest::EndOfSegmentF, base::Unretained(this)), | 170 base::Bind(&MP4StreamParserTest::EndOfSegmentF, base::Unretained(this)), |
152 new MediaLog()); | 171 media_log_); |
153 } | 172 } |
154 | 173 |
155 void InitializeParser() { | 174 void InitializeParser() { |
156 // Most unencrypted test mp4 files have zero duration and are treated as | 175 // Most unencrypted test mp4 files have zero duration and are treated as |
157 // live streams. | 176 // live streams. |
158 InitializeParserAndExpectLiveness(DemuxerStream::LIVENESS_LIVE); | 177 InitializeParserAndExpectLiveness(DemuxerStream::LIVENESS_LIVE); |
159 } | 178 } |
160 | 179 |
161 bool ParseMP4File(const std::string& filename, int append_bytes) { | 180 bool ParseMP4File(const std::string& filename, int append_bytes) { |
162 InitializeParser(); | 181 InitializeParser(); |
163 | 182 |
164 scoped_refptr<DecoderBuffer> buffer = ReadTestDataFile(filename); | 183 scoped_refptr<DecoderBuffer> buffer = ReadTestDataFile(filename); |
165 EXPECT_TRUE(AppendDataInPieces(buffer->data(), | 184 EXPECT_TRUE(AppendDataInPieces(buffer->data(), |
166 buffer->data_size(), | 185 buffer->data_size(), |
167 append_bytes)); | 186 append_bytes)); |
168 return true; | 187 return true; |
169 } | 188 } |
170 }; | 189 }; |
171 | 190 |
172 TEST_F(MP4StreamParserTest, UnalignedAppend) { | 191 TEST_F(MP4StreamParserTest, UnalignedAppend) { |
173 // Test small, non-segment-aligned appends (small enough to exercise | 192 // Test small, non-segment-aligned appends (small enough to exercise |
174 // incremental append system) | 193 // incremental append system) |
| 194 EXPECT_MEDIA_LOG(VideoCodecLog("avc1.6401f")); |
| 195 EXPECT_MEDIA_LOG(AudioCodecLog("mp4a.40.2")); |
175 ParseMP4File("bear-1280x720-av_frag.mp4", 512); | 196 ParseMP4File("bear-1280x720-av_frag.mp4", 512); |
176 } | 197 } |
177 | 198 |
178 TEST_F(MP4StreamParserTest, BytewiseAppend) { | 199 TEST_F(MP4StreamParserTest, BytewiseAppend) { |
179 // Ensure no incremental errors occur when parsing | 200 // Ensure no incremental errors occur when parsing |
| 201 EXPECT_MEDIA_LOG(VideoCodecLog("avc1.6401f")); |
| 202 EXPECT_MEDIA_LOG(AudioCodecLog("mp4a.40.2")); |
180 ParseMP4File("bear-1280x720-av_frag.mp4", 1); | 203 ParseMP4File("bear-1280x720-av_frag.mp4", 1); |
181 } | 204 } |
182 | 205 |
183 TEST_F(MP4StreamParserTest, MultiFragmentAppend) { | 206 TEST_F(MP4StreamParserTest, MultiFragmentAppend) { |
184 // Large size ensures multiple fragments are appended in one call (size is | 207 // Large size ensures multiple fragments are appended in one call (size is |
185 // larger than this particular test file) | 208 // larger than this particular test file) |
| 209 EXPECT_MEDIA_LOG(VideoCodecLog("avc1.6401f")); |
| 210 EXPECT_MEDIA_LOG(AudioCodecLog("mp4a.40.2")); |
186 ParseMP4File("bear-1280x720-av_frag.mp4", 768432); | 211 ParseMP4File("bear-1280x720-av_frag.mp4", 768432); |
187 } | 212 } |
188 | 213 |
189 TEST_F(MP4StreamParserTest, Flush) { | 214 TEST_F(MP4StreamParserTest, Flush) { |
190 // Flush while reading sample data, then start a new stream. | 215 // Flush while reading sample data, then start a new stream. |
| 216 EXPECT_MEDIA_LOG(VideoCodecLog("avc1.6401f")).Times(2); |
| 217 EXPECT_MEDIA_LOG(AudioCodecLog("mp4a.40.2")).Times(2); |
191 InitializeParser(); | 218 InitializeParser(); |
192 | 219 |
193 scoped_refptr<DecoderBuffer> buffer = | 220 scoped_refptr<DecoderBuffer> buffer = |
194 ReadTestDataFile("bear-1280x720-av_frag.mp4"); | 221 ReadTestDataFile("bear-1280x720-av_frag.mp4"); |
195 EXPECT_TRUE(AppendDataInPieces(buffer->data(), 65536, 512)); | 222 EXPECT_TRUE(AppendDataInPieces(buffer->data(), 65536, 512)); |
196 parser_->Flush(); | 223 parser_->Flush(); |
197 EXPECT_TRUE(AppendDataInPieces(buffer->data(), | 224 EXPECT_TRUE(AppendDataInPieces(buffer->data(), |
198 buffer->data_size(), | 225 buffer->data_size(), |
199 512)); | 226 512)); |
200 } | 227 } |
201 | 228 |
202 TEST_F(MP4StreamParserTest, Reinitialization) { | 229 TEST_F(MP4StreamParserTest, Reinitialization) { |
| 230 EXPECT_MEDIA_LOG(VideoCodecLog("avc1.6401f")).Times(2); |
| 231 EXPECT_MEDIA_LOG(AudioCodecLog("mp4a.40.2")).Times(2); |
203 InitializeParser(); | 232 InitializeParser(); |
204 | 233 |
205 scoped_refptr<DecoderBuffer> buffer = | 234 scoped_refptr<DecoderBuffer> buffer = |
206 ReadTestDataFile("bear-1280x720-av_frag.mp4"); | 235 ReadTestDataFile("bear-1280x720-av_frag.mp4"); |
207 EXPECT_TRUE(AppendDataInPieces(buffer->data(), | 236 EXPECT_TRUE(AppendDataInPieces(buffer->data(), |
208 buffer->data_size(), | 237 buffer->data_size(), |
209 512)); | 238 512)); |
210 EXPECT_TRUE(AppendDataInPieces(buffer->data(), | 239 EXPECT_TRUE(AppendDataInPieces(buffer->data(), |
211 buffer->data_size(), | 240 buffer->data_size(), |
212 512)); | 241 512)); |
213 } | 242 } |
214 | 243 |
215 TEST_F(MP4StreamParserTest, MPEG2_AAC_LC) { | 244 TEST_F(MP4StreamParserTest, MPEG2_AAC_LC) { |
| 245 InSequence s; |
216 std::set<int> audio_object_types; | 246 std::set<int> audio_object_types; |
217 audio_object_types.insert(kISO_13818_7_AAC_LC); | 247 audio_object_types.insert(kISO_13818_7_AAC_LC); |
218 parser_.reset(new MP4StreamParser(audio_object_types, false)); | 248 parser_.reset(new MP4StreamParser(audio_object_types, false)); |
| 249 EXPECT_MEDIA_LOG(AudioCodecLog("mp4a.67")); |
| 250 EXPECT_MEDIA_LOG(AudioCodecLog("mp4a.40.2")); |
219 ParseMP4File("bear-mpeg2-aac-only_frag.mp4", 512); | 251 ParseMP4File("bear-mpeg2-aac-only_frag.mp4", 512); |
220 } | 252 } |
221 | 253 |
222 // Test that a moov box is not always required after Flush() is called. | 254 // Test that a moov box is not always required after Flush() is called. |
223 TEST_F(MP4StreamParserTest, NoMoovAfterFlush) { | 255 TEST_F(MP4StreamParserTest, NoMoovAfterFlush) { |
| 256 EXPECT_MEDIA_LOG(VideoCodecLog("avc1.6401f")); |
| 257 EXPECT_MEDIA_LOG(AudioCodecLog("mp4a.40.2")); |
224 InitializeParser(); | 258 InitializeParser(); |
225 | 259 |
226 scoped_refptr<DecoderBuffer> buffer = | 260 scoped_refptr<DecoderBuffer> buffer = |
227 ReadTestDataFile("bear-1280x720-av_frag.mp4"); | 261 ReadTestDataFile("bear-1280x720-av_frag.mp4"); |
228 EXPECT_TRUE(AppendDataInPieces(buffer->data(), | 262 EXPECT_TRUE(AppendDataInPieces(buffer->data(), |
229 buffer->data_size(), | 263 buffer->data_size(), |
230 512)); | 264 512)); |
231 parser_->Flush(); | 265 parser_->Flush(); |
232 | 266 |
233 const int kFirstMoofOffset = 1307; | 267 const int kFirstMoofOffset = 1307; |
234 EXPECT_TRUE(AppendDataInPieces(buffer->data() + kFirstMoofOffset, | 268 EXPECT_TRUE(AppendDataInPieces(buffer->data() + kFirstMoofOffset, |
235 buffer->data_size() - kFirstMoofOffset, | 269 buffer->data_size() - kFirstMoofOffset, |
236 512)); | 270 512)); |
237 } | 271 } |
238 | 272 |
239 // Test an invalid file where there are encrypted samples, but | 273 // Test an invalid file where there are encrypted samples, but |
240 // SampleAuxiliaryInformation{Sizes|Offsets}Box (saiz|saio) are missing. | 274 // SampleAuxiliaryInformation{Sizes|Offsets}Box (saiz|saio) are missing. |
241 // The parser should fail instead of crash. See http://crbug.com/361347 | 275 // The parser should fail instead of crash. See http://crbug.com/361347 |
242 TEST_F(MP4StreamParserTest, MissingSampleAuxInfo) { | 276 TEST_F(MP4StreamParserTest, MissingSampleAuxInfo) { |
| 277 InSequence s; |
| 278 |
243 // Encrypted test mp4 files have non-zero duration and are treated as | 279 // Encrypted test mp4 files have non-zero duration and are treated as |
244 // recorded streams. | 280 // recorded streams. |
245 InitializeParserAndExpectLiveness(DemuxerStream::LIVENESS_RECORDED); | 281 InitializeParserAndExpectLiveness(DemuxerStream::LIVENESS_RECORDED); |
246 | 282 |
247 scoped_refptr<DecoderBuffer> buffer = | 283 scoped_refptr<DecoderBuffer> buffer = |
248 ReadTestDataFile("bear-1280x720-a_frag-cenc_missing-saiz-saio.mp4"); | 284 ReadTestDataFile("bear-1280x720-a_frag-cenc_missing-saiz-saio.mp4"); |
| 285 EXPECT_MEDIA_LOG(AudioCodecLog("mp4a.40.2")).Times(2); |
| 286 EXPECT_MEDIA_LOG(AuxInfoUnavailableLog()); |
249 EXPECT_FALSE(AppendDataInPieces(buffer->data(), buffer->data_size(), 512)); | 287 EXPECT_FALSE(AppendDataInPieces(buffer->data(), buffer->data_size(), 512)); |
250 } | 288 } |
251 | 289 |
252 // Test a file where all video samples start with an Access Unit | 290 // Test a file where all video samples start with an Access Unit |
253 // Delimiter (AUD) NALU. | 291 // Delimiter (AUD) NALU. |
254 TEST_F(MP4StreamParserTest, VideoSamplesStartWithAUDs) { | 292 TEST_F(MP4StreamParserTest, VideoSamplesStartWithAUDs) { |
| 293 EXPECT_MEDIA_LOG(VideoCodecLog("avc1.4d4028")); |
255 ParseMP4File("bear-1280x720-av_with-aud-nalus_frag.mp4", 512); | 294 ParseMP4File("bear-1280x720-av_with-aud-nalus_frag.mp4", 512); |
256 } | 295 } |
257 | 296 |
258 TEST_F(MP4StreamParserTest, CENC) { | 297 TEST_F(MP4StreamParserTest, CENC) { |
259 // Encrypted test mp4 files have non-zero duration and are treated as | 298 // Encrypted test mp4 files have non-zero duration and are treated as |
260 // recorded streams. | 299 // recorded streams. |
261 InitializeParserAndExpectLiveness(DemuxerStream::LIVENESS_RECORDED); | 300 InitializeParserAndExpectLiveness(DemuxerStream::LIVENESS_RECORDED); |
262 | 301 |
263 scoped_refptr<DecoderBuffer> buffer = | 302 scoped_refptr<DecoderBuffer> buffer = |
264 ReadTestDataFile("bear-1280x720-v_frag-cenc.mp4"); | 303 ReadTestDataFile("bear-1280x720-v_frag-cenc.mp4"); |
| 304 EXPECT_MEDIA_LOG(VideoCodecLog("avc1.6401f")); |
265 EXPECT_TRUE(AppendDataInPieces(buffer->data(), buffer->data_size(), 512)); | 305 EXPECT_TRUE(AppendDataInPieces(buffer->data(), buffer->data_size(), 512)); |
266 } | 306 } |
267 | 307 |
268 TEST_F(MP4StreamParserTest, NaturalSizeWithoutPASP) { | 308 TEST_F(MP4StreamParserTest, NaturalSizeWithoutPASP) { |
269 InitializeParserAndExpectLiveness(DemuxerStream::LIVENESS_RECORDED); | 309 InitializeParserAndExpectLiveness(DemuxerStream::LIVENESS_RECORDED); |
270 | 310 |
271 scoped_refptr<DecoderBuffer> buffer = | 311 scoped_refptr<DecoderBuffer> buffer = |
272 ReadTestDataFile("bear-640x360-non_square_pixel-without_pasp.mp4"); | 312 ReadTestDataFile("bear-640x360-non_square_pixel-without_pasp.mp4"); |
273 | 313 |
| 314 EXPECT_MEDIA_LOG(VideoCodecLog("avc1.6401e")); |
274 EXPECT_TRUE(AppendDataInPieces(buffer->data(), buffer->data_size(), 512)); | 315 EXPECT_TRUE(AppendDataInPieces(buffer->data(), buffer->data_size(), 512)); |
275 EXPECT_EQ(gfx::Size(639, 360), video_decoder_config_.natural_size()); | 316 EXPECT_EQ(gfx::Size(639, 360), video_decoder_config_.natural_size()); |
276 } | 317 } |
277 | 318 |
278 TEST_F(MP4StreamParserTest, NaturalSizeWithPASP) { | 319 TEST_F(MP4StreamParserTest, NaturalSizeWithPASP) { |
279 InitializeParserAndExpectLiveness(DemuxerStream::LIVENESS_RECORDED); | 320 InitializeParserAndExpectLiveness(DemuxerStream::LIVENESS_RECORDED); |
280 | 321 |
281 scoped_refptr<DecoderBuffer> buffer = | 322 scoped_refptr<DecoderBuffer> buffer = |
282 ReadTestDataFile("bear-640x360-non_square_pixel-with_pasp.mp4"); | 323 ReadTestDataFile("bear-640x360-non_square_pixel-with_pasp.mp4"); |
283 | 324 |
| 325 EXPECT_MEDIA_LOG(VideoCodecLog("avc1.6401e")); |
284 EXPECT_TRUE(AppendDataInPieces(buffer->data(), buffer->data_size(), 512)); | 326 EXPECT_TRUE(AppendDataInPieces(buffer->data(), buffer->data_size(), 512)); |
285 EXPECT_EQ(gfx::Size(639, 360), video_decoder_config_.natural_size()); | 327 EXPECT_EQ(gfx::Size(639, 360), video_decoder_config_.natural_size()); |
286 } | 328 } |
287 | 329 |
288 } // namespace mp4 | 330 } // namespace mp4 |
289 } // namespace media | 331 } // namespace media |
OLD | NEW |