Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(70)

Side by Side Diff: media/remoting/rpc/decoder_buffer_segment.cc

Issue 2261503002: Define remote playback proto buffer (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Add OWNERS file Created 4 years, 3 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
(Empty)
1 // Copyright 2016 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 "media/remoting/rpc/decoder_buffer_segment.h"
6
7 #include <algorithm>
8 #include <memory>
9 #include <utility>
10 #include <vector>
11
12 #include "base/big_endian.h"
13 #include "base/logging.h"
14 #include "base/time/time.h"
15 #include "base/values.h"
16 #include "media/base/decrypt_config.h"
17 #include "media/remoting/remoting_rpc_message.pb.h"
18
19 namespace media {
20 namespace remoting {
21
22 namespace {
23
24 const int kPayloadVersionFieldSize = 1;
25 const int kProtoBufferHeaderSize = 2;
26 const int kDataBufferHeaderSize = 4;
27
28 std::unique_ptr<::media::DecryptConfig> DeserializeDecryptConfig(
miu 2016/09/13 05:40:57 naming nit: This isn't deserializing from a wire f
erickung1 2016/09/15 02:13:33 Done.
29 const pb::DecryptConfig& config_message) {
30 std::vector<::media::SubsampleEntry> entries;
31
32 DCHECK(config_message.has_key_id());
33 DCHECK(config_message.has_iv());
34
35 for (int i = 0; i < config_message.sub_samples_size(); ++i) {
36 entries.push_back(
37 ::media::SubsampleEntry(config_message.sub_samples(i).clear_bytes(),
38 config_message.sub_samples(i).cypher_bytes()));
39 }
40
41 std::unique_ptr<::media::DecryptConfig> decrypt_config(
42 new ::media::DecryptConfig(config_message.key_id(), config_message.iv(),
43 entries));
44 return decrypt_config;
45 }
46
47 scoped_refptr<::media::DecoderBuffer> DeserializeDecoderBuffer(
48 const pb::DecoderBuffer& buffer_message,
49 scoped_refptr<::media::DecoderBuffer> buffer) {
50 std::unique_ptr<::media::DecryptConfig> decrypt_config;
miu 2016/09/13 05:40:57 Looks like this variable is unused. Otherwise, ple
erickung1 2016/09/15 02:13:33 Done. remove |decrypt_config| and also move |front
51 base::TimeDelta front_discard;
52 base::TimeDelta back_discard;
53 bool has_discard = true;
54
55 if (buffer_message.is_eos()) {
56 VLOG(1) << "EOS data";
57 return ::media::DecoderBuffer::CreateEOSBuffer();
58 }
59
60 if (buffer_message.has_timestamp_usec()) {
61 buffer->set_timestamp(
62 base::TimeDelta::FromMicroseconds(buffer_message.timestamp_usec()));
63 }
64
65 if (buffer_message.has_duration_usec()) {
66 buffer->set_duration(
67 base::TimeDelta::FromMicroseconds(buffer_message.duration_usec()));
68 }
69 VLOG(2) << "timestamp:" << buffer_message.timestamp_usec()
70 << " duration:" << buffer_message.duration_usec();
71
72 if (buffer_message.has_is_key_frame())
73 buffer->set_is_key_frame(buffer_message.is_key_frame());
74
75 if (buffer_message.has_decrypt_config()) {
76 buffer->set_decrypt_config(
77 DeserializeDecryptConfig(buffer_message.decrypt_config()));
78 }
79
80 if (buffer_message.has_front_discard_usec()) {
81 has_discard = true;
82 front_discard =
83 base::TimeDelta::FromMicroseconds(buffer_message.front_discard_usec());
84 }
85 if (buffer_message.has_back_discard_usec()) {
86 has_discard = true;
87 back_discard =
88 base::TimeDelta::FromMicroseconds(buffer_message.back_discard_usec());
89 }
90
91 if (has_discard) {
miu 2016/09/13 05:40:57 |has_discard| seems to be true no matter what. Is
erickung1 2016/09/15 02:13:33 Done. Yes, just noticed it and change the default
92 buffer->set_discard_padding(
93 ::media::DecoderBuffer::DiscardPadding(front_discard, back_discard));
94 }
95
96 if (buffer_message.has_splice_timestamp_usec()) {
97 buffer->set_splice_timestamp(base::TimeDelta::FromMicroseconds(
98 buffer_message.splice_timestamp_usec()));
99 }
100
101 if (buffer_message.has_side_data()) {
102 buffer->CopySideDataFrom(
103 reinterpret_cast<const uint8_t*>(buffer_message.side_data().data()),
104 buffer_message.side_data().size());
105 }
106
107 return buffer;
108 }
109
110 void SerializeDecryptConfig(const ::media::DecryptConfig& decrypt_config,
miu 2016/09/13 05:40:57 naming nit: This isn't serializing to a wire forma
erickung1 2016/09/15 02:13:33 Done.
111 pb::DecryptConfig* config_message) {
112 DCHECK(config_message);
113
114 config_message->set_key_id(decrypt_config.key_id());
115 config_message->set_iv(decrypt_config.iv());
116
117 for (const auto& entry : decrypt_config.subsamples()) {
118 pb::DecryptConfig::SubSample* sub_sample =
119 config_message->add_sub_samples();
120 sub_sample->set_clear_bytes(entry.clear_bytes);
121 sub_sample->set_cypher_bytes(entry.cypher_bytes);
122 }
123 }
124
125 void SerializeDecoderBuffer(
126 const scoped_refptr<::media::DecoderBuffer>& decoder_buffer,
127 pb::DecoderBuffer* buffer_message) {
128 if (decoder_buffer->end_of_stream()) {
129 buffer_message->set_is_eos(true);
130 return;
131 }
132
133 VLOG(2) << "timestamp:" << decoder_buffer->timestamp().InMicroseconds()
134 << " duration:" << decoder_buffer->duration().InMicroseconds();
135 buffer_message->set_timestamp_usec(
136 decoder_buffer->timestamp().InMicroseconds());
137 buffer_message->set_duration_usec(
138 decoder_buffer->duration().InMicroseconds());
139 buffer_message->set_is_key_frame(decoder_buffer->is_key_frame());
140
141 if (decoder_buffer->decrypt_config()) {
142 SerializeDecryptConfig(*decoder_buffer->decrypt_config(),
143 buffer_message->mutable_decrypt_config());
144 }
145
146 buffer_message->set_front_discard_usec(
147 decoder_buffer->discard_padding().first.InMicroseconds());
148 buffer_message->set_back_discard_usec(
149 decoder_buffer->discard_padding().second.InMicroseconds());
150 buffer_message->set_splice_timestamp_usec(
151 decoder_buffer->splice_timestamp().InMicroseconds());
152
153 if (decoder_buffer->side_data_size()) {
154 buffer_message->set_side_data(decoder_buffer->side_data(),
155 decoder_buffer->side_data_size());
156 }
157 }
158
159 } // namespace
160
161 scoped_refptr<::media::DecoderBuffer> ByteArrayToDecoderBuffer(
162 const uint8_t* data,
163 uint32_t size) {
164 base::BigEndianReader reader(reinterpret_cast<const char*>(data), size);
165 uint8_t payload_version = 0;
166 uint32_t proto_size = 0;
167 pb::DecoderBuffer segment;
168 uint32_t buffer_size = 0;
169 if (reader.ReadU8(&payload_version) && payload_version == 0 &&
170 reader.ReadU32(&proto_size) &&
miu 2016/09/13 05:40:57 Looks like this should be reader.ReadU16(&proto_si
erickung1 2016/09/15 02:13:33 Done. Yes, fixed in patch set#8 and also have this
171 static_cast<int64_t>(proto_size) < reader.remaining() &&
172 segment.ParseFromArray(reader.ptr(), proto_size) &&
173 reader.Skip(proto_size) && reader.ReadU32(&buffer_size) &&
174 static_cast<int64_t>(buffer_size) <= reader.remaining()) {
175 // Deserialize proto buffer. It passes the pre allocated DecoderBuffer into
176 // the function because the proto buffer may overwrite DecoderBuffer since
177 // it may be EOS buffer.
178 scoped_refptr<media::DecoderBuffer> decoder_buffer =
179 DeserializeDecoderBuffer(
180 segment,
181 DecoderBuffer::CopyFrom(
182 reinterpret_cast<const uint8_t*>(reader.ptr()), buffer_size));
183 return decoder_buffer;
184 }
185 return nullptr;
186 }
187
188 std::vector<uint8_t> DecoderBufferToByteArray(
189 const scoped_refptr<::media::DecoderBuffer> decoder_buffer) {
190 pb::DecoderBuffer decoder_buffer_message;
191 SerializeDecoderBuffer(decoder_buffer, &decoder_buffer_message);
192
193 std::vector<uint8_t> buffer;
miu 2016/09/13 05:40:57 Let's move this down to just before the call to re
erickung1 2016/09/15 02:13:33 Done.
194 size_t decoder_buffer_size =
195 decoder_buffer->end_of_stream() ? 0 : decoder_buffer->data_size();
196 size_t size = kPayloadVersionFieldSize + kProtoBufferHeaderSize +
197 decoder_buffer_message.ByteSize() + kDataBufferHeaderSize +
miu 2016/09/13 05:40:57 I see you're calling decoder_buffer_message.ByteSi
erickung1 2016/09/15 02:13:33 Done.
198 decoder_buffer_size;
199 buffer.resize(size);
200
201 base::BigEndianWriter writer(reinterpret_cast<char*>(buffer.data()),
202 buffer.size());
203 if (writer.WriteU8(0) &&
204 writer.WriteU16(
205 static_cast<uint16_t>(decoder_buffer_message.ByteSize())) &&
206 decoder_buffer_message.SerializeToArray(
207 writer.ptr(), decoder_buffer_message.ByteSize()) &&
208 writer.Skip(decoder_buffer_message.ByteSize()) &&
209 writer.WriteU32(decoder_buffer_size)) {
210 if (decoder_buffer_size) {
211 // DecoderBuffer frame data.
212 writer.WriteBytes(reinterpret_cast<const void*>(decoder_buffer->data()),
213 decoder_buffer->data_size());
214 }
215 return buffer;
216 }
217
218 // Reset buffer since data is corrupted during serialization.
miu 2016/09/13 05:40:57 s/data is corrupted during serialization/serializa
erickung1 2016/09/15 02:13:33 Done.
219 buffer.clear();
220 return buffer;
221 }
222
223 } // namespace remoting
224 } // namespace media
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698