Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(132)

Side by Side Diff: media/filters/chunk_demuxer_unittest.cc

Issue 276573002: Add gapless playback support for AAC playback. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Rebase. Comments. Created 6 years, 7 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
OLDNEW
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
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, ' ', &timestamps); 867 base::SplitString(expected, ' ', &timestamps);
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
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
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
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698