diff options
author | Allan Sandfeld Jensen <allan.jensen@qt.io> | 2018-10-24 11:30:15 +0200 |
---|---|---|
committer | Allan Sandfeld Jensen <allan.jensen@qt.io> | 2018-10-30 12:56:19 +0000 |
commit | 6036726eb981b6c4b42047513b9d3f4ac865daac (patch) | |
tree | 673593e70678e7789766d1f732eb51f613a2703b /chromium/media/gpu/android/codec_wrapper.cc | |
parent | 466052c4e7c052268fd931888cd58961da94c586 (diff) | |
download | qtwebengine-chromium-6036726eb981b6c4b42047513b9d3f4ac865daac.tar.gz |
BASELINE: Update Chromium to 70.0.3538.78
Change-Id: Ie634710bf039e26c1957f4ae45e101bd4c434ae7
Reviewed-by: Michael BrĂ¼ning <michael.bruning@qt.io>
Diffstat (limited to 'chromium/media/gpu/android/codec_wrapper.cc')
-rw-r--r-- | chromium/media/gpu/android/codec_wrapper.cc | 71 |
1 files changed, 59 insertions, 12 deletions
diff --git a/chromium/media/gpu/android/codec_wrapper.cc b/chromium/media/gpu/android/codec_wrapper.cc index 7d851d1a369..77a8dc25e4c 100644 --- a/chromium/media/gpu/android/codec_wrapper.cc +++ b/chromium/media/gpu/android/codec_wrapper.cc @@ -23,8 +23,10 @@ namespace media { // CodecOutputBuffer are the only two things that hold references to it. class CodecWrapperImpl : public base::RefCountedThreadSafe<CodecWrapperImpl> { public: - CodecWrapperImpl(CodecSurfacePair codec_surface_pair, - base::Closure output_buffer_release_cb); + CodecWrapperImpl( + CodecSurfacePair codec_surface_pair, + CodecWrapper::OutputReleasedCB output_buffer_release_cb, + scoped_refptr<base::SequencedTaskRunner> release_task_runner); using DequeueStatus = CodecWrapper::DequeueStatus; using QueueStatus = CodecWrapper::QueueStatus; @@ -89,12 +91,16 @@ class CodecWrapperImpl : public base::RefCountedThreadSafe<CodecWrapperImpl> { // A callback that's called whenever an output buffer is released back to the // codec. - base::Closure output_buffer_release_cb_; + CodecWrapper::OutputReleasedCB output_buffer_release_cb_; // Do we owe the client an EOS in DequeueOutput, due to an eos that we elided // while we're already flushed? bool elided_eos_pending_ = false; + // Task runner on which we'll release codec buffers without rendering. May be + // null to always do this on the calling task runner. + scoped_refptr<base::SequencedTaskRunner> release_task_runner_; + DISALLOW_COPY_AND_ASSIGN(CodecWrapperImpl); }; @@ -104,20 +110,28 @@ CodecOutputBuffer::CodecOutputBuffer(scoped_refptr<CodecWrapperImpl> codec, : codec_(std::move(codec)), id_(id), size_(size) {} CodecOutputBuffer::~CodecOutputBuffer() { - codec_->ReleaseCodecOutputBuffer(id_, false); + // While it will work if we re-release the buffer, since CodecWrapper handles + // it properly, we can save a lock + (possibly) post by checking here if we + // know that it has been rendered already. + if (!was_rendered_) + codec_->ReleaseCodecOutputBuffer(id_, false); } bool CodecOutputBuffer::ReleaseToSurface() { + was_rendered_ = true; return codec_->ReleaseCodecOutputBuffer(id_, true); } -CodecWrapperImpl::CodecWrapperImpl(CodecSurfacePair codec_surface_pair, - base::Closure output_buffer_release_cb) +CodecWrapperImpl::CodecWrapperImpl( + CodecSurfacePair codec_surface_pair, + CodecWrapper::OutputReleasedCB output_buffer_release_cb, + scoped_refptr<base::SequencedTaskRunner> release_task_runner) : state_(State::kFlushed), codec_(std::move(codec_surface_pair.first)), surface_bundle_(std::move(codec_surface_pair.second)), next_buffer_id_(0), - output_buffer_release_cb_(std::move(output_buffer_release_cb)) { + output_buffer_release_cb_(std::move(output_buffer_release_cb)), + release_task_runner_(std::move(release_task_runner)) { DVLOG(2) << __func__; } @@ -364,6 +378,34 @@ scoped_refptr<AVDASurfaceBundle> CodecWrapperImpl::SurfaceBundle() { } bool CodecWrapperImpl::ReleaseCodecOutputBuffer(int64_t id, bool render) { + if (!render && release_task_runner_ && + !release_task_runner_->RunsTasksInCurrentSequence()) { + // Note that this can only delay releases, but that won't ultimately change + // the ordering at the codec, assuming that releases / renders originate + // from the same thread. + // + // We know that a render call that happens before a release call will still + // run before the release's posted task, since it happens before we even + // post it. + // + // Similarly, renders are kept in order with each other. + // + // It is possible that a render happens before the posted task(s) of some + // earlier release(s) (with no intervening renders, since those are + // ordered). In this case, though, the loop below will still release + // everything earlier than the rendered buffer, so the codec still sees the + // same sequence of calls -- some releases follwed by a render. + // + // Of course, if releases and renders are posted from different threads, + // then it's unclear what the ordering was anyway. + release_task_runner_->PostTask( + FROM_HERE, + base::BindOnce( + base::IgnoreResult(&CodecWrapperImpl::ReleaseCodecOutputBuffer), + this, id, render)); + return true; + } + base::AutoLock l(lock_); if (!codec_ || state_ == State::kError) return false; @@ -386,15 +428,20 @@ bool CodecWrapperImpl::ReleaseCodecOutputBuffer(int64_t id, bool render) { int index = buffer_it->second; codec_->ReleaseOutputBuffer(index, render); buffer_ids_.erase(buffer_ids_.begin(), buffer_it + 1); - if (output_buffer_release_cb_) - output_buffer_release_cb_.Run(); + if (output_buffer_release_cb_) { + output_buffer_release_cb_.Run(state_ == State::kDrained || + state_ == State::kDraining); + } return true; } -CodecWrapper::CodecWrapper(CodecSurfacePair codec_surface_pair, - base::Closure output_buffer_release_cb) +CodecWrapper::CodecWrapper( + CodecSurfacePair codec_surface_pair, + OutputReleasedCB output_buffer_release_cb, + scoped_refptr<base::SequencedTaskRunner> release_task_runner) : impl_(new CodecWrapperImpl(std::move(codec_surface_pair), - std::move(output_buffer_release_cb))) {} + std::move(output_buffer_release_cb), + std::move(release_task_runner))) {} CodecWrapper::~CodecWrapper() { // The codec must have already been taken. |