| OLD | NEW |
| 1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2012 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/filters/source_buffer_stream.h" | 5 #include "media/filters/source_buffer_stream.h" |
| 6 | 6 |
| 7 #include <stddef.h> | 7 #include <stddef.h> |
| 8 #include <stdint.h> | 8 #include <stdint.h> |
| 9 #include <string> | 9 #include <string> |
| 10 #include <vector> | 10 #include <vector> |
| (...skipping 45 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 56 "Media append that overlapped current playback " | 56 "Media append that overlapped current playback " |
| 57 "position caused time gap in playing VIDEO stream " | 57 "position caused time gap in playing VIDEO stream " |
| 58 "because the next keyframe is " + | 58 "because the next keyframe is " + |
| 59 base::IntToString(skip_milliseconds) + | 59 base::IntToString(skip_milliseconds) + |
| 60 "ms beyond last overlapped frame. Media may " | 60 "ms beyond last overlapped frame. Media may " |
| 61 "appear temporarily frozen."); | 61 "appear temporarily frozen."); |
| 62 } | 62 } |
| 63 | 63 |
| 64 class SourceBufferStreamTest : public testing::Test { | 64 class SourceBufferStreamTest : public testing::Test { |
| 65 protected: | 65 protected: |
| 66 SourceBufferStreamTest() : media_log_(new StrictMock<MockMediaLog>()) { | 66 SourceBufferStreamTest() { |
| 67 video_config_ = TestVideoConfig::Normal(); | 67 video_config_ = TestVideoConfig::Normal(); |
| 68 SetStreamInfo(kDefaultFramesPerSecond, kDefaultKeyframesPerSecond); | 68 SetStreamInfo(kDefaultFramesPerSecond, kDefaultKeyframesPerSecond); |
| 69 stream_.reset(new SourceBufferStream(video_config_, media_log_)); | 69 stream_.reset(new SourceBufferStream(video_config_, &media_log_)); |
| 70 } | 70 } |
| 71 | 71 |
| 72 void SetMemoryLimit(size_t buffers_of_data) { | 72 void SetMemoryLimit(size_t buffers_of_data) { |
| 73 stream_->set_memory_limit(buffers_of_data * kDataSize); | 73 stream_->set_memory_limit(buffers_of_data * kDataSize); |
| 74 } | 74 } |
| 75 | 75 |
| 76 void SetStreamInfo(int frames_per_second, int keyframes_per_second) { | 76 void SetStreamInfo(int frames_per_second, int keyframes_per_second) { |
| 77 frames_per_second_ = frames_per_second; | 77 frames_per_second_ = frames_per_second; |
| 78 keyframes_per_second_ = keyframes_per_second; | 78 keyframes_per_second_ = keyframes_per_second; |
| 79 frame_duration_ = ConvertToFrameDuration(frames_per_second); | 79 frame_duration_ = ConvertToFrameDuration(frames_per_second); |
| 80 } | 80 } |
| 81 | 81 |
| 82 void SetTextStream() { | 82 void SetTextStream() { |
| 83 video_config_ = TestVideoConfig::Invalid(); | 83 video_config_ = TestVideoConfig::Invalid(); |
| 84 TextTrackConfig config(kTextSubtitles, "", "", ""); | 84 TextTrackConfig config(kTextSubtitles, "", "", ""); |
| 85 stream_.reset(new SourceBufferStream(config, media_log_)); | 85 stream_.reset(new SourceBufferStream(config, &media_log_)); |
| 86 SetStreamInfo(2, 2); | 86 SetStreamInfo(2, 2); |
| 87 } | 87 } |
| 88 | 88 |
| 89 void SetAudioStream() { | 89 void SetAudioStream() { |
| 90 video_config_ = TestVideoConfig::Invalid(); | 90 video_config_ = TestVideoConfig::Invalid(); |
| 91 audio_config_.Initialize(kCodecVorbis, kSampleFormatPlanarF32, | 91 audio_config_.Initialize(kCodecVorbis, kSampleFormatPlanarF32, |
| 92 CHANNEL_LAYOUT_STEREO, 1000, EmptyExtraData(), | 92 CHANNEL_LAYOUT_STEREO, 1000, EmptyExtraData(), |
| 93 Unencrypted(), base::TimeDelta(), 0); | 93 Unencrypted(), base::TimeDelta(), 0); |
| 94 stream_.reset(new SourceBufferStream(audio_config_, media_log_)); | 94 stream_.reset(new SourceBufferStream(audio_config_, &media_log_)); |
| 95 | 95 |
| 96 // Equivalent to 2ms per frame. | 96 // Equivalent to 2ms per frame. |
| 97 SetStreamInfo(500, 500); | 97 SetStreamInfo(500, 500); |
| 98 } | 98 } |
| 99 | 99 |
| 100 void NewCodedFrameGroupAppend(int starting_position, int number_of_buffers) { | 100 void NewCodedFrameGroupAppend(int starting_position, int number_of_buffers) { |
| 101 AppendBuffers(starting_position, number_of_buffers, true, | 101 AppendBuffers(starting_position, number_of_buffers, true, |
| 102 base::TimeDelta(), true, &kDataA, kDataSize); | 102 base::TimeDelta(), true, &kDataA, kDataSize); |
| 103 } | 103 } |
| 104 | 104 |
| (...skipping 296 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 401 | 401 |
| 402 void CheckAudioConfig(const AudioDecoderConfig& config) { | 402 void CheckAudioConfig(const AudioDecoderConfig& config) { |
| 403 const AudioDecoderConfig& actual = stream_->GetCurrentAudioDecoderConfig(); | 403 const AudioDecoderConfig& actual = stream_->GetCurrentAudioDecoderConfig(); |
| 404 EXPECT_TRUE(actual.Matches(config)) | 404 EXPECT_TRUE(actual.Matches(config)) |
| 405 << "Expected: " << config.AsHumanReadableString() | 405 << "Expected: " << config.AsHumanReadableString() |
| 406 << "\nActual: " << actual.AsHumanReadableString(); | 406 << "\nActual: " << actual.AsHumanReadableString(); |
| 407 } | 407 } |
| 408 | 408 |
| 409 base::TimeDelta frame_duration() const { return frame_duration_; } | 409 base::TimeDelta frame_duration() const { return frame_duration_; } |
| 410 | 410 |
| 411 StrictMock<MockMediaLog> media_log_; |
| 411 std::unique_ptr<SourceBufferStream> stream_; | 412 std::unique_ptr<SourceBufferStream> stream_; |
| 412 VideoDecoderConfig video_config_; | 413 VideoDecoderConfig video_config_; |
| 413 AudioDecoderConfig audio_config_; | 414 AudioDecoderConfig audio_config_; |
| 414 scoped_refptr<StrictMock<MockMediaLog>> media_log_; | |
| 415 | 415 |
| 416 private: | 416 private: |
| 417 base::TimeDelta ConvertToFrameDuration(int frames_per_second) { | 417 base::TimeDelta ConvertToFrameDuration(int frames_per_second) { |
| 418 return base::TimeDelta::FromMicroseconds( | 418 return base::TimeDelta::FromMicroseconds( |
| 419 base::Time::kMicrosecondsPerSecond / frames_per_second); | 419 base::Time::kMicrosecondsPerSecond / frames_per_second); |
| 420 } | 420 } |
| 421 | 421 |
| 422 void AppendBuffers(int starting_position, | 422 void AppendBuffers(int starting_position, |
| 423 int number_of_buffers, | 423 int number_of_buffers, |
| 424 bool begin_coded_frame_group, | 424 bool begin_coded_frame_group, |
| (...skipping 3226 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 3651 Seek(0); | 3651 Seek(0); |
| 3652 CheckExpectedBuffers("0K 20 40 60 80 90 90 110K 150"); | 3652 CheckExpectedBuffers("0K 20 40 60 80 90 90 110K 150"); |
| 3653 CheckNoNextBuffer(); | 3653 CheckNoNextBuffer(); |
| 3654 CheckExpectedRangesByTimestamp("{ [0,190) }"); | 3654 CheckExpectedRangesByTimestamp("{ [0,190) }"); |
| 3655 } | 3655 } |
| 3656 | 3656 |
| 3657 // Test all the valid same timestamp cases for audio. | 3657 // Test all the valid same timestamp cases for audio. |
| 3658 TEST_F(SourceBufferStreamTest, SameTimestamp_Audio) { | 3658 TEST_F(SourceBufferStreamTest, SameTimestamp_Audio) { |
| 3659 AudioDecoderConfig config(kCodecMP3, kSampleFormatF32, CHANNEL_LAYOUT_STEREO, | 3659 AudioDecoderConfig config(kCodecMP3, kSampleFormatF32, CHANNEL_LAYOUT_STEREO, |
| 3660 44100, EmptyExtraData(), Unencrypted()); | 3660 44100, EmptyExtraData(), Unencrypted()); |
| 3661 stream_.reset(new SourceBufferStream(config, media_log_)); | 3661 stream_.reset(new SourceBufferStream(config, &media_log_)); |
| 3662 Seek(0); | 3662 Seek(0); |
| 3663 NewCodedFrameGroupAppend("0K 0K 30K 30 60 60"); | 3663 NewCodedFrameGroupAppend("0K 0K 30K 30 60 60"); |
| 3664 CheckExpectedBuffers("0K 0K 30K 30 60 60"); | 3664 CheckExpectedBuffers("0K 0K 30K 30 60 60"); |
| 3665 } | 3665 } |
| 3666 | 3666 |
| 3667 TEST_F(SourceBufferStreamTest, SameTimestamp_Audio_SingleAppend_Warning) { | 3667 TEST_F(SourceBufferStreamTest, SameTimestamp_Audio_SingleAppend_Warning) { |
| 3668 EXPECT_MEDIA_LOG(ContainsSameTimestampAt30MillisecondsLog()); | 3668 EXPECT_MEDIA_LOG(ContainsSameTimestampAt30MillisecondsLog()); |
| 3669 | 3669 |
| 3670 AudioDecoderConfig config(kCodecMP3, kSampleFormatF32, CHANNEL_LAYOUT_STEREO, | 3670 AudioDecoderConfig config(kCodecMP3, kSampleFormatF32, CHANNEL_LAYOUT_STEREO, |
| 3671 44100, EmptyExtraData(), Unencrypted()); | 3671 44100, EmptyExtraData(), Unencrypted()); |
| 3672 stream_.reset(new SourceBufferStream(config, media_log_)); | 3672 stream_.reset(new SourceBufferStream(config, &media_log_)); |
| 3673 Seek(0); | 3673 Seek(0); |
| 3674 | 3674 |
| 3675 // Note, in reality, a non-keyframe audio frame is rare or perhaps not | 3675 // Note, in reality, a non-keyframe audio frame is rare or perhaps not |
| 3676 // possible. | 3676 // possible. |
| 3677 NewCodedFrameGroupAppend("0K 30 30K 60"); | 3677 NewCodedFrameGroupAppend("0K 30 30K 60"); |
| 3678 CheckExpectedBuffers("0K 30 30K 60"); | 3678 CheckExpectedBuffers("0K 30 30K 60"); |
| 3679 } | 3679 } |
| 3680 | 3680 |
| 3681 // If seeking past any existing range and the seek is pending | 3681 // If seeking past any existing range and the seek is pending |
| 3682 // because no data has been provided for that position, | 3682 // because no data has been provided for that position, |
| (...skipping 524 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 4207 | 4207 |
| 4208 TEST_F(SourceBufferStreamTest, Audio_SpliceFrame_NoMillisecondSplices) { | 4208 TEST_F(SourceBufferStreamTest, Audio_SpliceFrame_NoMillisecondSplices) { |
| 4209 EXPECT_MEDIA_LOG( | 4209 EXPECT_MEDIA_LOG( |
| 4210 HasSubstr("Skipping audio splice trimming at PTS=1250us. Found only 250us" | 4210 HasSubstr("Skipping audio splice trimming at PTS=1250us. Found only 250us" |
| 4211 " of overlap, need at least 1000us.")); | 4211 " of overlap, need at least 1000us.")); |
| 4212 | 4212 |
| 4213 video_config_ = TestVideoConfig::Invalid(); | 4213 video_config_ = TestVideoConfig::Invalid(); |
| 4214 audio_config_.Initialize(kCodecVorbis, kSampleFormatPlanarF32, | 4214 audio_config_.Initialize(kCodecVorbis, kSampleFormatPlanarF32, |
| 4215 CHANNEL_LAYOUT_STEREO, 4000, EmptyExtraData(), | 4215 CHANNEL_LAYOUT_STEREO, 4000, EmptyExtraData(), |
| 4216 Unencrypted(), base::TimeDelta(), 0); | 4216 Unencrypted(), base::TimeDelta(), 0); |
| 4217 stream_.reset(new SourceBufferStream(audio_config_, media_log_)); | 4217 stream_.reset(new SourceBufferStream(audio_config_, &media_log_)); |
| 4218 // Equivalent to 0.5ms per frame. | 4218 // Equivalent to 0.5ms per frame. |
| 4219 SetStreamInfo(2000, 2000); | 4219 SetStreamInfo(2000, 2000); |
| 4220 Seek(0); | 4220 Seek(0); |
| 4221 | 4221 |
| 4222 // Append four buffers with a 0.5ms duration each. | 4222 // Append four buffers with a 0.5ms duration each. |
| 4223 NewCodedFrameGroupAppend(0, 4); | 4223 NewCodedFrameGroupAppend(0, 4); |
| 4224 CheckExpectedRangesByTimestamp("{ [0,2) }"); | 4224 CheckExpectedRangesByTimestamp("{ [0,2) }"); |
| 4225 | 4225 |
| 4226 // Overlap the range [0, 2) with [1.25, 2); this results in an overlap of | 4226 // Overlap the range [0, 2) with [1.25, 2); this results in an overlap of |
| 4227 // 0.25ms between the original buffer at time 1.0 and the new buffer at time | 4227 // 0.25ms between the original buffer at time 1.0 and the new buffer at time |
| (...skipping 602 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 4830 CheckExpectedRangesByTimestamp("{ [9,16) }"); | 4830 CheckExpectedRangesByTimestamp("{ [9,16) }"); |
| 4831 } | 4831 } |
| 4832 | 4832 |
| 4833 // TODO(vrk): Add unit tests where keyframes are unaligned between streams. | 4833 // TODO(vrk): Add unit tests where keyframes are unaligned between streams. |
| 4834 // (crbug.com/133557) | 4834 // (crbug.com/133557) |
| 4835 | 4835 |
| 4836 // TODO(vrk): Add unit tests with end of stream being called at interesting | 4836 // TODO(vrk): Add unit tests with end of stream being called at interesting |
| 4837 // times. | 4837 // times. |
| 4838 | 4838 |
| 4839 } // namespace media | 4839 } // namespace media |
| OLD | NEW |