DASH Media Packaging SDK
 All Classes Namespaces Functions Variables Typedefs Enumerations Enumerator
webm_video_client.cc
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 "packager/media/formats/webm/webm_video_client.h"
6 
7 #include "packager/base/logging.h"
8 #include "packager/media/codecs/vp_codec_configuration_record.h"
9 #include "packager/media/formats/webm/webm_constants.h"
10 
11 namespace {
12 
13 // Timestamps are represented in double in WebM. Convert to uint64_t in us.
14 const uint32_t kWebMTimeScale = 1000000u;
15 
16 int64_t GetGreatestCommonDivisor(int64_t a, int64_t b) {
17  while (b) {
18  int64_t temp = b;
19  b = a % b;
20  a = temp;
21  }
22  return a;
23 }
24 
25 } // namespace
26 
27 namespace shaka {
28 namespace media {
29 
30 WebMVideoClient::WebMVideoClient() {
31  Reset();
32 }
33 
34 WebMVideoClient::~WebMVideoClient() {
35 }
36 
38  pixel_width_ = -1;
39  pixel_height_ = -1;
40  crop_bottom_ = -1;
41  crop_top_ = -1;
42  crop_left_ = -1;
43  crop_right_ = -1;
44  display_width_ = -1;
45  display_height_ = -1;
46  display_unit_ = -1;
47  alpha_mode_ = -1;
48 }
49 
50 std::shared_ptr<VideoStreamInfo> WebMVideoClient::GetVideoStreamInfo(
51  int64_t track_num,
52  const std::string& codec_id,
53  const std::vector<uint8_t>& codec_private,
54  bool is_encrypted) {
55  Codec video_codec = kUnknownCodec;
56  if (codec_id == "V_VP8") {
57  video_codec = kCodecVP8;
58  } else if (codec_id == "V_VP9") {
59  video_codec = kCodecVP9;
60  // The codec private data is in WebM format, but needs to be converted to
61  // MP4 format. Don't do it yet, it will be handled in
62  // webm_cluster_parser.cc
63  } else if (codec_id == "V_VP10") {
64  video_codec = kCodecVP10;
65  } else {
66  LOG(ERROR) << "Unsupported video codec_id " << codec_id;
67  return std::shared_ptr<VideoStreamInfo>();
68  }
69 
70  if (pixel_width_ <= 0 || pixel_height_ <= 0)
71  return std::shared_ptr<VideoStreamInfo>();
72 
73  // Set crop and display unit defaults if these elements are not present.
74  if (crop_bottom_ == -1)
75  crop_bottom_ = 0;
76 
77  if (crop_top_ == -1)
78  crop_top_ = 0;
79 
80  if (crop_left_ == -1)
81  crop_left_ = 0;
82 
83  if (crop_right_ == -1)
84  crop_right_ = 0;
85 
86  if (display_unit_ == -1)
87  display_unit_ = 0;
88 
89  uint16_t width_after_crop = pixel_width_ - (crop_left_ + crop_right_);
90  uint16_t height_after_crop = pixel_height_ - (crop_top_ + crop_bottom_);
91 
92  if (display_unit_ == 0) {
93  if (display_width_ <= 0)
94  display_width_ = width_after_crop;
95  if (display_height_ <= 0)
96  display_height_ = height_after_crop;
97  } else if (display_unit_ == 3) {
98  if (display_width_ <= 0 || display_height_ <= 0)
99  return std::shared_ptr<VideoStreamInfo>();
100  } else {
101  LOG(ERROR) << "Unsupported display unit type " << display_unit_;
102  return std::shared_ptr<VideoStreamInfo>();
103  }
104  // Calculate sample aspect ratio.
105  int64_t sar_x = display_width_ * height_after_crop;
106  int64_t sar_y = display_height_ * width_after_crop;
107  int64_t gcd = GetGreatestCommonDivisor(sar_x, sar_y);
108  sar_x /= gcd;
109  sar_y /= gcd;
110 
111  return std::make_shared<VideoStreamInfo>(
112  track_num, kWebMTimeScale, 0, video_codec, H26xStreamFormat::kUnSpecified,
113  std::string(), codec_private.data(), codec_private.size(),
114  width_after_crop, height_after_crop, sar_x, sar_y, 0, 0, std::string(),
115  is_encrypted);
116 }
117 
118 bool WebMVideoClient::OnUInt(int id, int64_t val) {
119  int64_t* dst = NULL;
120 
121  switch (id) {
122  case kWebMIdPixelWidth:
123  dst = &pixel_width_;
124  break;
125  case kWebMIdPixelHeight:
126  dst = &pixel_height_;
127  break;
128  case kWebMIdPixelCropTop:
129  dst = &crop_top_;
130  break;
131  case kWebMIdPixelCropBottom:
132  dst = &crop_bottom_;
133  break;
134  case kWebMIdPixelCropLeft:
135  dst = &crop_left_;
136  break;
137  case kWebMIdPixelCropRight:
138  dst = &crop_right_;
139  break;
140  case kWebMIdDisplayWidth:
141  dst = &display_width_;
142  break;
143  case kWebMIdDisplayHeight:
144  dst = &display_height_;
145  break;
146  case kWebMIdDisplayUnit:
147  dst = &display_unit_;
148  break;
149  case kWebMIdAlphaMode:
150  dst = &alpha_mode_;
151  break;
152  default:
153  return true;
154  }
155 
156  if (*dst != -1) {
157  LOG(ERROR) << "Multiple values for id " << std::hex << id << " specified ("
158  << *dst << " and " << val << ")";
159  return false;
160  }
161 
162  *dst = val;
163  return true;
164 }
165 
166 bool WebMVideoClient::OnBinary(int id, const uint8_t* data, int size) {
167  // Accept binary fields we don't care about for now.
168  return true;
169 }
170 
171 bool WebMVideoClient::OnFloat(int id, double val) {
172  // Accept float fields we don't care about for now.
173  return true;
174 }
175 
176 } // namespace media
177 } // namespace shaka
std::shared_ptr< VideoStreamInfo > GetVideoStreamInfo(int64_t track_num, const std::string &codec_id, const std::vector< uint8_t > &codec_private, bool is_encrypted)
void Reset()
Reset this object's state so it can process a new video track element.