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

Side by Side Diff: media/gpu/ipc/service/gpu_video_encode_accelerator.cc

Issue 2427053002: Move video encode accelerator IPC messages to GPU IO thread (Closed)
Patch Set: posciak@ comments. Created 4 years, 1 month 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
1 // Copyright 2013 The Chromium Authors. All rights reserved. 1 // Copyright 2013 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 #include "media/gpu/ipc/service/gpu_video_encode_accelerator.h" 5 #include "media/gpu/ipc/service/gpu_video_encode_accelerator.h"
6 6
7 #include <memory> 7 #include <memory>
8 8
9 #include "base/callback.h" 9 #include "base/callback.h"
10 #include "base/command_line.h" 10 #include "base/command_line.h"
11 #include "base/logging.h" 11 #include "base/logging.h"
12 #include "base/memory/ptr_util.h" 12 #include "base/memory/ptr_util.h"
13 #include "base/memory/shared_memory.h" 13 #include "base/memory/shared_memory.h"
14 #include "base/numerics/safe_math.h" 14 #include "base/numerics/safe_math.h"
15 #include "base/sys_info.h" 15 #include "base/sys_info.h"
16 #include "base/trace_event/trace_event.h"
16 #include "build/build_config.h" 17 #include "build/build_config.h"
17 #include "gpu/ipc/service/gpu_channel.h" 18 #include "gpu/ipc/service/gpu_channel.h"
18 #include "gpu/ipc/service/gpu_channel_manager.h" 19 #include "gpu/ipc/service/gpu_channel_manager.h"
19 #include "ipc/ipc_message_macros.h" 20 #include "ipc/ipc_message_macros.h"
20 #include "media/base/bind_to_current_loop.h" 21 #include "media/base/bind_to_current_loop.h"
21 #include "media/base/limits.h" 22 #include "media/base/limits.h"
22 #include "media/base/video_frame.h" 23 #include "media/base/video_frame.h"
23 #include "media/gpu/gpu_video_accelerator_util.h" 24 #include "media/gpu/gpu_video_accelerator_util.h"
24 #include "media/gpu/ipc/common/media_messages.h" 25 #include "media/gpu/ipc/common/media_messages.h"
25 26
(...skipping 66 matching lines...) Expand 10 before | Expand all | Expand 10 after
92 93
93 #if defined(OS_WIN) 94 #if defined(OS_WIN)
94 std::unique_ptr<VideoEncodeAccelerator> CreateMediaFoundationVEA() { 95 std::unique_ptr<VideoEncodeAccelerator> CreateMediaFoundationVEA() {
95 return base::WrapUnique<media::VideoEncodeAccelerator>( 96 return base::WrapUnique<media::VideoEncodeAccelerator>(
96 new MediaFoundationVideoEncodeAccelerator()); 97 new MediaFoundationVideoEncodeAccelerator());
97 } 98 }
98 #endif 99 #endif
99 100
100 } // anonymous namespace 101 } // anonymous namespace
101 102
103 class GpuVideoEncodeAccelerator::MessageFilter : public IPC::MessageFilter {
104 public:
105 MessageFilter(GpuVideoEncodeAccelerator* owner, int32_t host_route_id)
106 : owner_(owner), host_route_id_(host_route_id), sender_(nullptr) {}
107
108 void OnChannelError() override { sender_ = nullptr; }
109
110 void OnChannelClosing() override { sender_ = nullptr; }
111
112 void OnFilterAdded(IPC::Channel* channel) override { sender_ = channel; }
113
114 void OnFilterRemoved() override { owner_->OnFilterRemoved(); }
115
116 bool OnMessageReceived(const IPC::Message& msg) override {
117 if (msg.routing_id() != host_route_id_)
118 return false;
119
120 IPC_BEGIN_MESSAGE_MAP(MessageFilter, msg)
121 IPC_MESSAGE_FORWARD(AcceleratedVideoEncoderMsg_Encode, owner_,
122 GpuVideoEncodeAccelerator::OnEncode)
123 IPC_MESSAGE_FORWARD(AcceleratedVideoEncoderMsg_UseOutputBitstreamBuffer,
124 owner_,
125 GpuVideoEncodeAccelerator::OnUseOutputBitstreamBuffer)
126 IPC_MESSAGE_FORWARD(
127 AcceleratedVideoEncoderMsg_RequestEncodingParametersChange, owner_,
128 GpuVideoEncodeAccelerator::OnRequestEncodingParametersChange)
129 IPC_MESSAGE_UNHANDLED(return false)
130 IPC_END_MESSAGE_MAP()
131 return true;
132 }
133
134 bool SendOnIOThread(IPC::Message* message) {
135 if (!sender_ || message->is_sync()) {
136 delete message;
137 DCHECK(!message->is_sync());
Pawel Osciak 2016/10/27 01:45:19 We just deleted message...
emircan 2016/10/27 17:53:30 Thanks for the notice. I just swapped the lines.
138 return false;
139 }
140 return sender_->Send(message);
141 }
142
143 protected:
144 ~MessageFilter() override {}
145
146 private:
147 GpuVideoEncodeAccelerator* const owner_;
148 const int32_t host_route_id_;
149 // The sender to which this filter was added.
150 IPC::Sender* sender_;
151
152 DISALLOW_COPY_AND_ASSIGN(MessageFilter);
153 };
154
102 GpuVideoEncodeAccelerator::GpuVideoEncodeAccelerator( 155 GpuVideoEncodeAccelerator::GpuVideoEncodeAccelerator(
103 int32_t host_route_id, 156 int32_t host_route_id,
104 gpu::GpuCommandBufferStub* stub) 157 gpu::GpuCommandBufferStub* stub,
158 const scoped_refptr<base::SingleThreadTaskRunner>& io_task_runner)
105 : host_route_id_(host_route_id), 159 : host_route_id_(host_route_id),
106 stub_(stub), 160 stub_(stub),
107 input_format_(PIXEL_FORMAT_UNKNOWN), 161 input_format_(PIXEL_FORMAT_UNKNOWN),
108 output_buffer_size_(0), 162 output_buffer_size_(0),
163 filter_removed_(base::WaitableEvent::ResetPolicy::MANUAL,
164 base::WaitableEvent::InitialState::NOT_SIGNALED),
165 main_task_runner_(base::ThreadTaskRunnerHandle::Get()),
166 io_task_runner_(io_task_runner),
109 weak_this_factory_(this) { 167 weak_this_factory_(this) {
110 stub_->AddDestructionObserver(this); 168 stub_->AddDestructionObserver(this);
111 make_context_current_ = 169 make_context_current_ =
112 base::Bind(&MakeDecoderContextCurrent, stub_->AsWeakPtr()); 170 base::Bind(&MakeDecoderContextCurrent, stub_->AsWeakPtr());
113 } 171 }
114 172
115 GpuVideoEncodeAccelerator::~GpuVideoEncodeAccelerator() { 173 GpuVideoEncodeAccelerator::~GpuVideoEncodeAccelerator() {
116 // This class can only be self-deleted from OnWillDestroyStub(), which means 174 // This class can only be self-deleted from OnWillDestroyStub(), which means
117 // the VEA has already been destroyed in there. 175 // the VEA has already been destroyed in there.
118 DCHECK(!encoder_); 176 DCHECK(!encoder_);
119 } 177 }
120 178
121 bool GpuVideoEncodeAccelerator::Initialize(VideoPixelFormat input_format, 179 bool GpuVideoEncodeAccelerator::Initialize(VideoPixelFormat input_format,
122 const gfx::Size& input_visible_size, 180 const gfx::Size& input_visible_size,
123 VideoCodecProfile output_profile, 181 VideoCodecProfile output_profile,
124 uint32_t initial_bitrate) { 182 uint32_t initial_bitrate) {
125 DVLOG(1) << __FUNCTION__ 183 DCHECK(main_task_runner_->BelongsToCurrentThread());
184 DVLOG(1) << __func__
126 << " input_format=" << VideoPixelFormatToString(input_format) 185 << " input_format=" << VideoPixelFormatToString(input_format)
127 << ", input_visible_size=" << input_visible_size.ToString() 186 << ", input_visible_size=" << input_visible_size.ToString()
128 << ", output_profile=" << GetProfileName(output_profile) 187 << ", output_profile=" << GetProfileName(output_profile)
129 << ", initial_bitrate=" << initial_bitrate; 188 << ", initial_bitrate=" << initial_bitrate;
130 DCHECK(!encoder_); 189 DCHECK(!encoder_);
131 190
132 if (!stub_->channel()->AddRoute(host_route_id_, stub_->stream_id(), this)) { 191 if (!stub_->channel()->AddRoute(host_route_id_, stub_->stream_id(), this)) {
133 DLOG(ERROR) << __FUNCTION__ << " failed to add route"; 192 DLOG(ERROR) << __func__ << " failed to add route";
134 return false; 193 return false;
135 } 194 }
136 195
137 if (input_visible_size.width() > limits::kMaxDimension || 196 if (input_visible_size.width() > limits::kMaxDimension ||
138 input_visible_size.height() > limits::kMaxDimension || 197 input_visible_size.height() > limits::kMaxDimension ||
139 input_visible_size.GetArea() > limits::kMaxCanvas) { 198 input_visible_size.GetArea() > limits::kMaxCanvas) {
140 DLOG(ERROR) << __FUNCTION__ << "too large input_visible_size " 199 DLOG(ERROR) << __func__ << "too large input_visible_size "
141 << input_visible_size.ToString(); 200 << input_visible_size.ToString();
142 return false; 201 return false;
143 } 202 }
144 203
145 const gpu::GpuPreferences& gpu_preferences = 204 const gpu::GpuPreferences& gpu_preferences =
146 stub_->channel()->gpu_channel_manager()->gpu_preferences(); 205 stub_->channel()->gpu_channel_manager()->gpu_preferences();
147 206
148 // Try all possible encoders and use the first successful encoder. 207 // Try all possible encoders and use the first successful encoder.
149 for (const auto& factory_function : GetVEAFactoryFunctions(gpu_preferences)) { 208 for (const auto& factory_function : GetVEAFactoryFunctions(gpu_preferences)) {
150 encoder_ = factory_function.Run(); 209 encoder_ = factory_function.Run();
151 if (encoder_ && 210 if (encoder_ &&
152 encoder_->Initialize(input_format, input_visible_size, output_profile, 211 encoder_->Initialize(input_format, input_visible_size, output_profile,
153 initial_bitrate, this)) { 212 initial_bitrate, this)) {
154 input_format_ = input_format; 213 input_format_ = input_format;
155 input_visible_size_ = input_visible_size; 214 input_visible_size_ = input_visible_size;
215 // Attempt to set up performing encoding tasks on IO thread, if supported
216 // by the VEA.
217 if (encoder_->TryToSetupEncodeOnSeparateThread(
218 weak_this_factory_.GetWeakPtr(), io_task_runner_)) {
219 filter_ = new MessageFilter(this, host_route_id_);
220 stub_->channel()->AddFilter(filter_.get());
221 }
156 return true; 222 return true;
157 } 223 }
158 } 224 }
159 encoder_.reset(); 225 encoder_.reset();
160 DLOG(ERROR) << __FUNCTION__ << " VEA initialization failed"; 226 DLOG(ERROR) << __func__ << " VEA initialization failed";
161 return false; 227 return false;
162 } 228 }
163 229
164 bool GpuVideoEncodeAccelerator::OnMessageReceived(const IPC::Message& message) { 230 bool GpuVideoEncodeAccelerator::OnMessageReceived(const IPC::Message& message) {
165 bool handled = true; 231 bool handled = true;
166 IPC_BEGIN_MESSAGE_MAP(GpuVideoEncodeAccelerator, message) 232 IPC_BEGIN_MESSAGE_MAP(GpuVideoEncodeAccelerator, message)
167 IPC_MESSAGE_HANDLER(AcceleratedVideoEncoderMsg_Encode, OnEncode) 233 IPC_MESSAGE_HANDLER(AcceleratedVideoEncoderMsg_Encode, OnEncode)
168 IPC_MESSAGE_HANDLER(AcceleratedVideoEncoderMsg_UseOutputBitstreamBuffer, 234 IPC_MESSAGE_HANDLER(AcceleratedVideoEncoderMsg_UseOutputBitstreamBuffer,
169 OnUseOutputBitstreamBuffer) 235 OnUseOutputBitstreamBuffer)
170 IPC_MESSAGE_HANDLER( 236 IPC_MESSAGE_HANDLER(
171 AcceleratedVideoEncoderMsg_RequestEncodingParametersChange, 237 AcceleratedVideoEncoderMsg_RequestEncodingParametersChange,
172 OnRequestEncodingParametersChange) 238 OnRequestEncodingParametersChange)
173 IPC_MESSAGE_HANDLER(AcceleratedVideoEncoderMsg_Destroy, OnDestroy) 239 IPC_MESSAGE_HANDLER(AcceleratedVideoEncoderMsg_Destroy, OnDestroy)
174 IPC_MESSAGE_UNHANDLED(handled = false) 240 IPC_MESSAGE_UNHANDLED(handled = false)
175 IPC_END_MESSAGE_MAP() 241 IPC_END_MESSAGE_MAP()
176 return handled; 242 return handled;
177 } 243 }
178 244
179 void GpuVideoEncodeAccelerator::RequireBitstreamBuffers( 245 void GpuVideoEncodeAccelerator::RequireBitstreamBuffers(
180 unsigned int input_count, 246 unsigned int input_count,
181 const gfx::Size& input_coded_size, 247 const gfx::Size& input_coded_size,
182 size_t output_buffer_size) { 248 size_t output_buffer_size) {
183 Send(new AcceleratedVideoEncoderHostMsg_RequireBitstreamBuffers( 249 DCHECK(main_task_runner_->BelongsToCurrentThread());
184 host_route_id_, input_count, input_coded_size, output_buffer_size)); 250 if (!Send(new AcceleratedVideoEncoderHostMsg_RequireBitstreamBuffers(
251 host_route_id_, input_count, input_coded_size, output_buffer_size))) {
252 DLOG(ERROR) << __func__ << " failed.";
253 }
185 input_coded_size_ = input_coded_size; 254 input_coded_size_ = input_coded_size;
186 output_buffer_size_ = output_buffer_size; 255 output_buffer_size_ = output_buffer_size;
187 } 256 }
188 257
189 void GpuVideoEncodeAccelerator::BitstreamBufferReady( 258 void GpuVideoEncodeAccelerator::BitstreamBufferReady(
190 int32_t bitstream_buffer_id, 259 int32_t bitstream_buffer_id,
191 size_t payload_size, 260 size_t payload_size,
192 bool key_frame, 261 bool key_frame,
193 base::TimeDelta timestamp) { 262 base::TimeDelta timestamp) {
194 Send(new AcceleratedVideoEncoderHostMsg_BitstreamBufferReady( 263 DCHECK(CheckIfCalledOnCorrectThread());
195 host_route_id_, bitstream_buffer_id, payload_size, key_frame, timestamp)); 264 if (!Send(new AcceleratedVideoEncoderHostMsg_BitstreamBufferReady(
265 host_route_id_, bitstream_buffer_id, payload_size, key_frame,
266 timestamp))) {
267 DLOG(ERROR) << __func__ << " failed.";
268 }
196 } 269 }
197 270
198 void GpuVideoEncodeAccelerator::NotifyError( 271 void GpuVideoEncodeAccelerator::NotifyError(
199 VideoEncodeAccelerator::Error error) { 272 VideoEncodeAccelerator::Error error) {
200 Send(new AcceleratedVideoEncoderHostMsg_NotifyError(host_route_id_, error)); 273 DCHECK(main_task_runner_->BelongsToCurrentThread());
274 if (!Send(new AcceleratedVideoEncoderHostMsg_NotifyError(host_route_id_,
275 error))) {
276 DLOG(ERROR) << __func__ << " failed.";
277 }
201 } 278 }
202 279
203 void GpuVideoEncodeAccelerator::OnWillDestroyStub() { 280 void GpuVideoEncodeAccelerator::OnWillDestroyStub() {
281 DVLOG(2) << __func__;
282 DCHECK(main_task_runner_->BelongsToCurrentThread());
204 DCHECK(stub_); 283 DCHECK(stub_);
284
285 // The stub is going away, so we have to stop and destroy VEA here before
286 // returning. We cannot destroy the VEA before the IO thread message filter is
287 // removed however, since we cannot service incoming messages with VEA gone.
288 // We cannot simply check for existence of VEA on IO thread though, because
289 // we don't want to synchronize the IO thread with the ChildThread.
290 // So we have to wait for the RemoveFilter callback here instead and remove
291 // the VEA after it arrives and before returning.
292 if (filter_) {
293 stub_->channel()->RemoveFilter(filter_.get());
294 filter_removed_.Wait();
295 }
296
205 stub_->channel()->RemoveRoute(host_route_id_); 297 stub_->channel()->RemoveRoute(host_route_id_);
206 stub_->RemoveDestructionObserver(this); 298 stub_->RemoveDestructionObserver(this);
207 encoder_.reset(); 299 encoder_.reset();
208 delete this; 300 delete this;
209 } 301 }
210 302
211 // static 303 // static
212 gpu::VideoEncodeAcceleratorSupportedProfiles 304 gpu::VideoEncodeAcceleratorSupportedProfiles
213 GpuVideoEncodeAccelerator::GetSupportedProfiles( 305 GpuVideoEncodeAccelerator::GetSupportedProfiles(
214 const gpu::GpuPreferences& gpu_preferences) { 306 const gpu::GpuPreferences& gpu_preferences) {
215 VideoEncodeAccelerator::SupportedProfiles profiles; 307 VideoEncodeAccelerator::SupportedProfiles profiles;
216 308
217 for (const auto& factory_function : GetVEAFactoryFunctions(gpu_preferences)) { 309 for (const auto& factory_function : GetVEAFactoryFunctions(gpu_preferences)) {
218 std::unique_ptr<VideoEncodeAccelerator> encoder = factory_function.Run(); 310 std::unique_ptr<VideoEncodeAccelerator> encoder = factory_function.Run();
219 if (!encoder) 311 if (!encoder)
220 continue; 312 continue;
221 VideoEncodeAccelerator::SupportedProfiles vea_profiles = 313 VideoEncodeAccelerator::SupportedProfiles vea_profiles =
222 encoder->GetSupportedProfiles(); 314 encoder->GetSupportedProfiles();
223 GpuVideoAcceleratorUtil::InsertUniqueEncodeProfiles(vea_profiles, 315 GpuVideoAcceleratorUtil::InsertUniqueEncodeProfiles(vea_profiles,
224 &profiles); 316 &profiles);
225 } 317 }
226 return GpuVideoAcceleratorUtil::ConvertMediaToGpuEncodeProfiles(profiles); 318 return GpuVideoAcceleratorUtil::ConvertMediaToGpuEncodeProfiles(profiles);
227 } 319 }
228 320
321 void GpuVideoEncodeAccelerator::OnFilterRemoved() {
322 DVLOG(2) << __func__;
323
324 // We're destroying; cancel all callbacks.
325 weak_this_factory_.InvalidateWeakPtrs();
326 filter_removed_.Signal();
327 }
328
229 // static 329 // static
230 std::vector<GpuVideoEncodeAccelerator::VEAFactoryFunction> 330 std::vector<GpuVideoEncodeAccelerator::VEAFactoryFunction>
231 GpuVideoEncodeAccelerator::GetVEAFactoryFunctions( 331 GpuVideoEncodeAccelerator::GetVEAFactoryFunctions(
232 const gpu::GpuPreferences& gpu_preferences) { 332 const gpu::GpuPreferences& gpu_preferences) {
233 std::vector<VEAFactoryFunction> vea_factory_functions; 333 std::vector<VEAFactoryFunction> vea_factory_functions;
234 #if defined(OS_CHROMEOS) && defined(USE_V4L2_CODEC) 334 #if defined(OS_CHROMEOS) && defined(USE_V4L2_CODEC)
235 vea_factory_functions.push_back(base::Bind(&CreateV4L2VEA)); 335 vea_factory_functions.push_back(base::Bind(&CreateV4L2VEA));
236 #endif 336 #endif
237 #if defined(OS_CHROMEOS) && defined(ARCH_CPU_X86_FAMILY) 337 #if defined(OS_CHROMEOS) && defined(ARCH_CPU_X86_FAMILY)
238 if (!gpu_preferences.disable_vaapi_accelerated_video_encode) 338 if (!gpu_preferences.disable_vaapi_accelerated_video_encode)
239 vea_factory_functions.push_back(base::Bind(&CreateVaapiVEA)); 339 vea_factory_functions.push_back(base::Bind(&CreateVaapiVEA));
240 #endif 340 #endif
241 #if defined(OS_ANDROID) && defined(ENABLE_WEBRTC) 341 #if defined(OS_ANDROID) && defined(ENABLE_WEBRTC)
242 if (!gpu_preferences.disable_web_rtc_hw_encoding) 342 if (!gpu_preferences.disable_web_rtc_hw_encoding)
243 vea_factory_functions.push_back(base::Bind(&CreateAndroidVEA)); 343 vea_factory_functions.push_back(base::Bind(&CreateAndroidVEA));
244 #endif 344 #endif
245 #if defined(OS_MACOSX) 345 #if defined(OS_MACOSX)
246 vea_factory_functions.push_back(base::Bind(&CreateVTVEA)); 346 vea_factory_functions.push_back(base::Bind(&CreateVTVEA));
247 #endif 347 #endif
248 #if defined(OS_WIN) 348 #if defined(OS_WIN)
249 if (base::FeatureList::IsEnabled(kMediaFoundationH264Encoding)) 349 if (base::FeatureList::IsEnabled(kMediaFoundationH264Encoding))
250 vea_factory_functions.push_back(base::Bind(&CreateMediaFoundationVEA)); 350 vea_factory_functions.push_back(base::Bind(&CreateMediaFoundationVEA));
251 #endif 351 #endif
252 return vea_factory_functions; 352 return vea_factory_functions;
253 } 353 }
254 354
255 void GpuVideoEncodeAccelerator::OnEncode( 355 void GpuVideoEncodeAccelerator::OnEncode(
256 const AcceleratedVideoEncoderMsg_Encode_Params& params) { 356 const AcceleratedVideoEncoderMsg_Encode_Params& params) {
257 DVLOG(3) << __FUNCTION__ << " frame_id = " << params.frame_id 357 DVLOG(3) << __func__ << " frame_id = " << params.frame_id
258 << ", buffer_size=" << params.buffer_size 358 << ", buffer_size=" << params.buffer_size
259 << ", force_keyframe=" << params.force_keyframe; 359 << ", force_keyframe=" << params.force_keyframe;
360 DCHECK(CheckIfCalledOnCorrectThread());
260 DCHECK_EQ(PIXEL_FORMAT_I420, input_format_); 361 DCHECK_EQ(PIXEL_FORMAT_I420, input_format_);
362 TRACE_EVENT0("gpu", "GpuVideoEncodeAccelerator::OnEncode");
261 363
262 // Wrap into a SharedMemory in the beginning, so that |params.buffer_handle| 364 // Wrap into a SharedMemory in the beginning, so that |params.buffer_handle|
263 // is cleaned properly in case of an early return. 365 // is cleaned properly in case of an early return.
264 std::unique_ptr<base::SharedMemory> shm( 366 std::unique_ptr<base::SharedMemory> shm(
265 new base::SharedMemory(params.buffer_handle, true)); 367 new base::SharedMemory(params.buffer_handle, true));
266 368
267 if (!encoder_) 369 if (!encoder_)
268 return; 370 return;
269 371
270 if (params.frame_id < 0) { 372 if (params.frame_id < 0) {
271 DLOG(ERROR) << __FUNCTION__ << " invalid frame_id=" << params.frame_id; 373 DLOG(ERROR) << __func__ << " invalid frame_id=" << params.frame_id;
272 NotifyError(VideoEncodeAccelerator::kPlatformFailureError); 374 NotifyError(VideoEncodeAccelerator::kPlatformFailureError);
273 return; 375 return;
274 } 376 }
275 377
276 const uint32_t aligned_offset = 378 const uint32_t aligned_offset =
277 params.buffer_offset % base::SysInfo::VMAllocationGranularity(); 379 params.buffer_offset % base::SysInfo::VMAllocationGranularity();
278 base::CheckedNumeric<off_t> map_offset = params.buffer_offset; 380 base::CheckedNumeric<off_t> map_offset = params.buffer_offset;
279 map_offset -= aligned_offset; 381 map_offset -= aligned_offset;
280 base::CheckedNumeric<size_t> map_size = params.buffer_size; 382 base::CheckedNumeric<size_t> map_size = params.buffer_size;
281 map_size += aligned_offset; 383 map_size += aligned_offset;
282 384
283 if (!map_offset.IsValid() || !map_size.IsValid()) { 385 if (!map_offset.IsValid() || !map_size.IsValid()) {
284 DLOG(ERROR) << __FUNCTION__ << " invalid map_offset or map_size"; 386 DLOG(ERROR) << __func__ << " invalid map_offset or map_size";
285 NotifyError(VideoEncodeAccelerator::kPlatformFailureError); 387 NotifyError(VideoEncodeAccelerator::kPlatformFailureError);
286 return; 388 return;
287 } 389 }
288 390
289 if (!shm->MapAt(map_offset.ValueOrDie(), map_size.ValueOrDie())) { 391 if (!shm->MapAt(map_offset.ValueOrDie(), map_size.ValueOrDie())) {
290 DLOG(ERROR) << __FUNCTION__ 392 DLOG(ERROR) << __func__ << " could not map frame_id=" << params.frame_id;
291 << " could not map frame_id=" << params.frame_id;
292 NotifyError(VideoEncodeAccelerator::kPlatformFailureError); 393 NotifyError(VideoEncodeAccelerator::kPlatformFailureError);
293 return; 394 return;
294 } 395 }
295 396
296 uint8_t* shm_memory = 397 uint8_t* shm_memory =
297 reinterpret_cast<uint8_t*>(shm->memory()) + aligned_offset; 398 reinterpret_cast<uint8_t*>(shm->memory()) + aligned_offset;
298 scoped_refptr<VideoFrame> frame = VideoFrame::WrapExternalSharedMemory( 399 scoped_refptr<VideoFrame> frame = VideoFrame::WrapExternalSharedMemory(
299 input_format_, input_coded_size_, gfx::Rect(input_visible_size_), 400 input_format_, input_coded_size_, gfx::Rect(input_visible_size_),
300 input_visible_size_, shm_memory, params.buffer_size, params.buffer_handle, 401 input_visible_size_, shm_memory, params.buffer_size, params.buffer_handle,
301 params.buffer_offset, params.timestamp); 402 params.buffer_offset, params.timestamp);
302 if (!frame) { 403 if (!frame) {
303 DLOG(ERROR) << __FUNCTION__ << " could not create a frame"; 404 DLOG(ERROR) << __func__ << " could not create a frame";
304 NotifyError(VideoEncodeAccelerator::kPlatformFailureError); 405 NotifyError(VideoEncodeAccelerator::kPlatformFailureError);
305 return; 406 return;
306 } 407 }
307 frame->AddDestructionObserver(BindToCurrentLoop(base::Bind( 408 frame->AddDestructionObserver(BindToCurrentLoop(base::Bind(
308 &GpuVideoEncodeAccelerator::EncodeFrameFinished, 409 &GpuVideoEncodeAccelerator::EncodeFrameFinished,
309 weak_this_factory_.GetWeakPtr(), params.frame_id, base::Passed(&shm)))); 410 weak_this_factory_.GetWeakPtr(), params.frame_id, base::Passed(&shm))));
310 encoder_->Encode(frame, params.force_keyframe); 411 encoder_->Encode(frame, params.force_keyframe);
311 } 412 }
312 413
313 void GpuVideoEncodeAccelerator::OnUseOutputBitstreamBuffer( 414 void GpuVideoEncodeAccelerator::OnUseOutputBitstreamBuffer(
314 int32_t buffer_id, 415 int32_t buffer_id,
315 base::SharedMemoryHandle buffer_handle, 416 base::SharedMemoryHandle buffer_handle,
316 uint32_t buffer_size) { 417 uint32_t buffer_size) {
317 DVLOG(3) << __FUNCTION__ << " buffer_id=" << buffer_id 418 DVLOG(3) << __func__ << " buffer_id=" << buffer_id
318 << ", buffer_size=" << buffer_size; 419 << ", buffer_size=" << buffer_size;
420 DCHECK(CheckIfCalledOnCorrectThread());
319 if (!encoder_) 421 if (!encoder_)
320 return; 422 return;
321 if (buffer_id < 0) { 423 if (buffer_id < 0) {
322 DLOG(ERROR) << __FUNCTION__ << " invalid buffer_id=" << buffer_id; 424 DLOG(ERROR) << __func__ << " invalid buffer_id=" << buffer_id;
323 NotifyError(VideoEncodeAccelerator::kPlatformFailureError); 425 NotifyError(VideoEncodeAccelerator::kPlatformFailureError);
324 return; 426 return;
325 } 427 }
326 if (buffer_size < output_buffer_size_) { 428 if (buffer_size < output_buffer_size_) {
327 DLOG(ERROR) << __FUNCTION__ 429 DLOG(ERROR) << __func__ << " buffer too small for buffer_id=" << buffer_id;
328 << " buffer too small for buffer_id=" << buffer_id;
329 NotifyError(VideoEncodeAccelerator::kPlatformFailureError); 430 NotifyError(VideoEncodeAccelerator::kPlatformFailureError);
330 return; 431 return;
331 } 432 }
332 encoder_->UseOutputBitstreamBuffer( 433 encoder_->UseOutputBitstreamBuffer(
333 BitstreamBuffer(buffer_id, buffer_handle, buffer_size)); 434 BitstreamBuffer(buffer_id, buffer_handle, buffer_size));
334 } 435 }
335 436
336 void GpuVideoEncodeAccelerator::OnDestroy() { 437 void GpuVideoEncodeAccelerator::OnDestroy() {
337 DVLOG(2) << __FUNCTION__; 438 DVLOG(2) << __func__;
439 DCHECK(main_task_runner_->BelongsToCurrentThread());
338 OnWillDestroyStub(); 440 OnWillDestroyStub();
339 } 441 }
340 442
341 void GpuVideoEncodeAccelerator::OnRequestEncodingParametersChange( 443 void GpuVideoEncodeAccelerator::OnRequestEncodingParametersChange(
342 uint32_t bitrate, 444 uint32_t bitrate,
343 uint32_t framerate) { 445 uint32_t framerate) {
344 DVLOG(2) << __FUNCTION__ << " bitrate=" << bitrate 446 DVLOG(2) << __func__ << " bitrate=" << bitrate << ", framerate=" << framerate;
345 << ", framerate=" << framerate; 447 DCHECK(CheckIfCalledOnCorrectThread());
346 if (!encoder_) 448 if (!encoder_)
347 return; 449 return;
348 encoder_->RequestEncodingParametersChange(bitrate, framerate); 450 encoder_->RequestEncodingParametersChange(bitrate, framerate);
349 } 451 }
350 452
351 void GpuVideoEncodeAccelerator::EncodeFrameFinished( 453 void GpuVideoEncodeAccelerator::EncodeFrameFinished(
352 int32_t frame_id, 454 int32_t frame_id,
353 std::unique_ptr<base::SharedMemory> shm) { 455 std::unique_ptr<base::SharedMemory> shm) {
354 Send(new AcceleratedVideoEncoderHostMsg_NotifyInputDone(host_route_id_, 456 DCHECK(CheckIfCalledOnCorrectThread());
355 frame_id)); 457 if (!Send(new AcceleratedVideoEncoderHostMsg_NotifyInputDone(host_route_id_,
458 frame_id))) {
459 DLOG(ERROR) << __func__ << " failed.";
460 }
356 // Just let |shm| fall out of scope. 461 // Just let |shm| fall out of scope.
357 } 462 }
358 463
359 void GpuVideoEncodeAccelerator::Send(IPC::Message* message) { 464 bool GpuVideoEncodeAccelerator::Send(IPC::Message* message) {
360 stub_->channel()->Send(message); 465 if (filter_ && io_task_runner_->BelongsToCurrentThread()) {
466 return filter_->SendOnIOThread(message);
467 }
468 DCHECK(main_task_runner_->BelongsToCurrentThread());
469 return stub_->channel()->Send(message);
470 }
471
472 bool GpuVideoEncodeAccelerator::CheckIfCalledOnCorrectThread() {
473 return (filter_ && io_task_runner_->BelongsToCurrentThread()) ||
474 (!filter_ && main_task_runner_->BelongsToCurrentThread());
361 } 475 }
362 476
363 } // namespace media 477 } // namespace media
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698