| OLD | NEW |
| 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 "content/common/gpu/client/gpu_video_encode_accelerator_host.h" | 5 #include "content/common/gpu/client/gpu_video_encode_accelerator_host.h" |
| 6 | 6 |
| 7 #include "base/location.h" |
| 7 #include "base/logging.h" | 8 #include "base/logging.h" |
| 8 #include "content/common/gpu/client/gpu_channel_host.h" | 9 #include "content/common/gpu/client/gpu_channel_host.h" |
| 9 #include "content/common/gpu/gpu_messages.h" | 10 #include "content/common/gpu/gpu_messages.h" |
| 10 #include "content/common/gpu/media/gpu_video_accelerator_util.h" | 11 #include "content/common/gpu/media/gpu_video_accelerator_util.h" |
| 11 #include "media/base/video_frame.h" | 12 #include "media/base/video_frame.h" |
| 12 | 13 |
| 13 namespace content { | 14 namespace content { |
| 14 | 15 |
| 15 #define NOTIFY_ERROR(error) \ | |
| 16 PostNotifyError(error); \ | |
| 17 DLOG(ERROR) | |
| 18 | |
| 19 GpuVideoEncodeAcceleratorHost::GpuVideoEncodeAcceleratorHost( | 16 GpuVideoEncodeAcceleratorHost::GpuVideoEncodeAcceleratorHost( |
| 20 GpuChannelHost* channel, | 17 GpuChannelHost* channel, |
| 21 CommandBufferProxyImpl* impl) | 18 CommandBufferProxyImpl* impl) |
| 22 : channel_(channel), | 19 : channel_(channel), |
| 23 encoder_route_id_(MSG_ROUTING_NONE), | 20 encoder_route_id_(MSG_ROUTING_NONE), |
| 24 client_(NULL), | 21 client_(NULL), |
| 25 impl_(impl), | 22 impl_(impl), |
| 26 next_frame_id_(0), | 23 next_frame_id_(0), |
| 27 weak_this_factory_(this) { | 24 weak_this_factory_(this) { |
| 28 DCHECK(channel_); | 25 DCHECK(channel_); |
| (...skipping 29 matching lines...) Expand all Loading... |
| 58 return handled; | 55 return handled; |
| 59 } | 56 } |
| 60 | 57 |
| 61 void GpuVideoEncodeAcceleratorHost::OnChannelError() { | 58 void GpuVideoEncodeAcceleratorHost::OnChannelError() { |
| 62 DCHECK(CalledOnValidThread()); | 59 DCHECK(CalledOnValidThread()); |
| 63 if (channel_) { | 60 if (channel_) { |
| 64 if (encoder_route_id_ != MSG_ROUTING_NONE) | 61 if (encoder_route_id_ != MSG_ROUTING_NONE) |
| 65 channel_->RemoveRoute(encoder_route_id_); | 62 channel_->RemoveRoute(encoder_route_id_); |
| 66 channel_ = NULL; | 63 channel_ = NULL; |
| 67 } | 64 } |
| 68 NOTIFY_ERROR(kPlatformFailureError) << "OnChannelError()"; | 65 PostNotifyError(FROM_HERE, kPlatformFailureError, "OnChannelError()"); |
| 69 } | 66 } |
| 70 | 67 |
| 71 media::VideoEncodeAccelerator::SupportedProfiles | 68 media::VideoEncodeAccelerator::SupportedProfiles |
| 72 GpuVideoEncodeAcceleratorHost::GetSupportedProfiles() { | 69 GpuVideoEncodeAcceleratorHost::GetSupportedProfiles() { |
| 73 DCHECK(CalledOnValidThread()); | 70 DCHECK(CalledOnValidThread()); |
| 74 if (!channel_) | 71 if (!channel_) |
| 75 return media::VideoEncodeAccelerator::SupportedProfiles(); | 72 return media::VideoEncodeAccelerator::SupportedProfiles(); |
| 76 return GpuVideoAcceleratorUtil::ConvertGpuToMediaEncodeProfiles( | 73 return GpuVideoAcceleratorUtil::ConvertGpuToMediaEncodeProfiles( |
| 77 channel_->gpu_info().video_encode_accelerator_supported_profiles); | 74 channel_->gpu_info().video_encode_accelerator_supported_profiles); |
| 78 } | 75 } |
| (...skipping 28 matching lines...) Expand all Loading... |
| 107 } | 104 } |
| 108 | 105 |
| 109 void GpuVideoEncodeAcceleratorHost::Encode( | 106 void GpuVideoEncodeAcceleratorHost::Encode( |
| 110 const scoped_refptr<media::VideoFrame>& frame, | 107 const scoped_refptr<media::VideoFrame>& frame, |
| 111 bool force_keyframe) { | 108 bool force_keyframe) { |
| 112 DCHECK(CalledOnValidThread()); | 109 DCHECK(CalledOnValidThread()); |
| 113 if (!channel_) | 110 if (!channel_) |
| 114 return; | 111 return; |
| 115 | 112 |
| 116 if (!base::SharedMemory::IsHandleValid(frame->shared_memory_handle())) { | 113 if (!base::SharedMemory::IsHandleValid(frame->shared_memory_handle())) { |
| 117 NOTIFY_ERROR(kPlatformFailureError) << "EncodeSharedMemory(): cannot " | 114 PostNotifyError(FROM_HERE, kPlatformFailureError, |
| 118 "encode frame with invalid shared " | 115 "EncodeSharedMemory(): cannot encode frame with " |
| 119 "memory handle"; | 116 "invalid shared memory handle"); |
| 120 return; | 117 return; |
| 121 } | 118 } |
| 122 | 119 |
| 123 AcceleratedVideoEncoderMsg_Encode_Params params; | 120 AcceleratedVideoEncoderMsg_Encode_Params params; |
| 124 params.frame_id = next_frame_id_; | 121 params.frame_id = next_frame_id_; |
| 125 params.buffer_handle = | 122 params.buffer_handle = |
| 126 channel_->ShareToGpuProcess(frame->shared_memory_handle()); | 123 channel_->ShareToGpuProcess(frame->shared_memory_handle()); |
| 127 if (!base::SharedMemory::IsHandleValid(params.buffer_handle)) { | 124 if (!base::SharedMemory::IsHandleValid(params.buffer_handle)) { |
| 128 NOTIFY_ERROR(kPlatformFailureError) << "EncodeSharedMemory(): failed to " | 125 PostNotifyError(FROM_HERE, kPlatformFailureError, |
| 129 "duplicate buffer handle for GPU " | 126 "EncodeSharedMemory(): failed to duplicate buffer handle " |
| 130 "process"; | 127 "for GPU process"); |
| 131 return; | 128 return; |
| 132 } | 129 } |
| 133 params.buffer_offset = | 130 params.buffer_offset = |
| 134 base::checked_cast<uint32_t>(frame->shared_memory_offset()); | 131 base::checked_cast<uint32_t>(frame->shared_memory_offset()); |
| 135 // We assume that planar frame data passed here is packed and contiguous. | 132 // We assume that planar frame data passed here is packed and contiguous. |
| 136 base::CheckedNumeric<uint32_t> buffer_size = 0u; | 133 base::CheckedNumeric<uint32_t> buffer_size = 0u; |
| 137 for (size_t i = 0; i < media::VideoFrame::NumPlanes(frame->format()); ++i) { | 134 for (size_t i = 0; i < media::VideoFrame::NumPlanes(frame->format()); ++i) { |
| 138 // Cast DCHECK parameters to void* to avoid printing uint8* as a string. | 135 // Cast DCHECK parameters to void* to avoid printing uint8* as a string. |
| 139 DCHECK_EQ( | 136 DCHECK_EQ( |
| 140 reinterpret_cast<void*>(frame->data(i)), | 137 reinterpret_cast<void*>(frame->data(i)), |
| (...skipping 14 matching lines...) Expand all Loading... |
| 155 | 152 |
| 156 void GpuVideoEncodeAcceleratorHost::UseOutputBitstreamBuffer( | 153 void GpuVideoEncodeAcceleratorHost::UseOutputBitstreamBuffer( |
| 157 const media::BitstreamBuffer& buffer) { | 154 const media::BitstreamBuffer& buffer) { |
| 158 DCHECK(CalledOnValidThread()); | 155 DCHECK(CalledOnValidThread()); |
| 159 if (!channel_) | 156 if (!channel_) |
| 160 return; | 157 return; |
| 161 | 158 |
| 162 base::SharedMemoryHandle handle = | 159 base::SharedMemoryHandle handle = |
| 163 channel_->ShareToGpuProcess(buffer.handle()); | 160 channel_->ShareToGpuProcess(buffer.handle()); |
| 164 if (!base::SharedMemory::IsHandleValid(handle)) { | 161 if (!base::SharedMemory::IsHandleValid(handle)) { |
| 165 NOTIFY_ERROR(kPlatformFailureError) | 162 PostNotifyError( |
| 166 << "UseOutputBitstreamBuffer(): failed to duplicate buffer handle " | 163 FROM_HERE, kPlatformFailureError, |
| 167 "for GPU process: buffer.id()=" << buffer.id(); | 164 base::StringPrintf("UseOutputBitstreamBuffer(): failed to duplicate " |
| 165 "buffer handle for GPU process: buffer.id()=%d", |
| 166 buffer.id())); |
| 168 return; | 167 return; |
| 169 } | 168 } |
| 170 Send(new AcceleratedVideoEncoderMsg_UseOutputBitstreamBuffer( | 169 Send(new AcceleratedVideoEncoderMsg_UseOutputBitstreamBuffer( |
| 171 encoder_route_id_, buffer.id(), handle, buffer.size())); | 170 encoder_route_id_, buffer.id(), handle, buffer.size())); |
| 172 } | 171 } |
| 173 | 172 |
| 174 void GpuVideoEncodeAcceleratorHost::RequestEncodingParametersChange( | 173 void GpuVideoEncodeAcceleratorHost::RequestEncodingParametersChange( |
| 175 uint32 bitrate, | 174 uint32 bitrate, |
| 176 uint32 framerate) { | 175 uint32 framerate) { |
| 177 DCHECK(CalledOnValidThread()); | 176 DCHECK(CalledOnValidThread()); |
| (...skipping 13 matching lines...) Expand all Loading... |
| 191 } | 190 } |
| 192 | 191 |
| 193 void GpuVideoEncodeAcceleratorHost::OnWillDeleteImpl() { | 192 void GpuVideoEncodeAcceleratorHost::OnWillDeleteImpl() { |
| 194 DCHECK(CalledOnValidThread()); | 193 DCHECK(CalledOnValidThread()); |
| 195 impl_ = NULL; | 194 impl_ = NULL; |
| 196 | 195 |
| 197 // The CommandBufferProxyImpl is going away; error out this VEA. | 196 // The CommandBufferProxyImpl is going away; error out this VEA. |
| 198 OnChannelError(); | 197 OnChannelError(); |
| 199 } | 198 } |
| 200 | 199 |
| 201 void GpuVideoEncodeAcceleratorHost::PostNotifyError(Error error) { | 200 void GpuVideoEncodeAcceleratorHost::PostNotifyError( |
| 201 const tracked_objects::Location& location, Error error, |
| 202 const std::string& message) { |
| 202 DCHECK(CalledOnValidThread()); | 203 DCHECK(CalledOnValidThread()); |
| 203 DVLOG(2) << "PostNotifyError(): error=" << error; | 204 DLOG(ERROR) << "Error from " << location.function_name() |
| 205 << "(" << location.file_name() << ":" |
| 206 << location.line_number() << ") " |
| 207 << message << " (error = " << error << ")"; |
| 204 // Post the error notification back to this thread, to avoid re-entrancy. | 208 // Post the error notification back to this thread, to avoid re-entrancy. |
| 205 base::ThreadTaskRunnerHandle::Get()->PostTask( | 209 base::ThreadTaskRunnerHandle::Get()->PostTask( |
| 206 FROM_HERE, base::Bind(&GpuVideoEncodeAcceleratorHost::OnNotifyError, | 210 FROM_HERE, base::Bind(&GpuVideoEncodeAcceleratorHost::OnNotifyError, |
| 207 weak_this_factory_.GetWeakPtr(), error)); | 211 weak_this_factory_.GetWeakPtr(), error)); |
| 208 } | 212 } |
| 209 | 213 |
| 210 void GpuVideoEncodeAcceleratorHost::Send(IPC::Message* message) { | 214 void GpuVideoEncodeAcceleratorHost::Send(IPC::Message* message) { |
| 211 DCHECK(CalledOnValidThread()); | 215 DCHECK(CalledOnValidThread()); |
| 212 uint32 message_type = message->type(); | 216 uint32 message_type = message->type(); |
| 213 if (!channel_->Send(message)) { | 217 if (!channel_->Send(message)) { |
| 214 NOTIFY_ERROR(kPlatformFailureError) << "Send(" << message_type | 218 PostNotifyError(FROM_HERE, kPlatformFailureError, |
| 215 << ") failed"; | 219 base::StringPrintf("Send(%d) failed", message_type)); |
| 216 } | 220 } |
| 217 } | 221 } |
| 218 | 222 |
| 219 void GpuVideoEncodeAcceleratorHost::OnRequireBitstreamBuffers( | 223 void GpuVideoEncodeAcceleratorHost::OnRequireBitstreamBuffers( |
| 220 uint32 input_count, | 224 uint32 input_count, |
| 221 const gfx::Size& input_coded_size, | 225 const gfx::Size& input_coded_size, |
| 222 uint32 output_buffer_size) { | 226 uint32 output_buffer_size) { |
| 223 DCHECK(CalledOnValidThread()); | 227 DCHECK(CalledOnValidThread()); |
| 224 DVLOG(2) << "OnRequireBitstreamBuffers(): input_count=" << input_count | 228 DVLOG(2) << "OnRequireBitstreamBuffers(): input_count=" << input_count |
| 225 << ", input_coded_size=" << input_coded_size.ToString() | 229 << ", input_coded_size=" << input_coded_size.ToString() |
| (...skipping 45 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 271 weak_this_factory_.InvalidateWeakPtrs(); | 275 weak_this_factory_.InvalidateWeakPtrs(); |
| 272 | 276 |
| 273 // Client::NotifyError() may Destroy() |this|, so calling it needs to be the | 277 // Client::NotifyError() may Destroy() |this|, so calling it needs to be the |
| 274 // last thing done on this stack! | 278 // last thing done on this stack! |
| 275 media::VideoEncodeAccelerator::Client* client = NULL; | 279 media::VideoEncodeAccelerator::Client* client = NULL; |
| 276 std::swap(client_, client); | 280 std::swap(client_, client); |
| 277 client->NotifyError(error); | 281 client->NotifyError(error); |
| 278 } | 282 } |
| 279 | 283 |
| 280 } // namespace content | 284 } // namespace content |
| OLD | NEW |