// Copyright 2013 The Chromium Authors. All rights reserved. // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. #include "base/bind.h" #include "media/base/audio_decoder_config.h" #include "media/base/decoder_buffer.h" #include "media/base/stream_parser_buffer.h" #include "media/base/test_data_util.h" #include "media/base/video_decoder_config.h" #include "media/mp3/mp3_stream_parser.h" #include "testing/gtest/include/gtest/gtest.h" namespace media { class MP3StreamParserTest : public testing::Test { public: MP3StreamParserTest() {} protected: MP3StreamParser parser_; std::stringstream results_stream_; bool AppendData(const uint8* data, size_t length) { return parser_.Parse(data, length); } bool AppendDataInPieces(const uint8* data, size_t length, size_t piece_size) { const uint8* start = data; const uint8* end = data + length; while (start < end) { size_t append_size = std::min(piece_size, static_cast(end - start)); if (!AppendData(start, append_size)) return false; start += append_size; } return true; } void OnInitDone(bool success, base::TimeDelta duration) { DVLOG(1) << __FUNCTION__ << "(" << success << ", " << duration.InMilliseconds() << ")"; } bool OnNewConfig(const AudioDecoderConfig& audio_config, const VideoDecoderConfig& video_config) { DVLOG(1) << __FUNCTION__ << "(" << audio_config.IsValidConfig() << ", " << video_config.IsValidConfig() << ")"; EXPECT_TRUE(audio_config.IsValidConfig()); EXPECT_FALSE(video_config.IsValidConfig()); return true; } std::string BufferQueueToString(const StreamParser::BufferQueue& buffers) { std::stringstream ss; ss << "{"; for (StreamParser::BufferQueue::const_iterator itr = buffers.begin(); itr != buffers.end(); ++itr) { ss << " " << (*itr)->timestamp().InMilliseconds(); if ((*itr)->IsKeyframe()) ss << "K"; } ss << " }"; return ss.str(); } bool OnNewBuffers(const StreamParser::BufferQueue& audio_buffers, const StreamParser::BufferQueue& video_buffers) { EXPECT_FALSE(audio_buffers.empty()); EXPECT_TRUE(video_buffers.empty()); std::string buffers_str = BufferQueueToString(audio_buffers); DVLOG(1) << __FUNCTION__ << " : " << buffers_str; results_stream_ << buffers_str; return true; } bool OnNewTextBuffers(TextTrack* text_track, const StreamParser::BufferQueue& buffers) { return true; } void OnKeyNeeded(const std::string& type, const std::vector& init_data) { DVLOG(1) << __FUNCTION__ << "(" << type << ", " << init_data.size() << ")"; } scoped_ptr OnAddTextTrack(TextKind kind, const std::string& label, const std::string& language) { return scoped_ptr(); } void OnNewSegment() { DVLOG(1) << __FUNCTION__; results_stream_ << "NewSegment"; } void OnEndOfSegment() { DVLOG(1) << __FUNCTION__; results_stream_ << "EndOfSegment"; } void InitializeParser() { parser_.Init( base::Bind(&MP3StreamParserTest::OnInitDone, base::Unretained(this)), base::Bind(&MP3StreamParserTest::OnNewConfig, base::Unretained(this)), base::Bind(&MP3StreamParserTest::OnNewBuffers, base::Unretained(this)), base::Bind(&MP3StreamParserTest::OnNewTextBuffers, base::Unretained(this)), base::Bind(&MP3StreamParserTest::OnKeyNeeded, base::Unretained(this)), base::Bind(&MP3StreamParserTest::OnAddTextTrack, base::Unretained(this)), base::Bind(&MP3StreamParserTest::OnNewSegment, base::Unretained(this)), base::Bind(&MP3StreamParserTest::OnEndOfSegment, base::Unretained(this)), LogCB()); } std::string ParseFile(const std::string& filename, int append_bytes) { results_stream_.clear(); InitializeParser(); scoped_refptr buffer = ReadTestDataFile(filename); EXPECT_TRUE( AppendDataInPieces(buffer->data(), buffer->data_size(), append_bytes)); return results_stream_.str(); } }; // Test parsing with small prime sized chunks to smoke out "power of // 2" field size assumptions. TEST_F(MP3StreamParserTest, UnalignedAppend) { std::string expected = "NewSegment" "{ 0K }" "{ 26K }" "{ 52K }" "{ 78K }" "{ 104K }" "{ 130K }" "{ 156K }" "{ 182K }" "EndOfSegment" "NewSegment" "{ 208K }" "{ 235K }" "{ 261K }" "EndOfSegment" "NewSegment" "{ 287K }" "{ 313K }" "EndOfSegment"; EXPECT_EQ(expected, ParseFile("sfx.mp3", 17)); } // Test parsing with a larger piece size to verify that multiple buffers // are passed to |new_buffer_cb_|. TEST_F(MP3StreamParserTest, UnalignedAppend512) { std::string expected = "NewSegment" "{ 0K }" "{ 26K 52K 78K 104K }" "EndOfSegment" "NewSegment" "{ 130K 156K 182K }" "{ 208K 235K 261K 287K }" "{ 313K }" "EndOfSegment"; EXPECT_EQ(expected, ParseFile("sfx.mp3", 512)); } } // namespace media