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

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: Fix log order. 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"
(...skipping 81 matching lines...) Expand 10 before | Expand all | Expand 10 after
92 92
93 #if defined(OS_WIN) 93 #if defined(OS_WIN)
94 std::unique_ptr<VideoEncodeAccelerator> CreateMediaFoundationVEA() { 94 std::unique_ptr<VideoEncodeAccelerator> CreateMediaFoundationVEA() {
95 return base::WrapUnique<media::VideoEncodeAccelerator>( 95 return base::WrapUnique<media::VideoEncodeAccelerator>(
96 new MediaFoundationVideoEncodeAccelerator()); 96 new MediaFoundationVideoEncodeAccelerator());
97 } 97 }
98 #endif 98 #endif
99 99
100 } // anonymous namespace 100 } // anonymous namespace
101 101
102 class GpuVideoEncodeAccelerator::MessageFilter : public IPC::MessageFilter {
103 public:
104 MessageFilter(GpuVideoEncodeAccelerator* owner, int32_t host_route_id)
105 : owner_(owner), host_route_id_(host_route_id) {}
106
107 void OnChannelError() override { sender_ = NULL; }
Pawel Osciak 2016/10/25 01:44:04 sender_ = nullptr; and similarly below please.
emircan 2016/10/25 21:57:51 Done.
108
109 void OnChannelClosing() override { sender_ = NULL; }
110
111 void OnFilterAdded(IPC::Channel* channel) override { sender_ = channel; }
112
113 void OnFilterRemoved() override { owner_->OnFilterRemoved(); }
114
115 bool OnMessageReceived(const IPC::Message& msg) override {
116 if (msg.routing_id() != host_route_id_)
117 return false;
118
119 IPC_BEGIN_MESSAGE_MAP(MessageFilter, msg)
120 IPC_MESSAGE_FORWARD(AcceleratedVideoEncoderMsg_Encode, owner_,
121 GpuVideoEncodeAccelerator::OnEncode)
122 IPC_MESSAGE_FORWARD(AcceleratedVideoEncoderMsg_UseOutputBitstreamBuffer,
123 owner_,
124 GpuVideoEncodeAccelerator::OnUseOutputBitstreamBuffer)
125 IPC_MESSAGE_FORWARD(
126 AcceleratedVideoEncoderMsg_RequestEncodingParametersChange, owner_,
127 GpuVideoEncodeAccelerator::OnRequestEncodingParametersChange)
128 IPC_MESSAGE_UNHANDLED(return false)
129 IPC_END_MESSAGE_MAP()
130 return true;
131 }
132
133 bool SendOnIOThread(IPC::Message* message) {
134 CHECK(!message->is_sync());
Pawel Osciak 2016/10/25 01:44:05 Perhaps DCHECK and return false to avoid crashing
emircan 2016/10/25 21:57:50 I merged this error case with l.135 and made it a
135 if (!sender_) {
136 delete message;
137 return false;
138 }
139 return sender_->Send(message);
140 }
141
142 protected:
143 ~MessageFilter() override {}
144
145 private:
146 GpuVideoEncodeAccelerator* const owner_;
147 const int32_t host_route_id_;
148 // The sender to which this filter was added.
149 IPC::Sender* sender_;
Pawel Osciak 2016/10/25 01:44:04 = nullptr ?
emircan 2016/10/25 21:57:50 Added to the initializer list.
150 };
Pawel Osciak 2016/10/25 01:44:04 Should we also have some DISALLOW_COPY_AND_ASSIGN
emircan 2016/10/25 21:57:50 Done.
151
102 GpuVideoEncodeAccelerator::GpuVideoEncodeAccelerator( 152 GpuVideoEncodeAccelerator::GpuVideoEncodeAccelerator(
103 int32_t host_route_id, 153 int32_t host_route_id,
104 gpu::GpuCommandBufferStub* stub) 154 gpu::GpuCommandBufferStub* stub,
155 const scoped_refptr<base::SingleThreadTaskRunner>& io_task_runner)
105 : host_route_id_(host_route_id), 156 : host_route_id_(host_route_id),
106 stub_(stub), 157 stub_(stub),
107 input_format_(PIXEL_FORMAT_UNKNOWN), 158 input_format_(PIXEL_FORMAT_UNKNOWN),
108 output_buffer_size_(0), 159 output_buffer_size_(0),
160 filter_removed_(base::WaitableEvent::ResetPolicy::MANUAL,
161 base::WaitableEvent::InitialState::NOT_SIGNALED),
162 main_task_runner_(base::ThreadTaskRunnerHandle::Get()),
163 io_task_runner_(io_task_runner),
109 weak_this_factory_(this) { 164 weak_this_factory_(this) {
110 stub_->AddDestructionObserver(this); 165 stub_->AddDestructionObserver(this);
111 make_context_current_ = 166 make_context_current_ =
112 base::Bind(&MakeDecoderContextCurrent, stub_->AsWeakPtr()); 167 base::Bind(&MakeDecoderContextCurrent, stub_->AsWeakPtr());
113 } 168 }
114 169
115 GpuVideoEncodeAccelerator::~GpuVideoEncodeAccelerator() { 170 GpuVideoEncodeAccelerator::~GpuVideoEncodeAccelerator() {
116 // This class can only be self-deleted from OnWillDestroyStub(), which means 171 // This class can only be self-deleted from OnWillDestroyStub(), which means
117 // the VEA has already been destroyed in there. 172 // the VEA has already been destroyed in there.
118 DCHECK(!encoder_); 173 DCHECK(!encoder_);
119 } 174 }
120 175
121 bool GpuVideoEncodeAccelerator::Initialize(VideoPixelFormat input_format, 176 bool GpuVideoEncodeAccelerator::Initialize(VideoPixelFormat input_format,
122 const gfx::Size& input_visible_size, 177 const gfx::Size& input_visible_size,
123 VideoCodecProfile output_profile, 178 VideoCodecProfile output_profile,
124 uint32_t initial_bitrate) { 179 uint32_t initial_bitrate) {
125 DVLOG(1) << __FUNCTION__ 180 DCHECK(main_task_runner_->BelongsToCurrentThread());
181 DVLOG(1) << __func__
126 << " input_format=" << VideoPixelFormatToString(input_format) 182 << " input_format=" << VideoPixelFormatToString(input_format)
127 << ", input_visible_size=" << input_visible_size.ToString() 183 << ", input_visible_size=" << input_visible_size.ToString()
128 << ", output_profile=" << GetProfileName(output_profile) 184 << ", output_profile=" << GetProfileName(output_profile)
129 << ", initial_bitrate=" << initial_bitrate; 185 << ", initial_bitrate=" << initial_bitrate;
130 DCHECK(!encoder_); 186 DCHECK(!encoder_);
131 187
132 if (!stub_->channel()->AddRoute(host_route_id_, stub_->stream_id(), this)) { 188 if (!stub_->channel()->AddRoute(host_route_id_, stub_->stream_id(), this)) {
133 DLOG(ERROR) << __FUNCTION__ << " failed to add route"; 189 DLOG(ERROR) << __func__ << " failed to add route";
134 return false; 190 return false;
135 } 191 }
136 192
137 if (input_visible_size.width() > limits::kMaxDimension || 193 if (input_visible_size.width() > limits::kMaxDimension ||
138 input_visible_size.height() > limits::kMaxDimension || 194 input_visible_size.height() > limits::kMaxDimension ||
139 input_visible_size.GetArea() > limits::kMaxCanvas) { 195 input_visible_size.GetArea() > limits::kMaxCanvas) {
140 DLOG(ERROR) << __FUNCTION__ << "too large input_visible_size " 196 DLOG(ERROR) << __func__ << "too large input_visible_size "
141 << input_visible_size.ToString(); 197 << input_visible_size.ToString();
142 return false; 198 return false;
143 } 199 }
144 200
145 const gpu::GpuPreferences& gpu_preferences = 201 const gpu::GpuPreferences& gpu_preferences =
146 stub_->channel()->gpu_channel_manager()->gpu_preferences(); 202 stub_->channel()->gpu_channel_manager()->gpu_preferences();
147 203
148 // Try all possible encoders and use the first successful encoder. 204 // Try all possible encoders and use the first successful encoder.
149 for (const auto& factory_function : GetVEAFactoryFunctions(gpu_preferences)) { 205 for (const auto& factory_function : GetVEAFactoryFunctions(gpu_preferences)) {
150 encoder_ = factory_function.Run(); 206 encoder_ = factory_function.Run();
151 if (encoder_ && 207 if (encoder_ &&
152 encoder_->Initialize(input_format, input_visible_size, output_profile, 208 encoder_->Initialize(input_format, input_visible_size, output_profile,
153 initial_bitrate, this)) { 209 initial_bitrate, this)) {
154 input_format_ = input_format; 210 input_format_ = input_format;
155 input_visible_size_ = input_visible_size; 211 input_visible_size_ = input_visible_size;
212 // Attempt to set up performing encoding tasks on IO thread, if supported
213 // by the VEA.
214 if (encoder_->TryToSetupEncodeOnSeparateThread(
215 weak_this_factory_.GetWeakPtr(), io_task_runner_)) {
216 filter_ = new MessageFilter(this, host_route_id_);
217 stub_->channel()->AddFilter(filter_.get());
218 }
156 return true; 219 return true;
157 } 220 }
158 } 221 }
159 encoder_.reset(); 222 encoder_.reset();
160 DLOG(ERROR) << __FUNCTION__ << " VEA initialization failed"; 223 DLOG(ERROR) << __func__ << " VEA initialization failed";
161 return false; 224 return false;
162 } 225 }
163 226
164 bool GpuVideoEncodeAccelerator::OnMessageReceived(const IPC::Message& message) { 227 bool GpuVideoEncodeAccelerator::OnMessageReceived(const IPC::Message& message) {
165 bool handled = true; 228 bool handled = true;
166 IPC_BEGIN_MESSAGE_MAP(GpuVideoEncodeAccelerator, message) 229 IPC_BEGIN_MESSAGE_MAP(GpuVideoEncodeAccelerator, message)
167 IPC_MESSAGE_HANDLER(AcceleratedVideoEncoderMsg_Encode, OnEncode) 230 IPC_MESSAGE_HANDLER(AcceleratedVideoEncoderMsg_Encode, OnEncode)
168 IPC_MESSAGE_HANDLER(AcceleratedVideoEncoderMsg_UseOutputBitstreamBuffer, 231 IPC_MESSAGE_HANDLER(AcceleratedVideoEncoderMsg_UseOutputBitstreamBuffer,
169 OnUseOutputBitstreamBuffer) 232 OnUseOutputBitstreamBuffer)
170 IPC_MESSAGE_HANDLER( 233 IPC_MESSAGE_HANDLER(
171 AcceleratedVideoEncoderMsg_RequestEncodingParametersChange, 234 AcceleratedVideoEncoderMsg_RequestEncodingParametersChange,
172 OnRequestEncodingParametersChange) 235 OnRequestEncodingParametersChange)
173 IPC_MESSAGE_HANDLER(AcceleratedVideoEncoderMsg_Destroy, OnDestroy) 236 IPC_MESSAGE_HANDLER(AcceleratedVideoEncoderMsg_Destroy, OnDestroy)
174 IPC_MESSAGE_UNHANDLED(handled = false) 237 IPC_MESSAGE_UNHANDLED(handled = false)
175 IPC_END_MESSAGE_MAP() 238 IPC_END_MESSAGE_MAP()
176 return handled; 239 return handled;
177 } 240 }
178 241
179 void GpuVideoEncodeAccelerator::RequireBitstreamBuffers( 242 void GpuVideoEncodeAccelerator::RequireBitstreamBuffers(
180 unsigned int input_count, 243 unsigned int input_count,
181 const gfx::Size& input_coded_size, 244 const gfx::Size& input_coded_size,
182 size_t output_buffer_size) { 245 size_t output_buffer_size) {
183 Send(new AcceleratedVideoEncoderHostMsg_RequireBitstreamBuffers( 246 if (!Send(new AcceleratedVideoEncoderHostMsg_RequireBitstreamBuffers(
Pawel Osciak 2016/10/25 01:44:04 DCHECK(CheckCalledOnMessageFilterThread()) if we e
emircan 2016/10/25 21:57:50 I moved it to main thread after your comment and a
184 host_route_id_, input_count, input_coded_size, output_buffer_size)); 247 host_route_id_, input_count, input_coded_size, output_buffer_size))) {
248 DLOG(ERROR) << __func__ << " failed.";
249 }
185 input_coded_size_ = input_coded_size; 250 input_coded_size_ = input_coded_size;
186 output_buffer_size_ = output_buffer_size; 251 output_buffer_size_ = output_buffer_size;
187 } 252 }
188 253
189 void GpuVideoEncodeAccelerator::BitstreamBufferReady( 254 void GpuVideoEncodeAccelerator::BitstreamBufferReady(
190 int32_t bitstream_buffer_id, 255 int32_t bitstream_buffer_id,
191 size_t payload_size, 256 size_t payload_size,
192 bool key_frame, 257 bool key_frame,
193 base::TimeDelta timestamp) { 258 base::TimeDelta timestamp) {
194 Send(new AcceleratedVideoEncoderHostMsg_BitstreamBufferReady( 259 DCHECK(CheckCalledOnMessageFilterThread());
195 host_route_id_, bitstream_buffer_id, payload_size, key_frame, timestamp)); 260 if (!Send(new AcceleratedVideoEncoderHostMsg_BitstreamBufferReady(
261 host_route_id_, bitstream_buffer_id, payload_size, key_frame,
262 timestamp))) {
263 DLOG(ERROR) << __func__ << " failed.";
264 }
196 } 265 }
197 266
198 void GpuVideoEncodeAccelerator::NotifyError( 267 void GpuVideoEncodeAccelerator::NotifyError(
199 VideoEncodeAccelerator::Error error) { 268 VideoEncodeAccelerator::Error error) {
200 Send(new AcceleratedVideoEncoderHostMsg_NotifyError(host_route_id_, error)); 269 DCHECK(CheckCalledOnMessageFilterThread());
270 if (!Send(new AcceleratedVideoEncoderHostMsg_NotifyError(host_route_id_,
271 error))) {
272 DLOG(ERROR) << __func__ << " failed.";
273 }
201 } 274 }
202 275
203 void GpuVideoEncodeAccelerator::OnWillDestroyStub() { 276 void GpuVideoEncodeAccelerator::OnWillDestroyStub() {
277 DVLOG(2) << __func__;
278 DCHECK(main_task_runner_->BelongsToCurrentThread());
204 DCHECK(stub_); 279 DCHECK(stub_);
280
281 if (filter_) {
282 stub_->channel()->RemoveFilter(filter_.get());
283 filter_removed_.Wait();
Pawel Osciak 2016/10/25 01:44:04 Please add a comment similar to the one in gvda.cc
emircan 2016/10/25 21:57:51 Done.
284 }
285
205 stub_->channel()->RemoveRoute(host_route_id_); 286 stub_->channel()->RemoveRoute(host_route_id_);
206 stub_->RemoveDestructionObserver(this); 287 stub_->RemoveDestructionObserver(this);
207 encoder_.reset(); 288 encoder_.reset();
208 delete this; 289 delete this;
209 } 290 }
210 291
211 // static 292 // static
212 gpu::VideoEncodeAcceleratorSupportedProfiles 293 gpu::VideoEncodeAcceleratorSupportedProfiles
213 GpuVideoEncodeAccelerator::GetSupportedProfiles( 294 GpuVideoEncodeAccelerator::GetSupportedProfiles(
214 const gpu::GpuPreferences& gpu_preferences) { 295 const gpu::GpuPreferences& gpu_preferences) {
215 VideoEncodeAccelerator::SupportedProfiles profiles; 296 VideoEncodeAccelerator::SupportedProfiles profiles;
216 297
217 for (const auto& factory_function : GetVEAFactoryFunctions(gpu_preferences)) { 298 for (const auto& factory_function : GetVEAFactoryFunctions(gpu_preferences)) {
218 std::unique_ptr<VideoEncodeAccelerator> encoder = factory_function.Run(); 299 std::unique_ptr<VideoEncodeAccelerator> encoder = factory_function.Run();
219 if (!encoder) 300 if (!encoder)
220 continue; 301 continue;
221 VideoEncodeAccelerator::SupportedProfiles vea_profiles = 302 VideoEncodeAccelerator::SupportedProfiles vea_profiles =
222 encoder->GetSupportedProfiles(); 303 encoder->GetSupportedProfiles();
223 GpuVideoAcceleratorUtil::InsertUniqueEncodeProfiles(vea_profiles, 304 GpuVideoAcceleratorUtil::InsertUniqueEncodeProfiles(vea_profiles,
224 &profiles); 305 &profiles);
225 } 306 }
226 return GpuVideoAcceleratorUtil::ConvertMediaToGpuEncodeProfiles(profiles); 307 return GpuVideoAcceleratorUtil::ConvertMediaToGpuEncodeProfiles(profiles);
227 } 308 }
228 309
310 void GpuVideoEncodeAccelerator::OnFilterRemoved() {
311 DVLOG(2) << __func__;
312
313 // We're destroying; cancel all callbacks.
314 weak_this_factory_.InvalidateWeakPtrs();
315 filter_removed_.Signal();
316 }
317
229 // static 318 // static
230 std::vector<GpuVideoEncodeAccelerator::VEAFactoryFunction> 319 std::vector<GpuVideoEncodeAccelerator::VEAFactoryFunction>
231 GpuVideoEncodeAccelerator::GetVEAFactoryFunctions( 320 GpuVideoEncodeAccelerator::GetVEAFactoryFunctions(
232 const gpu::GpuPreferences& gpu_preferences) { 321 const gpu::GpuPreferences& gpu_preferences) {
233 std::vector<VEAFactoryFunction> vea_factory_functions; 322 std::vector<VEAFactoryFunction> vea_factory_functions;
234 #if defined(OS_CHROMEOS) && defined(USE_V4L2_CODEC) 323 #if defined(OS_CHROMEOS) && defined(USE_V4L2_CODEC)
235 vea_factory_functions.push_back(base::Bind(&CreateV4L2VEA)); 324 vea_factory_functions.push_back(base::Bind(&CreateV4L2VEA));
236 #endif 325 #endif
237 #if defined(OS_CHROMEOS) && defined(ARCH_CPU_X86_FAMILY) 326 #if defined(OS_CHROMEOS) && defined(ARCH_CPU_X86_FAMILY)
238 if (!gpu_preferences.disable_vaapi_accelerated_video_encode) 327 if (!gpu_preferences.disable_vaapi_accelerated_video_encode)
239 vea_factory_functions.push_back(base::Bind(&CreateVaapiVEA)); 328 vea_factory_functions.push_back(base::Bind(&CreateVaapiVEA));
240 #endif 329 #endif
241 #if defined(OS_ANDROID) && defined(ENABLE_WEBRTC) 330 #if defined(OS_ANDROID) && defined(ENABLE_WEBRTC)
242 if (!gpu_preferences.disable_web_rtc_hw_encoding) 331 if (!gpu_preferences.disable_web_rtc_hw_encoding)
243 vea_factory_functions.push_back(base::Bind(&CreateAndroidVEA)); 332 vea_factory_functions.push_back(base::Bind(&CreateAndroidVEA));
244 #endif 333 #endif
245 #if defined(OS_MACOSX) 334 #if defined(OS_MACOSX)
246 vea_factory_functions.push_back(base::Bind(&CreateVTVEA)); 335 vea_factory_functions.push_back(base::Bind(&CreateVTVEA));
247 #endif 336 #endif
248 #if defined(OS_WIN) 337 #if defined(OS_WIN)
249 if (base::FeatureList::IsEnabled(kMediaFoundationH264Encoding)) 338 if (base::FeatureList::IsEnabled(kMediaFoundationH264Encoding))
250 vea_factory_functions.push_back(base::Bind(&CreateMediaFoundationVEA)); 339 vea_factory_functions.push_back(base::Bind(&CreateMediaFoundationVEA));
251 #endif 340 #endif
252 return vea_factory_functions; 341 return vea_factory_functions;
253 } 342 }
254 343
255 void GpuVideoEncodeAccelerator::OnEncode( 344 void GpuVideoEncodeAccelerator::OnEncode(
256 const AcceleratedVideoEncoderMsg_Encode_Params& params) { 345 const AcceleratedVideoEncoderMsg_Encode_Params& params) {
257 DVLOG(3) << __FUNCTION__ << " frame_id = " << params.frame_id 346 DVLOG(3) << __func__ << " frame_id = " << params.frame_id
258 << ", buffer_size=" << params.buffer_size 347 << ", buffer_size=" << params.buffer_size
259 << ", force_keyframe=" << params.force_keyframe; 348 << ", force_keyframe=" << params.force_keyframe;
349 DCHECK(CheckCalledOnMessageFilterThread());
260 DCHECK_EQ(PIXEL_FORMAT_I420, input_format_); 350 DCHECK_EQ(PIXEL_FORMAT_I420, input_format_);
261 351
262 // Wrap into a SharedMemory in the beginning, so that |params.buffer_handle| 352 // Wrap into a SharedMemory in the beginning, so that |params.buffer_handle|
Pawel Osciak 2016/10/25 01:44:04 Could we move the reminder of this method off of t
emircan 2016/10/25 21:57:50 I added a trace to measure how long it takes here.
Pawel Osciak 2016/10/27 01:45:19 From my understanding, the rule of thumb is that n
emircan 2016/10/27 17:53:30 I like the idea of letting VideoFrame lazy evaluat
Pawel Osciak 2016/10/31 07:40:21 From our experience with this, the main performanc
emircan 2016/10/31 19:45:08 Sorry if my statement earlier wasn't clear. I am n
Pawel Osciak 2016/11/01 04:59:58 SGTM, thanks! That would be in this CL, right?
263 // is cleaned properly in case of an early return. 353 // is cleaned properly in case of an early return.
264 std::unique_ptr<base::SharedMemory> shm( 354 std::unique_ptr<base::SharedMemory> shm(
265 new base::SharedMemory(params.buffer_handle, true)); 355 new base::SharedMemory(params.buffer_handle, true));
266 356
267 if (!encoder_) 357 if (!encoder_)
268 return; 358 return;
269 359
270 if (params.frame_id < 0) { 360 if (params.frame_id < 0) {
271 DLOG(ERROR) << __FUNCTION__ << " invalid frame_id=" << params.frame_id; 361 DLOG(ERROR) << __func__ << " invalid frame_id=" << params.frame_id;
272 NotifyError(VideoEncodeAccelerator::kPlatformFailureError); 362 NotifyError(VideoEncodeAccelerator::kPlatformFailureError);
273 return; 363 return;
274 } 364 }
275 365
276 const uint32_t aligned_offset = 366 const uint32_t aligned_offset =
277 params.buffer_offset % base::SysInfo::VMAllocationGranularity(); 367 params.buffer_offset % base::SysInfo::VMAllocationGranularity();
278 base::CheckedNumeric<off_t> map_offset = params.buffer_offset; 368 base::CheckedNumeric<off_t> map_offset = params.buffer_offset;
279 map_offset -= aligned_offset; 369 map_offset -= aligned_offset;
280 base::CheckedNumeric<size_t> map_size = params.buffer_size; 370 base::CheckedNumeric<size_t> map_size = params.buffer_size;
281 map_size += aligned_offset; 371 map_size += aligned_offset;
282 372
283 if (!map_offset.IsValid() || !map_size.IsValid()) { 373 if (!map_offset.IsValid() || !map_size.IsValid()) {
284 DLOG(ERROR) << __FUNCTION__ << " invalid map_offset or map_size"; 374 DLOG(ERROR) << __func__ << " invalid map_offset or map_size";
285 NotifyError(VideoEncodeAccelerator::kPlatformFailureError); 375 NotifyError(VideoEncodeAccelerator::kPlatformFailureError);
286 return; 376 return;
287 } 377 }
288 378
289 if (!shm->MapAt(map_offset.ValueOrDie(), map_size.ValueOrDie())) { 379 if (!shm->MapAt(map_offset.ValueOrDie(), map_size.ValueOrDie())) {
290 DLOG(ERROR) << __FUNCTION__ 380 DLOG(ERROR) << __func__ << " could not map frame_id=" << params.frame_id;
291 << " could not map frame_id=" << params.frame_id;
292 NotifyError(VideoEncodeAccelerator::kPlatformFailureError); 381 NotifyError(VideoEncodeAccelerator::kPlatformFailureError);
293 return; 382 return;
294 } 383 }
295 384
296 uint8_t* shm_memory = 385 uint8_t* shm_memory =
297 reinterpret_cast<uint8_t*>(shm->memory()) + aligned_offset; 386 reinterpret_cast<uint8_t*>(shm->memory()) + aligned_offset;
298 scoped_refptr<VideoFrame> frame = VideoFrame::WrapExternalSharedMemory( 387 scoped_refptr<VideoFrame> frame = VideoFrame::WrapExternalSharedMemory(
299 input_format_, input_coded_size_, gfx::Rect(input_visible_size_), 388 input_format_, input_coded_size_, gfx::Rect(input_visible_size_),
300 input_visible_size_, shm_memory, params.buffer_size, params.buffer_handle, 389 input_visible_size_, shm_memory, params.buffer_size, params.buffer_handle,
301 params.buffer_offset, params.timestamp); 390 params.buffer_offset, params.timestamp);
302 if (!frame) { 391 if (!frame) {
303 DLOG(ERROR) << __FUNCTION__ << " could not create a frame"; 392 DLOG(ERROR) << __func__ << " could not create a frame";
304 NotifyError(VideoEncodeAccelerator::kPlatformFailureError); 393 NotifyError(VideoEncodeAccelerator::kPlatformFailureError);
305 return; 394 return;
306 } 395 }
307 frame->AddDestructionObserver(BindToCurrentLoop(base::Bind( 396 frame->AddDestructionObserver(BindToCurrentLoop(base::Bind(
308 &GpuVideoEncodeAccelerator::EncodeFrameFinished, 397 &GpuVideoEncodeAccelerator::EncodeFrameFinished,
309 weak_this_factory_.GetWeakPtr(), params.frame_id, base::Passed(&shm)))); 398 weak_this_factory_.GetWeakPtr(), params.frame_id, base::Passed(&shm))));
310 encoder_->Encode(frame, params.force_keyframe); 399 encoder_->Encode(frame, params.force_keyframe);
311 } 400 }
312 401
313 void GpuVideoEncodeAccelerator::OnUseOutputBitstreamBuffer( 402 void GpuVideoEncodeAccelerator::OnUseOutputBitstreamBuffer(
314 int32_t buffer_id, 403 int32_t buffer_id,
315 base::SharedMemoryHandle buffer_handle, 404 base::SharedMemoryHandle buffer_handle,
316 uint32_t buffer_size) { 405 uint32_t buffer_size) {
317 DVLOG(3) << __FUNCTION__ << " buffer_id=" << buffer_id 406 DVLOG(3) << __func__ << " buffer_id=" << buffer_id
318 << ", buffer_size=" << buffer_size; 407 << ", buffer_size=" << buffer_size;
408 DCHECK(CheckCalledOnMessageFilterThread());
319 if (!encoder_) 409 if (!encoder_)
320 return; 410 return;
321 if (buffer_id < 0) { 411 if (buffer_id < 0) {
322 DLOG(ERROR) << __FUNCTION__ << " invalid buffer_id=" << buffer_id; 412 DLOG(ERROR) << __func__ << " invalid buffer_id=" << buffer_id;
323 NotifyError(VideoEncodeAccelerator::kPlatformFailureError); 413 NotifyError(VideoEncodeAccelerator::kPlatformFailureError);
324 return; 414 return;
325 } 415 }
326 if (buffer_size < output_buffer_size_) { 416 if (buffer_size < output_buffer_size_) {
327 DLOG(ERROR) << __FUNCTION__ 417 DLOG(ERROR) << __func__ << " buffer too small for buffer_id=" << buffer_id;
328 << " buffer too small for buffer_id=" << buffer_id;
329 NotifyError(VideoEncodeAccelerator::kPlatformFailureError); 418 NotifyError(VideoEncodeAccelerator::kPlatformFailureError);
330 return; 419 return;
331 } 420 }
332 encoder_->UseOutputBitstreamBuffer( 421 encoder_->UseOutputBitstreamBuffer(
333 BitstreamBuffer(buffer_id, buffer_handle, buffer_size)); 422 BitstreamBuffer(buffer_id, buffer_handle, buffer_size));
334 } 423 }
335 424
336 void GpuVideoEncodeAccelerator::OnDestroy() { 425 void GpuVideoEncodeAccelerator::OnDestroy() {
337 DVLOG(2) << __FUNCTION__; 426 DVLOG(2) << __func__;
427 DCHECK(main_task_runner_->BelongsToCurrentThread());
338 OnWillDestroyStub(); 428 OnWillDestroyStub();
339 } 429 }
340 430
341 void GpuVideoEncodeAccelerator::OnRequestEncodingParametersChange( 431 void GpuVideoEncodeAccelerator::OnRequestEncodingParametersChange(
342 uint32_t bitrate, 432 uint32_t bitrate,
343 uint32_t framerate) { 433 uint32_t framerate) {
344 DVLOG(2) << __FUNCTION__ << " bitrate=" << bitrate 434 DVLOG(2) << __func__ << " bitrate=" << bitrate << ", framerate=" << framerate;
345 << ", framerate=" << framerate; 435 DCHECK(CheckCalledOnMessageFilterThread());
346 if (!encoder_) 436 if (!encoder_)
347 return; 437 return;
348 encoder_->RequestEncodingParametersChange(bitrate, framerate); 438 encoder_->RequestEncodingParametersChange(bitrate, framerate);
349 } 439 }
350 440
351 void GpuVideoEncodeAccelerator::EncodeFrameFinished( 441 void GpuVideoEncodeAccelerator::EncodeFrameFinished(
352 int32_t frame_id, 442 int32_t frame_id,
353 std::unique_ptr<base::SharedMemory> shm) { 443 std::unique_ptr<base::SharedMemory> shm) {
354 Send(new AcceleratedVideoEncoderHostMsg_NotifyInputDone(host_route_id_, 444 DCHECK(CheckCalledOnMessageFilterThread());
355 frame_id)); 445 if (!Send(new AcceleratedVideoEncoderHostMsg_NotifyInputDone(host_route_id_,
446 frame_id))) {
447 DLOG(ERROR) << __func__ << " failed.";
448 }
356 // Just let |shm| fall out of scope. 449 // Just let |shm| fall out of scope.
357 } 450 }
358 451
359 void GpuVideoEncodeAccelerator::Send(IPC::Message* message) { 452 bool GpuVideoEncodeAccelerator::Send(IPC::Message* message) {
360 stub_->channel()->Send(message); 453 if (filter_ && io_task_runner_->BelongsToCurrentThread()) {
454 return filter_->SendOnIOThread(message);
455 }
456 DCHECK(main_task_runner_->BelongsToCurrentThread());
457 return stub_->channel()->Send(message);
458 }
459
460 bool GpuVideoEncodeAccelerator::CheckCalledOnMessageFilterThread() {
461 return (filter_ && io_task_runner_->BelongsToCurrentThread()) ||
462 (!filter_ && main_task_runner_->BelongsToCurrentThread());
361 } 463 }
362 464
363 } // namespace media 465 } // namespace media
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698