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

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: Removed MediaCodec.CodecException that was added only at level 21 (Android L) 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(
214 input_buf_index, memory, bitstream_buffer.size(), key_id, iv,
215 subsamples, presentation_timestamp);
216 }
217
218 DVLOG(2) << __FUNCTION__
219 << ": QueueInputBuffer: pts:" << presentation_timestamp
220 << " status:" << status;
221
204 RETURN_ON_FAILURE(this, status == media::MEDIA_CODEC_OK, 222 RETURN_ON_FAILURE(this, status == media::MEDIA_CODEC_OK,
205 "Failed to QueueInputBuffer: " << status, PLATFORM_FAILURE); 223 "Failed to QueueInputBuffer: " << status, PLATFORM_FAILURE);
206 224
207 // We should call NotifyEndOfBitstreamBuffer(), when no more decoded output 225 // We should call NotifyEndOfBitstreamBuffer(), when no more decoded output
208 // will be returned from the bitstream buffer. However, MediaCodec API is 226 // will be returned from the bitstream buffer. However, MediaCodec API is
209 // not enough to guarantee it. 227 // not enough to guarantee it.
210 // So, here, we calls NotifyEndOfBitstreamBuffer() in advance in order to 228 // So, here, we calls NotifyEndOfBitstreamBuffer() in advance in order to
211 // keep getting more bitstreams from the client, and throttle them by using 229 // keep getting more bitstreams from the client, and throttle them by using
212 // |bitstreams_notified_in_advance_|. 230 // |bitstreams_notified_in_advance_|.
213 // TODO(dwkang): check if there is a way to remove this workaround. 231 // TODO(dwkang): check if there is a way to remove this workaround.
(...skipping 24 matching lines...) Expand all
238 size_t offset = 0; 256 size_t offset = 0;
239 size_t size = 0; 257 size_t size = 0;
240 258
241 TRACE_EVENT_BEGIN0("media", "AVDA::DequeueOutputBuffer"); 259 TRACE_EVENT_BEGIN0("media", "AVDA::DequeueOutputBuffer");
242 media::MediaCodecStatus status = media_codec_->DequeueOutputBuffer( 260 media::MediaCodecStatus status = media_codec_->DequeueOutputBuffer(
243 NoWaitTimeOut(), &buf_index, &offset, &size, &presentation_timestamp, 261 NoWaitTimeOut(), &buf_index, &offset, &size, &presentation_timestamp,
244 &eos, NULL); 262 &eos, NULL);
245 TRACE_EVENT_END2("media", "AVDA::DequeueOutputBuffer", "status", status, 263 TRACE_EVENT_END2("media", "AVDA::DequeueOutputBuffer", "status", status,
246 "presentation_timestamp (ms)", 264 "presentation_timestamp (ms)",
247 presentation_timestamp.InMilliseconds()); 265 presentation_timestamp.InMilliseconds());
266
267 DVLOG(3) << "AVDA::DequeueOutputBuffer: pts:" << presentation_timestamp
268 << " buf_index:" << buf_index << " offset:" << offset
269 << " size:" << size << " eos:" << eos;
270
248 switch (status) { 271 switch (status) {
249 case media::MEDIA_CODEC_DEQUEUE_OUTPUT_AGAIN_LATER: 272 case media::MEDIA_CODEC_DEQUEUE_OUTPUT_AGAIN_LATER:
250 case media::MEDIA_CODEC_ERROR: 273 case media::MEDIA_CODEC_ERROR:
251 return false; 274 return false;
252 275
253 case media::MEDIA_CODEC_OUTPUT_FORMAT_CHANGED: { 276 case media::MEDIA_CODEC_OUTPUT_FORMAT_CHANGED: {
254 int32 width, height; 277 int32 width, height;
255 media_codec_->GetOutputFormat(&width, &height); 278 media_codec_->GetOutputFormat(&width, &height);
256 279
257 if (!picturebuffers_requested_) { 280 if (!picturebuffers_requested_) {
(...skipping 22 matching lines...) Expand all
280 case media::MEDIA_CODEC_OK: 303 case media::MEDIA_CODEC_OK:
281 DCHECK_GE(buf_index, 0); 304 DCHECK_GE(buf_index, 0);
282 break; 305 break;
283 306
284 default: 307 default:
285 NOTREACHED(); 308 NOTREACHED();
286 break; 309 break;
287 } 310 }
288 } while (buf_index < 0); 311 } while (buf_index < 0);
289 312
290 if (eos) { 313 // Normally we assume that the decoder makes at most one output frame for each
314 // distinct input timestamp. A VP9 alt ref frame is a case where an input
315 // buffer, with a possibly unique timestamp, will not result in a
316 // corresponding output frame.
317
318 // However MediaCodecBridge uses timestamp correction and provides
319 // non-decreasing timestamp sequence, which might result in timestamp
320 // duplicates. Discard the frame if we cannot get corresponding buffer id.
321
322 // Get the bitstream buffer id from the timestamp.
323 auto it = eos ? bitstream_buffers_in_decoder_.end()
324 : bitstream_buffers_in_decoder_.find(presentation_timestamp);
325
326 if (it == bitstream_buffers_in_decoder_.end()) {
291 media_codec_->ReleaseOutputBuffer(buf_index, false); 327 media_codec_->ReleaseOutputBuffer(buf_index, false);
292 base::MessageLoop::current()->PostTask( 328 base::MessageLoop::current()->PostTask(
293 FROM_HERE, 329 FROM_HERE,
294 base::Bind(&AndroidVideoDecodeAccelerator::NotifyFlushDone, 330 base::Bind(&AndroidVideoDecodeAccelerator::NotifyFlushDone,
295 weak_this_factory_.GetWeakPtr())); 331 weak_this_factory_.GetWeakPtr()));
296 } else { 332 } 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; 333 const int32 bitstream_buffer_id = it->second;
306 bitstream_buffers_in_decoder_.erase(bitstream_buffers_in_decoder_.begin(), 334 bitstream_buffers_in_decoder_.erase(bitstream_buffers_in_decoder_.begin(),
307 ++it); 335 ++it);
308 SendCurrentSurfaceToClient(buf_index, bitstream_buffer_id); 336 SendCurrentSurfaceToClient(buf_index, bitstream_buffer_id);
309 337
310 // If we decoded a frame this time, then try for another. 338 // If we decoded a frame this time, then try for another.
311 should_try_again = true; 339 should_try_again = true;
312 340
313 // Removes ids former or equal than the id from decoder. Note that 341 // Removes ids former or equal than the id from decoder. Note that
314 // |bitstreams_notified_in_advance_| does not mean bitstream ids in decoder 342 // |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. 639 // software fallback for H264 on Android anyway.
612 profile.max_resolution.SetSize(3840, 2160); 640 profile.max_resolution.SetSize(3840, 2160);
613 profiles.push_back(profile); 641 profiles.push_back(profile);
614 } 642 }
615 #endif 643 #endif
616 644
617 return profiles; 645 return profiles;
618 } 646 }
619 647
620 } // namespace content 648 } // namespace content
OLDNEW
« no previous file with comments | « content/common/gpu/gpu_messages.h ('k') | content/common/gpu/media/gpu_video_decode_accelerator.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698