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