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

Side by Side Diff: content/common/gpu/media/gpu_video_encode_accelerator.cc

Issue 185403020: Make VEA client of command buffer; move sync. IPC to VDA/VEA::Initialize() (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: 56683e7a Rebase. Created 6 years, 9 months 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 | Annotate | Revision Log
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 "content/common/gpu/media/gpu_video_encode_accelerator.h" 5 #include "content/common/gpu/media/gpu_video_encode_accelerator.h"
6 6
7 #include "base/callback.h" 7 #include "base/callback.h"
8 #include "base/logging.h" 8 #include "base/logging.h"
9 #include "base/memory/shared_memory.h" 9 #include "base/memory/shared_memory.h"
10 #include "base/message_loop/message_loop_proxy.h" 10 #include "base/message_loop/message_loop_proxy.h"
11 #include "build/build_config.h" 11 #include "build/build_config.h"
12 #include "content/common/gpu/gpu_channel.h" 12 #include "content/common/gpu/gpu_channel.h"
13 #include "content/common/gpu/gpu_messages.h" 13 #include "content/common/gpu/gpu_messages.h"
14 #include "ipc/ipc_message_macros.h" 14 #include "ipc/ipc_message_macros.h"
15 #include "media/base/limits.h" 15 #include "media/base/limits.h"
16 #include "media/base/video_frame.h" 16 #include "media/base/video_frame.h"
17 17
18 #if defined(OS_CHROMEOS) && defined(ARCH_CPU_ARMEL) && defined(USE_X11) 18 #if defined(OS_CHROMEOS) && defined(ARCH_CPU_ARMEL) && defined(USE_X11)
19 #include "content/common/gpu/media/exynos_video_encode_accelerator.h" 19 #include "content/common/gpu/media/exynos_video_encode_accelerator.h"
20 #elif defined(OS_ANDROID) && defined(ENABLE_WEBRTC) 20 #elif defined(OS_ANDROID) && defined(ENABLE_WEBRTC)
21 #include "content/common/gpu/media/android_video_encode_accelerator.h" 21 #include "content/common/gpu/media/android_video_encode_accelerator.h"
22 #endif 22 #endif
23 23
24 namespace content { 24 namespace content {
25 25
26 GpuVideoEncodeAccelerator::GpuVideoEncodeAccelerator(GpuChannel* gpu_channel, 26 static bool MakeDecoderContextCurrent(
27 int32 route_id) 27 const base::WeakPtr<GpuCommandBufferStub> stub) {
28 : weak_this_factory_(this), 28 if (!stub.get()) {
29 channel_(gpu_channel), 29 DLOG(ERROR) << "Stub is gone; won't MakeCurrent().";
30 route_id_(route_id), 30 return false;
31 }
32
33 if (!stub->decoder()->MakeCurrent()) {
34 DLOG(ERROR) << "Failed to MakeCurrent()";
35 return false;
36 }
37
38 return true;
39 }
40
41 GpuVideoEncodeAccelerator::GpuVideoEncodeAccelerator(int32 host_route_id,
42 GpuCommandBufferStub* stub)
43 : host_route_id_(host_route_id),
44 stub_(stub),
31 input_format_(media::VideoFrame::UNKNOWN), 45 input_format_(media::VideoFrame::UNKNOWN),
32 output_buffer_size_(0) {} 46 output_buffer_size_(0),
47 weak_this_factory_(this) {
48 stub_->AddDestructionObserver(this);
49 stub_->channel()->AddRoute(host_route_id_, this);
50 make_context_current_ =
51 base::Bind(&MakeDecoderContextCurrent, stub_->AsWeakPtr());
52 }
33 53
34 GpuVideoEncodeAccelerator::~GpuVideoEncodeAccelerator() { 54 GpuVideoEncodeAccelerator::~GpuVideoEncodeAccelerator() {
35 if (encoder_) 55 // This class can only be self-deleted from OnWillDestroyStub(), which means
36 encoder_.release()->Destroy(); 56 // the VEA has already been destroyed in there.
57 DCHECK(!encoder_);
58 }
59
60 void GpuVideoEncodeAccelerator::Initialize(
61 media::VideoFrame::Format input_format,
62 const gfx::Size& input_visible_size,
63 media::VideoCodecProfile output_profile,
64 uint32 initial_bitrate,
65 IPC::Message* init_done_msg) {
66 DVLOG(2) << "GpuVideoEncodeAccelerator::Initialize(): "
67 "input_format=" << input_format
Pawel Osciak 2014/03/13 06:18:13 Nit: add "<<" and below.
sheu 2014/03/13 22:39:52 Concatenating strings? More "<<" not used elsewhe
68 << ", input_visible_size=" << input_visible_size.ToString()
69 << ", output_profile=" << output_profile
70 << ", initial_bitrate=" << initial_bitrate;
71 DCHECK(!encoder_);
72
73 if (input_visible_size.width() > media::limits::kMaxDimension ||
74 input_visible_size.height() > media::limits::kMaxDimension ||
75 input_visible_size.GetArea() > media::limits::kMaxCanvas) {
76 DLOG(ERROR) << "GpuVideoEncodeAccelerator::Initialize(): "
77 "input_visible_size " << input_visible_size.ToString()
78 << " too large";
79 GpuCommandBufferMsg_CreateVideoEncoder::WriteReplyParams(init_done_msg, -1);
80 Send(init_done_msg);
81 return;
82 }
83
84 CreateEncoder();
85 if (!encoder_) {
86 DLOG(ERROR)
87 << "GpuVideoEncodeAccelerator::Initialize(): VEA creation failed";
88 GpuCommandBufferMsg_CreateVideoEncoder::WriteReplyParams(init_done_msg, -1);
89 Send(init_done_msg);
90 return;
91 }
92 if (!encoder_->Initialize(input_format,
93 input_visible_size,
94 output_profile,
95 initial_bitrate,
96 this)) {
97 DLOG(ERROR)
98 << "GpuVideoEncodeAccelerator::Initialize(): VEA initialization failed";
99 GpuCommandBufferMsg_CreateVideoEncoder::WriteReplyParams(init_done_msg, -1);
100 Send(init_done_msg);
101 return;
102 }
103 input_format_ = input_format;
104 input_visible_size_ = input_visible_size;
105 GpuCommandBufferMsg_CreateVideoEncoder::WriteReplyParams(init_done_msg,
106 host_route_id_);
107 Send(init_done_msg);
37 } 108 }
38 109
39 bool GpuVideoEncodeAccelerator::OnMessageReceived(const IPC::Message& message) { 110 bool GpuVideoEncodeAccelerator::OnMessageReceived(const IPC::Message& message) {
40 bool handled = true; 111 bool handled = true;
41 IPC_BEGIN_MESSAGE_MAP(GpuVideoEncodeAccelerator, message) 112 IPC_BEGIN_MESSAGE_MAP(GpuVideoEncodeAccelerator, message)
42 IPC_MESSAGE_HANDLER(AcceleratedVideoEncoderMsg_Initialize, OnInitialize)
43 IPC_MESSAGE_HANDLER(AcceleratedVideoEncoderMsg_Encode, OnEncode) 113 IPC_MESSAGE_HANDLER(AcceleratedVideoEncoderMsg_Encode, OnEncode)
44 IPC_MESSAGE_HANDLER(AcceleratedVideoEncoderMsg_UseOutputBitstreamBuffer, 114 IPC_MESSAGE_HANDLER(AcceleratedVideoEncoderMsg_UseOutputBitstreamBuffer,
45 OnUseOutputBitstreamBuffer) 115 OnUseOutputBitstreamBuffer)
46 IPC_MESSAGE_HANDLER( 116 IPC_MESSAGE_HANDLER(
47 AcceleratedVideoEncoderMsg_RequestEncodingParametersChange, 117 AcceleratedVideoEncoderMsg_RequestEncodingParametersChange,
48 OnRequestEncodingParametersChange) 118 OnRequestEncodingParametersChange)
119 IPC_MESSAGE_HANDLER(AcceleratedVideoEncoderMsg_Destroy, OnDestroy)
49 IPC_MESSAGE_UNHANDLED(handled = false) 120 IPC_MESSAGE_UNHANDLED(handled = false)
50 IPC_END_MESSAGE_MAP() 121 IPC_END_MESSAGE_MAP()
51 return handled; 122 return handled;
52 } 123 }
53 124
54 void GpuVideoEncodeAccelerator::OnChannelError() {
55 NotifyError(media::VideoEncodeAccelerator::kPlatformFailureError);
56 if (channel_)
57 channel_ = NULL;
58 }
59
60 void GpuVideoEncodeAccelerator::NotifyInitializeDone() {
61 Send(new AcceleratedVideoEncoderHostMsg_NotifyInitializeDone(route_id_));
62 }
63
64 void GpuVideoEncodeAccelerator::RequireBitstreamBuffers( 125 void GpuVideoEncodeAccelerator::RequireBitstreamBuffers(
65 unsigned int input_count, 126 unsigned int input_count,
66 const gfx::Size& input_coded_size, 127 const gfx::Size& input_coded_size,
67 size_t output_buffer_size) { 128 size_t output_buffer_size) {
68 Send(new AcceleratedVideoEncoderHostMsg_RequireBitstreamBuffers( 129 Send(new AcceleratedVideoEncoderHostMsg_RequireBitstreamBuffers(
69 route_id_, input_count, input_coded_size, output_buffer_size)); 130 host_route_id_, input_count, input_coded_size, output_buffer_size));
70 input_coded_size_ = input_coded_size; 131 input_coded_size_ = input_coded_size;
71 output_buffer_size_ = output_buffer_size; 132 output_buffer_size_ = output_buffer_size;
72 } 133 }
73 134
74 void GpuVideoEncodeAccelerator::BitstreamBufferReady(int32 bitstream_buffer_id, 135 void GpuVideoEncodeAccelerator::BitstreamBufferReady(int32 bitstream_buffer_id,
75 size_t payload_size, 136 size_t payload_size,
76 bool key_frame) { 137 bool key_frame) {
77 Send(new AcceleratedVideoEncoderHostMsg_BitstreamBufferReady( 138 Send(new AcceleratedVideoEncoderHostMsg_BitstreamBufferReady(
78 route_id_, bitstream_buffer_id, payload_size, key_frame)); 139 host_route_id_, bitstream_buffer_id, payload_size, key_frame));
79 } 140 }
80 141
81 void GpuVideoEncodeAccelerator::NotifyError( 142 void GpuVideoEncodeAccelerator::NotifyError(
82 media::VideoEncodeAccelerator::Error error) { 143 media::VideoEncodeAccelerator::Error error) {
83 Send(new AcceleratedVideoEncoderHostMsg_NotifyError(route_id_, error)); 144 Send(new AcceleratedVideoEncoderHostMsg_NotifyError(host_route_id_, error));
145 }
146
147 void GpuVideoEncodeAccelerator::OnWillDestroyStub() {
148 DCHECK(stub_);
149 stub_->channel()->RemoveRoute(host_route_id_);
150 stub_->RemoveDestructionObserver(this);
151
152 if (encoder_)
153 encoder_.release()->Destroy();
154
155 delete this;
84 } 156 }
85 157
86 // static 158 // static
87 std::vector<media::VideoEncodeAccelerator::SupportedProfile> 159 std::vector<media::VideoEncodeAccelerator::SupportedProfile>
88 GpuVideoEncodeAccelerator::GetSupportedProfiles() { 160 GpuVideoEncodeAccelerator::GetSupportedProfiles() {
89 std::vector<media::VideoEncodeAccelerator::SupportedProfile> profiles; 161 std::vector<media::VideoEncodeAccelerator::SupportedProfile> profiles;
90 162
91 #if defined(OS_CHROMEOS) && defined(ARCH_CPU_ARMEL) && defined(USE_X11) 163 #if defined(OS_CHROMEOS) && defined(ARCH_CPU_ARMEL) && defined(USE_X11)
92 profiles = ExynosVideoEncodeAccelerator::GetSupportedProfiles(); 164 profiles = ExynosVideoEncodeAccelerator::GetSupportedProfiles();
93 #elif defined(OS_ANDROID) && defined(ENABLE_WEBRTC) 165 #elif defined(OS_ANDROID) && defined(ENABLE_WEBRTC)
94 profiles = AndroidVideoEncodeAccelerator::GetSupportedProfiles(); 166 profiles = AndroidVideoEncodeAccelerator::GetSupportedProfiles();
95 #endif 167 #endif
96 168
97 // TODO(sheu): return platform-specific profiles. 169 // TODO(sheu): return platform-specific profiles.
98 return profiles; 170 return profiles;
99 } 171 }
100 172
101 void GpuVideoEncodeAccelerator::CreateEncoder() { 173 void GpuVideoEncodeAccelerator::CreateEncoder() {
102 DCHECK(!encoder_); 174 DCHECK(!encoder_);
103 #if defined(OS_CHROMEOS) && defined(ARCH_CPU_ARMEL) && defined(USE_X11) 175 #if defined(OS_CHROMEOS) && defined(ARCH_CPU_ARMEL) && defined(USE_X11)
104 encoder_.reset(new ExynosVideoEncodeAccelerator()); 176 encoder_.reset(new ExynosVideoEncodeAccelerator());
105 #elif defined(OS_ANDROID) && defined(ENABLE_WEBRTC) 177 #elif defined(OS_ANDROID) && defined(ENABLE_WEBRTC)
106 encoder_.reset(new AndroidVideoEncodeAccelerator()); 178 encoder_.reset(new AndroidVideoEncodeAccelerator());
107 #endif 179 #endif
108 } 180 }
109 181
110 void GpuVideoEncodeAccelerator::OnInitialize(
111 media::VideoFrame::Format input_format,
112 const gfx::Size& input_visible_size,
113 media::VideoCodecProfile output_profile,
114 uint32 initial_bitrate) {
115 DVLOG(2) << "GpuVideoEncodeAccelerator::OnInitialize(): "
116 "input_format=" << input_format
117 << ", input_visible_size=" << input_visible_size.ToString()
118 << ", output_profile=" << output_profile
119 << ", initial_bitrate=" << initial_bitrate;
120 DCHECK(!encoder_);
121
122 if (input_visible_size.width() > media::limits::kMaxDimension ||
123 input_visible_size.height() > media::limits::kMaxDimension ||
124 input_visible_size.GetArea() > media::limits::kMaxCanvas) {
125 DLOG(ERROR) << "GpuVideoEncodeAccelerator::OnInitialize(): "
126 "input_visible_size " << input_visible_size.ToString()
127 << " too large";
128 NotifyError(media::VideoEncodeAccelerator::kPlatformFailureError);
129 return;
130 }
131
132 CreateEncoder();
133 if (!encoder_) {
134 DLOG(ERROR) << "GpuVideoEncodeAccelerator::OnInitialize(): VEA creation "
135 "failed";
136 NotifyError(media::VideoEncodeAccelerator::kPlatformFailureError);
137 return;
138 }
139 encoder_->Initialize(
140 input_format, input_visible_size, output_profile, initial_bitrate, this);
141 input_format_ = input_format;
142 input_visible_size_ = input_visible_size;
143 }
144
145 void GpuVideoEncodeAccelerator::OnEncode(int32 frame_id, 182 void GpuVideoEncodeAccelerator::OnEncode(int32 frame_id,
146 base::SharedMemoryHandle buffer_handle, 183 base::SharedMemoryHandle buffer_handle,
147 uint32 buffer_size, 184 uint32 buffer_size,
148 bool force_keyframe) { 185 bool force_keyframe) {
149 DVLOG(3) << "GpuVideoEncodeAccelerator::OnEncode(): frame_id=" << frame_id 186 DVLOG(3) << "GpuVideoEncodeAccelerator::OnEncode(): frame_id=" << frame_id
150 << ", buffer_size=" << buffer_size 187 << ", buffer_size=" << buffer_size
151 << ", force_keyframe=" << force_keyframe; 188 << ", force_keyframe=" << force_keyframe;
152 if (!encoder_) 189 if (!encoder_)
153 return; 190 return;
154 if (frame_id < 0) { 191 if (frame_id < 0) {
(...skipping 60 matching lines...) Expand 10 before | Expand all | Expand 10 after
215 if (buffer_size < output_buffer_size_) { 252 if (buffer_size < output_buffer_size_) {
216 DLOG(ERROR) << "GpuVideoEncodeAccelerator::OnUseOutputBitstreamBuffer(): " 253 DLOG(ERROR) << "GpuVideoEncodeAccelerator::OnUseOutputBitstreamBuffer(): "
217 "buffer too small for buffer_id=" << buffer_id; 254 "buffer too small for buffer_id=" << buffer_id;
218 NotifyError(media::VideoEncodeAccelerator::kPlatformFailureError); 255 NotifyError(media::VideoEncodeAccelerator::kPlatformFailureError);
219 return; 256 return;
220 } 257 }
221 encoder_->UseOutputBitstreamBuffer( 258 encoder_->UseOutputBitstreamBuffer(
222 media::BitstreamBuffer(buffer_id, buffer_handle, buffer_size)); 259 media::BitstreamBuffer(buffer_id, buffer_handle, buffer_size));
223 } 260 }
224 261
262 void GpuVideoEncodeAccelerator::OnDestroy() {
263 DVLOG(2) << "GpuVideoEncodeAccelerator::OnDestroy()";
264 OnWillDestroyStub();
265 }
266
225 void GpuVideoEncodeAccelerator::OnRequestEncodingParametersChange( 267 void GpuVideoEncodeAccelerator::OnRequestEncodingParametersChange(
226 uint32 bitrate, 268 uint32 bitrate,
227 uint32 framerate) { 269 uint32 framerate) {
228 DVLOG(2) << "GpuVideoEncodeAccelerator::OnRequestEncodingParametersChange(): " 270 DVLOG(2) << "GpuVideoEncodeAccelerator::OnRequestEncodingParametersChange(): "
229 "bitrate=" << bitrate 271 "bitrate=" << bitrate
230 << ", framerate=" << framerate; 272 << ", framerate=" << framerate;
231 if (!encoder_) 273 if (!encoder_)
232 return; 274 return;
233 encoder_->RequestEncodingParametersChange(bitrate, framerate); 275 encoder_->RequestEncodingParametersChange(bitrate, framerate);
234 } 276 }
235 277
236 void GpuVideoEncodeAccelerator::EncodeFrameFinished( 278 void GpuVideoEncodeAccelerator::EncodeFrameFinished(
237 int32 frame_id, 279 int32 frame_id,
238 scoped_ptr<base::SharedMemory> shm) { 280 scoped_ptr<base::SharedMemory> shm) {
239 Send(new AcceleratedVideoEncoderHostMsg_NotifyInputDone(route_id_, frame_id)); 281 Send(new AcceleratedVideoEncoderHostMsg_NotifyInputDone(host_route_id_,
282 frame_id));
240 // Just let shm fall out of scope. 283 // Just let shm fall out of scope.
241 } 284 }
242 285
243 void GpuVideoEncodeAccelerator::Send(IPC::Message* message) { 286 void GpuVideoEncodeAccelerator::Send(IPC::Message* message) {
244 if (!channel_) { 287 stub_->channel()->Send(message);
245 DLOG(ERROR) << "GpuVideoEncodeAccelerator::Send(): no channel";
246 delete message;
247 return;
248 } else if (!channel_->Send(message)) {
249 DLOG(ERROR) << "GpuVideoEncodeAccelerator::Send(): sending failed: "
250 "message->type()=" << message->type();
251 NotifyError(media::VideoEncodeAccelerator::kPlatformFailureError);
252 return;
253 }
254 } 288 }
255 289
256 } // namespace content 290 } // namespace content
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698