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

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: 7dec70f6 Whoops, one last linker thing I missed 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 "content/common/gpu/client/gpu_channel_host.h"
9 #include "content/common/gpu/gpu_messages.h"
10 #include "content/common/gpu/media/gpu_video_encode_accelerator.h"
11 #include "media/base/video_frame.h"
12
13 namespace content {
14
15 GpuVideoEncodeAcceleratorHost::GpuVideoEncodeAcceleratorHost(
16 media::VideoEncodeAccelerator::Client* client,
17 const scoped_refptr<GpuChannelHost>& gpu_channel_host,
18 int32 route_id)
19 : client_(client),
20 channel_(gpu_channel_host),
21 route_id_(route_id),
22 next_frame_id_(0) {
23 channel_->AddRoute(route_id_, AsWeakPtr());
24 }
25
26 GpuVideoEncodeAcceleratorHost::~GpuVideoEncodeAcceleratorHost() {
27 if (channel_)
28 channel_->RemoveRoute(route_id_);
29 }
30
31 // static
32 std::vector<media::VideoEncodeAccelerator::SupportedProfile>
33 GpuVideoEncodeAcceleratorHost::GetSupportedProfiles() {
34 return GpuVideoEncodeAccelerator::GetSupportedProfiles();
35 }
36
37 bool GpuVideoEncodeAcceleratorHost::OnMessageReceived(
38 const IPC::Message& message) {
39 bool handled = true;
40 IPC_BEGIN_MESSAGE_MAP(GpuVideoEncodeAcceleratorHost, message)
41 IPC_MESSAGE_HANDLER(AcceleratedVideoEncoderHostMsg_NotifyInitializeDone,
42 OnNotifyInitializeDone)
43 IPC_MESSAGE_HANDLER(AcceleratedVideoEncoderHostMsg_RequireBitstreamBuffers,
44 OnRequireBitstreamBuffers)
45 IPC_MESSAGE_HANDLER(AcceleratedVideoEncoderHostMsg_NotifyInputDone,
46 OnNotifyInputDone)
47 IPC_MESSAGE_HANDLER(AcceleratedVideoEncoderHostMsg_BitstreamBufferReady,
48 OnBitstreamBufferReady)
49 IPC_MESSAGE_HANDLER(AcceleratedVideoEncoderHostMsg_NotifyError,
50 OnNotifyError)
51 IPC_MESSAGE_UNHANDLED(handled = false)
52 IPC_END_MESSAGE_MAP()
53 DCHECK(handled);
54 return handled;
55 }
56
57 void GpuVideoEncodeAcceleratorHost::OnChannelError() {
58 DLOG(ERROR) << "OnChannelError()";
59 OnNotifyError(kPlatformFailureError);
60 if (channel_) {
61 channel_->RemoveRoute(route_id_);
62 channel_ = NULL;
63 }
64 }
65
66 void GpuVideoEncodeAcceleratorHost::Initialize(
67 media::VideoFrame::Format input_format,
68 const gfx::Size& input_visible_size,
69 media::VideoCodecProfile output_profile,
70 int32 initial_bitrate) {
71 if (!channel_)
72 return;
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 OnNotifyError(kPlatformFailureError);
88 }
89 base::SharedMemoryHandle handle =
90 channel_->ShareToGpuProcess(frame->shared_memory_handle());
91 if (!base::SharedMemory::IsHandleValid(handle)) {
92 DLOG(ERROR) << "Encode(): failed to duplicate buffer handle for GPU "
93 "process";
94 OnNotifyError(kPlatformFailureError);
95 return;
96 }
97
98 // We assume that planar frame data passed here is packed and contiguous.
99 const size_t plane_count = media::VideoFrame::NumPlanes(frame->format());
100 size_t frame_size = 0;
101 for (size_t i = 0; i < plane_count; ++i) {
102 // Cast DCHECK parameters to void* to avoid printing uint8* as a string.
103 DCHECK_EQ(reinterpret_cast<void*>(frame->data(i)),
104 reinterpret_cast<void*>((frame->data(0) + frame_size)))
105 << "plane=" << i;
106 frame_size += frame->stride(i) * frame->rows(i);
107 }
108
109 Send(new AcceleratedVideoEncoderMsg_Encode(
110 route_id_, next_frame_id_, handle, frame_size, force_keyframe));
111 frame_map_[next_frame_id_] = frame;
112
113 // Mask against 30 bits, to avoid (undefined) wraparound on signed integer.
piman 2013/08/09 04:04:58 why not use unsigned?
sheu 2013/08/09 08:26:41 Generally using negative values as error condition
114 next_frame_id_ = (next_frame_id_ + 1) & 0x3FFFFFFF;
115 }
116
117 void GpuVideoEncodeAcceleratorHost::UseOutputBitstreamBuffer(
118 const media::BitstreamBuffer& buffer) {
119 if (!channel_)
120 return;
121 base::SharedMemoryHandle handle =
122 channel_->ShareToGpuProcess(buffer.handle());
123 if (!base::SharedMemory::IsHandleValid(handle)) {
124 DLOG(ERROR) << "UseOutputBitstreamBuffer(): failed to duplicate buffer "
125 "handle for GPU process: buffer.id()=" << buffer.id();
126 OnNotifyError(kPlatformFailureError);
127 return;
128 }
129 Send(new AcceleratedVideoEncoderMsg_UseOutputBitstreamBuffer(
130 route_id_, buffer.id(), handle, buffer.size()));
131 }
132
133 void GpuVideoEncodeAcceleratorHost::RequestEncodingParametersChange(
134 int32 bitrate,
135 uint32 framerate) {
136 if (!channel_)
137 return;
138 Send(new AcceleratedVideoEncoderMsg_RequestEncodingParametersChange(
139 route_id_, bitrate, framerate));
140 }
141
142 void GpuVideoEncodeAcceleratorHost::Destroy() {
143 if (channel_)
144 Send(new GpuChannelMsg_DestroyVideoEncoder(route_id_));
145 delete this;
146 }
147
148 void GpuVideoEncodeAcceleratorHost::OnNotifyInitializeDone() {
149 DVLOG(2) << "OnNotifyInitializeDone()";
150 if (client_)
151 client_->NotifyInitializeDone();
152 }
153
154 void GpuVideoEncodeAcceleratorHost::OnRequireBitstreamBuffers(
155 int input_count,
156 const gfx::Size& input_coded_size,
157 uint32 output_buffer_size) {
158 DVLOG(2) << "OnRequireBitstreamBuffers(): input_count=" << input_count
159 << ", input_coded_size=" << input_coded_size.ToString()
160 << ", output_buffer_size=" << output_buffer_size;
161 if (client_) {
162 client_->RequireBitstreamBuffers(
163 input_count, input_coded_size, output_buffer_size);
164 }
165 }
166
167 void GpuVideoEncodeAcceleratorHost::OnNotifyInputDone(int32 frame_id) {
168 DVLOG(3) << "OnNotifyInputDone(): frame_id=" << frame_id;
169 if (!frame_map_.erase(frame_id)) {
170 DLOG(ERROR) << "OnNotifyInputDone(): "
171 "invalid frame_id=" << frame_id;
172 OnNotifyError(kPlatformFailureError);
173 return;
174 }
175 }
176
177 void GpuVideoEncodeAcceleratorHost::OnBitstreamBufferReady(
178 int32 bitstream_buffer_id,
179 uint32 payload_size,
180 bool key_frame) {
181 DVLOG(3) << "OnBitstreamBufferReady(): "
182 "bitstream_buffer_id=" << bitstream_buffer_id
183 << ", payload_size=" << payload_size
184 << ", key_frame=" << key_frame;
185 if (client_)
186 client_->BitstreamBufferReady(bitstream_buffer_id, payload_size, key_frame);
187 }
188
189 void GpuVideoEncodeAcceleratorHost::OnNotifyError(Error error) {
190 DVLOG(2) << "OnNotifyError(): error=" << error;
191 if (client_) {
192 client_->NotifyError(error);
193 client_ = NULL;
194 }
195 }
196
197 void GpuVideoEncodeAcceleratorHost::Send(IPC::Message* message) {
198 if (!channel_) {
piman 2013/08/09 04:04:58 I think all the callers are checking channel_ anyw
sheu 2013/08/09 08:26:41 All things considered, I think we should remove th
199 DLOG(ERROR) << "Send(): no channel";
200 delete message;
201 return;
202 OnNotifyError(kPlatformFailureError);
piman 2013/08/09 04:04:58 dead code (after return). Do you need the explici
sheu 2013/08/09 08:26:41 Done.
203 } else if (!channel_->Send(message)) {
204 DLOG(ERROR) << "Send(): sending failed: message->type()="
205 << message->type();
206 OnNotifyError(kPlatformFailureError);
207 return;
piman 2013/08/09 04:04:58 same here, do you need the explicit return?
sheu 2013/08/09 08:26:41 Done.
208 }
209 }
210
211 } // namespace content
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698