Index: media/gpu/fake_jpeg_decode_accelerator.cc |
diff --git a/media/gpu/fake_jpeg_decode_accelerator.cc b/media/gpu/fake_jpeg_decode_accelerator.cc |
new file mode 100644 |
index 0000000000000000000000000000000000000000..cfaba2b7bb89b41e7ea4e143d89da4234adfa0bd |
--- /dev/null |
+++ b/media/gpu/fake_jpeg_decode_accelerator.cc |
@@ -0,0 +1,103 @@ |
+// Copyright 2017 The Chromium Authors. All rights reserved. |
+// Use of this source code is governed by a BSD-style license that can be |
+// found in the LICENSE file. |
+ |
+#include "media/gpu/fake_jpeg_decode_accelerator.h" |
+ |
+#include "base/bind.h" |
+#include "base/single_thread_task_runner.h" |
+#include "base/threading/thread_task_runner_handle.h" |
+#include "media/gpu/shared_memory_region.h" |
+ |
+namespace media { |
+ |
+FakeJpegDecodeAccelerator::FakeJpegDecodeAccelerator( |
+ const scoped_refptr<base::SingleThreadTaskRunner>& io_task_runner) |
+ : client_task_runner_(base::ThreadTaskRunnerHandle::Get()), |
+ io_task_runner_(std::move(io_task_runner)), |
+ decoder_thread_("FakeJpegDecoderThread"), |
+ weak_factory_(this) {} |
+ |
+FakeJpegDecodeAccelerator::~FakeJpegDecodeAccelerator() { |
+ DCHECK(client_task_runner_->BelongsToCurrentThread()); |
+} |
+ |
+bool FakeJpegDecodeAccelerator::Initialize( |
+ JpegDecodeAccelerator::Client* client) { |
+ DCHECK(client_task_runner_->BelongsToCurrentThread()); |
+ client_ = client; |
+ |
+ if (!decoder_thread_.Start()) { |
+ DLOG(ERROR) << "Failed to start decoding thread."; |
+ return false; |
+ } |
+ decoder_task_runner_ = decoder_thread_.task_runner(); |
+ |
+ return true; |
+} |
+ |
+void FakeJpegDecodeAccelerator::Decode( |
+ const BitstreamBuffer& bitstream_buffer, |
+ const scoped_refptr<VideoFrame>& video_frame) { |
+ DCHECK(io_task_runner_->BelongsToCurrentThread()); |
+ |
+ // SharedMemoryRegion will take over the |bitstream_buffer.handle()|. |
+ std::unique_ptr<SharedMemoryRegion> src_shm( |
+ new SharedMemoryRegion(bitstream_buffer, true)); |
+ if (!src_shm->Map()) { |
+ DLOG(ERROR) << "Unable to map shared memory in FakeJpegDecodeAccelerator"; |
+ NotifyError(bitstream_buffer.id(), JpegDecodeAccelerator::UNREADABLE_INPUT); |
+ return; |
+ } |
+ |
+ // Unretained |this| is safe because |this| owns |decoder_thread_|. |
+ decoder_task_runner_->PostTask( |
+ FROM_HERE, base::Bind(&FakeJpegDecodeAccelerator::DecodeOnDecoderThread, |
+ base::Unretained(this), bitstream_buffer, |
+ video_frame, base::Passed(&src_shm))); |
+} |
+ |
+void FakeJpegDecodeAccelerator::DecodeOnDecoderThread( |
+ const BitstreamBuffer& bitstream_buffer, |
+ const scoped_refptr<VideoFrame>& video_frame, |
+ std::unique_ptr<SharedMemoryRegion> src_shm) { |
+ DCHECK(decoder_task_runner_->BelongsToCurrentThread()); |
+ |
+ // Do not actually decode the Jpeg data. |
+ // Instead, just fill the output buffer with zeros. |
+ size_t allocation_size = |
+ VideoFrame::AllocationSize(PIXEL_FORMAT_I420, video_frame->coded_size()); |
+ memset(video_frame->data(0), 0, allocation_size); |
+ |
+ client_task_runner_->PostTask( |
+ FROM_HERE, |
+ base::Bind(&FakeJpegDecodeAccelerator::OnDecodeDoneOnClientThread, |
+ weak_factory_.GetWeakPtr(), bitstream_buffer.id())); |
+} |
+ |
+bool FakeJpegDecodeAccelerator::IsSupported() { |
+ return true; |
+} |
+ |
+void FakeJpegDecodeAccelerator::NotifyError(int32_t bitstream_buffer_id, |
+ Error error) { |
+ client_task_runner_->PostTask( |
+ FROM_HERE, |
+ base::Bind(&FakeJpegDecodeAccelerator::NotifyErrorOnClientThread, |
+ weak_factory_.GetWeakPtr(), bitstream_buffer_id, error)); |
+} |
+ |
+void FakeJpegDecodeAccelerator::NotifyErrorOnClientThread( |
+ int32_t bitstream_buffer_id, |
+ Error error) { |
+ DCHECK(client_task_runner_->BelongsToCurrentThread()); |
+ client_->NotifyError(bitstream_buffer_id, error); |
+} |
+ |
+void FakeJpegDecodeAccelerator::OnDecodeDoneOnClientThread( |
+ int32_t input_buffer_id) { |
+ DCHECK(client_task_runner_->BelongsToCurrentThread()); |
+ client_->VideoFrameReady(input_buffer_id); |
+} |
+ |
+} // namespace media |