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, std::string(),
113  codec_private.data(), codec_private.size(), width_after_crop,
114  height_after_crop, sar_x, sar_y, 0, 0, std::string(), is_encrypted);
115 }
116 
117 bool WebMVideoClient::OnUInt(int id, int64_t val) {
118  int64_t* dst = NULL;
119 
120  switch (id) {
121  case kWebMIdPixelWidth:
122  dst = &pixel_width_;
123  break;
124  case kWebMIdPixelHeight:
125  dst = &pixel_height_;
126  break;
127  case kWebMIdPixelCropTop:
128  dst = &crop_top_;
129  break;
130  case kWebMIdPixelCropBottom:
131  dst = &crop_bottom_;
132  break;
133  case kWebMIdPixelCropLeft:
134  dst = &crop_left_;
135  break;
136  case kWebMIdPixelCropRight:
137  dst = &crop_right_;
138  break;
139  case kWebMIdDisplayWidth:
140  dst = &display_width_;
141  break;
142  case kWebMIdDisplayHeight:
143  dst = &display_height_;
144  break;
145  case kWebMIdDisplayUnit:
146  dst = &display_unit_;
147  break;
148  case kWebMIdAlphaMode:
149  dst = &alpha_mode_;
150  break;
151  default:
152  return true;
153  }
154 
155  if (*dst != -1) {
156  LOG(ERROR) << "Multiple values for id " << std::hex << id << " specified ("
157  << *dst << " and " << val << ")";
158  return false;
159  }
160 
161  *dst = val;
162  return true;
163 }
164 
165 bool WebMVideoClient::OnBinary(int id, const uint8_t* data, int size) {
166  // Accept binary fields we don't care about for now.
167  return true;
168 }
169 
170 bool WebMVideoClient::OnFloat(int id, double val) {
171  // Accept float fields we don't care about for now.
172  return true;
173 }
174 
175 } // namespace media
176 } // 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.