Chromium Code Reviews| Index: content/common/gpu/media/gpu_video_encode_accelerator.cc |
| diff --git a/content/common/gpu/media/gpu_video_encode_accelerator.cc b/content/common/gpu/media/gpu_video_encode_accelerator.cc |
| index 9227847beb58bebcacb5359a1aba08489afaa982..a15f1cf74393c4e2cc6d7d5b482ab6cdd5c22ad4 100644 |
| --- a/content/common/gpu/media/gpu_video_encode_accelerator.cc |
| +++ b/content/common/gpu/media/gpu_video_encode_accelerator.cc |
| @@ -23,50 +23,114 @@ |
| namespace content { |
| -GpuVideoEncodeAccelerator::GpuVideoEncodeAccelerator(GpuChannel* gpu_channel, |
| - int32 route_id) |
| - : weak_this_factory_(this), |
| - channel_(gpu_channel), |
| - route_id_(route_id), |
| +static bool MakeDecoderContextCurrent( |
| + const base::WeakPtr<GpuCommandBufferStub> stub) { |
| + if (!stub.get()) { |
|
Ami GONE FROM CHROMIUM
2014/03/17 03:17:54
.get() shouldn't be necessary (search weak_ptr.h f
sheu
2014/03/18 22:38:35
Done.
|
| + DLOG(ERROR) << "Stub is gone; won't MakeCurrent()."; |
| + return false; |
| + } |
| + |
| + if (!stub->decoder()->MakeCurrent()) { |
| + DLOG(ERROR) << "Failed to MakeCurrent()"; |
| + return false; |
| + } |
| + |
| + return true; |
| +} |
| + |
| +GpuVideoEncodeAccelerator::GpuVideoEncodeAccelerator(int32 host_route_id, |
| + GpuCommandBufferStub* stub) |
| + : host_route_id_(host_route_id), |
| + stub_(stub), |
| input_format_(media::VideoFrame::UNKNOWN), |
| - output_buffer_size_(0) {} |
| + output_buffer_size_(0), |
| + weak_this_factory_(this) { |
| + stub_->AddDestructionObserver(this); |
| + stub_->channel()->AddRoute(host_route_id_, this); |
| + make_context_current_ = |
| + base::Bind(&MakeDecoderContextCurrent, stub_->AsWeakPtr()); |
| +} |
| GpuVideoEncodeAccelerator::~GpuVideoEncodeAccelerator() { |
| - if (encoder_) |
| - encoder_.release()->Destroy(); |
| + // This class can only be self-deleted from OnWillDestroyStub(), which means |
| + // the VEA has already been destroyed in there. |
| + DCHECK(!encoder_); |
| } |
| +#define WRITE_REPLY_AND_SEND(msg, route_id) \ |
| + do { \ |
| + GpuCommandBufferMsg_CreateVideoEncoder::WriteReplyParams(msg, route_id); \ |
| + Send(init_done_msg); \ |
|
Ami GONE FROM CHROMIUM
2014/03/17 03:17:54
again, this should just be |msg|, and should be in
sheu
2014/03/18 22:38:35
Done.
|
| + } while (0) |
| + |
| +void GpuVideoEncodeAccelerator::Initialize( |
| + media::VideoFrame::Format input_format, |
| + const gfx::Size& input_visible_size, |
| + media::VideoCodecProfile output_profile, |
| + uint32 initial_bitrate, |
| + IPC::Message* init_done_msg) { |
| + DVLOG(2) << "GpuVideoEncodeAccelerator::Initialize(): " |
| + "input_format=" << input_format |
| + << ", input_visible_size=" << input_visible_size.ToString() |
| + << ", output_profile=" << output_profile |
| + << ", initial_bitrate=" << initial_bitrate; |
| + DCHECK(!encoder_); |
| + |
| + if (input_visible_size.width() > media::limits::kMaxDimension || |
| + input_visible_size.height() > media::limits::kMaxDimension || |
| + input_visible_size.GetArea() > media::limits::kMaxCanvas) { |
| + DLOG(ERROR) << "GpuVideoEncodeAccelerator::Initialize(): " |
| + "input_visible_size " << input_visible_size.ToString() |
| + << " too large"; |
| + WRITE_REPLY_AND_SEND(init_done_msg, -1); |
| + return; |
| + } |
| + |
| + CreateEncoder(); |
| + if (!encoder_) { |
| + DLOG(ERROR) |
| + << "GpuVideoEncodeAccelerator::Initialize(): VEA creation failed"; |
| + WRITE_REPLY_AND_SEND(init_done_msg, -1); |
| + return; |
| + } |
| + if (!encoder_->Initialize(input_format, |
| + input_visible_size, |
| + output_profile, |
| + initial_bitrate, |
| + this)) { |
| + DLOG(ERROR) |
| + << "GpuVideoEncodeAccelerator::Initialize(): VEA initialization failed"; |
| + WRITE_REPLY_AND_SEND(init_done_msg, -1); |
| + return; |
| + } |
| + input_format_ = input_format; |
| + input_visible_size_ = input_visible_size; |
| + WRITE_REPLY_AND_SEND(init_done_msg, host_route_id_); |
| +} |
| + |
| +#undef WRITE_REPLY_AND_SEND |
| + |
| bool GpuVideoEncodeAccelerator::OnMessageReceived(const IPC::Message& message) { |
| bool handled = true; |
| IPC_BEGIN_MESSAGE_MAP(GpuVideoEncodeAccelerator, message) |
| - IPC_MESSAGE_HANDLER(AcceleratedVideoEncoderMsg_Initialize, OnInitialize) |
| IPC_MESSAGE_HANDLER(AcceleratedVideoEncoderMsg_Encode, OnEncode) |
| IPC_MESSAGE_HANDLER(AcceleratedVideoEncoderMsg_UseOutputBitstreamBuffer, |
| OnUseOutputBitstreamBuffer) |
| IPC_MESSAGE_HANDLER( |
| AcceleratedVideoEncoderMsg_RequestEncodingParametersChange, |
| OnRequestEncodingParametersChange) |
| + IPC_MESSAGE_HANDLER(AcceleratedVideoEncoderMsg_Destroy, OnDestroy) |
| IPC_MESSAGE_UNHANDLED(handled = false) |
| IPC_END_MESSAGE_MAP() |
| return handled; |
| } |
| -void GpuVideoEncodeAccelerator::OnChannelError() { |
| - NotifyError(media::VideoEncodeAccelerator::kPlatformFailureError); |
| - if (channel_) |
| - channel_ = NULL; |
| -} |
| - |
| -void GpuVideoEncodeAccelerator::NotifyInitializeDone() { |
| - Send(new AcceleratedVideoEncoderHostMsg_NotifyInitializeDone(route_id_)); |
| -} |
| - |
| void GpuVideoEncodeAccelerator::RequireBitstreamBuffers( |
| unsigned int input_count, |
| const gfx::Size& input_coded_size, |
| size_t output_buffer_size) { |
| Send(new AcceleratedVideoEncoderHostMsg_RequireBitstreamBuffers( |
| - route_id_, input_count, input_coded_size, output_buffer_size)); |
| + host_route_id_, input_count, input_coded_size, output_buffer_size)); |
| input_coded_size_ = input_coded_size; |
| output_buffer_size_ = output_buffer_size; |
| } |
| @@ -75,12 +139,23 @@ void GpuVideoEncodeAccelerator::BitstreamBufferReady(int32 bitstream_buffer_id, |
| size_t payload_size, |
| bool key_frame) { |
| Send(new AcceleratedVideoEncoderHostMsg_BitstreamBufferReady( |
| - route_id_, bitstream_buffer_id, payload_size, key_frame)); |
| + host_route_id_, bitstream_buffer_id, payload_size, key_frame)); |
| } |
| void GpuVideoEncodeAccelerator::NotifyError( |
| media::VideoEncodeAccelerator::Error error) { |
| - Send(new AcceleratedVideoEncoderHostMsg_NotifyError(route_id_, error)); |
| + Send(new AcceleratedVideoEncoderHostMsg_NotifyError(host_route_id_, error)); |
| +} |
| + |
| +void GpuVideoEncodeAccelerator::OnWillDestroyStub() { |
| + DCHECK(stub_); |
| + stub_->channel()->RemoveRoute(host_route_id_); |
| + stub_->RemoveDestructionObserver(this); |
| + |
| + if (encoder_) |
| + encoder_.release()->Destroy(); |
| + |
| + delete this; |
| } |
| // static |
| @@ -107,41 +182,6 @@ void GpuVideoEncodeAccelerator::CreateEncoder() { |
| #endif |
| } |
| -void GpuVideoEncodeAccelerator::OnInitialize( |
| - media::VideoFrame::Format input_format, |
| - const gfx::Size& input_visible_size, |
| - media::VideoCodecProfile output_profile, |
| - uint32 initial_bitrate) { |
| - DVLOG(2) << "GpuVideoEncodeAccelerator::OnInitialize(): " |
| - "input_format=" << input_format |
| - << ", input_visible_size=" << input_visible_size.ToString() |
| - << ", output_profile=" << output_profile |
| - << ", initial_bitrate=" << initial_bitrate; |
| - DCHECK(!encoder_); |
| - |
| - if (input_visible_size.width() > media::limits::kMaxDimension || |
| - input_visible_size.height() > media::limits::kMaxDimension || |
| - input_visible_size.GetArea() > media::limits::kMaxCanvas) { |
| - DLOG(ERROR) << "GpuVideoEncodeAccelerator::OnInitialize(): " |
| - "input_visible_size " << input_visible_size.ToString() |
| - << " too large"; |
| - NotifyError(media::VideoEncodeAccelerator::kPlatformFailureError); |
| - return; |
| - } |
| - |
| - CreateEncoder(); |
| - if (!encoder_) { |
| - DLOG(ERROR) << "GpuVideoEncodeAccelerator::OnInitialize(): VEA creation " |
| - "failed"; |
| - NotifyError(media::VideoEncodeAccelerator::kPlatformFailureError); |
| - return; |
| - } |
| - encoder_->Initialize( |
| - input_format, input_visible_size, output_profile, initial_bitrate, this); |
| - input_format_ = input_format; |
| - input_visible_size_ = input_visible_size; |
| -} |
| - |
| void GpuVideoEncodeAccelerator::OnEncode(int32 frame_id, |
| base::SharedMemoryHandle buffer_handle, |
| uint32 buffer_size, |
| @@ -222,6 +262,11 @@ void GpuVideoEncodeAccelerator::OnUseOutputBitstreamBuffer( |
| media::BitstreamBuffer(buffer_id, buffer_handle, buffer_size)); |
| } |
| +void GpuVideoEncodeAccelerator::OnDestroy() { |
| + DVLOG(2) << "GpuVideoEncodeAccelerator::OnDestroy()"; |
| + OnWillDestroyStub(); |
| +} |
| + |
| void GpuVideoEncodeAccelerator::OnRequestEncodingParametersChange( |
| uint32 bitrate, |
| uint32 framerate) { |
| @@ -236,21 +281,13 @@ void GpuVideoEncodeAccelerator::OnRequestEncodingParametersChange( |
| void GpuVideoEncodeAccelerator::EncodeFrameFinished( |
| int32 frame_id, |
| scoped_ptr<base::SharedMemory> shm) { |
| - Send(new AcceleratedVideoEncoderHostMsg_NotifyInputDone(route_id_, frame_id)); |
| + Send(new AcceleratedVideoEncoderHostMsg_NotifyInputDone(host_route_id_, |
| + frame_id)); |
| // Just let shm fall out of scope. |
| } |
| void GpuVideoEncodeAccelerator::Send(IPC::Message* message) { |
| - if (!channel_) { |
| - DLOG(ERROR) << "GpuVideoEncodeAccelerator::Send(): no channel"; |
| - delete message; |
| - return; |
| - } else if (!channel_->Send(message)) { |
| - DLOG(ERROR) << "GpuVideoEncodeAccelerator::Send(): sending failed: " |
| - "message->type()=" << message->type(); |
| - NotifyError(media::VideoEncodeAccelerator::kPlatformFailureError); |
| - return; |
| - } |
| + stub_->channel()->Send(message); |
| } |
| } // namespace content |