1// Copyright (c) 2013 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 "media/webm/webm_video_client.h"
6
7#include "media/base/video_decoder_config.h"
8#include "media/webm/webm_constants.h"
9
10namespace media {
11
12WebMVideoClient::WebMVideoClient(const LogCB& log_cb)
13    : log_cb_(log_cb) {
14  Reset();
15}
16
17WebMVideoClient::~WebMVideoClient() {
18}
19
20void WebMVideoClient::Reset() {
21  pixel_width_ = -1;
22  pixel_height_ = -1;
23  crop_bottom_ = -1;
24  crop_top_ = -1;
25  crop_left_ = -1;
26  crop_right_ = -1;
27  display_width_ = -1;
28  display_height_ = -1;
29  display_unit_ = -1;
30  alpha_mode_ = -1;
31}
32
33bool WebMVideoClient::InitializeConfig(
34    const std::string& codec_id, const std::vector<uint8>& codec_private,
35    bool is_encrypted, VideoDecoderConfig* config) {
36  DCHECK(config);
37
38  VideoCodec video_codec = kUnknownVideoCodec;
39  VideoCodecProfile profile = VIDEO_CODEC_PROFILE_UNKNOWN;
40  if (codec_id == "V_VP8") {
41    video_codec = kCodecVP8;
42    profile = VP8PROFILE_MAIN;
43  } else if (codec_id == "V_VP9") {
44    video_codec = kCodecVP9;
45    profile = VP9PROFILE_MAIN;
46  } else {
47    MEDIA_LOG(log_cb_) << "Unsupported video codec_id " << codec_id;
48    return false;
49  }
50
51  VideoFrame::Format format =
52      (alpha_mode_ == 1) ? VideoFrame::YV12A : VideoFrame::YV12;
53
54  if (pixel_width_ <= 0 || pixel_height_ <= 0)
55    return false;
56
57  // Set crop and display unit defaults if these elements are not present.
58  if (crop_bottom_ == -1)
59    crop_bottom_ = 0;
60
61  if (crop_top_ == -1)
62    crop_top_ = 0;
63
64  if (crop_left_ == -1)
65    crop_left_ = 0;
66
67  if (crop_right_ == -1)
68    crop_right_ = 0;
69
70  if (display_unit_ == -1)
71    display_unit_ = 0;
72
73  gfx::Size coded_size(pixel_width_, pixel_height_);
74  gfx::Rect visible_rect(crop_top_, crop_left_,
75                         pixel_width_ - (crop_left_ + crop_right_),
76                         pixel_height_ - (crop_top_ + crop_bottom_));
77  gfx::Size natural_size = coded_size;
78  if (display_unit_ == 0) {
79    if (display_width_ <= 0)
80      display_width_ = pixel_width_;
81    if (display_height_ <= 0)
82      display_height_ = pixel_height_;
83    natural_size = gfx::Size(display_width_, display_height_);
84  } else if (display_unit_ == 3) {
85    if (display_width_ <= 0 || display_height_ <= 0)
86      return false;
87    natural_size = gfx::Size(display_width_, display_height_);
88  } else {
89    MEDIA_LOG(log_cb_) << "Unsupported display unit type " << display_unit_;
90    return false;
91  }
92  const uint8* extra_data = NULL;
93  size_t extra_data_size = 0;
94  if (codec_private.size() > 0) {
95    extra_data = &codec_private[0];
96    extra_data_size = codec_private.size();
97  }
98
99  config->Initialize(
100      video_codec, profile, format, coded_size, visible_rect, natural_size,
101      extra_data, extra_data_size, is_encrypted, true);
102  return config->IsValidConfig();
103}
104
105bool WebMVideoClient::OnUInt(int id, int64 val) {
106  int64* dst = NULL;
107
108  switch (id) {
109    case kWebMIdPixelWidth:
110      dst = &pixel_width_;
111      break;
112    case kWebMIdPixelHeight:
113      dst = &pixel_height_;
114      break;
115    case kWebMIdPixelCropTop:
116      dst = &crop_top_;
117      break;
118    case kWebMIdPixelCropBottom:
119      dst = &crop_bottom_;
120      break;
121    case kWebMIdPixelCropLeft:
122      dst = &crop_left_;
123      break;
124    case kWebMIdPixelCropRight:
125      dst = &crop_right_;
126      break;
127    case kWebMIdDisplayWidth:
128      dst = &display_width_;
129      break;
130    case kWebMIdDisplayHeight:
131      dst = &display_height_;
132      break;
133    case kWebMIdDisplayUnit:
134      dst = &display_unit_;
135      break;
136    case kWebMIdAlphaMode:
137      dst = &alpha_mode_;
138      break;
139    default:
140      return true;
141  }
142
143  if (*dst != -1) {
144    MEDIA_LOG(log_cb_) << "Multiple values for id " << std::hex << id
145                       << " specified (" << *dst << " and " << val << ")";
146    return false;
147  }
148
149  *dst = val;
150  return true;
151}
152
153bool WebMVideoClient::OnBinary(int id, const uint8* data, int size) {
154  // Accept binary fields we don't care about for now.
155  return true;
156}
157
158bool WebMVideoClient::OnFloat(int id, double val) {
159  // Accept float fields we don't care about for now.
160  return true;
161}
162
163}  // namespace media
164