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