| 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..cd2f6c4c90e75ba08a21385efa751ae6c23b5b48 100644
|
| --- a/content/common/gpu/media/gpu_video_encode_accelerator.cc
|
| +++ b/content/common/gpu/media/gpu_video_encode_accelerator.cc
|
| @@ -23,50 +23,106 @@
|
|
|
| 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) {
|
| + 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_);
|
| +}
|
| +
|
| +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";
|
| + SendCreateEncoderReply(init_done_msg, MSG_ROUTING_NONE);
|
| + return;
|
| + }
|
| +
|
| + CreateEncoder();
|
| + if (!encoder_) {
|
| + DLOG(ERROR)
|
| + << "GpuVideoEncodeAccelerator::Initialize(): VEA creation failed";
|
| + SendCreateEncoderReply(init_done_msg, MSG_ROUTING_NONE);
|
| + return;
|
| + }
|
| + if (!encoder_->Initialize(input_format,
|
| + input_visible_size,
|
| + output_profile,
|
| + initial_bitrate,
|
| + this)) {
|
| + DLOG(ERROR)
|
| + << "GpuVideoEncodeAccelerator::Initialize(): VEA initialization failed";
|
| + SendCreateEncoderReply(init_done_msg, MSG_ROUTING_NONE);
|
| + return;
|
| + }
|
| + input_format_ = input_format;
|
| + input_visible_size_ = input_visible_size;
|
| + SendCreateEncoderReply(init_done_msg, host_route_id_);
|
| }
|
|
|
| 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 +131,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 +174,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 +254,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 +273,19 @@ 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);
|
| +}
|
| +
|
| +void GpuVideoEncodeAccelerator::SendCreateEncoderReply(IPC::Message* message,
|
| + int32 route_id) {
|
| + GpuCommandBufferMsg_CreateVideoEncoder::WriteReplyParams(message, route_id);
|
| + Send(message);
|
| }
|
|
|
| } // namespace content
|
|
|