1 // Copyright 2014 The Chromium Authors. All rights reserved.
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 "media/formats/common/stream_parser_test_base.h"
6 
7 #include <memory>
8 #include <utility>
9 
10 #include "base/bind.h"
11 #include "media/base/media_log.h"
12 #include "media/base/media_track.h"
13 #include "media/base/media_tracks.h"
14 #include "media/base/test_data_util.h"
15 #include "testing/gtest/include/gtest/gtest.h"
16 
17 namespace media {
18 
BufferQueueToString(const StreamParser::BufferQueue & buffers)19 static std::string BufferQueueToString(
20     const StreamParser::BufferQueue& buffers) {
21   std::stringstream ss;
22 
23   ss << "{";
24   for (StreamParser::BufferQueue::const_iterator itr = buffers.begin();
25        itr != buffers.end();
26        ++itr) {
27     ss << " " << (*itr)->timestamp().InMilliseconds();
28     if ((*itr)->is_key_frame())
29       ss << "K";
30   }
31   ss << " }";
32 
33   return ss.str();
34 }
35 
StreamParserTestBase(std::unique_ptr<StreamParser> stream_parser)36 StreamParserTestBase::StreamParserTestBase(
37     std::unique_ptr<StreamParser> stream_parser)
38     : parser_(std::move(stream_parser)) {
39   parser_->Init(
40       base::BindOnce(&StreamParserTestBase::OnInitDone, base::Unretained(this)),
41       base::BindRepeating(&StreamParserTestBase::OnNewConfig,
42                           base::Unretained(this)),
43       base::BindRepeating(&StreamParserTestBase::OnNewBuffers,
44                           base::Unretained(this)),
45       true,
46       base::BindRepeating(&StreamParserTestBase::OnKeyNeeded,
47                           base::Unretained(this)),
48       base::BindRepeating(&StreamParserTestBase::OnNewSegment,
49                           base::Unretained(this)),
50       base::BindRepeating(&StreamParserTestBase::OnEndOfSegment,
51                           base::Unretained(this)),
52       &media_log_);
53 }
54 
55 StreamParserTestBase::~StreamParserTestBase() = default;
56 
ParseFile(const std::string & filename,int append_bytes)57 std::string StreamParserTestBase::ParseFile(const std::string& filename,
58                                             int append_bytes) {
59   results_stream_.clear();
60   scoped_refptr<DecoderBuffer> buffer = ReadTestDataFile(filename);
61   EXPECT_TRUE(
62       AppendDataInPieces(buffer->data(), buffer->data_size(), append_bytes));
63   return results_stream_.str();
64 }
65 
ParseData(const uint8_t * data,size_t length)66 std::string StreamParserTestBase::ParseData(const uint8_t* data,
67                                             size_t length) {
68   results_stream_.clear();
69   EXPECT_TRUE(AppendDataInPieces(data, length, length));
70   return results_stream_.str();
71 }
72 
AppendDataInPieces(const uint8_t * data,size_t length,size_t piece_size)73 bool StreamParserTestBase::AppendDataInPieces(const uint8_t* data,
74                                               size_t length,
75                                               size_t piece_size) {
76   const uint8_t* start = data;
77   const uint8_t* end = data + length;
78   while (start < end) {
79     size_t append_size = std::min(piece_size, static_cast<size_t>(end - start));
80     if (!parser_->Parse(start, append_size))
81       return false;
82     start += append_size;
83   }
84   return true;
85 }
86 
OnInitDone(const StreamParser::InitParameters & params)87 void StreamParserTestBase::OnInitDone(
88     const StreamParser::InitParameters& params) {
89   DVLOG(1) << __func__ << "(" << params.duration.InMilliseconds() << ")";
90 }
91 
OnNewConfig(std::unique_ptr<MediaTracks> tracks,const StreamParser::TextTrackConfigMap & text_config)92 bool StreamParserTestBase::OnNewConfig(
93     std::unique_ptr<MediaTracks> tracks,
94     const StreamParser::TextTrackConfigMap& text_config) {
95   DVLOG(1) << __func__ << ": got " << tracks->tracks().size() << " tracks";
96   EXPECT_EQ(tracks->tracks().size(), 1u);
97   const auto& track = tracks->tracks()[0];
98   EXPECT_EQ(track->type(), MediaTrack::Audio);
99   audio_track_id_ = track->bytestream_track_id();
100   last_audio_config_ = tracks->getAudioConfig(track->bytestream_track_id());
101   EXPECT_TRUE(last_audio_config_.IsValidConfig());
102   return true;
103 }
104 
OnNewBuffers(const StreamParser::BufferQueueMap & buffer_queue_map)105 bool StreamParserTestBase::OnNewBuffers(
106     const StreamParser::BufferQueueMap& buffer_queue_map) {
107   EXPECT_EQ(1u, buffer_queue_map.size());
108   const auto& itr_audio = buffer_queue_map.find(audio_track_id_);
109   EXPECT_NE(buffer_queue_map.end(), itr_audio);
110   const StreamParser::BufferQueue& audio_buffers = itr_audio->second;
111   EXPECT_FALSE(audio_buffers.empty());
112 
113   // Ensure that track ids are properly assigned on all emitted buffers.
114   for (const auto& buf : audio_buffers) {
115     EXPECT_EQ(audio_track_id_, buf->track_id());
116   }
117 
118   const std::string buffers_str = BufferQueueToString(audio_buffers);
119   DVLOG(1) << __func__ << " : " << buffers_str;
120   results_stream_ << buffers_str;
121   return true;
122 }
123 
OnKeyNeeded(EmeInitDataType type,const std::vector<uint8_t> & init_data)124 void StreamParserTestBase::OnKeyNeeded(EmeInitDataType type,
125                                        const std::vector<uint8_t>& init_data) {
126   DVLOG(1) << __func__ << "(" << static_cast<int>(type) << ", "
127            << init_data.size() << ")";
128 }
129 
OnNewSegment()130 void StreamParserTestBase::OnNewSegment() {
131   DVLOG(1) << __func__;
132   results_stream_ << "NewSegment";
133 }
134 
OnEndOfSegment()135 void StreamParserTestBase::OnEndOfSegment() {
136   DVLOG(1) << __func__;
137   results_stream_ << "EndOfSegment";
138 }
139 
140 }  // namespace media
141