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

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: f2a9ccb5 Rebase, posciak@ comments. 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()) {
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.
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_);
37 } 58 }
38 59
60 #define WRITE_REPLY_AND_SEND(msg, route_id) \
61 do { \
62 GpuCommandBufferMsg_CreateVideoEncoder::WriteReplyParams(msg, route_id); \
63 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.
64 } while (0)
65
66 void GpuVideoEncodeAccelerator::Initialize(
67 media::VideoFrame::Format input_format,
68 const gfx::Size& input_visible_size,
69 media::VideoCodecProfile output_profile,
70 uint32 initial_bitrate,
71 IPC::Message* init_done_msg) {
72 DVLOG(2) << "GpuVideoEncodeAccelerator::Initialize(): "
73 "input_format=" << input_format
74 << ", input_visible_size=" << input_visible_size.ToString()
75 << ", output_profile=" << output_profile
76 << ", initial_bitrate=" << initial_bitrate;
77 DCHECK(!encoder_);
78
79 if (input_visible_size.width() > media::limits::kMaxDimension ||
80 input_visible_size.height() > media::limits::kMaxDimension ||
81 input_visible_size.GetArea() > media::limits::kMaxCanvas) {
82 DLOG(ERROR) << "GpuVideoEncodeAccelerator::Initialize(): "
83 "input_visible_size " << input_visible_size.ToString()
84 << " too large";
85 WRITE_REPLY_AND_SEND(init_done_msg, -1);
86 return;
87 }
88
89 CreateEncoder();
90 if (!encoder_) {
91 DLOG(ERROR)
92 << "GpuVideoEncodeAccelerator::Initialize(): VEA creation failed";
93 WRITE_REPLY_AND_SEND(init_done_msg, -1);
94 return;
95 }
96 if (!encoder_->Initialize(input_format,
97 input_visible_size,
98 output_profile,
99 initial_bitrate,
100 this)) {
101 DLOG(ERROR)
102 << "GpuVideoEncodeAccelerator::Initialize(): VEA initialization failed";
103 WRITE_REPLY_AND_SEND(init_done_msg, -1);
104 return;
105 }
106 input_format_ = input_format;
107 input_visible_size_ = input_visible_size;
108 WRITE_REPLY_AND_SEND(init_done_msg, host_route_id_);
109 }
110
111 #undef WRITE_REPLY_AND_SEND
112
39 bool GpuVideoEncodeAccelerator::OnMessageReceived(const IPC::Message& message) { 113 bool GpuVideoEncodeAccelerator::OnMessageReceived(const IPC::Message& message) {
40 bool handled = true; 114 bool handled = true;
41 IPC_BEGIN_MESSAGE_MAP(GpuVideoEncodeAccelerator, message) 115 IPC_BEGIN_MESSAGE_MAP(GpuVideoEncodeAccelerator, message)
42 IPC_MESSAGE_HANDLER(AcceleratedVideoEncoderMsg_Initialize, OnInitialize)
43 IPC_MESSAGE_HANDLER(AcceleratedVideoEncoderMsg_Encode, OnEncode) 116 IPC_MESSAGE_HANDLER(AcceleratedVideoEncoderMsg_Encode, OnEncode)
44 IPC_MESSAGE_HANDLER(AcceleratedVideoEncoderMsg_UseOutputBitstreamBuffer, 117 IPC_MESSAGE_HANDLER(AcceleratedVideoEncoderMsg_UseOutputBitstreamBuffer,
45 OnUseOutputBitstreamBuffer) 118 OnUseOutputBitstreamBuffer)
46 IPC_MESSAGE_HANDLER( 119 IPC_MESSAGE_HANDLER(
47 AcceleratedVideoEncoderMsg_RequestEncodingParametersChange, 120 AcceleratedVideoEncoderMsg_RequestEncodingParametersChange,
48 OnRequestEncodingParametersChange) 121 OnRequestEncodingParametersChange)
122 IPC_MESSAGE_HANDLER(AcceleratedVideoEncoderMsg_Destroy, OnDestroy)
49 IPC_MESSAGE_UNHANDLED(handled = false) 123 IPC_MESSAGE_UNHANDLED(handled = false)
50 IPC_END_MESSAGE_MAP() 124 IPC_END_MESSAGE_MAP()
51 return handled; 125 return handled;
52 } 126 }
53 127
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( 128 void GpuVideoEncodeAccelerator::RequireBitstreamBuffers(
65 unsigned int input_count, 129 unsigned int input_count,
66 const gfx::Size& input_coded_size, 130 const gfx::Size& input_coded_size,
67 size_t output_buffer_size) { 131 size_t output_buffer_size) {
68 Send(new AcceleratedVideoEncoderHostMsg_RequireBitstreamBuffers( 132 Send(new AcceleratedVideoEncoderHostMsg_RequireBitstreamBuffers(
69 route_id_, input_count, input_coded_size, output_buffer_size)); 133 host_route_id_, input_count, input_coded_size, output_buffer_size));
70 input_coded_size_ = input_coded_size; 134 input_coded_size_ = input_coded_size;
71 output_buffer_size_ = output_buffer_size; 135 output_buffer_size_ = output_buffer_size;
72 } 136 }
73 137
74 void GpuVideoEncodeAccelerator::BitstreamBufferReady(int32 bitstream_buffer_id, 138 void GpuVideoEncodeAccelerator::BitstreamBufferReady(int32 bitstream_buffer_id,
75 size_t payload_size, 139 size_t payload_size,
76 bool key_frame) { 140 bool key_frame) {
77 Send(new AcceleratedVideoEncoderHostMsg_BitstreamBufferReady( 141 Send(new AcceleratedVideoEncoderHostMsg_BitstreamBufferReady(
78 route_id_, bitstream_buffer_id, payload_size, key_frame)); 142 host_route_id_, bitstream_buffer_id, payload_size, key_frame));
79 } 143 }
80 144
81 void GpuVideoEncodeAccelerator::NotifyError( 145 void GpuVideoEncodeAccelerator::NotifyError(
82 media::VideoEncodeAccelerator::Error error) { 146 media::VideoEncodeAccelerator::Error error) {
83 Send(new AcceleratedVideoEncoderHostMsg_NotifyError(route_id_, error)); 147 Send(new AcceleratedVideoEncoderHostMsg_NotifyError(host_route_id_, error));
148 }
149
150 void GpuVideoEncodeAccelerator::OnWillDestroyStub() {
151 DCHECK(stub_);
152 stub_->channel()->RemoveRoute(host_route_id_);
153 stub_->RemoveDestructionObserver(this);
154
155 if (encoder_)
156 encoder_.release()->Destroy();
157
158 delete this;
84 } 159 }
85 160
86 // static 161 // static
87 std::vector<media::VideoEncodeAccelerator::SupportedProfile> 162 std::vector<media::VideoEncodeAccelerator::SupportedProfile>
88 GpuVideoEncodeAccelerator::GetSupportedProfiles() { 163 GpuVideoEncodeAccelerator::GetSupportedProfiles() {
89 std::vector<media::VideoEncodeAccelerator::SupportedProfile> profiles; 164 std::vector<media::VideoEncodeAccelerator::SupportedProfile> profiles;
90 165
91 #if defined(OS_CHROMEOS) && defined(ARCH_CPU_ARMEL) && defined(USE_X11) 166 #if defined(OS_CHROMEOS) && defined(ARCH_CPU_ARMEL) && defined(USE_X11)
92 profiles = ExynosVideoEncodeAccelerator::GetSupportedProfiles(); 167 profiles = ExynosVideoEncodeAccelerator::GetSupportedProfiles();
93 #elif defined(OS_ANDROID) && defined(ENABLE_WEBRTC) 168 #elif defined(OS_ANDROID) && defined(ENABLE_WEBRTC)
94 profiles = AndroidVideoEncodeAccelerator::GetSupportedProfiles(); 169 profiles = AndroidVideoEncodeAccelerator::GetSupportedProfiles();
95 #endif 170 #endif
96 171
97 // TODO(sheu): return platform-specific profiles. 172 // TODO(sheu): return platform-specific profiles.
98 return profiles; 173 return profiles;
99 } 174 }
100 175
101 void GpuVideoEncodeAccelerator::CreateEncoder() { 176 void GpuVideoEncodeAccelerator::CreateEncoder() {
102 DCHECK(!encoder_); 177 DCHECK(!encoder_);
103 #if defined(OS_CHROMEOS) && defined(ARCH_CPU_ARMEL) && defined(USE_X11) 178 #if defined(OS_CHROMEOS) && defined(ARCH_CPU_ARMEL) && defined(USE_X11)
104 encoder_.reset(new ExynosVideoEncodeAccelerator()); 179 encoder_.reset(new ExynosVideoEncodeAccelerator());
105 #elif defined(OS_ANDROID) && defined(ENABLE_WEBRTC) 180 #elif defined(OS_ANDROID) && defined(ENABLE_WEBRTC)
106 encoder_.reset(new AndroidVideoEncodeAccelerator()); 181 encoder_.reset(new AndroidVideoEncodeAccelerator());
107 #endif 182 #endif
108 } 183 }
109 184
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, 185 void GpuVideoEncodeAccelerator::OnEncode(int32 frame_id,
146 base::SharedMemoryHandle buffer_handle, 186 base::SharedMemoryHandle buffer_handle,
147 uint32 buffer_size, 187 uint32 buffer_size,
148 bool force_keyframe) { 188 bool force_keyframe) {
149 DVLOG(3) << "GpuVideoEncodeAccelerator::OnEncode(): frame_id=" << frame_id 189 DVLOG(3) << "GpuVideoEncodeAccelerator::OnEncode(): frame_id=" << frame_id
150 << ", buffer_size=" << buffer_size 190 << ", buffer_size=" << buffer_size
151 << ", force_keyframe=" << force_keyframe; 191 << ", force_keyframe=" << force_keyframe;
152 if (!encoder_) 192 if (!encoder_)
153 return; 193 return;
154 if (frame_id < 0) { 194 if (frame_id < 0) {
(...skipping 60 matching lines...) Expand 10 before | Expand all | Expand 10 after
215 if (buffer_size < output_buffer_size_) { 255 if (buffer_size < output_buffer_size_) {
216 DLOG(ERROR) << "GpuVideoEncodeAccelerator::OnUseOutputBitstreamBuffer(): " 256 DLOG(ERROR) << "GpuVideoEncodeAccelerator::OnUseOutputBitstreamBuffer(): "
217 "buffer too small for buffer_id=" << buffer_id; 257 "buffer too small for buffer_id=" << buffer_id;
218 NotifyError(media::VideoEncodeAccelerator::kPlatformFailureError); 258 NotifyError(media::VideoEncodeAccelerator::kPlatformFailureError);
219 return; 259 return;
220 } 260 }
221 encoder_->UseOutputBitstreamBuffer( 261 encoder_->UseOutputBitstreamBuffer(
222 media::BitstreamBuffer(buffer_id, buffer_handle, buffer_size)); 262 media::BitstreamBuffer(buffer_id, buffer_handle, buffer_size));
223 } 263 }
224 264
265 void GpuVideoEncodeAccelerator::OnDestroy() {
266 DVLOG(2) << "GpuVideoEncodeAccelerator::OnDestroy()";
267 OnWillDestroyStub();
268 }
269
225 void GpuVideoEncodeAccelerator::OnRequestEncodingParametersChange( 270 void GpuVideoEncodeAccelerator::OnRequestEncodingParametersChange(
226 uint32 bitrate, 271 uint32 bitrate,
227 uint32 framerate) { 272 uint32 framerate) {
228 DVLOG(2) << "GpuVideoEncodeAccelerator::OnRequestEncodingParametersChange(): " 273 DVLOG(2) << "GpuVideoEncodeAccelerator::OnRequestEncodingParametersChange(): "
229 "bitrate=" << bitrate 274 "bitrate=" << bitrate
230 << ", framerate=" << framerate; 275 << ", framerate=" << framerate;
231 if (!encoder_) 276 if (!encoder_)
232 return; 277 return;
233 encoder_->RequestEncodingParametersChange(bitrate, framerate); 278 encoder_->RequestEncodingParametersChange(bitrate, framerate);
234 } 279 }
235 280
236 void GpuVideoEncodeAccelerator::EncodeFrameFinished( 281 void GpuVideoEncodeAccelerator::EncodeFrameFinished(
237 int32 frame_id, 282 int32 frame_id,
238 scoped_ptr<base::SharedMemory> shm) { 283 scoped_ptr<base::SharedMemory> shm) {
239 Send(new AcceleratedVideoEncoderHostMsg_NotifyInputDone(route_id_, frame_id)); 284 Send(new AcceleratedVideoEncoderHostMsg_NotifyInputDone(host_route_id_,
285 frame_id));
240 // Just let shm fall out of scope. 286 // Just let shm fall out of scope.
241 } 287 }
242 288
243 void GpuVideoEncodeAccelerator::Send(IPC::Message* message) { 289 void GpuVideoEncodeAccelerator::Send(IPC::Message* message) {
244 if (!channel_) { 290 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 } 291 }
255 292
256 } // namespace content 293 } // namespace content
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698