Revert "[M120 Migration]Fix for crash during chrome exit"
[platform/framework/web/chromium-efl.git] / media / filters / audio_decoder_stream_unittest.cc
1 // Copyright 2018 The Chromium Authors
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4
5 #include <memory>
6 #include <utility>
7
8 #include "base/functional/bind.h"
9 #include "base/functional/callback_helpers.h"
10 #include "base/memory/raw_ptr.h"
11 #include "base/run_loop.h"
12 #include "base/task/sequenced_task_runner.h"
13 #include "base/test/gmock_callback_support.h"
14 #include "base/test/task_environment.h"
15 #include "base/time/time.h"
16 #include "media/base/media_util.h"
17 #include "media/base/mock_filters.h"
18 #include "media/filters/decoder_stream.h"
19 #include "testing/gmock/include/gmock/gmock.h"
20 #include "testing/gtest/include/gtest/gtest.h"
21
22 using ::base::test::RunCallback;
23 using ::base::test::RunOnceCallback;
24 using testing::_;
25 using testing::AnyNumber;
26 using testing::DoAll;
27 using testing::Invoke;
28 using testing::Return;
29 using testing::SaveArg;
30
31 namespace media {
32
33 MATCHER(IsRegularDecoderBuffer, "") {
34   return !arg->end_of_stream();
35 }
36
37 MATCHER(IsEOSDecoderBuffer, "") {
38   return arg->end_of_stream();
39 }
40
41 static void OnAudioDecoderStreamInitialized(base::OnceClosure closure,
42                                             bool success) {
43   ASSERT_TRUE(success);
44   std::move(closure).Run();
45 }
46
47 class AudioDecoderStreamTest : public testing::Test {
48  public:
49   AudioDecoderStreamTest()
50       : audio_decoder_stream_(
51             std::make_unique<AudioDecoderStream::StreamTraits>(
52                 &media_log_,
53                 CHANNEL_LAYOUT_STEREO,
54                 kSampleFormatPlanarF32),
55             task_environment_.GetMainThreadTaskRunner(),
56             base::BindRepeating(&AudioDecoderStreamTest::CreateMockAudioDecoder,
57                                 base::Unretained(this)),
58             &media_log_) {
59     // Any valid config will do.
60     demuxer_stream_.set_audio_decoder_config({AudioCodec::kAAC,
61                                               kSampleFormatS16,
62                                               CHANNEL_LAYOUT_STEREO,
63                                               44100,
64                                               {},
65                                               {}});
66     EXPECT_CALL(demuxer_stream_, SupportsConfigChanges())
67         .WillRepeatedly(Return(true));
68
69     base::RunLoop run_loop;
70     audio_decoder_stream_.Initialize(
71         &demuxer_stream_,
72         base::BindOnce(&OnAudioDecoderStreamInitialized,
73                        run_loop.QuitClosure()),
74         nullptr, base::DoNothing(), base::DoNothing());
75     run_loop.Run();
76   }
77
78   AudioDecoderStreamTest(const AudioDecoderStreamTest&) = delete;
79   AudioDecoderStreamTest& operator=(const AudioDecoderStreamTest&) = delete;
80
81   MockDemuxerStream* demuxer_stream() { return &demuxer_stream_; }
82   MockAudioDecoder* decoder() { return decoder_; }
83
84   void ReadAudioBuffer(base::OnceClosure closure) {
85     audio_decoder_stream_.Read(
86         base::BindOnce(&AudioDecoderStreamTest::OnAudioBufferReadDone,
87                        base::Unretained(this), std::move(closure)));
88   }
89
90   void ProduceDecoderOutput(scoped_refptr<DecoderBuffer> buffer,
91                             AudioDecoder::DecodeCB decode_cb) {
92     // Make sure successive AudioBuffers have increasing timestamps.
93     last_timestamp_ += base::Milliseconds(27);
94     const auto& config = demuxer_stream_.audio_decoder_config();
95     base::SequencedTaskRunner::GetCurrentDefault()->PostTask(
96         FROM_HERE,
97         base::BindOnce(
98             decoder_output_cb_,
99             AudioBuffer::CreateEmptyBuffer(
100                 config.channel_layout(), config.channels(),
101                 config.samples_per_second(), 1221, last_timestamp_)));
102     base::SequencedTaskRunner::GetCurrentDefault()->PostTask(
103         FROM_HERE,
104         base::BindOnce(std::move(decode_cb), DecoderStatus::Codes::kOk));
105   }
106
107   void RunUntilIdle() { task_environment_.RunUntilIdle(); }
108
109  private:
110   std::vector<std::unique_ptr<AudioDecoder>> CreateMockAudioDecoder() {
111     auto decoder = std::make_unique<MockAudioDecoder>();
112     EXPECT_CALL(*decoder, Initialize_(_, _, _, _, _))
113         .Times(AnyNumber())
114         .WillRepeatedly(DoAll(SaveArg<3>(&decoder_output_cb_),
115                               RunOnceCallback<2>(DecoderStatus::Codes::kOk)));
116     decoder_ = decoder.get();
117
118     std::vector<std::unique_ptr<AudioDecoder>> result;
119     result.push_back(std::move(decoder));
120     return result;
121   }
122
123   void OnAudioBufferReadDone(base::OnceClosure closure,
124                              AudioDecoderStream::ReadResult result) {
125     std::move(closure).Run();
126   }
127
128   base::test::TaskEnvironment task_environment_;
129   NullMediaLog media_log_;
130   testing::NiceMock<MockDemuxerStream> demuxer_stream_{DemuxerStream::AUDIO};
131   AudioDecoderStream audio_decoder_stream_;
132
133   raw_ptr<MockAudioDecoder> decoder_ = nullptr;
134   AudioDecoder::OutputCB decoder_output_cb_;
135   base::TimeDelta last_timestamp_;
136 };
137
138 TEST_F(AudioDecoderStreamTest, FlushOnConfigChange) {
139   MockAudioDecoder* first_decoder = decoder();
140   ASSERT_NE(first_decoder, nullptr);
141
142   // Make a regular DemuxerStream::Read().
143   scoped_refptr<DecoderBuffer> buffer = base::MakeRefCounted<DecoderBuffer>(12);
144   DemuxerStream::DecoderBufferVector buffers;
145   buffers.emplace_back(buffer);
146   EXPECT_CALL(*demuxer_stream(), OnRead(_))
147       .WillOnce(RunOnceCallback<0>(DemuxerStream::kOk, buffers));
148   EXPECT_CALL(*decoder(), Decode(IsRegularDecoderBuffer(), _))
149       .WillOnce(Invoke(this, &AudioDecoderStreamTest::ProduceDecoderOutput));
150   base::RunLoop run_loop0;
151   ReadAudioBuffer(run_loop0.QuitClosure());
152   run_loop0.Run();
153
154   // Make a config-change DemuxerStream::Read().
155   // Expect the decoder to be flushed.  Upon flushing, the decoder releases
156   // internally buffered output.
157   EXPECT_CALL(*demuxer_stream(), OnRead(_))
158       .WillOnce(RunOnceCallback<0>(DemuxerStream::kConfigChanged,
159                                    DemuxerStream::DecoderBufferVector()));
160   EXPECT_CALL(*decoder(), Decode(IsEOSDecoderBuffer(), _))
161       .WillOnce(Invoke(this, &AudioDecoderStreamTest::ProduceDecoderOutput));
162   base::RunLoop run_loop1;
163   ReadAudioBuffer(run_loop1.QuitClosure());
164   run_loop1.Run();
165
166   // Expect the decoder to be re-initialized when AudioDecoderStream finishes
167   // processing the last decode.
168   EXPECT_CALL(*decoder(), Initialize_(_, _, _, _, _));
169   RunUntilIdle();
170 }
171
172 }  // namespace media