11320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci// Copyright 2014 The Chromium Authors. All rights reserved.
21320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci// Use of this source code is governed by a BSD-style license that can be
31320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci// found in the LICENSE file.
41320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci
51320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci#include "chromecast/media/cma/ipc_streamer/decoder_buffer_base_marshaller.h"
61320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci
71320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci#include "base/logging.h"
81320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci#include "chromecast/media/cma/base/decoder_buffer_base.h"
91320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci#include "chromecast/media/cma/ipc/media_message.h"
101320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci#include "chromecast/media/cma/ipc/media_message_type.h"
111320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci#include "chromecast/media/cma/ipc_streamer/decrypt_config_marshaller.h"
121320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci#include "media/base/decrypt_config.h"
131320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci
141320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tuccinamespace chromecast {
151320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tuccinamespace media {
161320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci
171320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tuccinamespace {
181320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucciconst size_t kMaxFrameSize = 4 * 1024 * 1024;
191320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci
201320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucciclass DecoderBufferFromMsg : public DecoderBufferBase {
211320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci public:
221320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  explicit DecoderBufferFromMsg(scoped_ptr<MediaMessage> msg);
231320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci
241320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  void Initialize();
251320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci
261320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  // DecoderBufferBase implementation.
271320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  virtual base::TimeDelta timestamp() const OVERRIDE;
281320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  virtual const uint8* data() const OVERRIDE;
291320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  virtual uint8* writable_data() const OVERRIDE;
301320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  virtual int data_size() const OVERRIDE;
311320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  virtual const ::media::DecryptConfig* decrypt_config() const OVERRIDE;
321320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  virtual bool end_of_stream() const OVERRIDE;
331320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci
341320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci private:
351320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  virtual ~DecoderBufferFromMsg();
361320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci
371320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  // Indicates whether this is an end of stream frame.
381320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  bool is_eos_;
391320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci
401320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  // Frame timestamp.
411320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  base::TimeDelta pts_;
421320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci
431320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  // CENC parameters.
441320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  scoped_ptr< ::media::DecryptConfig> decrypt_config_;
451320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci
461320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  // Size of the frame.
471320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  int data_size_;
481320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci
491320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  // Keeps the message since frame data is not copied.
501320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  scoped_ptr<MediaMessage> msg_;
511320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  uint8* data_;
521320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci
531320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  DISALLOW_COPY_AND_ASSIGN(DecoderBufferFromMsg);
541320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci};
551320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci
561320f92c476a1ad9d19dba2a48c72b75566198e9Primiano TucciDecoderBufferFromMsg::DecoderBufferFromMsg(
571320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    scoped_ptr<MediaMessage> msg)
581320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    : msg_(msg.Pass()),
591320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci      is_eos_(true),
601320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci      data_(NULL) {
611320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  CHECK(msg_);
621320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci}
631320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci
641320f92c476a1ad9d19dba2a48c72b75566198e9Primiano TucciDecoderBufferFromMsg::~DecoderBufferFromMsg() {
651320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci}
661320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci
671320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tuccivoid DecoderBufferFromMsg::Initialize() {
681320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  CHECK_EQ(msg_->type(), FrameMediaMsg);
691320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci
701320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  CHECK(msg_->ReadPod(&is_eos_));
711320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  if (is_eos_)
721320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    return;
731320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci
741320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  int64 pts_internal = 0;
751320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  CHECK(msg_->ReadPod(&pts_internal));
761320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  pts_ = base::TimeDelta::FromInternalValue(pts_internal);
771320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci
781320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  bool has_decrypt_config = false;
791320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  CHECK(msg_->ReadPod(&has_decrypt_config));
801320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  if (has_decrypt_config)
811320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    decrypt_config_.reset(DecryptConfigMarshaller::Read(msg_.get()).release());
821320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci
831320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  CHECK(msg_->ReadPod(&data_size_));
841320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  CHECK_GT(data_size_, 0);
851320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  CHECK_LT(data_size_, kMaxFrameSize);
861320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci
871320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  // Get a pointer to the frame data inside the message.
881320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  // Avoid copying the frame data here.
891320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  data_ = static_cast<uint8*>(msg_->GetWritableBuffer(data_size_));
901320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  CHECK(data_);
911320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci
921320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  if (decrypt_config_) {
931320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    uint32 subsample_total_size = 0;
941320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    for (size_t k = 0; k < decrypt_config_->subsamples().size(); k++) {
951320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci      subsample_total_size += decrypt_config_->subsamples()[k].clear_bytes;
961320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci      subsample_total_size += decrypt_config_->subsamples()[k].cypher_bytes;
971320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    }
981320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    CHECK_EQ(subsample_total_size, data_size_);
991320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  }
1001320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci}
1011320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci
1021320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tuccibase::TimeDelta DecoderBufferFromMsg::timestamp() const {
1031320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  return pts_;
1041320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci}
1051320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci
1061320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucciconst uint8* DecoderBufferFromMsg::data() const {
1071320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  CHECK(msg_->IsSerializedMsgAvailable());
1081320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  return data_;
1091320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci}
1101320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci
1111320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucciuint8* DecoderBufferFromMsg::writable_data() const {
1121320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  CHECK(msg_->IsSerializedMsgAvailable());
1131320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  return data_;
1141320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci}
1151320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci
1161320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucciint DecoderBufferFromMsg::data_size() const {
1171320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  return data_size_;
1181320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci}
1191320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci
1201320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucciconst ::media::DecryptConfig* DecoderBufferFromMsg::decrypt_config() const {
1211320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  return decrypt_config_.get();
1221320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci}
1231320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci
1241320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tuccibool DecoderBufferFromMsg::end_of_stream() const {
1251320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  return is_eos_;
1261320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci}
1271320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci
1281320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci}  // namespace
1291320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci
1301320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci// static
1311320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tuccivoid DecoderBufferBaseMarshaller::Write(
1321320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    const scoped_refptr<DecoderBufferBase>& buffer,
1331320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    MediaMessage* msg) {
1341320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  CHECK(msg->WritePod(buffer->end_of_stream()));
1351320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  if (buffer->end_of_stream())
1361320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    return;
1371320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci
1381320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  CHECK(msg->WritePod(buffer->timestamp().ToInternalValue()));
1391320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci
1401320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  bool has_decrypt_config =
1411320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci      (buffer->decrypt_config() != NULL &&
1421320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci       buffer->decrypt_config()->iv().size() > 0);
1431320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  CHECK(msg->WritePod(has_decrypt_config));
1441320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  if (has_decrypt_config)
1451320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    DecryptConfigMarshaller::Write(*buffer->decrypt_config(), msg);
1461320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci
1471320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  CHECK(msg->WritePod(buffer->data_size()));
1481320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  CHECK(msg->WriteBuffer(buffer->data(), buffer->data_size()));
1491320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci}
1501320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci
1511320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci// static
1521320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucciscoped_refptr<DecoderBufferBase> DecoderBufferBaseMarshaller::Read(
1531320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    scoped_ptr<MediaMessage> msg) {
1541320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  scoped_refptr<DecoderBufferFromMsg> buffer(
1551320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci      new DecoderBufferFromMsg(msg.Pass()));
1561320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  buffer->Initialize();
1571320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  return buffer;
1581320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci}
1591320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci
1601320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci}  // namespace media
1611320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci}  // namespace chromecast
162