DASH Media Packaging SDK
 All Classes Namespaces Functions Variables Typedefs 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/filters/vp_codec_configuration.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 edash_packager {
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,
55  bool is_encrypted) {
56  VideoCodec video_codec = kUnknownVideoCodec;
57  if (codec_id == "V_VP8") {
58  video_codec = kCodecVP8;
59  } else if (codec_id == "V_VP9") {
60  video_codec = kCodecVP9;
61  } else if (codec_id == "V_VP10") {
62  video_codec = kCodecVP10;
63  } else {
64  LOG(ERROR) << "Unsupported video codec_id " << codec_id;
65  return scoped_refptr<VideoStreamInfo>();
66  }
67 
68  if (pixel_width_ <= 0 || pixel_height_ <= 0)
69  return scoped_refptr<VideoStreamInfo>();
70 
71  // Set crop and display unit defaults if these elements are not present.
72  if (crop_bottom_ == -1)
73  crop_bottom_ = 0;
74 
75  if (crop_top_ == -1)
76  crop_top_ = 0;
77 
78  if (crop_left_ == -1)
79  crop_left_ = 0;
80 
81  if (crop_right_ == -1)
82  crop_right_ = 0;
83 
84  if (display_unit_ == -1)
85  display_unit_ = 0;
86 
87  uint16_t width_after_crop = pixel_width_ - (crop_left_ + crop_right_);
88  uint16_t height_after_crop = pixel_height_ - (crop_top_ + crop_bottom_);
89 
90  if (display_unit_ == 0) {
91  if (display_width_ <= 0)
92  display_width_ = width_after_crop;
93  if (display_height_ <= 0)
94  display_height_ = height_after_crop;
95  } else if (display_unit_ == 3) {
96  if (display_width_ <= 0 || display_height_ <= 0)
97  return scoped_refptr<VideoStreamInfo>();
98  } else {
99  LOG(ERROR) << "Unsupported display unit type " << display_unit_;
100  return scoped_refptr<VideoStreamInfo>();
101  }
102  // Calculate sample aspect ratio.
103  int64_t sar_x = display_width_ * height_after_crop;
104  int64_t sar_y = display_height_ * width_after_crop;
105  int64_t gcd = GetGreatestCommonDivisor(sar_x, sar_y);
106  sar_x /= gcd;
107  sar_y /= gcd;
108 
109  // TODO(kqyang): Fill in the values for vp codec configuration.
110  const uint8_t profile = 0;
111  const uint8_t level = 0;
112  const uint8_t bit_depth = 8;
113  const uint8_t color_space = 0;
114  const uint8_t chroma_subsampling = 0;
115  const uint8_t transfer_function = 0;
116  const bool video_full_range_flag = false;
117  VPCodecConfiguration vp_config(profile, level, bit_depth, color_space,
118  chroma_subsampling, transfer_function,
119  video_full_range_flag, codec_private);
120  std::vector<uint8_t> extra_data;
121  vp_config.Write(&extra_data);
122 
123  return scoped_refptr<VideoStreamInfo>(new VideoStreamInfo(
124  track_num, kWebMTimeScale, 0, video_codec,
125  vp_config.GetCodecString(video_codec), std::string(), width_after_crop,
126  height_after_crop, sar_x, sar_y, 0, 0, vector_as_array(&extra_data),
127  extra_data.size(), is_encrypted));
128 }
129 
130 bool WebMVideoClient::OnUInt(int id, int64_t val) {
131  int64_t* dst = NULL;
132 
133  switch (id) {
134  case kWebMIdPixelWidth:
135  dst = &pixel_width_;
136  break;
137  case kWebMIdPixelHeight:
138  dst = &pixel_height_;
139  break;
140  case kWebMIdPixelCropTop:
141  dst = &crop_top_;
142  break;
143  case kWebMIdPixelCropBottom:
144  dst = &crop_bottom_;
145  break;
146  case kWebMIdPixelCropLeft:
147  dst = &crop_left_;
148  break;
149  case kWebMIdPixelCropRight:
150  dst = &crop_right_;
151  break;
152  case kWebMIdDisplayWidth:
153  dst = &display_width_;
154  break;
155  case kWebMIdDisplayHeight:
156  dst = &display_height_;
157  break;
158  case kWebMIdDisplayUnit:
159  dst = &display_unit_;
160  break;
161  case kWebMIdAlphaMode:
162  dst = &alpha_mode_;
163  break;
164  default:
165  return true;
166  }
167 
168  if (*dst != -1) {
169  LOG(ERROR) << "Multiple values for id " << std::hex << id << " specified ("
170  << *dst << " and " << val << ")";
171  return false;
172  }
173 
174  *dst = val;
175  return true;
176 }
177 
178 bool WebMVideoClient::OnBinary(int id, const uint8_t* data, int size) {
179  // Accept binary fields we don't care about for now.
180  return true;
181 }
182 
183 bool WebMVideoClient::OnFloat(int id, double val) {
184  // Accept float fields we don't care about for now.
185  return true;
186 }
187 
188 } // namespace media
189 } // namespace edash_packager
void Write(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)
std::string GetCodecString(VideoCodec codec) const
void Reset()
Reset this object's state so it can process a new video track element.
Holds video stream information.
Class for parsing or writing VP codec configuration data.