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,
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  // The codec private data is in WebM format, but needs to be converted to
62  // MP4 format. Don't do it yet, it will be handled in
63  // webm_cluster_parser.cc
64  } else if (codec_id == "V_VP10") {
65  video_codec = kCodecVP10;
66  } else {
67  LOG(ERROR) << "Unsupported video codec_id " << codec_id;
68  return scoped_refptr<VideoStreamInfo>();
69  }
70 
71  if (pixel_width_ <= 0 || pixel_height_ <= 0)
72  return scoped_refptr<VideoStreamInfo>();
73 
74  // Set crop and display unit defaults if these elements are not present.
75  if (crop_bottom_ == -1)
76  crop_bottom_ = 0;
77 
78  if (crop_top_ == -1)
79  crop_top_ = 0;
80 
81  if (crop_left_ == -1)
82  crop_left_ = 0;
83 
84  if (crop_right_ == -1)
85  crop_right_ = 0;
86 
87  if (display_unit_ == -1)
88  display_unit_ = 0;
89 
90  uint16_t width_after_crop = pixel_width_ - (crop_left_ + crop_right_);
91  uint16_t height_after_crop = pixel_height_ - (crop_top_ + crop_bottom_);
92 
93  if (display_unit_ == 0) {
94  if (display_width_ <= 0)
95  display_width_ = width_after_crop;
96  if (display_height_ <= 0)
97  display_height_ = height_after_crop;
98  } else if (display_unit_ == 3) {
99  if (display_width_ <= 0 || display_height_ <= 0)
100  return scoped_refptr<VideoStreamInfo>();
101  } else {
102  LOG(ERROR) << "Unsupported display unit type " << display_unit_;
103  return scoped_refptr<VideoStreamInfo>();
104  }
105  // Calculate sample aspect ratio.
106  int64_t sar_x = display_width_ * height_after_crop;
107  int64_t sar_y = display_height_ * width_after_crop;
108  int64_t gcd = GetGreatestCommonDivisor(sar_x, sar_y);
109  sar_x /= gcd;
110  sar_y /= gcd;
111 
112  return scoped_refptr<VideoStreamInfo>(new VideoStreamInfo(
113  track_num, kWebMTimeScale, 0, video_codec, std::string(), std::string(),
114  width_after_crop, height_after_crop, sar_x, sar_y, 0, 0,
115  codec_private.data(), codec_private.size(), 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
void Reset()
Reset this object's state so it can process a new video track element.
scoped_refptr< VideoStreamInfo > GetVideoStreamInfo(int64_t track_num, const std::string &codec_id, const std::vector< uint8_t > &codec_private, bool is_encrypted)
Holds video stream information.