Shaka Packager SDK
Loading...
Searching...
No Matches
segmenter_test_base.cc
1// Copyright 2015 Google LLC. All rights reserved.
2//
3// Use of this source code is governed by a BSD-style
4// license that can be found in the LICENSE file or at
5// https://developers.google.com/open-source/licenses/bsd
6
7#include <packager/media/formats/webm/segmenter_test_base.h>
8
9#include <absl/log/check.h>
10
11#include <packager/file/memory_file.h>
12#include <packager/media/formats/webm/webm_constants.h>
13#include <packager/version/version.h>
14
15namespace shaka {
16namespace media {
17namespace {
18
19// The contents of a frame does not mater.
20const uint8_t kTestMediaSampleData[] = {0xde, 0xad, 0xbe, 0xef, 0x00};
21const uint8_t kTestMediaSampleSideData[] = {
22 // First 8 bytes of side_data is the BlockAddID element in big endian.
23 0x12, 0x34, 0x56, 0x78, 0x9a, 0x00, 0x00, 0x00,
24 0x73, 0x69, 0x64, 0x65, 0x00};
25
26const int kTrackId = 1;
27const int64_t kDurationInSeconds = 8;
28const Codec kCodec = kCodecVP8;
29const std::string kCodecString = "vp8";
30const std::string kLanguage = "en";
31const uint16_t kWidth = 100;
32const uint16_t kHeight = 100;
33const uint16_t kPixelWidth = 100;
34const uint16_t kPixelHeight = 100;
35const uint8_t kColorPrimaries = 0;
36const uint8_t kMatrixCoefficients = 0;
37const uint8_t kTransferCharacteristics = 0;
38const int16_t kTrickPlayFactor = 1;
39const uint8_t kNaluLengthSize = 0;
40
41} // namespace
42
43SegmentTestBase::SegmentTestBase() {}
44
45void SegmentTestBase::SetUp() {
46 SetPackagerVersionForTesting("test");
47
48 output_file_name_ = std::string(kMemoryFilePrefix) + "output-file.webm";
49 cur_timestamp_ = 0;
50}
51
52void SegmentTestBase::TearDown() {
54}
55
56std::shared_ptr<MediaSample> SegmentTestBase::CreateSample(
57 KeyFrameFlag key_frame_flag,
58 int64_t duration,
59 SideDataFlag side_data_flag) {
60 std::shared_ptr<MediaSample> sample;
61 const bool is_key_frame = key_frame_flag == kKeyFrame;
62 if (side_data_flag == kGenerateSideData) {
63 sample = MediaSample::CopyFrom(
64 kTestMediaSampleData, sizeof(kTestMediaSampleData),
65 kTestMediaSampleSideData, sizeof(kTestMediaSampleSideData),
66 is_key_frame);
67 } else {
68 sample = MediaSample::CopyFrom(kTestMediaSampleData,
69 sizeof(kTestMediaSampleData), is_key_frame);
70 }
71 sample->set_dts(cur_timestamp_);
72 sample->set_pts(cur_timestamp_);
73 sample->set_duration(duration);
74
75 cur_timestamp_ += duration;
76 return sample;
77}
78
80 MuxerOptions ret;
81 ret.output_file_name = output_file_name_;
82 // Use memory files for temp storage. Normally this would be a bad idea
83 // since it wouldn't support large files, but for tests the files are small.
84 ret.temp_dir = std::string(kMemoryFilePrefix) + "temp/";
85 return ret;
86}
87
89 int32_t time_scale) const {
90 return new VideoStreamInfo(
91 kTrackId, time_scale, kDurationInSeconds * time_scale, kCodec,
92 H26xStreamFormat::kUnSpecified, kCodecString, NULL, 0, kWidth, kHeight,
93 kPixelWidth, kPixelHeight, kColorPrimaries, kMatrixCoefficients,
94 kTransferCharacteristics, kTrickPlayFactor, kNaluLengthSize, kLanguage,
95 false);
96}
97
99 return output_file_name_;
100}
101
102SegmentTestBase::ClusterParser::ClusterParser() {}
103
104SegmentTestBase::ClusterParser::~ClusterParser() {}
105
106void SegmentTestBase::ClusterParser::PopulateFromCluster(
107 const std::string& file_name) {
108 frame_timecodes_.clear();
109 std::string file_contents;
110 ASSERT_TRUE(File::ReadFileToString(file_name.c_str(), &file_contents));
111
112 const uint8_t* data = reinterpret_cast<const uint8_t*>(file_contents.c_str());
113 const size_t size = file_contents.size();
114 WebMListParser cluster_parser(kWebMIdCluster, this);
115 size_t position = 0;
116 while (position < size) {
117 int read = cluster_parser.Parse(data + position,
118 static_cast<int>(size - position));
119 ASSERT_LT(0, read);
120
121 cluster_parser.Reset();
122 position += read;
123 }
124}
125
126void SegmentTestBase::ClusterParser::PopulateFromSegment(
127 const std::string& file_name) {
128 frame_timecodes_.clear();
129 std::string file_contents;
130 ASSERT_TRUE(File::ReadFileToString(file_name.c_str(), &file_contents));
131
132 const uint8_t* data = reinterpret_cast<const uint8_t*>(file_contents.c_str());
133 const size_t size = file_contents.size();
134 WebMListParser header_parser(kWebMIdEBMLHeader, this);
135 int offset = header_parser.Parse(data, static_cast<int>(size));
136 ASSERT_LT(0, offset);
137
138 WebMListParser segment_parser(kWebMIdSegment, this);
139 ASSERT_LT(
140 0, segment_parser.Parse(data + offset, static_cast<int>(size) - offset));
141}
142
143size_t SegmentTestBase::ClusterParser::GetFrameCountForCluster(
144 size_t cluster_index) const {
145 DCHECK_LT(cluster_index, frame_timecodes_.size());
146 return frame_timecodes_[cluster_index].size();
147}
148
149int64_t SegmentTestBase::ClusterParser::GetFrameTimecode(
150 size_t cluster_index,
151 size_t frame_index) const {
152 DCHECK_LT(cluster_index, frame_timecodes_.size());
153 DCHECK_LT(frame_index, frame_timecodes_[cluster_index].size());
154 return frame_timecodes_[cluster_index][frame_index];
155}
156
157size_t SegmentTestBase::ClusterParser::cluster_count() const {
158 return frame_timecodes_.size();
159}
160
161WebMParserClient* SegmentTestBase::ClusterParser::OnListStart(int id) {
162 if (id == kWebMIdCluster) {
163 if (in_cluster_)
164 return NULL;
165
166 frame_timecodes_.emplace_back();
167 cluster_timecode_ = -1;
168 in_cluster_ = true;
169 }
170
171 return this;
172}
173
174bool SegmentTestBase::ClusterParser::OnListEnd(int id) {
175 if (id == kWebMIdCluster) {
176 if (!in_cluster_)
177 return false;
178 in_cluster_ = false;
179 }
180
181 return true;
182}
183
184bool SegmentTestBase::ClusterParser::OnUInt(int id, int64_t val) {
185 if (id == kWebMIdTimecode)
186 cluster_timecode_ = val;
187 return true;
188}
189
190bool SegmentTestBase::ClusterParser::OnFloat(int /*id*/, double /*val*/) {
191 return true;
192}
193
194bool SegmentTestBase::ClusterParser::OnBinary(int id,
195 const uint8_t* data,
196 int /*size*/) {
197 if (in_cluster_ && (id == kWebMIdSimpleBlock || id == kWebMIdBlock)) {
198 if (cluster_timecode_ == -1) {
199 LOG(WARNING) << "Cluster timecode not yet available";
200 return false;
201 }
202 int timecode = data[1] << 8 | data[2];
203 frame_timecodes_.back().push_back(cluster_timecode_ + timecode);
204 }
205
206 return true;
207}
208
209bool SegmentTestBase::ClusterParser::OnString(int /*id*/,
210 const std::string& /*str*/) {
211 return true;
212}
213
214} // namespace media
215} // namespace shaka
static void DeleteAll()
static std::shared_ptr< MediaSample > CopyFrom(const uint8_t *data, size_t size, bool is_key_frame)
VideoStreamInfo * CreateVideoStreamInfo(int32_t time_scale) const
Creates a video stream info object for testing.
MuxerOptions CreateMuxerOptions() const
Creates a Muxer options object for testing.
std::string OutputFileName() const
Gets the file name of the current output file.
std::shared_ptr< MediaSample > CreateSample(KeyFrameFlag key_frame_flag, int64_t duration, SideDataFlag side_data_flag)
Creates a new media sample.
Holds video stream information.
All the methods that are virtual are virtual for mocking.
This structure contains the list of configuration options for Muxer.
std::string temp_dir
Specify temporary directory for intermediate files.