Home | History | Annotate | Download | only in ipc_streamer
      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/decoder_buffer_base_marshaller.h"
      6 
      7 #include "base/logging.h"
      8 #include "chromecast/media/cma/base/decoder_buffer_base.h"
      9 #include "chromecast/media/cma/ipc/media_message.h"
     10 #include "chromecast/media/cma/ipc/media_message_type.h"
     11 #include "chromecast/media/cma/ipc_streamer/decrypt_config_marshaller.h"
     12 #include "media/base/decrypt_config.h"
     13 
     14 namespace chromecast {
     15 namespace media {
     16 
     17 namespace {
     18 const size_t kMaxFrameSize = 4 * 1024 * 1024;
     19 
     20 class DecoderBufferFromMsg : public DecoderBufferBase {
     21  public:
     22   explicit DecoderBufferFromMsg(scoped_ptr<MediaMessage> msg);
     23 
     24   void Initialize();
     25 
     26   // DecoderBufferBase implementation.
     27   virtual base::TimeDelta timestamp() const OVERRIDE;
     28   virtual const uint8* data() const OVERRIDE;
     29   virtual uint8* writable_data() const OVERRIDE;
     30   virtual int data_size() const OVERRIDE;
     31   virtual const ::media::DecryptConfig* decrypt_config() const OVERRIDE;
     32   virtual bool end_of_stream() const OVERRIDE;
     33 
     34  private:
     35   virtual ~DecoderBufferFromMsg();
     36 
     37   // Indicates whether this is an end of stream frame.
     38   bool is_eos_;
     39 
     40   // Frame timestamp.
     41   base::TimeDelta pts_;
     42 
     43   // CENC parameters.
     44   scoped_ptr< ::media::DecryptConfig> decrypt_config_;
     45 
     46   // Size of the frame.
     47   int data_size_;
     48 
     49   // Keeps the message since frame data is not copied.
     50   scoped_ptr<MediaMessage> msg_;
     51   uint8* data_;
     52 
     53   DISALLOW_COPY_AND_ASSIGN(DecoderBufferFromMsg);
     54 };
     55 
     56 DecoderBufferFromMsg::DecoderBufferFromMsg(
     57     scoped_ptr<MediaMessage> msg)
     58     : msg_(msg.Pass()),
     59       is_eos_(true),
     60       data_(NULL) {
     61   CHECK(msg_);
     62 }
     63 
     64 DecoderBufferFromMsg::~DecoderBufferFromMsg() {
     65 }
     66 
     67 void DecoderBufferFromMsg::Initialize() {
     68   CHECK_EQ(msg_->type(), FrameMediaMsg);
     69 
     70   CHECK(msg_->ReadPod(&is_eos_));
     71   if (is_eos_)
     72     return;
     73 
     74   int64 pts_internal = 0;
     75   CHECK(msg_->ReadPod(&pts_internal));
     76   pts_ = base::TimeDelta::FromInternalValue(pts_internal);
     77 
     78   bool has_decrypt_config = false;
     79   CHECK(msg_->ReadPod(&has_decrypt_config));
     80   if (has_decrypt_config)
     81     decrypt_config_.reset(DecryptConfigMarshaller::Read(msg_.get()).release());
     82 
     83   CHECK(msg_->ReadPod(&data_size_));
     84   CHECK_GT(data_size_, 0);
     85   CHECK_LT(data_size_, kMaxFrameSize);
     86 
     87   // Get a pointer to the frame data inside the message.
     88   // Avoid copying the frame data here.
     89   data_ = static_cast<uint8*>(msg_->GetWritableBuffer(data_size_));
     90   CHECK(data_);
     91 
     92   if (decrypt_config_) {
     93     uint32 subsample_total_size = 0;
     94     for (size_t k = 0; k < decrypt_config_->subsamples().size(); k++) {
     95       subsample_total_size += decrypt_config_->subsamples()[k].clear_bytes;
     96       subsample_total_size += decrypt_config_->subsamples()[k].cypher_bytes;
     97     }
     98     CHECK_EQ(subsample_total_size, data_size_);
     99   }
    100 }
    101 
    102 base::TimeDelta DecoderBufferFromMsg::timestamp() const {
    103   return pts_;
    104 }
    105 
    106 const uint8* DecoderBufferFromMsg::data() const {
    107   CHECK(msg_->IsSerializedMsgAvailable());
    108   return data_;
    109 }
    110 
    111 uint8* DecoderBufferFromMsg::writable_data() const {
    112   CHECK(msg_->IsSerializedMsgAvailable());
    113   return data_;
    114 }
    115 
    116 int DecoderBufferFromMsg::data_size() const {
    117   return data_size_;
    118 }
    119 
    120 const ::media::DecryptConfig* DecoderBufferFromMsg::decrypt_config() const {
    121   return decrypt_config_.get();
    122 }
    123 
    124 bool DecoderBufferFromMsg::end_of_stream() const {
    125   return is_eos_;
    126 }
    127 
    128 }  // namespace
    129 
    130 // static
    131 void DecoderBufferBaseMarshaller::Write(
    132     const scoped_refptr<DecoderBufferBase>& buffer,
    133     MediaMessage* msg) {
    134   CHECK(msg->WritePod(buffer->end_of_stream()));
    135   if (buffer->end_of_stream())
    136     return;
    137 
    138   CHECK(msg->WritePod(buffer->timestamp().ToInternalValue()));
    139 
    140   bool has_decrypt_config =
    141       (buffer->decrypt_config() != NULL &&
    142        buffer->decrypt_config()->iv().size() > 0);
    143   CHECK(msg->WritePod(has_decrypt_config));
    144   if (has_decrypt_config)
    145     DecryptConfigMarshaller::Write(*buffer->decrypt_config(), msg);
    146 
    147   CHECK(msg->WritePod(buffer->data_size()));
    148   CHECK(msg->WriteBuffer(buffer->data(), buffer->data_size()));
    149 }
    150 
    151 // static
    152 scoped_refptr<DecoderBufferBase> DecoderBufferBaseMarshaller::Read(
    153     scoped_ptr<MediaMessage> msg) {
    154   scoped_refptr<DecoderBufferFromMsg> buffer(
    155       new DecoderBufferFromMsg(msg.Pass()));
    156   buffer->Initialize();
    157   return buffer;
    158 }
    159 
    160 }  // namespace media
    161 }  // namespace chromecast
    162