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 first buffer should be trimmed off since it |
wolenetz
2014/05/30 19:58:45
nit: This comment seems confusing to me. The test
DaleCurtis
2014/05/30 20:54:30
acolwell@ suggested my previous comment to that ef
| |
3080 // overlaps the start of the append window. | 3090 // overlaps 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"); | 3092 CheckExpectedBuffers(stream, "50P 50 60 90 120 150 180 210 240"); |
3083 | 3093 |
3084 // Extend the append window to [20,650). | 3094 // Extend the append window to [50,650). |
3085 append_window_end_for_next_append_ = base::TimeDelta::FromMilliseconds(650); | 3095 append_window_end_for_next_append_ = base::TimeDelta::FromMilliseconds(650); |
3086 | 3096 |
3087 // Append more data and verify that a new range is created. | 3097 // Append more data and verify that a new range is created. |
3088 AppendSingleStreamCluster( | 3098 AppendSingleStreamCluster( |
3089 kSourceId, kAudioTrackNum, | 3099 kSourceId, kAudioTrackNum, |
3090 "360K 390K 420K 450K 480K 510K 540K 570K 600K 630K"); | 3100 "360K 390K 420K 450K 480K 510K 540K 570K 600K 630K"); |
3091 CheckExpectedRanges(kSourceId, "{ [20,270) [360,630) }"); | 3101 CheckExpectedRanges(kSourceId, "{ [50,270) [360,630) }"); |
3092 } | 3102 } |
3093 | 3103 |
3094 TEST_P(ChunkDemuxerTest, AppendWindow_AudioOverlapStartAndEnd) { | 3104 TEST_P(ChunkDemuxerTest, AppendWindow_AudioOverlapStartAndEnd) { |
3095 ASSERT_TRUE(InitDemuxer(HAS_AUDIO)); | 3105 ASSERT_TRUE(InitDemuxer(HAS_AUDIO)); |
3096 | 3106 |
3097 // Set the append window to [10,20). | 3107 // Set the append window to [10,20). |
3098 append_window_start_for_next_append_ = base::TimeDelta::FromMilliseconds(10); | 3108 append_window_start_for_next_append_ = base::TimeDelta::FromMilliseconds(10); |
3099 append_window_end_for_next_append_ = base::TimeDelta::FromMilliseconds(20); | 3109 append_window_end_for_next_append_ = base::TimeDelta::FromMilliseconds(20); |
3100 | 3110 |
3101 // Append a cluster that starts before and ends after the append window. | 3111 // Append a cluster that starts before and ends after the append window. |
3102 AppendSingleStreamCluster(kSourceId, kAudioTrackNum, "0K"); | 3112 AppendSingleStreamCluster(kSourceId, kAudioTrackNum, "0K"); |
3103 | 3113 |
3104 // Verify that everything is dropped in this case. No partial append should | 3114 // Verify that everything is dropped in this case. No partial append should |
3105 // be generated. | 3115 // be generated. |
3106 CheckExpectedRanges(kSourceId, "{ }"); | 3116 CheckExpectedRanges(kSourceId, "{ }"); |
3107 } | 3117 } |
3108 | 3118 |
3119 TEST_P(ChunkDemuxerTest, AppendWindow_WebMFile_AudioOnly) { | |
3120 EXPECT_CALL(*this, DemuxerOpened()); | |
3121 demuxer_->Initialize( | |
3122 &host_, | |
3123 CreateInitDoneCB(base::TimeDelta::FromMilliseconds(2744), PIPELINE_OK), | |
3124 true); | |
3125 ASSERT_EQ(ChunkDemuxer::kOk, AddId(kSourceId, HAS_AUDIO)); | |
3126 | |
3127 // Set the append window to [50,150). | |
3128 append_window_start_for_next_append_ = base::TimeDelta::FromMilliseconds(50); | |
3129 append_window_end_for_next_append_ = base::TimeDelta::FromMilliseconds(150); | |
3130 | |
3131 // Read a WebM file into memory and send the data to the demuxer. The chunk | |
3132 // size has been chosen carefully to ensure the preroll buffer used by the | |
3133 // partial append window trim must come from a previous Append() call. | |
3134 scoped_refptr<DecoderBuffer> buffer = | |
3135 ReadTestDataFile("bear-320x240-audio-only.webm"); | |
3136 AppendDataInPieces(buffer->data(), buffer->data_size(), 128); | |
3137 | |
3138 DemuxerStream* stream = demuxer_->GetStream(DemuxerStream::AUDIO); | |
3139 CheckExpectedBuffers(stream, "50P 50 62 86 109 122 125 128"); | |
3140 } | |
3141 | |
3142 TEST_P(ChunkDemuxerTest, AppendWindow_AudioConfigUpdateRemovesPreroll) { | |
3143 EXPECT_CALL(*this, DemuxerOpened()); | |
3144 demuxer_->Initialize( | |
3145 &host_, | |
3146 CreateInitDoneCB(base::TimeDelta::FromMilliseconds(2744), PIPELINE_OK), | |
3147 true); | |
3148 ASSERT_EQ(ChunkDemuxer::kOk, AddId(kSourceId, HAS_AUDIO)); | |
3149 | |
3150 // Set the append window such that the first file is completely before the | |
3151 // append window. | |
3152 const base::TimeDelta duration_1 = base::TimeDelta::FromMilliseconds(2746); | |
wolenetz
2014/05/30 19:58:45
nit: Please add similar TODO(wolenetz): Update thi
DaleCurtis
2014/05/30 20:54:30
Done.
| |
3153 append_window_start_for_next_append_ = duration_1; | |
3154 | |
3155 // Read a WebM file into memory and append the data. | |
3156 scoped_refptr<DecoderBuffer> buffer = | |
3157 ReadTestDataFile("bear-320x240-audio-only.webm"); | |
3158 AppendDataInPieces(buffer->data(), buffer->data_size(), 512); | |
3159 CheckExpectedRanges(kSourceId, "{ }"); | |
3160 | |
3161 DemuxerStream* stream = demuxer_->GetStream(DemuxerStream::AUDIO); | |
3162 AudioDecoderConfig config_1 = stream->audio_decoder_config(); | |
3163 | |
3164 // Read a second WebM with a different config in and append the data. | |
3165 scoped_refptr<DecoderBuffer> buffer2 = | |
3166 ReadTestDataFile("bear-320x240-audio-only-48khz.webm"); | |
3167 EXPECT_CALL(host_, SetDuration(_)).Times(AnyNumber()); | |
3168 ASSERT_TRUE(SetTimestampOffset(kSourceId, duration_1)); | |
3169 AppendDataInPieces(buffer2->data(), buffer2->data_size(), 512); | |
3170 CheckExpectedRanges(kSourceId, "{ [2746,5519) }"); | |
3171 | |
3172 Seek(duration_1); | |
3173 ExpectConfigChanged(DemuxerStream::AUDIO); | |
3174 ASSERT_FALSE(config_1.Matches(stream->audio_decoder_config())); | |
3175 CheckExpectedBuffers(stream, "2746 2767 2789 2810"); | |
3176 } | |
3177 | |
3109 TEST_P(ChunkDemuxerTest, AppendWindow_Text) { | 3178 TEST_P(ChunkDemuxerTest, AppendWindow_Text) { |
3110 DemuxerStream* text_stream = NULL; | 3179 DemuxerStream* text_stream = NULL; |
3111 EXPECT_CALL(host_, AddTextStream(_, _)) | 3180 EXPECT_CALL(host_, AddTextStream(_, _)) |
3112 .WillOnce(SaveArg<0>(&text_stream)); | 3181 .WillOnce(SaveArg<0>(&text_stream)); |
3113 ASSERT_TRUE(InitDemuxer(HAS_VIDEO | HAS_TEXT)); | 3182 ASSERT_TRUE(InitDemuxer(HAS_VIDEO | HAS_TEXT)); |
3114 DemuxerStream* video_stream = demuxer_->GetStream(DemuxerStream::VIDEO); | 3183 DemuxerStream* video_stream = demuxer_->GetStream(DemuxerStream::VIDEO); |
3115 | 3184 |
3116 // Set the append window to [20,280). | 3185 // Set the append window to [20,280). |
3117 append_window_start_for_next_append_ = base::TimeDelta::FromMilliseconds(20); | 3186 append_window_start_for_next_append_ = base::TimeDelta::FromMilliseconds(20); |
3118 append_window_end_for_next_append_ = base::TimeDelta::FromMilliseconds(280); | 3187 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"); | 3319 CheckExpectedBuffers(audio_stream, "160 180"); |
3251 CheckExpectedBuffers(video_stream, "180 210"); | 3320 CheckExpectedBuffers(video_stream, "180 210"); |
3252 } | 3321 } |
3253 | 3322 |
3254 // Generate two sets of tests: one using FrameProcessor, and one using | 3323 // Generate two sets of tests: one using FrameProcessor, and one using |
3255 // LegacyFrameProcessor. | 3324 // LegacyFrameProcessor. |
3256 INSTANTIATE_TEST_CASE_P(NewFrameProcessor, ChunkDemuxerTest, Values(false)); | 3325 INSTANTIATE_TEST_CASE_P(NewFrameProcessor, ChunkDemuxerTest, Values(false)); |
3257 INSTANTIATE_TEST_CASE_P(LegacyFrameProcessor, ChunkDemuxerTest, Values(true)); | 3326 INSTANTIATE_TEST_CASE_P(LegacyFrameProcessor, ChunkDemuxerTest, Values(true)); |
3258 | 3327 |
3259 } // namespace media | 3328 } // namespace media |
OLD | NEW |