Chromium Code Reviews| 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 |