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