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