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 "chromecast/media/cma/ipc_streamer/video_decoder_config_marshaller.h"
6
7#include "base/basictypes.h"
8#include "base/logging.h"
9#include "chromecast/media/cma/ipc/media_message.h"
10#include "media/base/video_decoder_config.h"
11#include "ui/gfx/rect.h"
12#include "ui/gfx/size.h"
13
14namespace chromecast {
15namespace media {
16
17namespace {
18const size_t kMaxExtraDataSize = 16 * 1024;
19
20class SizeMarshaller {
21 public:
22  static void Write(const gfx::Size& size, MediaMessage* msg) {
23    CHECK(msg->WritePod(size.width()));
24    CHECK(msg->WritePod(size.height()));
25  }
26
27  static gfx::Size Read(MediaMessage* msg) {
28    int w, h;
29    CHECK(msg->ReadPod(&w));
30    CHECK(msg->ReadPod(&h));
31    return gfx::Size(w, h);
32  }
33};
34
35class RectMarshaller {
36 public:
37  static void Write(const gfx::Rect& rect, MediaMessage* msg) {
38    CHECK(msg->WritePod(rect.x()));
39    CHECK(msg->WritePod(rect.y()));
40    CHECK(msg->WritePod(rect.width()));
41    CHECK(msg->WritePod(rect.height()));
42  }
43
44  static gfx::Rect Read(MediaMessage* msg) {
45    int x, y, w, h;
46    CHECK(msg->ReadPod(&x));
47    CHECK(msg->ReadPod(&y));
48    CHECK(msg->ReadPod(&w));
49    CHECK(msg->ReadPod(&h));
50    return gfx::Rect(x, y, w, h);
51  }
52};
53
54}  // namespace
55
56// static
57void VideoDecoderConfigMarshaller::Write(
58    const ::media::VideoDecoderConfig& config, MediaMessage* msg) {
59  CHECK(msg->WritePod(config.codec()));
60  CHECK(msg->WritePod(config.profile()));
61  CHECK(msg->WritePod(config.format()));
62  SizeMarshaller::Write(config.coded_size(), msg);
63  RectMarshaller::Write(config.visible_rect(), msg);
64  SizeMarshaller::Write(config.natural_size(), msg);
65  CHECK(msg->WritePod(config.is_encrypted()));
66  CHECK(msg->WritePod(config.extra_data_size()));
67  if (config.extra_data_size() > 0)
68    CHECK(msg->WriteBuffer(config.extra_data(), config.extra_data_size()));
69}
70
71// static
72::media::VideoDecoderConfig VideoDecoderConfigMarshaller::Read(
73    MediaMessage* msg) {
74  ::media::VideoCodec codec;
75  ::media::VideoCodecProfile profile;
76  ::media::VideoFrame::Format format;
77  gfx::Size coded_size;
78  gfx::Rect visible_rect;
79  gfx::Size natural_size;
80  bool is_encrypted;
81  size_t extra_data_size;
82  scoped_ptr<uint8[]> extra_data;
83
84  CHECK(msg->ReadPod(&codec));
85  CHECK(msg->ReadPod(&profile));
86  CHECK(msg->ReadPod(&format));
87  coded_size = SizeMarshaller::Read(msg);
88  visible_rect = RectMarshaller::Read(msg);
89  natural_size = SizeMarshaller::Read(msg);
90  CHECK(msg->ReadPod(&is_encrypted));
91  CHECK(msg->ReadPod(&extra_data_size));
92
93  CHECK_GE(codec, ::media::kUnknownVideoCodec);
94  CHECK_LE(codec, ::media::kVideoCodecMax);
95  CHECK_GE(profile, ::media::VIDEO_CODEC_PROFILE_UNKNOWN);
96  CHECK_LE(profile, ::media::VIDEO_CODEC_PROFILE_MAX);
97  CHECK_GE(format, ::media::VideoFrame::UNKNOWN);
98  CHECK_LE(format, ::media::VideoFrame::FORMAT_MAX);
99  CHECK_LT(extra_data_size, kMaxExtraDataSize);
100  if (extra_data_size > 0) {
101    extra_data.reset(new uint8[extra_data_size]);
102    CHECK(msg->ReadBuffer(extra_data.get(), extra_data_size));
103  }
104
105  return ::media::VideoDecoderConfig(
106      codec, profile, format,
107      coded_size, visible_rect, natural_size,
108      extra_data.get(), extra_data_size,
109      is_encrypted);
110}
111
112}  // namespace media
113}  // namespace chromecast
114