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 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 Loading... | |
| 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 Loading... | |
| 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 |
| OLD | NEW |