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

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: Fix msvc error. Created 6 years, 6 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();
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 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
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
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