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