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

Side by Side Diff: content/common/gpu/client/gpu_video_encode_accelerator_host.cc

Issue 20632002: Add media::VideoEncodeAccelerator with WebRTC integration (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@git-svn
Patch Set: d3982027 CQ nits. Created 7 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 unified diff | Download patch
OLDNEW
(Empty)
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
3 // found in the LICENSE file.
4
5 #include "content/common/gpu/client/gpu_video_encode_accelerator_host.h"
6
7 #include "base/logging.h"
8 #include "base/message_loop/message_loop_proxy.h"
9 #include "content/common/gpu/client/gpu_channel_host.h"
10 #include "content/common/gpu/gpu_messages.h"
11 #include "content/common/gpu/media/gpu_video_encode_accelerator.h"
12 #include "media/base/video_frame.h"
13
14 namespace content {
15
16 GpuVideoEncodeAcceleratorHost::GpuVideoEncodeAcceleratorHost(
17 media::VideoEncodeAccelerator::Client* client,
18 const scoped_refptr<GpuChannelHost>& gpu_channel_host,
19 int32 route_id)
20 : client_(client),
21 client_ptr_factory_(client_),
22 channel_(gpu_channel_host),
23 route_id_(route_id),
24 next_frame_id_(0) {
25 channel_->AddRoute(route_id_, AsWeakPtr());
26 }
27
28 GpuVideoEncodeAcceleratorHost::~GpuVideoEncodeAcceleratorHost() {
29 if (channel_)
30 channel_->RemoveRoute(route_id_);
31 }
32
33 // static
34 std::vector<media::VideoEncodeAccelerator::SupportedProfile>
35 GpuVideoEncodeAcceleratorHost::GetSupportedProfiles() {
36 return GpuVideoEncodeAccelerator::GetSupportedProfiles();
37 }
38
39 bool GpuVideoEncodeAcceleratorHost::OnMessageReceived(
40 const IPC::Message& message) {
41 bool handled = true;
42 IPC_BEGIN_MESSAGE_MAP(GpuVideoEncodeAcceleratorHost, message)
43 IPC_MESSAGE_HANDLER(AcceleratedVideoEncoderHostMsg_NotifyInitializeDone,
44 OnNotifyInitializeDone)
45 IPC_MESSAGE_HANDLER(AcceleratedVideoEncoderHostMsg_RequireBitstreamBuffers,
46 OnRequireBitstreamBuffers)
47 IPC_MESSAGE_HANDLER(AcceleratedVideoEncoderHostMsg_NotifyInputDone,
48 OnNotifyInputDone)
49 IPC_MESSAGE_HANDLER(AcceleratedVideoEncoderHostMsg_BitstreamBufferReady,
50 OnBitstreamBufferReady)
51 IPC_MESSAGE_HANDLER(AcceleratedVideoEncoderHostMsg_NotifyError,
52 OnNotifyError)
53 IPC_MESSAGE_UNHANDLED(handled = false)
54 IPC_END_MESSAGE_MAP()
55 DCHECK(handled);
56 return handled;
57 }
58
59 void GpuVideoEncodeAcceleratorHost::OnChannelError() {
60 DLOG(ERROR) << "OnChannelError()";
61 OnNotifyError(kPlatformFailureError);
62 if (channel_) {
63 channel_->RemoveRoute(route_id_);
64 channel_ = NULL;
65 }
66 }
67
68 void GpuVideoEncodeAcceleratorHost::Initialize(
69 media::VideoFrame::Format input_format,
70 const gfx::Size& input_visible_size,
71 media::VideoCodecProfile output_profile,
72 uint32 initial_bitrate) {
73 Send(new AcceleratedVideoEncoderMsg_Initialize(route_id_,
74 input_format,
75 input_visible_size,
76 output_profile,
77 initial_bitrate));
78 }
79
80 void GpuVideoEncodeAcceleratorHost::Encode(
81 const scoped_refptr<media::VideoFrame>& frame,
82 bool force_keyframe) {
83 if (!channel_)
84 return;
85 if (!base::SharedMemory::IsHandleValid(frame->shared_memory_handle())) {
86 DLOG(ERROR) << "Encode(): cannot encode frame not backed by shared memory";
87 NotifyError(kPlatformFailureError);
88 return;
89 }
90 base::SharedMemoryHandle handle =
91 channel_->ShareToGpuProcess(frame->shared_memory_handle());
92 if (!base::SharedMemory::IsHandleValid(handle)) {
93 DLOG(ERROR) << "Encode(): failed to duplicate buffer handle for GPU "
94 "process";
95 NotifyError(kPlatformFailureError);
96 return;
97 }
98
99 // We assume that planar frame data passed here is packed and contiguous.
100 const size_t plane_count = media::VideoFrame::NumPlanes(frame->format());
101 size_t frame_size = 0;
102 for (size_t i = 0; i < plane_count; ++i) {
103 // Cast DCHECK parameters to void* to avoid printing uint8* as a string.
104 DCHECK_EQ(reinterpret_cast<void*>(frame->data(i)),
105 reinterpret_cast<void*>((frame->data(0) + frame_size)))
106 << "plane=" << i;
107 frame_size += frame->stride(i) * frame->rows(i);
108 }
109
110 Send(new AcceleratedVideoEncoderMsg_Encode(
111 route_id_, next_frame_id_, handle, frame_size, force_keyframe));
112 frame_map_[next_frame_id_] = frame;
113
114 // Mask against 30 bits, to avoid (undefined) wraparound on signed integer.
115 next_frame_id_ = (next_frame_id_ + 1) & 0x3FFFFFFF;
116 }
117
118 void GpuVideoEncodeAcceleratorHost::UseOutputBitstreamBuffer(
119 const media::BitstreamBuffer& buffer) {
120 if (!channel_)
121 return;
122 base::SharedMemoryHandle handle =
123 channel_->ShareToGpuProcess(buffer.handle());
124 if (!base::SharedMemory::IsHandleValid(handle)) {
125 DLOG(ERROR) << "UseOutputBitstreamBuffer(): failed to duplicate buffer "
126 "handle for GPU process: buffer.id()=" << buffer.id();
127 NotifyError(kPlatformFailureError);
128 return;
129 }
130 Send(new AcceleratedVideoEncoderMsg_UseOutputBitstreamBuffer(
131 route_id_, buffer.id(), handle, buffer.size()));
132 }
133
134 void GpuVideoEncodeAcceleratorHost::RequestEncodingParametersChange(
135 uint32 bitrate,
136 uint32 framerate) {
137 Send(new AcceleratedVideoEncoderMsg_RequestEncodingParametersChange(
138 route_id_, bitrate, framerate));
139 }
140
141 void GpuVideoEncodeAcceleratorHost::Destroy() {
142 Send(new GpuChannelMsg_DestroyVideoEncoder(route_id_));
143 delete this;
144 }
145
146 void GpuVideoEncodeAcceleratorHost::NotifyError(Error error) {
147 DVLOG(2) << "NotifyError(): error=" << error;
148 base::MessageLoopProxy::current()->PostTask(
149 FROM_HERE,
150 base::Bind(&media::VideoEncodeAccelerator::Client::NotifyError,
151 client_ptr_factory_.GetWeakPtr(),
152 error));
153 }
154
155 void GpuVideoEncodeAcceleratorHost::OnNotifyInitializeDone() {
156 DVLOG(2) << "OnNotifyInitializeDone()";
157 if (client_)
158 client_->NotifyInitializeDone();
159 }
160
161 void GpuVideoEncodeAcceleratorHost::OnRequireBitstreamBuffers(
162 uint32 input_count,
163 const gfx::Size& input_coded_size,
164 uint32 output_buffer_size) {
165 DVLOG(2) << "OnRequireBitstreamBuffers(): input_count=" << input_count
166 << ", input_coded_size=" << input_coded_size.ToString()
167 << ", output_buffer_size=" << output_buffer_size;
168 if (client_) {
169 client_->RequireBitstreamBuffers(
170 input_count, input_coded_size, output_buffer_size);
171 }
172 }
173
174 void GpuVideoEncodeAcceleratorHost::OnNotifyInputDone(int32 frame_id) {
175 DVLOG(3) << "OnNotifyInputDone(): frame_id=" << frame_id;
176 if (!frame_map_.erase(frame_id)) {
177 DLOG(ERROR) << "OnNotifyInputDone(): "
178 "invalid frame_id=" << frame_id;
179 OnNotifyError(kPlatformFailureError);
180 return;
181 }
182 }
183
184 void GpuVideoEncodeAcceleratorHost::OnBitstreamBufferReady(
185 int32 bitstream_buffer_id,
186 uint32 payload_size,
187 bool key_frame) {
188 DVLOG(3) << "OnBitstreamBufferReady(): "
189 "bitstream_buffer_id=" << bitstream_buffer_id
190 << ", payload_size=" << payload_size
191 << ", key_frame=" << key_frame;
192 if (client_)
193 client_->BitstreamBufferReady(bitstream_buffer_id, payload_size, key_frame);
194 }
195
196 void GpuVideoEncodeAcceleratorHost::OnNotifyError(Error error) {
197 DVLOG(2) << "OnNotifyError(): error=" << error;
198 if (client_) {
199 client_->NotifyError(error);
200 client_ = NULL;
201 client_ptr_factory_.InvalidateWeakPtrs();
202 }
203 }
204
205 void GpuVideoEncodeAcceleratorHost::Send(IPC::Message* message) {
206 if (!channel_) {
207 DLOG(ERROR) << "Send(): no channel";
208 delete message;
209 NotifyError(kPlatformFailureError);
210 } else if (!channel_->Send(message)) {
211 DLOG(ERROR) << "Send(): sending failed: message->type()="
212 << message->type();
213 NotifyError(kPlatformFailureError);
214 }
215 }
216
217 } // namespace content
OLDNEW
« no previous file with comments | « content/common/gpu/client/gpu_video_encode_accelerator_host.h ('k') | content/common/gpu/gpu_channel.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698