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

Side by Side Diff: content/common/gpu/media/android_video_decode_accelerator.cc

Issue 1422643002: Pass DecryptConfig parameters over IPC and use it in AVDA. (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Rebase only Created 5 years, 1 month 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
1 // Copyright (c) 2013 The Chromium Authors. All rights reserved. 1 // Copyright (c) 2013 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 #include "content/common/gpu/media/android_video_decode_accelerator.h" 5 #include "content/common/gpu/media/android_video_decode_accelerator.h"
6 6
7 #include "base/bind.h" 7 #include "base/bind.h"
8 #include "base/logging.h" 8 #include "base/logging.h"
9 #include "base/message_loop/message_loop.h" 9 #include "base/message_loop/message_loop.h"
10 #include "base/metrics/histogram.h" 10 #include "base/metrics/histogram.h"
(...skipping 172 matching lines...) Expand 10 before | Expand all | Expand 10 after
183 183
184 scoped_ptr<base::SharedMemory> shm( 184 scoped_ptr<base::SharedMemory> shm(
185 new base::SharedMemory(bitstream_buffer.handle(), true)); 185 new base::SharedMemory(bitstream_buffer.handle(), true));
186 RETURN_ON_FAILURE(this, shm->Map(bitstream_buffer.size()), 186 RETURN_ON_FAILURE(this, shm->Map(bitstream_buffer.size()),
187 "Failed to SharedMemory::Map()", UNREADABLE_INPUT); 187 "Failed to SharedMemory::Map()", UNREADABLE_INPUT);
188 188
189 const base::TimeDelta presentation_timestamp = 189 const base::TimeDelta presentation_timestamp =
190 bitstream_buffer.presentation_timestamp(); 190 bitstream_buffer.presentation_timestamp();
191 DCHECK(presentation_timestamp != media::kNoTimestamp()) 191 DCHECK(presentation_timestamp != media::kNoTimestamp())
192 << "Bitstream buffers must have valid presentation timestamps"; 192 << "Bitstream buffers must have valid presentation timestamps";
193
193 // There may already be a bitstream buffer with this timestamp, e.g., VP9 alt 194 // There may already be a bitstream buffer with this timestamp, e.g., VP9 alt
194 // ref frames, but it's OK to overwrite it because we only expect a single 195 // ref frames, but it's OK to overwrite it because we only expect a single
195 // output frame to have that timestamp. AVDA clients only use the bitstream 196 // output frame to have that timestamp. AVDA clients only use the bitstream
196 // buffer id in the returned Pictures to map a bitstream buffer back to a 197 // buffer id in the returned Pictures to map a bitstream buffer back to a
197 // timestamp on their side, so either one of the bitstream buffer ids will 198 // timestamp on their side, so either one of the bitstream buffer ids will
198 // result in them finding the right timestamp. 199 // result in them finding the right timestamp.
199 bitstream_buffers_in_decoder_[presentation_timestamp] = bitstream_buffer.id(); 200 bitstream_buffers_in_decoder_[presentation_timestamp] = bitstream_buffer.id();
200 201
201 status = media_codec_->QueueInputBuffer( 202 const uint8_t* memory = static_cast<const uint8_t*>(shm->memory());
202 input_buf_index, static_cast<const uint8*>(shm->memory()), 203 const std::string& key_id = bitstream_buffer.key_id();
203 bitstream_buffer.size(), presentation_timestamp); 204 const std::string& iv = bitstream_buffer.iv();
205 const std::vector<media::SubsampleEntry>& subsamples =
206 bitstream_buffer.subsamples();
207
208 if (key_id.empty() || iv.empty()) {
209 status = media_codec_->QueueInputBuffer(input_buf_index, memory,
210 bitstream_buffer.size(),
211 presentation_timestamp);
212 } else {
213 status = media_codec_->QueueSecureInputBuffer(
dcheng 2015/10/23 00:44:47 Why doesn't this function just take std::string fo
Tima Vaisburd 2015/10/23 18:51:40 I think because this function was designed to work
214 input_buf_index, memory, bitstream_buffer.size(),
215 reinterpret_cast<const uint8_t*>(key_id.data()), key_id.size(),
216 reinterpret_cast<const uint8_t*>(iv.data()), iv.size(),
217 subsamples.empty() ? nullptr : &subsamples[0], subsamples.size(),
218 presentation_timestamp);
219 }
220
221 DVLOG(2) << __FUNCTION__
222 << ": QueueInputBuffer: pts:" << presentation_timestamp
223 << " status:" << status;
224
204 RETURN_ON_FAILURE(this, status == media::MEDIA_CODEC_OK, 225 RETURN_ON_FAILURE(this, status == media::MEDIA_CODEC_OK,
205 "Failed to QueueInputBuffer: " << status, PLATFORM_FAILURE); 226 "Failed to QueueInputBuffer: " << status, PLATFORM_FAILURE);
206 227
207 // We should call NotifyEndOfBitstreamBuffer(), when no more decoded output 228 // We should call NotifyEndOfBitstreamBuffer(), when no more decoded output
208 // will be returned from the bitstream buffer. However, MediaCodec API is 229 // will be returned from the bitstream buffer. However, MediaCodec API is
209 // not enough to guarantee it. 230 // not enough to guarantee it.
210 // So, here, we calls NotifyEndOfBitstreamBuffer() in advance in order to 231 // So, here, we calls NotifyEndOfBitstreamBuffer() in advance in order to
211 // keep getting more bitstreams from the client, and throttle them by using 232 // keep getting more bitstreams from the client, and throttle them by using
212 // |bitstreams_notified_in_advance_|. 233 // |bitstreams_notified_in_advance_|.
213 // TODO(dwkang): check if there is a way to remove this workaround. 234 // TODO(dwkang): check if there is a way to remove this workaround.
(...skipping 24 matching lines...) Expand all
238 size_t offset = 0; 259 size_t offset = 0;
239 size_t size = 0; 260 size_t size = 0;
240 261
241 TRACE_EVENT_BEGIN0("media", "AVDA::DequeueOutputBuffer"); 262 TRACE_EVENT_BEGIN0("media", "AVDA::DequeueOutputBuffer");
242 media::MediaCodecStatus status = media_codec_->DequeueOutputBuffer( 263 media::MediaCodecStatus status = media_codec_->DequeueOutputBuffer(
243 NoWaitTimeOut(), &buf_index, &offset, &size, &presentation_timestamp, 264 NoWaitTimeOut(), &buf_index, &offset, &size, &presentation_timestamp,
244 &eos, NULL); 265 &eos, NULL);
245 TRACE_EVENT_END2("media", "AVDA::DequeueOutputBuffer", "status", status, 266 TRACE_EVENT_END2("media", "AVDA::DequeueOutputBuffer", "status", status,
246 "presentation_timestamp (ms)", 267 "presentation_timestamp (ms)",
247 presentation_timestamp.InMilliseconds()); 268 presentation_timestamp.InMilliseconds());
269
270 DVLOG(3) << "AVDA::DequeueOutputBuffer: pts:" << presentation_timestamp
271 << " buf_index:" << buf_index << " offset:" << offset
272 << " size:" << size << " eos:" << eos;
273
248 switch (status) { 274 switch (status) {
249 case media::MEDIA_CODEC_DEQUEUE_OUTPUT_AGAIN_LATER: 275 case media::MEDIA_CODEC_DEQUEUE_OUTPUT_AGAIN_LATER:
250 case media::MEDIA_CODEC_ERROR: 276 case media::MEDIA_CODEC_ERROR:
251 return false; 277 return false;
252 278
253 case media::MEDIA_CODEC_OUTPUT_FORMAT_CHANGED: { 279 case media::MEDIA_CODEC_OUTPUT_FORMAT_CHANGED: {
254 int32 width, height; 280 int32 width, height;
255 media_codec_->GetOutputFormat(&width, &height); 281 media_codec_->GetOutputFormat(&width, &height);
256 282
257 if (!picturebuffers_requested_) { 283 if (!picturebuffers_requested_) {
(...skipping 22 matching lines...) Expand all
280 case media::MEDIA_CODEC_OK: 306 case media::MEDIA_CODEC_OK:
281 DCHECK_GE(buf_index, 0); 307 DCHECK_GE(buf_index, 0);
282 break; 308 break;
283 309
284 default: 310 default:
285 NOTREACHED(); 311 NOTREACHED();
286 break; 312 break;
287 } 313 }
288 } while (buf_index < 0); 314 } while (buf_index < 0);
289 315
290 if (eos) { 316 // Normaly we assume that the decoder makes at most one output frame for each
watk 2015/10/22 22:49:26 "Normally"
Tima Vaisburd 2015/10/23 18:51:40 Done.
317 // distinct input timestamp. A VP9 alt ref frame is a case where an input
318 // buffer, with a possibly unique timestamp, will not result in a
319 // corresponding output frame.
320
321 // However MediaCodecBridge uses timestamp correction and provides
322 // non-decreasing timestamp sequence, which might result in timestamp
323 // duplicates. Discard the frame if we cannot get corresponding buffer id.
324
325 // Get the bitstream buffer id from the timestamp.
326 auto it = eos ? bitstream_buffers_in_decoder_.end()
327 : bitstream_buffers_in_decoder_.find(presentation_timestamp);
328
329 if (it == bitstream_buffers_in_decoder_.end()) {
291 media_codec_->ReleaseOutputBuffer(buf_index, false); 330 media_codec_->ReleaseOutputBuffer(buf_index, false);
292 base::MessageLoop::current()->PostTask( 331 base::MessageLoop::current()->PostTask(
293 FROM_HERE, 332 FROM_HERE,
294 base::Bind(&AndroidVideoDecodeAccelerator::NotifyFlushDone, 333 base::Bind(&AndroidVideoDecodeAccelerator::NotifyFlushDone,
295 weak_this_factory_.GetWeakPtr())); 334 weak_this_factory_.GetWeakPtr()));
296 } else { 335 } else {
297 // Get the bitstream buffer id from the timestamp.
298 auto it = bitstream_buffers_in_decoder_.find(presentation_timestamp);
299 // Require the decoder to output at most one frame for each distinct input
300 // buffer timestamp. A VP9 alt ref frame is a case where an input buffer,
301 // with a possibly unique timestamp, will not result in a corresponding
302 // output frame.
303 CHECK(it != bitstream_buffers_in_decoder_.end())
304 << "Unexpected output frame timestamp";
305 const int32 bitstream_buffer_id = it->second; 336 const int32 bitstream_buffer_id = it->second;
306 bitstream_buffers_in_decoder_.erase(bitstream_buffers_in_decoder_.begin(), 337 bitstream_buffers_in_decoder_.erase(bitstream_buffers_in_decoder_.begin(),
307 ++it); 338 ++it);
308 SendCurrentSurfaceToClient(buf_index, bitstream_buffer_id); 339 SendCurrentSurfaceToClient(buf_index, bitstream_buffer_id);
309 340
310 // If we decoded a frame this time, then try for another. 341 // If we decoded a frame this time, then try for another.
311 should_try_again = true; 342 should_try_again = true;
312 343
313 // Removes ids former or equal than the id from decoder. Note that 344 // Removes ids former or equal than the id from decoder. Note that
314 // |bitstreams_notified_in_advance_| does not mean bitstream ids in decoder 345 // |bitstreams_notified_in_advance_| does not mean bitstream ids in decoder
(...skipping 296 matching lines...) Expand 10 before | Expand all | Expand 10 after
611 // software fallback for H264 on Android anyway. 642 // software fallback for H264 on Android anyway.
612 profile.max_resolution.SetSize(3840, 2160); 643 profile.max_resolution.SetSize(3840, 2160);
613 profiles.push_back(profile); 644 profiles.push_back(profile);
614 } 645 }
615 #endif 646 #endif
616 647
617 return profiles; 648 return profiles;
618 } 649 }
619 650
620 } // namespace content 651 } // namespace content
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698