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

Unified Diff: chrome/renderer/gpu_video_decoder_host.cc

Issue 2873089: media: gpu process ipc video decoder implementation (Closed) Base URL: http://src.chromium.org/svn/trunk/src/
Patch Set: remove mft Created 10 years, 4 months 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 side-by-side diff with in-line comments
Download patch
« no previous file with comments | « chrome/renderer/gpu_video_decoder_host.h ('k') | chrome/renderer/gpu_video_service_host.h » ('j') | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: chrome/renderer/gpu_video_decoder_host.cc
diff --git a/chrome/renderer/gpu_video_decoder_host.cc b/chrome/renderer/gpu_video_decoder_host.cc
new file mode 100644
index 0000000000000000000000000000000000000000..5e0f727695bc8ce7220de87fba88c9d8b5ac590e
--- /dev/null
+++ b/chrome/renderer/gpu_video_decoder_host.cc
@@ -0,0 +1,199 @@
+// Copyright (c) 2010 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 "chrome/renderer/gpu_video_decoder_host.h"
+
+#include "chrome/common/gpu_messages.h"
+#include "chrome/renderer/gpu_video_service_host.h"
+#include "chrome/renderer/render_thread.h"
+
+void GpuVideoDecoderHost::OnChannelError() {
+ channel_host_.release();
+}
+
+void GpuVideoDecoderHost::OnMessageReceived(const IPC::Message& msg) {
+ IPC_BEGIN_MESSAGE_MAP(GpuVideoDecoderHost, msg)
+ IPC_MESSAGE_HANDLER(GpuVideoDecoderHostMsg_InitializeACK,
+ OnInitializeDone)
+ IPC_MESSAGE_HANDLER(GpuVideoDecoderHostMsg_DestroyACK,
+ OnUninitializeDone)
+ IPC_MESSAGE_HANDLER(GpuVideoDecoderHostMsg_FlushACK,
+ OnFlushDone)
+ IPC_MESSAGE_HANDLER(GpuVideoDecoderHostMsg_EmptyThisBufferACK,
+ OnEmptyThisBufferACK)
+ IPC_MESSAGE_HANDLER(GpuVideoDecoderHostMsg_EmptyThisBufferDone,
+ OnEmptyThisBufferDone)
+ IPC_MESSAGE_HANDLER(GpuVideoDecoderHostMsg_FillThisBufferDone,
+ OnFillThisBufferDone)
+ IPC_MESSAGE_UNHANDLED_ERROR()
+ IPC_END_MESSAGE_MAP()
+}
+
+bool GpuVideoDecoderHost::Initialize(const GpuVideoDecoderInitParam& param) {
+ DCHECK_EQ(state_, kStateUninitialized);
+
+ init_param_ = param;
+ if (!channel_host_->Send(
+ new GpuVideoDecoderMsg_Initialize(route_id(), param))) {
+ LOG(ERROR) << "GpuVideoDecoderMsg_Initialize failed";
+ return false;
+ }
+ return true;
+}
+
+bool GpuVideoDecoderHost::Uninitialize() {
+ if (!channel_host_->Send(new GpuVideoDecoderMsg_Destroy(route_id()))) {
+ LOG(ERROR) << "GpuVideoDecoderMsg_Destroy failed";
+ return false;
+ }
+ return true;
+}
+
+void GpuVideoDecoderHost::EmptyThisBuffer(scoped_refptr<Buffer> buffer) {
+ DCHECK_NE(state_, kStateUninitialized);
+ DCHECK_NE(state_, kStateFlushing);
+
+ // We never own input buffers, therefore when client in flush state, it
+ // never call us with EmptyThisBuffer.
+ if (state_ != kStateNormal)
+ return;
+
+ input_buffer_queue_.push_back(buffer);
+ SendInputBufferToGpu();
+}
+
+void GpuVideoDecoderHost::FillThisBuffer(scoped_refptr<VideoFrame> frame) {
+ DCHECK_NE(state_, kStateUninitialized);
+
+ // Depends on who provides buffer. client could return buffer to
+ // us while flushing.
+ if (state_ == kStateError)
+ return;
+
+ GpuVideoDecoderOutputBufferParam param;
+ if (!channel_host_->Send(
+ new GpuVideoDecoderMsg_FillThisBuffer(route_id(), param))) {
+ LOG(ERROR) << "GpuVideoDecoderMsg_FillThisBuffer failed";
+ }
+}
+
+bool GpuVideoDecoderHost::Flush() {
+ state_ = kStateFlushing;
+ if (!channel_host_->Send(new GpuVideoDecoderMsg_Flush(route_id()))) {
+ LOG(ERROR) << "GpuVideoDecoderMsg_Flush failed";
+ return false;
+ }
+ input_buffer_queue_.clear();
+ // TODO(jiesun): because GpuVideoDeocder/GpuVideoDecoder are asynchronously.
+ // We need a way to make flush logic more clear. but I think ring buffer
+ // should make the busy flag obsolete, therefore I will leave it for now.
+ input_buffer_busy_ = false;
+ return true;
+}
+
+void GpuVideoDecoderHost::OnInitializeDone(
+ const GpuVideoDecoderInitDoneParam& param) {
+ done_param_ = param;
+ bool success = false;
+
+ do {
+ if (!param.success_)
+ break;
+
+ if (!base::SharedMemory::IsHandleValid(param.input_buffer_handle_))
+ break;
+ input_transfer_buffer_.reset(
+ new base::SharedMemory(param.input_buffer_handle_, false));
+ if (!input_transfer_buffer_->Map(param.input_buffer_size_))
+ break;
+
+ if (!base::SharedMemory::IsHandleValid(param.output_buffer_handle_))
+ break;
+ output_transfer_buffer_.reset(
+ new base::SharedMemory(param.output_buffer_handle_, false));
+ if (!output_transfer_buffer_->Map(param.output_buffer_size_))
+ break;
+
+ success = true;
+ } while (0);
+
+ state_ = success ? kStateNormal : kStateError;
+ event_handler_->OnInitializeDone(success, param);
+}
+
+void GpuVideoDecoderHost::OnUninitializeDone() {
+ input_transfer_buffer_.reset();
+ output_transfer_buffer_.reset();
+
+ event_handler_->OnUninitializeDone();
+}
+
+void GpuVideoDecoderHost::OnFlushDone() {
+ state_ = kStateNormal;
+ event_handler_->OnFlushDone();
+}
+
+void GpuVideoDecoderHost::OnEmptyThisBufferDone() {
+ scoped_refptr<Buffer> buffer;
+ event_handler_->OnEmptyBufferDone(buffer);
+}
+
+void GpuVideoDecoderHost::OnFillThisBufferDone(
+ const GpuVideoDecoderOutputBufferParam& param) {
+ scoped_refptr<VideoFrame> frame;
+
+ if (param.flags_ & GpuVideoDecoderOutputBufferParam::kFlagsEndOfStream) {
+ VideoFrame::CreateEmptyFrame(&frame);
+ } else {
+ VideoFrame::CreateFrame(VideoFrame::YV12,
+ init_param_.width_,
+ init_param_.height_,
+ base::TimeDelta::FromMicroseconds(param.timestamp_),
+ base::TimeDelta::FromMicroseconds(param.duration_),
+ &frame);
+
+ uint8* src = static_cast<uint8*>(output_transfer_buffer_->memory());
+ uint8* data0 = frame->data(0);
+ uint8* data1 = frame->data(1);
+ uint8* data2 = frame->data(2);
+ int32 size = init_param_.width_ * init_param_.height_;
+ memcpy(data0, src, size);
+ memcpy(data1, src + size, size / 4);
+ memcpy(data2, src + size + size / 4, size / 4);
+ }
+
+ event_handler_->OnFillBufferDone(frame);
+ if (!channel_host_->Send(
+ new GpuVideoDecoderMsg_FillThisBufferDoneACK(route_id()))) {
+ LOG(ERROR) << "GpuVideoDecoderMsg_FillThisBufferDoneACK failed";
+ }
+}
+
+void GpuVideoDecoderHost::OnEmptyThisBufferACK() {
+ input_buffer_busy_ = false;
+ SendInputBufferToGpu();
+}
+
+void GpuVideoDecoderHost::SendInputBufferToGpu() {
+ if (input_buffer_busy_) return;
+ if (input_buffer_queue_.empty()) return;
+
+ input_buffer_busy_ = true;
+
+ scoped_refptr<Buffer> buffer;
+ buffer = input_buffer_queue_.front();
+ input_buffer_queue_.pop_front();
+
+ // Send input data to GPU process.
+ GpuVideoDecoderInputBufferParam param;
+ param.offset_ = 0;
+ param.size_ = buffer->GetDataSize();
+ param.timestamp_ = buffer->GetTimestamp().InMicroseconds();
+ memcpy(input_transfer_buffer_->memory(), buffer->GetData(), param.size_);
+ if (!channel_host_->Send(
+ new GpuVideoDecoderMsg_EmptyThisBuffer(route_id(), param))) {
+ LOG(ERROR) << "GpuVideoDecoderMsg_EmptyThisBuffer failed";
+ }
+}
+
« no previous file with comments | « chrome/renderer/gpu_video_decoder_host.h ('k') | chrome/renderer/gpu_video_service_host.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698