| OLD | NEW |
| (Empty) |
| 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 <stddef.h> | |
| 8 #include <stdint.h> | |
| 9 #include <utility> | |
| 10 | |
| 11 #include "base/logging.h" | |
| 12 #include "base/macros.h" | |
| 13 #include "chromecast/media/cma/base/cast_decrypt_config_impl.h" | |
| 14 #include "chromecast/media/cma/base/decoder_buffer_base.h" | |
| 15 #include "chromecast/media/cma/ipc/media_message.h" | |
| 16 #include "chromecast/media/cma/ipc/media_message_type.h" | |
| 17 #include "chromecast/media/cma/ipc_streamer/decrypt_config_marshaller.h" | |
| 18 #include "chromecast/public/media/cast_decrypt_config.h" | |
| 19 #include "media/base/decoder_buffer.h" | |
| 20 #include "media/base/decrypt_config.h" | |
| 21 | |
| 22 namespace chromecast { | |
| 23 namespace media { | |
| 24 | |
| 25 namespace { | |
| 26 const size_t kMaxFrameSize = 4 * 1024 * 1024; | |
| 27 | |
| 28 class DecoderBufferFromMsg : public DecoderBufferBase { | |
| 29 public: | |
| 30 explicit DecoderBufferFromMsg(std::unique_ptr<MediaMessage> msg); | |
| 31 | |
| 32 void Initialize(); | |
| 33 | |
| 34 // DecoderBufferBase implementation. | |
| 35 StreamId stream_id() const override; | |
| 36 int64_t timestamp() const override; | |
| 37 void set_timestamp(base::TimeDelta timestamp) override; | |
| 38 const uint8_t* data() const override; | |
| 39 uint8_t* writable_data() const override; | |
| 40 size_t data_size() const override; | |
| 41 const CastDecryptConfig* decrypt_config() const override; | |
| 42 bool end_of_stream() const override; | |
| 43 scoped_refptr<::media::DecoderBuffer> ToMediaBuffer() const override; | |
| 44 | |
| 45 private: | |
| 46 ~DecoderBufferFromMsg() override; | |
| 47 | |
| 48 // Indicates whether this is an end of stream frame. | |
| 49 bool is_eos_; | |
| 50 | |
| 51 // Stream Id this decoder buffer belongs to. | |
| 52 StreamId stream_id_; | |
| 53 | |
| 54 // Frame timestamp. | |
| 55 base::TimeDelta pts_; | |
| 56 | |
| 57 // CENC parameters. | |
| 58 std::unique_ptr<CastDecryptConfig> decrypt_config_; | |
| 59 | |
| 60 // Size of the frame. | |
| 61 size_t data_size_; | |
| 62 | |
| 63 // Keeps the message since frame data is not copied. | |
| 64 std::unique_ptr<MediaMessage> msg_; | |
| 65 uint8_t* data_; | |
| 66 | |
| 67 DISALLOW_COPY_AND_ASSIGN(DecoderBufferFromMsg); | |
| 68 }; | |
| 69 | |
| 70 DecoderBufferFromMsg::DecoderBufferFromMsg(std::unique_ptr<MediaMessage> msg) | |
| 71 : is_eos_(true), stream_id_(kPrimary), msg_(std::move(msg)), data_(NULL) { | |
| 72 CHECK(msg_); | |
| 73 } | |
| 74 | |
| 75 DecoderBufferFromMsg::~DecoderBufferFromMsg() { | |
| 76 } | |
| 77 | |
| 78 void DecoderBufferFromMsg::Initialize() { | |
| 79 CHECK_EQ(msg_->type(), FrameMediaMsg); | |
| 80 | |
| 81 CHECK(msg_->ReadPod(&is_eos_)); | |
| 82 if (is_eos_) | |
| 83 return; | |
| 84 | |
| 85 CHECK(msg_->ReadPod(&stream_id_)); | |
| 86 | |
| 87 int64_t pts_internal = 0; | |
| 88 CHECK(msg_->ReadPod(&pts_internal)); | |
| 89 pts_ = base::TimeDelta::FromMicroseconds(pts_internal); | |
| 90 | |
| 91 bool has_decrypt_config = false; | |
| 92 CHECK(msg_->ReadPod(&has_decrypt_config)); | |
| 93 if (has_decrypt_config) | |
| 94 decrypt_config_.reset(DecryptConfigMarshaller::Read(msg_.get()).release()); | |
| 95 | |
| 96 CHECK(msg_->ReadPod(&data_size_)); | |
| 97 CHECK_GT(data_size_, 0u); | |
| 98 CHECK_LT(data_size_, kMaxFrameSize); | |
| 99 | |
| 100 // Get a pointer to the frame data inside the message. | |
| 101 // Avoid copying the frame data here. | |
| 102 data_ = static_cast<uint8_t*>(msg_->GetWritableBuffer(data_size_)); | |
| 103 CHECK(data_); | |
| 104 | |
| 105 if (decrypt_config_) { | |
| 106 uint32_t subsample_total_size = 0; | |
| 107 for (size_t k = 0; k < decrypt_config_->subsamples().size(); k++) { | |
| 108 subsample_total_size += decrypt_config_->subsamples()[k].clear_bytes; | |
| 109 subsample_total_size += decrypt_config_->subsamples()[k].cypher_bytes; | |
| 110 } | |
| 111 CHECK_EQ(subsample_total_size, data_size_); | |
| 112 } | |
| 113 } | |
| 114 | |
| 115 StreamId DecoderBufferFromMsg::stream_id() const { | |
| 116 return stream_id_; | |
| 117 } | |
| 118 | |
| 119 int64_t DecoderBufferFromMsg::timestamp() const { | |
| 120 return pts_.InMicroseconds(); | |
| 121 } | |
| 122 | |
| 123 void DecoderBufferFromMsg::set_timestamp(base::TimeDelta timestamp) { | |
| 124 pts_ = timestamp; | |
| 125 } | |
| 126 | |
| 127 const uint8_t* DecoderBufferFromMsg::data() const { | |
| 128 CHECK(msg_->IsSerializedMsgAvailable()); | |
| 129 return data_; | |
| 130 } | |
| 131 | |
| 132 uint8_t* DecoderBufferFromMsg::writable_data() const { | |
| 133 CHECK(msg_->IsSerializedMsgAvailable()); | |
| 134 return data_; | |
| 135 } | |
| 136 | |
| 137 size_t DecoderBufferFromMsg::data_size() const { | |
| 138 return data_size_; | |
| 139 } | |
| 140 | |
| 141 const CastDecryptConfig* DecoderBufferFromMsg::decrypt_config() const { | |
| 142 return decrypt_config_.get(); | |
| 143 } | |
| 144 | |
| 145 bool DecoderBufferFromMsg::end_of_stream() const { | |
| 146 return is_eos_; | |
| 147 } | |
| 148 | |
| 149 scoped_refptr<::media::DecoderBuffer> | |
| 150 DecoderBufferFromMsg::ToMediaBuffer() const { | |
| 151 if (is_eos_) | |
| 152 return ::media::DecoderBuffer::CreateEOSBuffer(); | |
| 153 | |
| 154 scoped_refptr<::media::DecoderBuffer> copy = | |
| 155 ::media::DecoderBuffer::CopyFrom(data(), data_size()); | |
| 156 copy->set_timestamp(base::TimeDelta::FromMicroseconds(timestamp())); | |
| 157 return copy; | |
| 158 } | |
| 159 | |
| 160 } // namespace | |
| 161 | |
| 162 // static | |
| 163 void DecoderBufferBaseMarshaller::Write( | |
| 164 const scoped_refptr<DecoderBufferBase>& buffer, | |
| 165 MediaMessage* msg) { | |
| 166 CHECK(msg->WritePod(buffer->end_of_stream())); | |
| 167 if (buffer->end_of_stream()) | |
| 168 return; | |
| 169 | |
| 170 CHECK(msg->WritePod(buffer->stream_id())); | |
| 171 CHECK(msg->WritePod(buffer->timestamp())); | |
| 172 | |
| 173 bool has_decrypt_config = buffer->decrypt_config() != nullptr; | |
| 174 CHECK(msg->WritePod(has_decrypt_config)); | |
| 175 | |
| 176 if (has_decrypt_config) | |
| 177 DecryptConfigMarshaller::Write(*buffer->decrypt_config(), msg); | |
| 178 | |
| 179 CHECK(msg->WritePod(buffer->data_size())); | |
| 180 CHECK(msg->WriteBuffer(buffer->data(), buffer->data_size())); | |
| 181 } | |
| 182 | |
| 183 // static | |
| 184 scoped_refptr<DecoderBufferBase> DecoderBufferBaseMarshaller::Read( | |
| 185 std::unique_ptr<MediaMessage> msg) { | |
| 186 scoped_refptr<DecoderBufferFromMsg> buffer( | |
| 187 new DecoderBufferFromMsg(std::move(msg))); | |
| 188 buffer->Initialize(); | |
| 189 return buffer; | |
| 190 } | |
| 191 | |
| 192 } // namespace media | |
| 193 } // namespace chromecast | |
| OLD | NEW |