| 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 |