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 <algorithm> | 5 #include <algorithm> |
6 | 6 |
7 #include "base/bind.h" | 7 #include "base/bind.h" |
8 #include "base/message_loop/message_loop.h" | 8 #include "base/message_loop/message_loop.h" |
9 #include "base/strings/string_number_conversions.h" | 9 #include "base/strings/string_number_conversions.h" |
10 #include "base/strings/string_split.h" | 10 #include "base/strings/string_split.h" |
(...skipping 849 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
860 &ChunkDemuxerTest::ReadDone, base::Unretained(this))); | 860 &ChunkDemuxerTest::ReadDone, base::Unretained(this))); |
861 message_loop_.RunUntilIdle(); | 861 message_loop_.RunUntilIdle(); |
862 } | 862 } |
863 | 863 |
864 void CheckExpectedBuffers(DemuxerStream* stream, | 864 void CheckExpectedBuffers(DemuxerStream* stream, |
865 const std::string& expected) { | 865 const std::string& expected) { |
866 std::vector<std::string> timestamps; | 866 std::vector<std::string> timestamps; |
867 base::SplitString(expected, ' ', ×tamps); | 867 base::SplitString(expected, ' ', ×tamps); |
868 std::stringstream ss; | 868 std::stringstream ss; |
869 for (size_t i = 0; i < timestamps.size(); ++i) { | 869 for (size_t i = 0; i < timestamps.size(); ++i) { |
870 DemuxerStream::Status status; | 870 // Initialize status to kAborted since it's possible for Read() to return |
| 871 // without calling StoreStatusAndBuffer() if it doesn't have any buffers |
| 872 // left to return. |
| 873 DemuxerStream::Status status = DemuxerStream::kAborted; |
871 scoped_refptr<DecoderBuffer> buffer; | 874 scoped_refptr<DecoderBuffer> buffer; |
872 stream->Read(base::Bind(&ChunkDemuxerTest::StoreStatusAndBuffer, | 875 stream->Read(base::Bind(&ChunkDemuxerTest::StoreStatusAndBuffer, |
873 base::Unretained(this), &status, &buffer)); | 876 base::Unretained(this), &status, &buffer)); |
874 base::MessageLoop::current()->RunUntilIdle(); | 877 base::MessageLoop::current()->RunUntilIdle(); |
875 if (status != DemuxerStream::kOk || buffer->end_of_stream()) | 878 if (status != DemuxerStream::kOk || buffer->end_of_stream()) |
876 break; | 879 break; |
877 | 880 |
878 if (i > 0) | 881 if (i > 0) |
879 ss << " "; | 882 ss << " "; |
880 ss << buffer->timestamp().InMilliseconds(); | 883 ss << buffer->timestamp().InMilliseconds(); |
| 884 |
| 885 // Handle preroll buffers. |
| 886 if (EndsWith(timestamps[i], "P", true)) { |
| 887 ASSERT_EQ(kInfiniteDuration(), buffer->discard_padding().first); |
| 888 ASSERT_EQ(base::TimeDelta(), buffer->discard_padding().second); |
| 889 ss << "P"; |
| 890 } |
881 } | 891 } |
882 EXPECT_EQ(expected, ss.str()); | 892 EXPECT_EQ(expected, ss.str()); |
883 } | 893 } |
884 | 894 |
885 MOCK_METHOD1(Checkpoint, void(int id)); | 895 MOCK_METHOD1(Checkpoint, void(int id)); |
886 | 896 |
887 struct BufferTimestamps { | 897 struct BufferTimestamps { |
888 int video_time_ms; | 898 int video_time_ms; |
889 int audio_time_ms; | 899 int audio_time_ms; |
890 }; | 900 }; |
(...skipping 2137 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3028 EXPECT_EQ(ChunkDemuxer::kOk, AddId(kSourceId, HAS_AUDIO | HAS_VIDEO)); | 3038 EXPECT_EQ(ChunkDemuxer::kOk, AddId(kSourceId, HAS_AUDIO | HAS_VIDEO)); |
3029 | 3039 |
3030 demuxer_->Remove(kSourceId, base::TimeDelta::FromMilliseconds(0), | 3040 demuxer_->Remove(kSourceId, base::TimeDelta::FromMilliseconds(0), |
3031 base::TimeDelta::FromMilliseconds(1)); | 3041 base::TimeDelta::FromMilliseconds(1)); |
3032 } | 3042 } |
3033 | 3043 |
3034 TEST_P(ChunkDemuxerTest, AppendWindow_Video) { | 3044 TEST_P(ChunkDemuxerTest, AppendWindow_Video) { |
3035 ASSERT_TRUE(InitDemuxer(HAS_VIDEO)); | 3045 ASSERT_TRUE(InitDemuxer(HAS_VIDEO)); |
3036 DemuxerStream* stream = demuxer_->GetStream(DemuxerStream::VIDEO); | 3046 DemuxerStream* stream = demuxer_->GetStream(DemuxerStream::VIDEO); |
3037 | 3047 |
3038 // Set the append window to [20,280). | 3048 // Set the append window to [50,280). |
3039 append_window_start_for_next_append_ = base::TimeDelta::FromMilliseconds(20); | 3049 append_window_start_for_next_append_ = base::TimeDelta::FromMilliseconds(50); |
3040 append_window_end_for_next_append_ = base::TimeDelta::FromMilliseconds(280); | 3050 append_window_end_for_next_append_ = base::TimeDelta::FromMilliseconds(280); |
3041 | 3051 |
3042 // Append a cluster that starts before and ends after the append window. | 3052 // Append a cluster that starts before and ends after the append window. |
3043 AppendSingleStreamCluster(kSourceId, kVideoTrackNum, | 3053 AppendSingleStreamCluster(kSourceId, kVideoTrackNum, |
3044 "0K 30 60 90 120K 150 180 210 240K 270 300 330K"); | 3054 "0K 30 60 90 120K 150 180 210 240K 270 300 330K"); |
3045 | 3055 |
3046 // Verify that GOPs that start outside the window are not included | 3056 // Verify that GOPs that start outside the window are not included |
3047 // in the buffer. Also verify that buffers that start inside the | 3057 // in the buffer. Also verify that buffers that start inside the |
3048 // window and extend beyond the end of the window are not included. | 3058 // window and extend beyond the end of the window are not included. |
3049 CheckExpectedRanges(kSourceId, "{ [120,270) }"); | 3059 CheckExpectedRanges(kSourceId, "{ [120,270) }"); |
3050 CheckExpectedBuffers(stream, "120 150 180 210 240"); | 3060 CheckExpectedBuffers(stream, "120 150 180 210 240"); |
3051 | 3061 |
3052 // Extend the append window to [20,650). | 3062 // Extend the append window to [50,650). |
3053 append_window_end_for_next_append_ = base::TimeDelta::FromMilliseconds(650); | 3063 append_window_end_for_next_append_ = base::TimeDelta::FromMilliseconds(650); |
3054 | 3064 |
3055 // Append more data and verify that adding buffers start at the next | 3065 // Append more data and verify that adding buffers start at the next |
3056 // keyframe. | 3066 // keyframe. |
3057 AppendSingleStreamCluster(kSourceId, kVideoTrackNum, | 3067 AppendSingleStreamCluster(kSourceId, kVideoTrackNum, |
3058 "360 390 420K 450 480 510 540K 570 600 630K"); | 3068 "360 390 420K 450 480 510 540K 570 600 630K"); |
3059 CheckExpectedRanges(kSourceId, "{ [120,270) [420,630) }"); | 3069 CheckExpectedRanges(kSourceId, "{ [120,270) [420,630) }"); |
3060 } | 3070 } |
3061 | 3071 |
3062 TEST_P(ChunkDemuxerTest, AppendWindow_Audio) { | 3072 TEST_P(ChunkDemuxerTest, AppendWindow_Audio) { |
3063 ASSERT_TRUE(InitDemuxer(HAS_AUDIO)); | 3073 ASSERT_TRUE(InitDemuxer(HAS_AUDIO)); |
3064 DemuxerStream* stream = demuxer_->GetStream(DemuxerStream::AUDIO); | 3074 DemuxerStream* stream = demuxer_->GetStream(DemuxerStream::AUDIO); |
3065 | 3075 |
3066 // Set the append window to [20,280). | 3076 // Set the append window to [50,280). |
3067 append_window_start_for_next_append_ = base::TimeDelta::FromMilliseconds(20); | 3077 append_window_start_for_next_append_ = base::TimeDelta::FromMilliseconds(50); |
3068 append_window_end_for_next_append_ = base::TimeDelta::FromMilliseconds(280); | 3078 append_window_end_for_next_append_ = base::TimeDelta::FromMilliseconds(280); |
3069 | 3079 |
3070 // Append a cluster that starts before and ends after the append window. | 3080 // Append a cluster that starts before and ends after the append window. |
3071 AppendSingleStreamCluster( | 3081 AppendSingleStreamCluster( |
3072 kSourceId, kAudioTrackNum, | 3082 kSourceId, kAudioTrackNum, |
3073 "0K 30K 60K 90K 120K 150K 180K 210K 240K 270K 300K 330K"); | 3083 "0K 30K 60K 90K 120K 150K 180K 210K 240K 270K 300K 330K"); |
3074 | 3084 |
3075 // Verify that frames that end outside the window are not included | 3085 // Verify that frames that end outside the window are not included |
3076 // in the buffer. Also verify that buffers that start inside the | 3086 // in the buffer. Also verify that buffers that start inside the |
3077 // window and extend beyond the end of the window are not included. | 3087 // window and extend beyond the end of the window are not included. |
3078 // | 3088 // |
3079 // The first 20ms of the first buffer should be trimmed off since it | 3089 // The first 50ms of the range should be truncated since it overlaps |
3080 // overlaps the start of the append window. | 3090 // the start of the append window. |
3081 CheckExpectedRanges(kSourceId, "{ [20,270) }"); | 3091 CheckExpectedRanges(kSourceId, "{ [50,270) }"); |
3082 CheckExpectedBuffers(stream, "20 30 60 90 120 150 180 210 240"); | |
3083 | 3092 |
3084 // Extend the append window to [20,650). | 3093 // The "50P" buffer is the "0" buffer marked for complete discard. The next |
| 3094 // "50" buffer is the "30" buffer marked with 20ms of start discard. |
| 3095 CheckExpectedBuffers(stream, "50P 50 60 90 120 150 180 210 240"); |
| 3096 |
| 3097 // Extend the append window to [50,650). |
3085 append_window_end_for_next_append_ = base::TimeDelta::FromMilliseconds(650); | 3098 append_window_end_for_next_append_ = base::TimeDelta::FromMilliseconds(650); |
3086 | 3099 |
3087 // Append more data and verify that a new range is created. | 3100 // Append more data and verify that a new range is created. |
3088 AppendSingleStreamCluster( | 3101 AppendSingleStreamCluster( |
3089 kSourceId, kAudioTrackNum, | 3102 kSourceId, kAudioTrackNum, |
3090 "360K 390K 420K 450K 480K 510K 540K 570K 600K 630K"); | 3103 "360K 390K 420K 450K 480K 510K 540K 570K 600K 630K"); |
3091 CheckExpectedRanges(kSourceId, "{ [20,270) [360,630) }"); | 3104 CheckExpectedRanges(kSourceId, "{ [50,270) [360,630) }"); |
3092 } | 3105 } |
3093 | 3106 |
3094 TEST_P(ChunkDemuxerTest, AppendWindow_AudioOverlapStartAndEnd) { | 3107 TEST_P(ChunkDemuxerTest, AppendWindow_AudioOverlapStartAndEnd) { |
3095 ASSERT_TRUE(InitDemuxer(HAS_AUDIO)); | 3108 ASSERT_TRUE(InitDemuxer(HAS_AUDIO)); |
3096 | 3109 |
3097 // Set the append window to [10,20). | 3110 // Set the append window to [10,20). |
3098 append_window_start_for_next_append_ = base::TimeDelta::FromMilliseconds(10); | 3111 append_window_start_for_next_append_ = base::TimeDelta::FromMilliseconds(10); |
3099 append_window_end_for_next_append_ = base::TimeDelta::FromMilliseconds(20); | 3112 append_window_end_for_next_append_ = base::TimeDelta::FromMilliseconds(20); |
3100 | 3113 |
3101 // Append a cluster that starts before and ends after the append window. | 3114 // Append a cluster that starts before and ends after the append window. |
3102 AppendSingleStreamCluster(kSourceId, kAudioTrackNum, "0K"); | 3115 AppendSingleStreamCluster(kSourceId, kAudioTrackNum, "0K"); |
3103 | 3116 |
3104 // Verify that everything is dropped in this case. No partial append should | 3117 // Verify that everything is dropped in this case. No partial append should |
3105 // be generated. | 3118 // be generated. |
3106 CheckExpectedRanges(kSourceId, "{ }"); | 3119 CheckExpectedRanges(kSourceId, "{ }"); |
3107 } | 3120 } |
3108 | 3121 |
| 3122 TEST_P(ChunkDemuxerTest, AppendWindow_WebMFile_AudioOnly) { |
| 3123 EXPECT_CALL(*this, DemuxerOpened()); |
| 3124 demuxer_->Initialize( |
| 3125 &host_, |
| 3126 CreateInitDoneCB(base::TimeDelta::FromMilliseconds(2744), PIPELINE_OK), |
| 3127 true); |
| 3128 ASSERT_EQ(ChunkDemuxer::kOk, AddId(kSourceId, HAS_AUDIO)); |
| 3129 |
| 3130 // Set the append window to [50,150). |
| 3131 append_window_start_for_next_append_ = base::TimeDelta::FromMilliseconds(50); |
| 3132 append_window_end_for_next_append_ = base::TimeDelta::FromMilliseconds(150); |
| 3133 |
| 3134 // Read a WebM file into memory and send the data to the demuxer. The chunk |
| 3135 // size has been chosen carefully to ensure the preroll buffer used by the |
| 3136 // partial append window trim must come from a previous Append() call. |
| 3137 scoped_refptr<DecoderBuffer> buffer = |
| 3138 ReadTestDataFile("bear-320x240-audio-only.webm"); |
| 3139 AppendDataInPieces(buffer->data(), buffer->data_size(), 128); |
| 3140 |
| 3141 DemuxerStream* stream = demuxer_->GetStream(DemuxerStream::AUDIO); |
| 3142 CheckExpectedBuffers(stream, "50P 50 62 86 109 122 125 128"); |
| 3143 } |
| 3144 |
| 3145 TEST_P(ChunkDemuxerTest, AppendWindow_AudioConfigUpdateRemovesPreroll) { |
| 3146 EXPECT_CALL(*this, DemuxerOpened()); |
| 3147 demuxer_->Initialize( |
| 3148 &host_, |
| 3149 CreateInitDoneCB(base::TimeDelta::FromMilliseconds(2744), PIPELINE_OK), |
| 3150 true); |
| 3151 ASSERT_EQ(ChunkDemuxer::kOk, AddId(kSourceId, HAS_AUDIO)); |
| 3152 |
| 3153 // Set the append window such that the first file is completely before the |
| 3154 // append window. |
| 3155 // TODO(wolenetz/acolwell): Update this duration once the files are fixed to |
| 3156 // have the correct duration in their init segments, and the |
| 3157 // CreateInitDoneCB() call, above, is fixed to used that duration. See |
| 3158 // http://crbug.com/354284. |
| 3159 const base::TimeDelta duration_1 = base::TimeDelta::FromMilliseconds(2746); |
| 3160 append_window_start_for_next_append_ = duration_1; |
| 3161 |
| 3162 // Read a WebM file into memory and append the data. |
| 3163 scoped_refptr<DecoderBuffer> buffer = |
| 3164 ReadTestDataFile("bear-320x240-audio-only.webm"); |
| 3165 AppendDataInPieces(buffer->data(), buffer->data_size(), 512); |
| 3166 CheckExpectedRanges(kSourceId, "{ }"); |
| 3167 |
| 3168 DemuxerStream* stream = demuxer_->GetStream(DemuxerStream::AUDIO); |
| 3169 AudioDecoderConfig config_1 = stream->audio_decoder_config(); |
| 3170 |
| 3171 // Read a second WebM with a different config in and append the data. |
| 3172 scoped_refptr<DecoderBuffer> buffer2 = |
| 3173 ReadTestDataFile("bear-320x240-audio-only-48khz.webm"); |
| 3174 EXPECT_CALL(host_, SetDuration(_)).Times(AnyNumber()); |
| 3175 ASSERT_TRUE(SetTimestampOffset(kSourceId, duration_1)); |
| 3176 AppendDataInPieces(buffer2->data(), buffer2->data_size(), 512); |
| 3177 CheckExpectedRanges(kSourceId, "{ [2746,5519) }"); |
| 3178 |
| 3179 Seek(duration_1); |
| 3180 ExpectConfigChanged(DemuxerStream::AUDIO); |
| 3181 ASSERT_FALSE(config_1.Matches(stream->audio_decoder_config())); |
| 3182 CheckExpectedBuffers(stream, "2746 2767 2789 2810"); |
| 3183 } |
| 3184 |
3109 TEST_P(ChunkDemuxerTest, AppendWindow_Text) { | 3185 TEST_P(ChunkDemuxerTest, AppendWindow_Text) { |
3110 DemuxerStream* text_stream = NULL; | 3186 DemuxerStream* text_stream = NULL; |
3111 EXPECT_CALL(host_, AddTextStream(_, _)) | 3187 EXPECT_CALL(host_, AddTextStream(_, _)) |
3112 .WillOnce(SaveArg<0>(&text_stream)); | 3188 .WillOnce(SaveArg<0>(&text_stream)); |
3113 ASSERT_TRUE(InitDemuxer(HAS_VIDEO | HAS_TEXT)); | 3189 ASSERT_TRUE(InitDemuxer(HAS_VIDEO | HAS_TEXT)); |
3114 DemuxerStream* video_stream = demuxer_->GetStream(DemuxerStream::VIDEO); | 3190 DemuxerStream* video_stream = demuxer_->GetStream(DemuxerStream::VIDEO); |
3115 | 3191 |
3116 // Set the append window to [20,280). | 3192 // Set the append window to [20,280). |
3117 append_window_start_for_next_append_ = base::TimeDelta::FromMilliseconds(20); | 3193 append_window_start_for_next_append_ = base::TimeDelta::FromMilliseconds(20); |
3118 append_window_end_for_next_append_ = base::TimeDelta::FromMilliseconds(280); | 3194 append_window_end_for_next_append_ = base::TimeDelta::FromMilliseconds(280); |
(...skipping 131 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3250 CheckExpectedBuffers(audio_stream, "160 180"); | 3326 CheckExpectedBuffers(audio_stream, "160 180"); |
3251 CheckExpectedBuffers(video_stream, "180 210"); | 3327 CheckExpectedBuffers(video_stream, "180 210"); |
3252 } | 3328 } |
3253 | 3329 |
3254 // Generate two sets of tests: one using FrameProcessor, and one using | 3330 // Generate two sets of tests: one using FrameProcessor, and one using |
3255 // LegacyFrameProcessor. | 3331 // LegacyFrameProcessor. |
3256 INSTANTIATE_TEST_CASE_P(NewFrameProcessor, ChunkDemuxerTest, Values(false)); | 3332 INSTANTIATE_TEST_CASE_P(NewFrameProcessor, ChunkDemuxerTest, Values(false)); |
3257 INSTANTIATE_TEST_CASE_P(LegacyFrameProcessor, ChunkDemuxerTest, Values(true)); | 3333 INSTANTIATE_TEST_CASE_P(LegacyFrameProcessor, ChunkDemuxerTest, Values(true)); |
3258 | 3334 |
3259 } // namespace media | 3335 } // namespace media |
OLD | NEW |