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