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

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

Powered by Google App Engine
This is Rietveld 408576698