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

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

Issue 20632002: Add media::VideoEncodeAccelerator with WebRTC integration (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@git-svn
Patch Set: b4cd612a Comments, added framerate to RequestEncodingParametersChange Created 7 years, 4 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
OLDNEW
(Empty)
1 // Copyright (c) 2013 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4
5 #include "content/common/gpu/media/gpu_video_encode_accelerator.h"
6
7 #include "base/logging.h"
8 #include "base/memory/shared_memory.h"
9 #include "content/common/gpu/gpu_channel.h"
10 #include "content/common/gpu/gpu_messages.h"
11 #include "ipc/ipc_message_macros.h"
12 #include "media/base/video_frame.h"
13
14 namespace content {
15
16 GpuVideoEncodeAccelerator::GpuVideoEncodeAccelerator(GpuChannel* gpu_channel,
17 int32 route_id)
18 : channel_(gpu_channel),
19 route_id_(route_id),
20 input_format_(media::VideoFrame::INVALID),
21 output_buffer_size_(0) {}
22
23 GpuVideoEncodeAccelerator::~GpuVideoEncodeAccelerator() {
24 if (encoder_)
25 encoder_.release()->Destroy();
26 }
27
28 bool GpuVideoEncodeAccelerator::OnMessageReceived(const IPC::Message& message) {
29 bool handled = true;
30 IPC_BEGIN_MESSAGE_MAP(GpuVideoEncodeAccelerator, message)
31 IPC_MESSAGE_HANDLER(AcceleratedVideoEncoderMsg_Initialize, OnInitialize)
32 IPC_MESSAGE_HANDLER(AcceleratedVideoEncoderMsg_Encode, OnEncode)
33 IPC_MESSAGE_HANDLER(AcceleratedVideoEncoderMsg_UseOutputBitstreamBuffer,
34 OnUseOutputBitstreamBuffer)
35 IPC_MESSAGE_HANDLER(
36 AcceleratedVideoEncoderMsg_RequestEncodingParametersChange,
37 OnRequestEncodingParametersChange)
38 IPC_MESSAGE_UNHANDLED(handled = false)
39 IPC_END_MESSAGE_MAP()
40 return handled;
41 }
42
43 void GpuVideoEncodeAccelerator::OnChannelError() {
44 NotifyError(media::VideoEncodeAccelerator::kPlatformFailureError);
45 if (channel_)
46 channel_ = NULL;
47 }
48
49 void GpuVideoEncodeAccelerator::NotifyInitializeDone() {
50 Send(new AcceleratedVideoEncoderHostMsg_NotifyInitializeDone(route_id_));
51 }
52
53 void GpuVideoEncodeAccelerator::RequireBitstreamBuffers(
54 int input_count,
55 const gfx::Size& input_coded_size,
56 size_t output_buffer_size) {
57 Send(new AcceleratedVideoEncoderHostMsg_RequireBitstreamBuffers(
58 route_id_, input_count, input_coded_size, output_buffer_size));
59 input_coded_size_ = input_coded_size;
60 output_buffer_size_ = output_buffer_size;
61 }
62
63 void GpuVideoEncodeAccelerator::BitstreamBufferReady(int32 bitstream_buffer_id,
64 size_t payload_size,
65 bool key_frame) {
66 Send(new AcceleratedVideoEncoderHostMsg_BitstreamBufferReady(
67 route_id_, bitstream_buffer_id, payload_size, key_frame));
68 }
69
70 void GpuVideoEncodeAccelerator::NotifyError(
71 media::VideoEncodeAccelerator::Error error) {
72 Send(new AcceleratedVideoEncoderHostMsg_NotifyError(route_id_, error));
73 }
74
75 // static
76 std::vector<media::VideoEncodeAccelerator::SupportedProfile>
77 GpuVideoEncodeAccelerator::GetSupportedProfiles() {
78 std::vector<media::VideoEncodeAccelerator::SupportedProfile> profiles;
79
80 // TODO(sheu): return platform-specific profiles.
81 return profiles;
82 }
83
84 void GpuVideoEncodeAccelerator::CreateEncoder() {
85 // TODO(sheu): actual create the encoder.
86 }
87
88 void GpuVideoEncodeAccelerator::OnInitialize(
89 media::VideoFrame::Format input_format,
90 const gfx::Size& input_visible_size,
91 media::VideoCodecProfile output_profile,
92 int32 initial_bitrate) {
93 DVLOG(2) << "GpuVideoEncodeAccelerator::OnInitialize(): "
94 "input_format=" << input_format
95 << ", input_visible_size=" << input_visible_size.ToString()
96 << ", output_profile=" << output_profile
97 << ", initial_bitrate=" << initial_bitrate;
98 DCHECK(!encoder_);
99
100 CreateEncoder();
101 if (!encoder_) {
102 DLOG(ERROR) << "GpuVideoEncodeAccelerator::OnInitialize(): VEA creation "
103 "failed";
104 NotifyError(media::VideoEncodeAccelerator::kPlatformFailureError);
105 return;
106 }
107 encoder_->Initialize(
108 input_format, input_visible_size, output_profile, initial_bitrate);
109 input_format_ = input_format;
110 input_visible_size_ = input_visible_size;
111 }
112
113 void GpuVideoEncodeAccelerator::OnEncode(int32 frame_id,
114 base::SharedMemoryHandle buffer_handle,
115 uint32 buffer_size,
116 bool force_keyframe) {
117 DVLOG(3) << "GpuVideoEncodeAccelerator::OnEncode(): frame_id=" << frame_id
118 << ", buffer_size=" << buffer_size
119 << ", force_keyframe=" << force_keyframe;
120 if (!encoder_)
121 return;
122 if (frame_id < 0) {
123 DLOG(ERROR) << "GpuVideoEncodeAccelerator::OnEncode(): invalid frame_id="
124 << frame_id;
125 NotifyError(media::VideoEncodeAccelerator::kPlatformFailureError);
Ami GONE FROM CHROMIUM 2013/08/08 23:08:19 I think these changes are wrong; here, the trigger
sheu 2013/08/09 00:15:24 Thus triggering condition isn't actually from VEA:
126 return;
127 }
128
129 scoped_ptr<base::SharedMemory> shm(
130 new base::SharedMemory(buffer_handle, true));
131 if (!shm->Map(buffer_size)) {
132 DLOG(ERROR) << "GpuVideoEncodeAccelerator::OnEncode(): "
133 "could not map frame_id=" << frame_id;
134 NotifyError(media::VideoEncodeAccelerator::kPlatformFailureError);
135 return;
136 }
137
138 scoped_refptr<media::VideoFrame> frame;
139 switch (input_format_) {
140 case media::VideoFrame::I420: {
141 if (buffer_size <
142 static_cast<size_t>(input_coded_size_.GetArea() * 3 / 2)) {
143 DLOG(ERROR) << "GpuVideoEncodeAccelerator::OnEncode(): "
144 "buffer too small for frame_id=" << frame_id;
145 NotifyError(media::VideoEncodeAccelerator::kPlatformFailureError);
146 return;
147 }
148 uint8* data = reinterpret_cast<uint8*>(shm->memory());
149 frame = media::VideoFrame::WrapExternalYuvData(
150 media::VideoFrame::I420,
151 input_coded_size_,
152 gfx::Rect(input_visible_size_),
153 input_visible_size_,
154 input_coded_size_.width(),
155 input_coded_size_.width() / 2,
156 input_coded_size_.width() / 2,
157 data,
158 data + input_coded_size_.GetArea(),
159 data + (input_coded_size_.GetArea() * 5 / 4),
160 base::TimeDelta(),
161 buffer_handle,
162 base::Bind(&GpuVideoEncodeAccelerator::EncodeFrameFinished,
163 base::Unretained(this),
164 frame_id,
165 base::Passed(&shm)));
166 break;
167 }
168 default:
169 NOTREACHED();
170 NotifyError(media::VideoEncodeAccelerator::kPlatformFailureError);
171 return;
172 }
173
174 encoder_->Encode(frame, force_keyframe);
175 }
176
177 void GpuVideoEncodeAccelerator::OnUseOutputBitstreamBuffer(
178 int32 buffer_id,
179 base::SharedMemoryHandle buffer_handle,
180 uint32 buffer_size) {
181 DVLOG(3) << "GpuVideoEncodeAccelerator::OnUseOutputBitstreamBuffer(): "
182 "buffer_id=" << buffer_id
183 << ", buffer_size=" << buffer_size;
184 if (!encoder_)
185 return;
186 if (buffer_id < 0) {
187 DLOG(ERROR) << "GpuVideoEncodeAccelerator::OnUseOutputBitstreamBuffer(): "
188 "invalid buffer_id=" << buffer_id;
189 NotifyError(media::VideoEncodeAccelerator::kPlatformFailureError);
190 return;
191 }
192 if (buffer_size < output_buffer_size_) {
193 DLOG(ERROR) << "GpuVideoEncodeAccelerator::OnUseOutputBitstreamBuffer(): "
194 "buffer too small for buffer_id=" << buffer_id;
195 NotifyError(media::VideoEncodeAccelerator::kPlatformFailureError);
196 return;
197 }
198 encoder_->UseOutputBitstreamBuffer(
199 media::BitstreamBuffer(buffer_id, buffer_handle, buffer_size));
200 }
201
202 void GpuVideoEncodeAccelerator::OnRequestEncodingParametersChange(
203 int32 bitrate,
204 uint32 framerate_num,
205 uint32 framerate_denom) {
206 DVLOG(2) << "GpuVideoEncodeAccelerator::OnRequestEncodingParametersChange(): "
207 "bitrate=" << bitrate
208 << ", framerate=" << framerate_num << "/" << framerate_denom;
209 if (!encoder_)
210 return;
211 encoder_->RequestEncodingParametersChange(
Ami GONE FROM CHROMIUM 2013/08/08 23:08:19 If denom is 0 then InvalidArgumentError to avoid b
sheu 2013/08/09 00:15:24 I'll just make it 1-parameter and dispense with th
212 bitrate, framerate_num, framerate_denom);
213 }
214
215 void GpuVideoEncodeAccelerator::EncodeFrameFinished(
216 int32 frame_id,
217 scoped_ptr<base::SharedMemory> shm) {
218 Send(new AcceleratedVideoEncoderHostMsg_NotifyInputDone(route_id_, frame_id));
219 // Just let shm fall out of scope.
220 }
221
222 void GpuVideoEncodeAccelerator::Send(IPC::Message* message) {
223 if (!channel_) {
224 DLOG(ERROR) << "GpuVideoEncodeAccelerator::Send(): no channel";
225 delete message;
226 return;
227 } else if (!channel_->Send(message)) {
228 DLOG(ERROR) << "GpuVideoEncodeAccelerator::Send(): sending failed: "
229 "message->type()=" << message->type();
230 NotifyError(media::VideoEncodeAccelerator::kPlatformFailureError);
231 return;
232 }
233 }
234
235 } // namespace content
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698