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

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 scoped_refptr<DecoderBuffer> preroll_buffer;
888 preroll_buffer.swap(buffer);
889
890 // When a preroll buffer is encountered we should be able to request one
891 // more buffer. The first buffer should have a timestamp equal to the
892 // second buffer and its discard_padding() should be its duration.
893 stream->Read(base::Bind(&ChunkDemuxerTest::StoreStatusAndBuffer,
894 base::Unretained(this), &status, &buffer));
895 base::MessageLoop::current()->RunUntilIdle();
896 ASSERT_EQ(buffer->timestamp(), preroll_buffer->timestamp());
acolwell GONE FROM CHROMIUM 2014/05/23 17:27:30 nit: remove? The expectations string should be abl
DaleCurtis 2014/05/23 21:46:26 Done.
897 ASSERT_EQ(kInfiniteDuration(), preroll_buffer->discard_padding().first);
898 ASSERT_EQ(base::TimeDelta(), preroll_buffer->discard_padding().second);
899 ss << "P";
900 }
881 } 901 }
882 EXPECT_EQ(expected, ss.str()); 902 EXPECT_EQ(expected, ss.str());
883 } 903 }
884 904
885 MOCK_METHOD1(Checkpoint, void(int id)); 905 MOCK_METHOD1(Checkpoint, void(int id));
886 906
887 struct BufferTimestamps { 907 struct BufferTimestamps {
888 int video_time_ms; 908 int video_time_ms;
889 int audio_time_ms; 909 int audio_time_ms;
890 }; 910 };
(...skipping 2137 matching lines...) Expand 10 before | Expand all | Expand 10 after
3028 EXPECT_EQ(ChunkDemuxer::kOk, AddId(kSourceId, HAS_AUDIO | HAS_VIDEO)); 3048 EXPECT_EQ(ChunkDemuxer::kOk, AddId(kSourceId, HAS_AUDIO | HAS_VIDEO));
3029 3049
3030 demuxer_->Remove(kSourceId, base::TimeDelta::FromMilliseconds(0), 3050 demuxer_->Remove(kSourceId, base::TimeDelta::FromMilliseconds(0),
3031 base::TimeDelta::FromMilliseconds(1)); 3051 base::TimeDelta::FromMilliseconds(1));
3032 } 3052 }
3033 3053
3034 TEST_P(ChunkDemuxerTest, AppendWindow_Video) { 3054 TEST_P(ChunkDemuxerTest, AppendWindow_Video) {
3035 ASSERT_TRUE(InitDemuxer(HAS_VIDEO)); 3055 ASSERT_TRUE(InitDemuxer(HAS_VIDEO));
3036 DemuxerStream* stream = demuxer_->GetStream(DemuxerStream::VIDEO); 3056 DemuxerStream* stream = demuxer_->GetStream(DemuxerStream::VIDEO);
3037 3057
3038 // Set the append window to [20,280). 3058 // Set the append window to [50,280).
3039 append_window_start_for_next_append_ = base::TimeDelta::FromMilliseconds(20); 3059 append_window_start_for_next_append_ = base::TimeDelta::FromMilliseconds(50);
3040 append_window_end_for_next_append_ = base::TimeDelta::FromMilliseconds(280); 3060 append_window_end_for_next_append_ = base::TimeDelta::FromMilliseconds(280);
3041 3061
3042 // Append a cluster that starts before and ends after the append window. 3062 // Append a cluster that starts before and ends after the append window.
3043 AppendSingleStreamCluster(kSourceId, kVideoTrackNum, 3063 AppendSingleStreamCluster(kSourceId, kVideoTrackNum,
3044 "0K 30 60 90 120K 150 180 210 240K 270 300 330K"); 3064 "0K 30 60 90 120K 150 180 210 240K 270 300 330K");
3045 3065
3046 // Verify that GOPs that start outside the window are not included 3066 // Verify that GOPs that start outside the window are not included
3047 // in the buffer. Also verify that buffers that start inside the 3067 // in the buffer. Also verify that buffers that start inside the
3048 // window and extend beyond the end of the window are not included. 3068 // window and extend beyond the end of the window are not included.
3049 CheckExpectedRanges(kSourceId, "{ [120,270) }"); 3069 CheckExpectedRanges(kSourceId, "{ [120,270) }");
3050 CheckExpectedBuffers(stream, "120 150 180 210 240"); 3070 CheckExpectedBuffers(stream, "120 150 180 210 240");
3051 3071
3052 // Extend the append window to [20,650). 3072 // Extend the append window to [50,650).
3053 append_window_end_for_next_append_ = base::TimeDelta::FromMilliseconds(650); 3073 append_window_end_for_next_append_ = base::TimeDelta::FromMilliseconds(650);
3054 3074
3055 // Append more data and verify that adding buffers start at the next 3075 // Append more data and verify that adding buffers start at the next
3056 // keyframe. 3076 // keyframe.
3057 AppendSingleStreamCluster(kSourceId, kVideoTrackNum, 3077 AppendSingleStreamCluster(kSourceId, kVideoTrackNum,
3058 "360 390 420K 450 480 510 540K 570 600 630K"); 3078 "360 390 420K 450 480 510 540K 570 600 630K");
3059 CheckExpectedRanges(kSourceId, "{ [120,270) [420,630) }"); 3079 CheckExpectedRanges(kSourceId, "{ [120,270) [420,630) }");
3060 } 3080 }
3061 3081
3062 TEST_P(ChunkDemuxerTest, AppendWindow_Audio) { 3082 TEST_P(ChunkDemuxerTest, AppendWindow_Audio) {
3063 ASSERT_TRUE(InitDemuxer(HAS_AUDIO)); 3083 ASSERT_TRUE(InitDemuxer(HAS_AUDIO));
3064 DemuxerStream* stream = demuxer_->GetStream(DemuxerStream::AUDIO); 3084 DemuxerStream* stream = demuxer_->GetStream(DemuxerStream::AUDIO);
3065 3085
3066 // Set the append window to [20,280). 3086 // Set the append window to [50,280).
3067 append_window_start_for_next_append_ = base::TimeDelta::FromMilliseconds(20); 3087 append_window_start_for_next_append_ = base::TimeDelta::FromMilliseconds(50);
3068 append_window_end_for_next_append_ = base::TimeDelta::FromMilliseconds(280); 3088 append_window_end_for_next_append_ = base::TimeDelta::FromMilliseconds(280);
3069 3089
3070 // Append a cluster that starts before and ends after the append window. 3090 // Append a cluster that starts before and ends after the append window.
3071 AppendSingleStreamCluster( 3091 AppendSingleStreamCluster(
3072 kSourceId, kAudioTrackNum, 3092 kSourceId, kAudioTrackNum,
3073 "0K 30K 60K 90K 120K 150K 180K 210K 240K 270K 300K 330K"); 3093 "0K 30K 60K 90K 120K 150K 180K 210K 240K 270K 300K 330K");
3074 3094
3075 // Verify that frames that end outside the window are not included 3095 // Verify that frames that end outside the window are not included
3076 // in the buffer. Also verify that buffers that start inside the 3096 // in the buffer. Also verify that buffers that start inside the
3077 // window and extend beyond the end of the window are not included. 3097 // window and extend beyond the end of the window are not included.
3078 // 3098 //
3079 // The first 20ms of the first buffer should be trimmed off since it 3099 // The first 50ms of the first buffer should be trimmed off since it
wolenetz 2014/05/23 19:59:45 nit: include mention in comment that the 'first bu
DaleCurtis 2014/05/23 21:46:26 Done.
3080 // overlaps the start of the append window. 3100 // overlaps the start of the append window.
3081 CheckExpectedRanges(kSourceId, "{ [20,270) }"); 3101 CheckExpectedRanges(kSourceId, "{ [50,270) }");
3082 CheckExpectedBuffers(stream, "20 30 60 90 120 150 180 210 240"); 3102 CheckExpectedBuffers(stream, "50P 60 90 120 150 180 210 240");
3083 3103
3084 // Extend the append window to [20,650). 3104 // Extend the append window to [50,650).
3085 append_window_end_for_next_append_ = base::TimeDelta::FromMilliseconds(650); 3105 append_window_end_for_next_append_ = base::TimeDelta::FromMilliseconds(650);
3086 3106
3087 // Append more data and verify that a new range is created. 3107 // Append more data and verify that a new range is created.
3088 AppendSingleStreamCluster( 3108 AppendSingleStreamCluster(
3089 kSourceId, kAudioTrackNum, 3109 kSourceId, kAudioTrackNum,
3090 "360K 390K 420K 450K 480K 510K 540K 570K 600K 630K"); 3110 "360K 390K 420K 450K 480K 510K 540K 570K 600K 630K");
3091 CheckExpectedRanges(kSourceId, "{ [20,270) [360,630) }"); 3111 CheckExpectedRanges(kSourceId, "{ [50,270) [360,630) }");
3092 } 3112 }
3093 3113
3094 TEST_P(ChunkDemuxerTest, AppendWindow_AudioOverlapStartAndEnd) { 3114 TEST_P(ChunkDemuxerTest, AppendWindow_AudioOverlapStartAndEnd) {
3095 ASSERT_TRUE(InitDemuxer(HAS_AUDIO)); 3115 ASSERT_TRUE(InitDemuxer(HAS_AUDIO));
3096 3116
3097 // Set the append window to [10,20). 3117 // Set the append window to [10,20).
3098 append_window_start_for_next_append_ = base::TimeDelta::FromMilliseconds(10); 3118 append_window_start_for_next_append_ = base::TimeDelta::FromMilliseconds(10);
3099 append_window_end_for_next_append_ = base::TimeDelta::FromMilliseconds(20); 3119 append_window_end_for_next_append_ = base::TimeDelta::FromMilliseconds(20);
3100 3120
3101 // Append a cluster that starts before and ends after the append window. 3121 // Append a cluster that starts before and ends after the append window.
3102 AppendSingleStreamCluster(kSourceId, kAudioTrackNum, "0K"); 3122 AppendSingleStreamCluster(kSourceId, kAudioTrackNum, "0K");
3103 3123
3104 // Verify that everything is dropped in this case. No partial append should 3124 // Verify that everything is dropped in this case. No partial append should
3105 // be generated. 3125 // be generated.
3106 CheckExpectedRanges(kSourceId, "{ }"); 3126 CheckExpectedRanges(kSourceId, "{ }");
3107 } 3127 }
3108 3128
3129 TEST_P(ChunkDemuxerTest, AppendWindow_WebMFile_AudioOnly) {
3130 EXPECT_CALL(*this, DemuxerOpened());
3131 demuxer_->Initialize(
3132 &host_,
3133 CreateInitDoneCB(base::TimeDelta::FromMilliseconds(2744), PIPELINE_OK),
3134 true);
3135 ASSERT_EQ(ChunkDemuxer::kOk, AddId(kSourceId, HAS_AUDIO));
3136
3137 // Set the append window to [50,100).
acolwell GONE FROM CHROMIUM 2014/05/23 17:27:30 nit: s/100/150/ since the comment doesn't match th
DaleCurtis 2014/05/23 21:46:26 Done.
3138 append_window_start_for_next_append_ = base::TimeDelta::FromMilliseconds(50);
3139 append_window_end_for_next_append_ = base::TimeDelta::FromMilliseconds(150);
3140
3141 // Read a WebM file into memory and send the data to the demuxer. The chunk
3142 // size has been chosen carefully to ensure the preroll buffer used by the
3143 // partial append window trim must come from a previous Append() call.
3144 scoped_refptr<DecoderBuffer> buffer =
3145 ReadTestDataFile("bear-320x240-audio-only.webm");
3146 AppendDataInPieces(buffer->data(), buffer->data_size(), 128);
3147
3148 DemuxerStream* stream = demuxer_->GetStream(DemuxerStream::AUDIO);
3149 CheckExpectedBuffers(stream, "50P 62 86 109 122 125 128");
3150 }
3151
3109 TEST_P(ChunkDemuxerTest, AppendWindow_Text) { 3152 TEST_P(ChunkDemuxerTest, AppendWindow_Text) {
3110 DemuxerStream* text_stream = NULL; 3153 DemuxerStream* text_stream = NULL;
3111 EXPECT_CALL(host_, AddTextStream(_, _)) 3154 EXPECT_CALL(host_, AddTextStream(_, _))
3112 .WillOnce(SaveArg<0>(&text_stream)); 3155 .WillOnce(SaveArg<0>(&text_stream));
3113 ASSERT_TRUE(InitDemuxer(HAS_VIDEO | HAS_TEXT)); 3156 ASSERT_TRUE(InitDemuxer(HAS_VIDEO | HAS_TEXT));
3114 DemuxerStream* video_stream = demuxer_->GetStream(DemuxerStream::VIDEO); 3157 DemuxerStream* video_stream = demuxer_->GetStream(DemuxerStream::VIDEO);
3115 3158
3116 // Set the append window to [20,280). 3159 // Set the append window to [20,280).
3117 append_window_start_for_next_append_ = base::TimeDelta::FromMilliseconds(20); 3160 append_window_start_for_next_append_ = base::TimeDelta::FromMilliseconds(20);
3118 append_window_end_for_next_append_ = base::TimeDelta::FromMilliseconds(280); 3161 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"); 3293 CheckExpectedBuffers(audio_stream, "160 180");
3251 CheckExpectedBuffers(video_stream, "180 210"); 3294 CheckExpectedBuffers(video_stream, "180 210");
3252 } 3295 }
3253 3296
3254 // Generate two sets of tests: one using FrameProcessor, and one using 3297 // Generate two sets of tests: one using FrameProcessor, and one using
3255 // LegacyFrameProcessor. 3298 // LegacyFrameProcessor.
3256 INSTANTIATE_TEST_CASE_P(NewFrameProcessor, ChunkDemuxerTest, Values(false)); 3299 INSTANTIATE_TEST_CASE_P(NewFrameProcessor, ChunkDemuxerTest, Values(false));
3257 INSTANTIATE_TEST_CASE_P(LegacyFrameProcessor, ChunkDemuxerTest, Values(true)); 3300 INSTANTIATE_TEST_CASE_P(LegacyFrameProcessor, ChunkDemuxerTest, Values(true));
3258 3301
3259 } // namespace media 3302 } // namespace media
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698