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

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. Add config change test. 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
« no previous file with comments | « media/filters/chunk_demuxer.cc ('k') | media/filters/frame_processor.h » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
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();
(...skipping 2147 matching lines...) Expand 10 before | Expand all | Expand 10 after
3028 EXPECT_EQ(ChunkDemuxer::kOk, AddId(kSourceId, HAS_AUDIO | HAS_VIDEO)); 3031 EXPECT_EQ(ChunkDemuxer::kOk, AddId(kSourceId, HAS_AUDIO | HAS_VIDEO));
3029 3032
3030 demuxer_->Remove(kSourceId, base::TimeDelta::FromMilliseconds(0), 3033 demuxer_->Remove(kSourceId, base::TimeDelta::FromMilliseconds(0),
3031 base::TimeDelta::FromMilliseconds(1)); 3034 base::TimeDelta::FromMilliseconds(1));
3032 } 3035 }
3033 3036
3034 TEST_P(ChunkDemuxerTest, AppendWindow_Video) { 3037 TEST_P(ChunkDemuxerTest, AppendWindow_Video) {
3035 ASSERT_TRUE(InitDemuxer(HAS_VIDEO)); 3038 ASSERT_TRUE(InitDemuxer(HAS_VIDEO));
3036 DemuxerStream* stream = demuxer_->GetStream(DemuxerStream::VIDEO); 3039 DemuxerStream* stream = demuxer_->GetStream(DemuxerStream::VIDEO);
3037 3040
3038 // Set the append window to [20,280). 3041 // Set the append window to [50,280).
3039 append_window_start_for_next_append_ = base::TimeDelta::FromMilliseconds(20); 3042 append_window_start_for_next_append_ = base::TimeDelta::FromMilliseconds(50);
3040 append_window_end_for_next_append_ = base::TimeDelta::FromMilliseconds(280); 3043 append_window_end_for_next_append_ = base::TimeDelta::FromMilliseconds(280);
3041 3044
3042 // Append a cluster that starts before and ends after the append window. 3045 // Append a cluster that starts before and ends after the append window.
3043 AppendSingleStreamCluster(kSourceId, kVideoTrackNum, 3046 AppendSingleStreamCluster(kSourceId, kVideoTrackNum,
3044 "0K 30 60 90 120K 150 180 210 240K 270 300 330K"); 3047 "0K 30 60 90 120K 150 180 210 240K 270 300 330K");
3045 3048
3046 // Verify that GOPs that start outside the window are not included 3049 // Verify that GOPs that start outside the window are not included
3047 // in the buffer. Also verify that buffers that start inside the 3050 // in the buffer. Also verify that buffers that start inside the
3048 // window and extend beyond the end of the window are not included. 3051 // window and extend beyond the end of the window are not included.
3049 CheckExpectedRanges(kSourceId, "{ [120,270) }"); 3052 CheckExpectedRanges(kSourceId, "{ [120,270) }");
3050 CheckExpectedBuffers(stream, "120 150 180 210 240"); 3053 CheckExpectedBuffers(stream, "120 150 180 210 240");
3051 3054
3052 // Extend the append window to [20,650). 3055 // Extend the append window to [50,650).
3053 append_window_end_for_next_append_ = base::TimeDelta::FromMilliseconds(650); 3056 append_window_end_for_next_append_ = base::TimeDelta::FromMilliseconds(650);
3054 3057
3055 // Append more data and verify that adding buffers start at the next 3058 // Append more data and verify that adding buffers start at the next
3056 // keyframe. 3059 // keyframe.
3057 AppendSingleStreamCluster(kSourceId, kVideoTrackNum, 3060 AppendSingleStreamCluster(kSourceId, kVideoTrackNum,
3058 "360 390 420K 450 480 510 540K 570 600 630K"); 3061 "360 390 420K 450 480 510 540K 570 600 630K");
3059 CheckExpectedRanges(kSourceId, "{ [120,270) [420,630) }"); 3062 CheckExpectedRanges(kSourceId, "{ [120,270) [420,630) }");
3060 } 3063 }
3061 3064
3062 TEST_P(ChunkDemuxerTest, AppendWindow_Audio) { 3065 TEST_P(ChunkDemuxerTest, AppendWindow_Audio) {
3063 ASSERT_TRUE(InitDemuxer(HAS_AUDIO)); 3066 ASSERT_TRUE(InitDemuxer(HAS_AUDIO));
3064 DemuxerStream* stream = demuxer_->GetStream(DemuxerStream::AUDIO); 3067 DemuxerStream* stream = demuxer_->GetStream(DemuxerStream::AUDIO);
3065 3068
3066 // Set the append window to [20,280). 3069 // Set the append window to [50,280).
3067 append_window_start_for_next_append_ = base::TimeDelta::FromMilliseconds(20); 3070 append_window_start_for_next_append_ = base::TimeDelta::FromMilliseconds(50);
3068 append_window_end_for_next_append_ = base::TimeDelta::FromMilliseconds(280); 3071 append_window_end_for_next_append_ = base::TimeDelta::FromMilliseconds(280);
3069 3072
3070 // Append a cluster that starts before and ends after the append window. 3073 // Append a cluster that starts before and ends after the append window.
3071 AppendSingleStreamCluster( 3074 AppendSingleStreamCluster(
3072 kSourceId, kAudioTrackNum, 3075 kSourceId, kAudioTrackNum,
3073 "0K 30K 60K 90K 120K 150K 180K 210K 240K 270K 300K 330K"); 3076 "0K 30K 60K 90K 120K 150K 180K 210K 240K 270K 300K 330K");
3074 3077
3075 // Verify that frames that end outside the window are not included 3078 // Verify that frames that end outside the window are not included
3076 // in the buffer. Also verify that buffers that start inside the 3079 // in the buffer. Also verify that buffers that start inside the
3077 // window and extend beyond the end of the window are not included. 3080 // window and extend beyond the end of the window are not included.
3078 // 3081 //
3079 // The first 20ms of the first buffer should be trimmed off since it 3082 // The first 50ms of the first buffer should be trimmed off since it
3080 // overlaps the start of the append window. 3083 // overlaps the start of the append window.
3081 CheckExpectedRanges(kSourceId, "{ [20,270) }"); 3084 CheckExpectedRanges(kSourceId, "{ [50,270) }");
3082 CheckExpectedBuffers(stream, "20 30 60 90 120 150 180 210 240");
3083 3085
3084 // Extend the append window to [20,650). 3086 // 50 shows up twice in the expected buffers since the first one should be a
3087 // preroll buffer; this is tested more carefully in SourceBufferStream tests.
3088 //
3089 // The first "50" is the "0" buffer marked for complete discard. The second
3090 // "50" is the "30" buffer marked with 20ms of start discard.
3091 CheckExpectedBuffers(stream, "50 50 60 90 120 150 180 210 240");
acolwell GONE FROM CHROMIUM 2014/05/24 00:58:21 Oh. I thought you'd keep the P suffix so you didn'
DaleCurtis 2014/05/27 23:59:32 Done.
3092
3093 // Extend the append window to [50,650).
3085 append_window_end_for_next_append_ = base::TimeDelta::FromMilliseconds(650); 3094 append_window_end_for_next_append_ = base::TimeDelta::FromMilliseconds(650);
3086 3095
3087 // Append more data and verify that a new range is created. 3096 // Append more data and verify that a new range is created.
3088 AppendSingleStreamCluster( 3097 AppendSingleStreamCluster(
3089 kSourceId, kAudioTrackNum, 3098 kSourceId, kAudioTrackNum,
3090 "360K 390K 420K 450K 480K 510K 540K 570K 600K 630K"); 3099 "360K 390K 420K 450K 480K 510K 540K 570K 600K 630K");
3091 CheckExpectedRanges(kSourceId, "{ [20,270) [360,630) }"); 3100 CheckExpectedRanges(kSourceId, "{ [50,270) [360,630) }");
3092 } 3101 }
3093 3102
3094 TEST_P(ChunkDemuxerTest, AppendWindow_AudioOverlapStartAndEnd) { 3103 TEST_P(ChunkDemuxerTest, AppendWindow_AudioOverlapStartAndEnd) {
3095 ASSERT_TRUE(InitDemuxer(HAS_AUDIO)); 3104 ASSERT_TRUE(InitDemuxer(HAS_AUDIO));
3096 3105
3097 // Set the append window to [10,20). 3106 // Set the append window to [10,20).
3098 append_window_start_for_next_append_ = base::TimeDelta::FromMilliseconds(10); 3107 append_window_start_for_next_append_ = base::TimeDelta::FromMilliseconds(10);
3099 append_window_end_for_next_append_ = base::TimeDelta::FromMilliseconds(20); 3108 append_window_end_for_next_append_ = base::TimeDelta::FromMilliseconds(20);
3100 3109
3101 // Append a cluster that starts before and ends after the append window. 3110 // Append a cluster that starts before and ends after the append window.
3102 AppendSingleStreamCluster(kSourceId, kAudioTrackNum, "0K"); 3111 AppendSingleStreamCluster(kSourceId, kAudioTrackNum, "0K");
3103 3112
3104 // Verify that everything is dropped in this case. No partial append should 3113 // Verify that everything is dropped in this case. No partial append should
3105 // be generated. 3114 // be generated.
3106 CheckExpectedRanges(kSourceId, "{ }"); 3115 CheckExpectedRanges(kSourceId, "{ }");
3107 } 3116 }
3108 3117
3118 TEST_P(ChunkDemuxerTest, AppendWindow_WebMFile_AudioOnly) {
3119 EXPECT_CALL(*this, DemuxerOpened());
3120 demuxer_->Initialize(
3121 &host_,
3122 CreateInitDoneCB(base::TimeDelta::FromMilliseconds(2744), PIPELINE_OK),
3123 true);
3124 ASSERT_EQ(ChunkDemuxer::kOk, AddId(kSourceId, HAS_AUDIO));
3125
3126 // Set the append window to [50,150).
3127 append_window_start_for_next_append_ = base::TimeDelta::FromMilliseconds(50);
3128 append_window_end_for_next_append_ = base::TimeDelta::FromMilliseconds(150);
3129
3130 // Read a WebM file into memory and send the data to the demuxer. The chunk
3131 // size has been chosen carefully to ensure the preroll buffer used by the
3132 // partial append window trim must come from a previous Append() call.
3133 scoped_refptr<DecoderBuffer> buffer =
3134 ReadTestDataFile("bear-320x240-audio-only.webm");
3135 AppendDataInPieces(buffer->data(), buffer->data_size(), 128);
3136
3137 DemuxerStream* stream = demuxer_->GetStream(DemuxerStream::AUDIO);
3138 // 50 shows up twice in the expected buffers since the first one should be a
3139 // preroll buffer; this is tested more carefully in SourceBufferStream tests.
3140 CheckExpectedBuffers(stream, "50 50 62 86 109 122 125 128");
3141 }
3142
3143 TEST_P(ChunkDemuxerTest, AppendWindow_AudioConfigUpdateRemovesPreroll) {
3144 EXPECT_CALL(*this, DemuxerOpened());
3145 demuxer_->Initialize(
3146 &host_,
3147 CreateInitDoneCB(base::TimeDelta::FromMilliseconds(2744), PIPELINE_OK),
3148 true);
3149 ASSERT_EQ(ChunkDemuxer::kOk, AddId(kSourceId, HAS_AUDIO));
3150
3151 // Set the timestamp offset so everything in the first file is before zero.
3152 const base::TimeDelta duration_1 = base::TimeDelta::FromMilliseconds(2746);
3153 ASSERT_TRUE(SetTimestampOffset(kSourceId, -duration_1));
3154
3155 // Set the append window such that the first file is completely before the
3156 // append window.
3157 append_window_start_for_next_append_ = base::TimeDelta();
3158
3159 // Read a WebM file into memory and append the data.
3160 scoped_refptr<DecoderBuffer> buffer =
3161 ReadTestDataFile("bear-320x240-audio-only.webm");
3162 AppendDataInPieces(buffer->data(), buffer->data_size(), 512);
3163 CheckExpectedRanges(kSourceId, "{ }");
3164
3165 DemuxerStream* stream = demuxer_->GetStream(DemuxerStream::AUDIO);
3166 AudioDecoderConfig config_1 = stream->audio_decoder_config();
3167
3168 if (use_legacy_frame_processor_)
3169 ASSERT_TRUE(SetTimestampOffset(kSourceId, base::TimeDelta()));
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(base::TimeDelta::FromMilliseconds(2773)));
3175 AppendDataInPieces(buffer2->data(), buffer2->data_size(), 512);
3176 CheckExpectedRanges(kSourceId, "{ [0,2773) }");
3177
3178 ExpectConfigChanged(DemuxerStream::AUDIO);
3179 ASSERT_FALSE(config_1.Matches(stream->audio_decoder_config()));
3180 CheckExpectedBuffers(stream, "0 21 43 64");
3181 }
3182
3109 TEST_P(ChunkDemuxerTest, AppendWindow_Text) { 3183 TEST_P(ChunkDemuxerTest, AppendWindow_Text) {
3110 DemuxerStream* text_stream = NULL; 3184 DemuxerStream* text_stream = NULL;
3111 EXPECT_CALL(host_, AddTextStream(_, _)) 3185 EXPECT_CALL(host_, AddTextStream(_, _))
3112 .WillOnce(SaveArg<0>(&text_stream)); 3186 .WillOnce(SaveArg<0>(&text_stream));
3113 ASSERT_TRUE(InitDemuxer(HAS_VIDEO | HAS_TEXT)); 3187 ASSERT_TRUE(InitDemuxer(HAS_VIDEO | HAS_TEXT));
3114 DemuxerStream* video_stream = demuxer_->GetStream(DemuxerStream::VIDEO); 3188 DemuxerStream* video_stream = demuxer_->GetStream(DemuxerStream::VIDEO);
3115 3189
3116 // Set the append window to [20,280). 3190 // Set the append window to [20,280).
3117 append_window_start_for_next_append_ = base::TimeDelta::FromMilliseconds(20); 3191 append_window_start_for_next_append_ = base::TimeDelta::FromMilliseconds(20);
3118 append_window_end_for_next_append_ = base::TimeDelta::FromMilliseconds(280); 3192 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"); 3324 CheckExpectedBuffers(audio_stream, "160 180");
3251 CheckExpectedBuffers(video_stream, "180 210"); 3325 CheckExpectedBuffers(video_stream, "180 210");
3252 } 3326 }
3253 3327
3254 // Generate two sets of tests: one using FrameProcessor, and one using 3328 // Generate two sets of tests: one using FrameProcessor, and one using
3255 // LegacyFrameProcessor. 3329 // LegacyFrameProcessor.
3256 INSTANTIATE_TEST_CASE_P(NewFrameProcessor, ChunkDemuxerTest, Values(false)); 3330 INSTANTIATE_TEST_CASE_P(NewFrameProcessor, ChunkDemuxerTest, Values(false));
3257 INSTANTIATE_TEST_CASE_P(LegacyFrameProcessor, ChunkDemuxerTest, Values(true)); 3331 INSTANTIATE_TEST_CASE_P(LegacyFrameProcessor, ChunkDemuxerTest, Values(true));
3258 3332
3259 } // namespace media 3333 } // namespace media
OLDNEW
« no previous file with comments | « media/filters/chunk_demuxer.cc ('k') | media/filters/frame_processor.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698