Chromium Code Reviews| Index: content/common/gpu/media/android_video_decode_accelerator.cc |
| diff --git a/content/common/gpu/media/android_video_decode_accelerator.cc b/content/common/gpu/media/android_video_decode_accelerator.cc |
| index f4c81f9999559ad670d197039435e876fb778e0b..41b3c16ce53a49cc569887460d26ff86f05ccef3 100644 |
| --- a/content/common/gpu/media/android_video_decode_accelerator.cc |
| +++ b/content/common/gpu/media/android_video_decode_accelerator.cc |
| @@ -190,6 +190,7 @@ void AndroidVideoDecodeAccelerator::QueueInput() { |
| bitstream_buffer.presentation_timestamp(); |
| DCHECK(presentation_timestamp != media::kNoTimestamp()) |
| << "Bitstream buffers must have valid presentation timestamps"; |
| + |
| // There may already be a bitstream buffer with this timestamp, e.g., VP9 alt |
| // ref frames, but it's OK to overwrite it because we only expect a single |
| // output frame to have that timestamp. AVDA clients only use the bitstream |
| @@ -198,9 +199,29 @@ void AndroidVideoDecodeAccelerator::QueueInput() { |
| // result in them finding the right timestamp. |
| bitstream_buffers_in_decoder_[presentation_timestamp] = bitstream_buffer.id(); |
| - status = media_codec_->QueueInputBuffer( |
| - input_buf_index, static_cast<const uint8*>(shm->memory()), |
| - bitstream_buffer.size(), presentation_timestamp); |
| + const uint8_t* memory = static_cast<const uint8_t*>(shm->memory()); |
| + const std::string& key_id = bitstream_buffer.key_id(); |
| + const std::string& iv = bitstream_buffer.iv(); |
| + const std::vector<media::SubsampleEntry>& subsamples = |
| + bitstream_buffer.subsamples(); |
| + |
| + if (key_id.empty() || iv.empty()) { |
| + status = media_codec_->QueueInputBuffer(input_buf_index, memory, |
| + bitstream_buffer.size(), |
| + presentation_timestamp); |
| + } else { |
| + 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
|
| + input_buf_index, memory, bitstream_buffer.size(), |
| + reinterpret_cast<const uint8_t*>(key_id.data()), key_id.size(), |
| + reinterpret_cast<const uint8_t*>(iv.data()), iv.size(), |
| + subsamples.empty() ? nullptr : &subsamples[0], subsamples.size(), |
| + presentation_timestamp); |
| + } |
| + |
| + DVLOG(2) << __FUNCTION__ |
| + << ": QueueInputBuffer: pts:" << presentation_timestamp |
| + << " status:" << status; |
| + |
| RETURN_ON_FAILURE(this, status == media::MEDIA_CODEC_OK, |
| "Failed to QueueInputBuffer: " << status, PLATFORM_FAILURE); |
| @@ -245,6 +266,11 @@ bool AndroidVideoDecodeAccelerator::DequeueOutput() { |
| TRACE_EVENT_END2("media", "AVDA::DequeueOutputBuffer", "status", status, |
| "presentation_timestamp (ms)", |
| presentation_timestamp.InMilliseconds()); |
| + |
| + DVLOG(3) << "AVDA::DequeueOutputBuffer: pts:" << presentation_timestamp |
| + << " buf_index:" << buf_index << " offset:" << offset |
| + << " size:" << size << " eos:" << eos; |
| + |
| switch (status) { |
| case media::MEDIA_CODEC_DEQUEUE_OUTPUT_AGAIN_LATER: |
| case media::MEDIA_CODEC_ERROR: |
| @@ -287,21 +313,26 @@ bool AndroidVideoDecodeAccelerator::DequeueOutput() { |
| } |
| } while (buf_index < 0); |
| - if (eos) { |
| + // 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.
|
| + // distinct input timestamp. A VP9 alt ref frame is a case where an input |
| + // buffer, with a possibly unique timestamp, will not result in a |
| + // corresponding output frame. |
| + |
| + // However MediaCodecBridge uses timestamp correction and provides |
| + // non-decreasing timestamp sequence, which might result in timestamp |
| + // duplicates. Discard the frame if we cannot get corresponding buffer id. |
| + |
| + // Get the bitstream buffer id from the timestamp. |
| + auto it = eos ? bitstream_buffers_in_decoder_.end() |
| + : bitstream_buffers_in_decoder_.find(presentation_timestamp); |
| + |
| + if (it == bitstream_buffers_in_decoder_.end()) { |
| media_codec_->ReleaseOutputBuffer(buf_index, false); |
| base::MessageLoop::current()->PostTask( |
| FROM_HERE, |
| base::Bind(&AndroidVideoDecodeAccelerator::NotifyFlushDone, |
| weak_this_factory_.GetWeakPtr())); |
| } else { |
| - // Get the bitstream buffer id from the timestamp. |
| - auto it = bitstream_buffers_in_decoder_.find(presentation_timestamp); |
| - // Require the decoder to output at most one frame for each distinct input |
| - // buffer timestamp. A VP9 alt ref frame is a case where an input buffer, |
| - // with a possibly unique timestamp, will not result in a corresponding |
| - // output frame. |
| - CHECK(it != bitstream_buffers_in_decoder_.end()) |
| - << "Unexpected output frame timestamp"; |
| const int32 bitstream_buffer_id = it->second; |
| bitstream_buffers_in_decoder_.erase(bitstream_buffers_in_decoder_.begin(), |
| ++it); |