OLD | NEW |
1 // Copyright 2014 The Chromium Authors. All rights reserved. | 1 // Copyright 2014 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 "media/cast/video_sender/external_video_encoder.h" | 5 #include "media/cast/video_sender/external_video_encoder.h" |
6 | 6 |
7 #include "base/bind.h" | 7 #include "base/bind.h" |
8 #include "base/logging.h" | 8 #include "base/logging.h" |
9 #include "base/memory/scoped_vector.h" | 9 #include "base/memory/scoped_vector.h" |
10 #include "base/memory/shared_memory.h" | 10 #include "base/memory/shared_memory.h" |
11 #include "base/message_loop/message_loop.h" | 11 #include "base/message_loop/message_loop.h" |
12 #include "media/base/video_frame.h" | 12 #include "media/base/video_frame.h" |
13 #include "media/base/video_util.h" | 13 #include "media/base/video_util.h" |
14 #include "media/cast/cast_defines.h" | 14 #include "media/cast/cast_defines.h" |
15 #include "media/cast/transport/cast_transport_config.h" | 15 #include "media/cast/transport/cast_transport_config.h" |
16 #include "media/video/video_encode_accelerator.h" | 16 #include "media/video/video_encode_accelerator.h" |
17 | 17 |
| 18 namespace media { |
| 19 namespace cast { |
| 20 class LocalVideoEncodeAcceleratorClient; |
| 21 } // namespace cast |
| 22 } // namespace media |
| 23 |
18 namespace { | 24 namespace { |
19 // We allocate more input buffers than what is asked for by | |
20 // RequireBitstreamBuffers() due to potential threading timing. | |
21 static const int kInputBufferExtraCount = 1; | |
22 static const int kOutputBufferCount = 3; | 25 static const int kOutputBufferCount = 3; |
23 | 26 |
24 void LogFrameEncodedEvent(media::cast::CastEnvironment* const cast_environment, | 27 void LogFrameEncodedEvent(media::cast::CastEnvironment* const cast_environment, |
25 const base::TimeTicks& capture_time) { | 28 const base::TimeTicks& capture_time) { |
26 cast_environment->Logging()->InsertFrameEvent( | 29 cast_environment->Logging()->InsertFrameEvent( |
27 cast_environment->Clock()->NowTicks(), | 30 cast_environment->Clock()->NowTicks(), |
28 media::cast::kVideoFrameEncoded, | 31 media::cast::kVideoFrameEncoded, |
29 media::cast::GetVideoRtpTimestamp(capture_time), | 32 media::cast::GetVideoRtpTimestamp(capture_time), |
30 media::cast::kFrameIdUnknown); | 33 media::cast::kFrameIdUnknown); |
31 } | 34 } |
| 35 |
| 36 // Proxy this call to ExternalVideoEncoder on the cast main thread. |
| 37 void ProxyCreateVideoEncodeAccelerator( |
| 38 const scoped_refptr<media::cast::CastEnvironment>& cast_environment, |
| 39 const base::WeakPtr<media::cast::ExternalVideoEncoder>& weak_ptr, |
| 40 const media::cast::CreateVideoEncodeMemoryCallback& |
| 41 create_video_encode_mem_cb, |
| 42 scoped_refptr<base::SingleThreadTaskRunner> encoder_task_runner, |
| 43 scoped_ptr<media::VideoEncodeAccelerator> vea) { |
| 44 cast_environment->PostTask( |
| 45 media::cast::CastEnvironment::MAIN, |
| 46 FROM_HERE, |
| 47 base::Bind( |
| 48 &media::cast::ExternalVideoEncoder::OnCreateVideoEncodeAccelerator, |
| 49 weak_ptr, |
| 50 create_video_encode_mem_cb, |
| 51 encoder_task_runner, |
| 52 base::Passed(&vea))); |
| 53 } |
32 } // namespace | 54 } // namespace |
33 | 55 |
34 namespace media { | 56 namespace media { |
35 namespace cast { | 57 namespace cast { |
36 | 58 |
37 // Container for the associated data of a video frame being processed. | 59 // Container for the associated data of a video frame being processed. |
38 struct EncodedFrameReturnData { | 60 struct EncodedFrameReturnData { |
39 EncodedFrameReturnData(base::TimeTicks c_time, | 61 EncodedFrameReturnData(base::TimeTicks c_time, |
40 VideoEncoder::FrameEncodedCallback callback) { | 62 VideoEncoder::FrameEncodedCallback callback) { |
41 capture_time = c_time; | 63 capture_time = c_time; |
42 frame_encoded_callback = callback; | 64 frame_encoded_callback = callback; |
43 } | 65 } |
44 base::TimeTicks capture_time; | 66 base::TimeTicks capture_time; |
45 VideoEncoder::FrameEncodedCallback frame_encoded_callback; | 67 VideoEncoder::FrameEncodedCallback frame_encoded_callback; |
46 }; | 68 }; |
47 | 69 |
48 // The ExternalVideoEncoder class can be deleted directly by cast, while | 70 // The ExternalVideoEncoder class can be deleted directly by cast, while |
49 // LocalVideoEncodeAcceleratorClient stays around long enough to properly shut | 71 // LocalVideoEncodeAcceleratorClient stays around long enough to properly shut |
50 // down the VideoEncodeAccelerator. | 72 // down the VideoEncodeAccelerator. |
51 class LocalVideoEncodeAcceleratorClient | 73 class LocalVideoEncodeAcceleratorClient |
52 : public VideoEncodeAccelerator::Client, | 74 : public VideoEncodeAccelerator::Client, |
53 public base::RefCountedThreadSafe<LocalVideoEncodeAcceleratorClient> { | 75 public base::RefCountedThreadSafe<LocalVideoEncodeAcceleratorClient> { |
54 public: | 76 public: |
55 LocalVideoEncodeAcceleratorClient( | 77 LocalVideoEncodeAcceleratorClient( |
56 scoped_refptr<CastEnvironment> cast_environment, | 78 scoped_refptr<CastEnvironment> cast_environment, |
57 scoped_refptr<GpuVideoAcceleratorFactories> gpu_factories, | 79 scoped_refptr<base::SingleThreadTaskRunner> encoder_task_runner, |
| 80 scoped_ptr<media::VideoEncodeAccelerator> vea, |
| 81 const CreateVideoEncodeMemoryCallback& create_video_encode_mem_cb, |
58 const base::WeakPtr<ExternalVideoEncoder>& weak_owner) | 82 const base::WeakPtr<ExternalVideoEncoder>& weak_owner) |
59 : cast_environment_(cast_environment), | 83 : cast_environment_(cast_environment), |
60 gpu_factories_(gpu_factories), | 84 encoder_task_runner_(encoder_task_runner), |
61 encoder_task_runner_(gpu_factories->GetTaskRunner()), | 85 video_encode_accelerator_(vea.Pass()), |
| 86 create_video_encode_memory_cb_(create_video_encode_mem_cb), |
62 weak_owner_(weak_owner), | 87 weak_owner_(weak_owner), |
63 last_encoded_frame_id_(kStartFrameId) { | 88 last_encoded_frame_id_(kStartFrameId) { |
64 DCHECK(encoder_task_runner_); | 89 DCHECK(encoder_task_runner_); |
65 } | 90 } |
66 | 91 |
67 // Initialize the real HW encoder. | 92 // Initialize the real HW encoder. |
68 void Initialize(const VideoSenderConfig& video_config) { | 93 void Initialize(const VideoSenderConfig& video_config) { |
69 DCHECK(gpu_factories_); | |
70 DCHECK(encoder_task_runner_); | 94 DCHECK(encoder_task_runner_); |
71 | |
72 DCHECK(encoder_task_runner_->RunsTasksOnCurrentThread()); | 95 DCHECK(encoder_task_runner_->RunsTasksOnCurrentThread()); |
73 | 96 |
74 video_encode_accelerator_ = | |
75 gpu_factories_->CreateVideoEncodeAccelerator().Pass(); | |
76 if (!video_encode_accelerator_) | |
77 return; | |
78 | |
79 VideoCodecProfile output_profile = media::VIDEO_CODEC_PROFILE_UNKNOWN; | 97 VideoCodecProfile output_profile = media::VIDEO_CODEC_PROFILE_UNKNOWN; |
80 switch (video_config.codec) { | 98 switch (video_config.codec) { |
81 case transport::kVp8: | 99 case transport::kVp8: |
82 output_profile = media::VP8PROFILE_MAIN; | 100 output_profile = media::VP8PROFILE_MAIN; |
83 break; | 101 break; |
84 case transport::kH264: | 102 case transport::kH264: |
85 output_profile = media::H264PROFILE_MAIN; | 103 output_profile = media::H264PROFILE_MAIN; |
86 break; | 104 break; |
87 } | 105 } |
88 codec_ = video_config.codec; | 106 codec_ = video_config.codec; |
(...skipping 28 matching lines...) Expand all Loading... |
117 } | 135 } |
118 | 136 |
119 void EncodeVideoFrame( | 137 void EncodeVideoFrame( |
120 const scoped_refptr<media::VideoFrame>& video_frame, | 138 const scoped_refptr<media::VideoFrame>& video_frame, |
121 const base::TimeTicks& capture_time, | 139 const base::TimeTicks& capture_time, |
122 bool key_frame_requested, | 140 bool key_frame_requested, |
123 const VideoEncoder::FrameEncodedCallback& frame_encoded_callback) { | 141 const VideoEncoder::FrameEncodedCallback& frame_encoded_callback) { |
124 DCHECK(encoder_task_runner_); | 142 DCHECK(encoder_task_runner_); |
125 DCHECK(encoder_task_runner_->RunsTasksOnCurrentThread()); | 143 DCHECK(encoder_task_runner_->RunsTasksOnCurrentThread()); |
126 | 144 |
127 if (input_buffers_free_.empty()) { | |
128 NOTREACHED(); | |
129 VLOG(2) << "EncodeVideoFrame(): drop frame due to no hw buffers"; | |
130 return; | |
131 } | |
132 const int index = input_buffers_free_.back(); | |
133 base::SharedMemory* input_buffer = input_buffers_[index]; | |
134 | |
135 // TODO(pwestin): this allocation and copy can be removed once we don't | |
136 // pass the video frame through liblingle. | |
137 | |
138 scoped_refptr<media::VideoFrame> frame = | |
139 media::VideoFrame::WrapExternalPackedMemory( | |
140 video_frame->format(), | |
141 video_frame->coded_size(), | |
142 video_frame->visible_rect(), | |
143 video_frame->natural_size(), | |
144 reinterpret_cast<uint8*>(input_buffer->memory()), | |
145 input_buffer->mapped_size(), | |
146 input_buffer->handle(), | |
147 video_frame->GetTimestamp(), | |
148 base::Bind(&LocalVideoEncodeAcceleratorClient::FinishedWithInBuffer, | |
149 this, | |
150 index)); | |
151 | |
152 if (!frame) { | |
153 VLOG(1) << "EncodeVideoFrame(): failed to create frame"; | |
154 NotifyError(media::VideoEncodeAccelerator::kPlatformFailureError); | |
155 return; | |
156 } | |
157 // Do a stride copy of the input frame to match the input requirements. | |
158 media::CopyYPlane(video_frame->data(VideoFrame::kYPlane), | |
159 video_frame->stride(VideoFrame::kYPlane), | |
160 video_frame->natural_size().height(), | |
161 frame.get()); | |
162 media::CopyUPlane(video_frame->data(VideoFrame::kUPlane), | |
163 video_frame->stride(VideoFrame::kUPlane), | |
164 video_frame->natural_size().height(), | |
165 frame.get()); | |
166 media::CopyVPlane(video_frame->data(VideoFrame::kVPlane), | |
167 video_frame->stride(VideoFrame::kVPlane), | |
168 video_frame->natural_size().height(), | |
169 frame.get()); | |
170 | |
171 encoded_frame_data_storage_.push_back( | 145 encoded_frame_data_storage_.push_back( |
172 EncodedFrameReturnData(capture_time, frame_encoded_callback)); | 146 EncodedFrameReturnData(capture_time, frame_encoded_callback)); |
173 | 147 |
174 // BitstreamBufferReady will be called once the encoder is done. | 148 // BitstreamBufferReady will be called once the encoder is done. |
175 video_encode_accelerator_->Encode(frame, key_frame_requested); | 149 video_encode_accelerator_->Encode(video_frame, key_frame_requested); |
176 } | 150 } |
177 | 151 |
178 protected: | 152 protected: |
179 virtual void NotifyInitializeDone() OVERRIDE { | 153 virtual void NotifyInitializeDone() OVERRIDE { |
180 DCHECK(encoder_task_runner_); | 154 DCHECK(encoder_task_runner_); |
181 DCHECK(encoder_task_runner_->RunsTasksOnCurrentThread()); | 155 DCHECK(encoder_task_runner_->RunsTasksOnCurrentThread()); |
182 | 156 |
183 cast_environment_->PostTask( | 157 // Wait until shared memory is allocated to indicate that encoder is |
184 CastEnvironment::MAIN, | 158 // initialized. |
185 FROM_HERE, | |
186 base::Bind(&ExternalVideoEncoder::EncoderInitialized, weak_owner_)); | |
187 } | 159 } |
188 | 160 |
189 virtual void NotifyError(VideoEncodeAccelerator::Error error) OVERRIDE { | 161 virtual void NotifyError(VideoEncodeAccelerator::Error error) OVERRIDE { |
190 DCHECK(encoder_task_runner_); | 162 DCHECK(encoder_task_runner_); |
191 DCHECK(encoder_task_runner_->RunsTasksOnCurrentThread()); | 163 DCHECK(encoder_task_runner_->RunsTasksOnCurrentThread()); |
192 VLOG(1) << "ExternalVideoEncoder NotifyError: " << error; | 164 VLOG(1) << "ExternalVideoEncoder NotifyError: " << error; |
193 | 165 |
194 if (video_encode_accelerator_) { | 166 if (video_encode_accelerator_) { |
195 video_encode_accelerator_.release()->Destroy(); | 167 video_encode_accelerator_.release()->Destroy(); |
196 } | 168 } |
197 cast_environment_->PostTask( | 169 cast_environment_->PostTask( |
198 CastEnvironment::MAIN, | 170 CastEnvironment::MAIN, |
199 FROM_HERE, | 171 FROM_HERE, |
200 base::Bind(&ExternalVideoEncoder::EncoderError, weak_owner_)); | 172 base::Bind(&ExternalVideoEncoder::EncoderError, weak_owner_)); |
201 } | 173 } |
202 | 174 |
203 // Called to allocate the input and output buffers. | 175 // Called to allocate the input and output buffers. |
204 virtual void RequireBitstreamBuffers(unsigned int input_count, | 176 virtual void RequireBitstreamBuffers(unsigned int input_count, |
205 const gfx::Size& input_coded_size, | 177 const gfx::Size& input_coded_size, |
206 size_t output_buffer_size) OVERRIDE { | 178 size_t output_buffer_size) OVERRIDE { |
207 DCHECK(encoder_task_runner_); | 179 DCHECK(encoder_task_runner_); |
208 DCHECK(encoder_task_runner_->RunsTasksOnCurrentThread()); | 180 DCHECK(encoder_task_runner_->RunsTasksOnCurrentThread()); |
209 DCHECK(video_encode_accelerator_); | 181 DCHECK(video_encode_accelerator_); |
210 | 182 |
211 for (unsigned int i = 0; i < input_count + kInputBufferExtraCount; ++i) { | |
212 base::SharedMemory* shm = | |
213 gpu_factories_->CreateSharedMemory(media::VideoFrame::AllocationSize( | |
214 media::VideoFrame::I420, input_coded_size)); | |
215 if (!shm) { | |
216 VLOG(1) << "RequireBitstreamBuffers(): failed to create input buffer "; | |
217 return; | |
218 } | |
219 input_buffers_.push_back(shm); | |
220 input_buffers_free_.push_back(i); | |
221 } | |
222 | |
223 for (int j = 0; j < kOutputBufferCount; ++j) { | 183 for (int j = 0; j < kOutputBufferCount; ++j) { |
224 base::SharedMemory* shm = | 184 create_video_encode_memory_cb_.Run( |
225 gpu_factories_->CreateSharedMemory(output_buffer_size); | 185 output_buffer_size, |
226 if (!shm) { | 186 base::Bind(&LocalVideoEncodeAcceleratorClient::OnCreateSharedMemory, |
227 VLOG(1) << "RequireBitstreamBuffers(): failed to create input buffer "; | 187 this)); |
228 return; | |
229 } | |
230 output_buffers_.push_back(shm); | |
231 } | |
232 // Immediately provide all output buffers to the VEA. | |
233 for (size_t i = 0; i < output_buffers_.size(); ++i) { | |
234 video_encode_accelerator_->UseOutputBitstreamBuffer( | |
235 media::BitstreamBuffer(static_cast<int32>(i), | |
236 output_buffers_[i]->handle(), | |
237 output_buffers_[i]->mapped_size())); | |
238 } | 188 } |
239 } | 189 } |
240 | 190 |
241 // Encoder has encoded a frame and it's available in one of out output | 191 // Encoder has encoded a frame and it's available in one of out output |
242 // buffers. | 192 // buffers. |
243 virtual void BitstreamBufferReady(int32 bitstream_buffer_id, | 193 virtual void BitstreamBufferReady(int32 bitstream_buffer_id, |
244 size_t payload_size, | 194 size_t payload_size, |
245 bool key_frame) OVERRIDE { | 195 bool key_frame) OVERRIDE { |
246 DCHECK(encoder_task_runner_); | 196 DCHECK(encoder_task_runner_); |
247 DCHECK(encoder_task_runner_->RunsTasksOnCurrentThread()); | 197 DCHECK(encoder_task_runner_->RunsTasksOnCurrentThread()); |
(...skipping 54 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
302 | 252 |
303 // We need to re-add the output buffer to the encoder after we are done | 253 // We need to re-add the output buffer to the encoder after we are done |
304 // with it. | 254 // with it. |
305 video_encode_accelerator_->UseOutputBitstreamBuffer(media::BitstreamBuffer( | 255 video_encode_accelerator_->UseOutputBitstreamBuffer(media::BitstreamBuffer( |
306 bitstream_buffer_id, | 256 bitstream_buffer_id, |
307 output_buffers_[bitstream_buffer_id]->handle(), | 257 output_buffers_[bitstream_buffer_id]->handle(), |
308 output_buffers_[bitstream_buffer_id]->mapped_size())); | 258 output_buffers_[bitstream_buffer_id]->mapped_size())); |
309 } | 259 } |
310 | 260 |
311 private: | 261 private: |
312 // Encoder is done with the provided input buffer. | 262 // Note: This method can be called on any thread. |
313 void FinishedWithInBuffer(int input_index) { | 263 void OnCreateSharedMemory(scoped_ptr<base::SharedMemory> memory) { |
| 264 encoder_task_runner_->PostTask( |
| 265 FROM_HERE, |
| 266 base::Bind(&LocalVideoEncodeAcceleratorClient::ReceivedSharedMemory, |
| 267 this, |
| 268 base::Passed(&memory))); |
| 269 } |
| 270 |
| 271 void ReceivedSharedMemory(scoped_ptr<base::SharedMemory> memory) { |
314 DCHECK(encoder_task_runner_); | 272 DCHECK(encoder_task_runner_); |
315 DCHECK(encoder_task_runner_->RunsTasksOnCurrentThread()); | 273 DCHECK(encoder_task_runner_->RunsTasksOnCurrentThread()); |
316 DCHECK_GE(input_index, 0); | 274 |
317 DCHECK_LT(input_index, static_cast<int>(input_buffers_.size())); | 275 output_buffers_.push_back(memory.release()); |
318 VLOG(2) << "EncodeFrameFinished(): index=" << input_index; | 276 |
319 input_buffers_free_.push_back(input_index); | 277 // Wait until all requested buffers are received. |
| 278 if (output_buffers_.size() < kOutputBufferCount) |
| 279 return; |
| 280 |
| 281 // Immediately provide all output buffers to the VEA. |
| 282 for (size_t i = 0; i < output_buffers_.size(); ++i) { |
| 283 video_encode_accelerator_->UseOutputBitstreamBuffer( |
| 284 media::BitstreamBuffer(static_cast<int32>(i), |
| 285 output_buffers_[i]->handle(), |
| 286 output_buffers_[i]->mapped_size())); |
| 287 } |
| 288 |
| 289 cast_environment_->PostTask( |
| 290 CastEnvironment::MAIN, |
| 291 FROM_HERE, |
| 292 base::Bind(&ExternalVideoEncoder::EncoderInitialized, weak_owner_)); |
320 } | 293 } |
321 | 294 |
322 friend class base::RefCountedThreadSafe<LocalVideoEncodeAcceleratorClient>; | 295 friend class base::RefCountedThreadSafe<LocalVideoEncodeAcceleratorClient>; |
323 | 296 |
324 virtual ~LocalVideoEncodeAcceleratorClient() {} | 297 virtual ~LocalVideoEncodeAcceleratorClient() {} |
325 | 298 |
326 const scoped_refptr<CastEnvironment> cast_environment_; | 299 const scoped_refptr<CastEnvironment> cast_environment_; |
327 scoped_refptr<GpuVideoAcceleratorFactories> gpu_factories_; | |
328 scoped_refptr<base::SingleThreadTaskRunner> encoder_task_runner_; | 300 scoped_refptr<base::SingleThreadTaskRunner> encoder_task_runner_; |
| 301 scoped_ptr<media::VideoEncodeAccelerator> video_encode_accelerator_; |
| 302 const CreateVideoEncodeMemoryCallback create_video_encode_memory_cb_; |
329 const base::WeakPtr<ExternalVideoEncoder> weak_owner_; | 303 const base::WeakPtr<ExternalVideoEncoder> weak_owner_; |
330 | |
331 scoped_ptr<media::VideoEncodeAccelerator> video_encode_accelerator_; | |
332 int max_frame_rate_; | 304 int max_frame_rate_; |
333 transport::VideoCodec codec_; | 305 transport::VideoCodec codec_; |
334 uint32 last_encoded_frame_id_; | 306 uint32 last_encoded_frame_id_; |
335 | 307 |
336 // Shared memory buffers for input/output with the VideoAccelerator. | 308 // Shared memory buffers for output with the VideoAccelerator. |
337 ScopedVector<base::SharedMemory> input_buffers_; | |
338 ScopedVector<base::SharedMemory> output_buffers_; | 309 ScopedVector<base::SharedMemory> output_buffers_; |
339 | 310 |
340 // Input buffers ready to be filled with input from Encode(). As a LIFO since | |
341 // we don't care about ordering. | |
342 std::vector<int> input_buffers_free_; | |
343 | |
344 // FIFO list. | 311 // FIFO list. |
345 std::list<EncodedFrameReturnData> encoded_frame_data_storage_; | 312 std::list<EncodedFrameReturnData> encoded_frame_data_storage_; |
346 | 313 |
347 DISALLOW_COPY_AND_ASSIGN(LocalVideoEncodeAcceleratorClient); | 314 DISALLOW_COPY_AND_ASSIGN(LocalVideoEncodeAcceleratorClient); |
348 }; | 315 }; |
349 | 316 |
350 ExternalVideoEncoder::ExternalVideoEncoder( | 317 ExternalVideoEncoder::ExternalVideoEncoder( |
351 scoped_refptr<CastEnvironment> cast_environment, | 318 scoped_refptr<CastEnvironment> cast_environment, |
352 const VideoSenderConfig& video_config, | 319 const VideoSenderConfig& video_config, |
353 scoped_refptr<GpuVideoAcceleratorFactories> gpu_factories) | 320 const CreateVideoEncodeAcceleratorCallback& create_vea_cb, |
| 321 const CreateVideoEncodeMemoryCallback& create_video_encode_mem_cb) |
354 : video_config_(video_config), | 322 : video_config_(video_config), |
355 cast_environment_(cast_environment), | 323 cast_environment_(cast_environment), |
356 encoder_active_(false), | 324 encoder_active_(false), |
357 key_frame_requested_(false), | 325 key_frame_requested_(false), |
358 skip_next_frame_(false), | 326 skip_next_frame_(false), |
359 skip_count_(0), | 327 skip_count_(0), |
360 encoder_task_runner_(gpu_factories->GetTaskRunner()), | |
361 weak_factory_(this) { | 328 weak_factory_(this) { |
362 DCHECK(gpu_factories); | |
363 DCHECK(cast_environment_->CurrentlyOn(CastEnvironment::MAIN)); | 329 DCHECK(cast_environment_->CurrentlyOn(CastEnvironment::MAIN)); |
364 video_accelerator_client_ = new LocalVideoEncodeAcceleratorClient( | |
365 cast_environment, gpu_factories, weak_factory_.GetWeakPtr()); | |
366 | 330 |
367 encoder_task_runner_->PostTask( | 331 create_vea_cb.Run(base::Bind(&ProxyCreateVideoEncodeAccelerator, |
368 FROM_HERE, | 332 cast_environment, |
369 base::Bind(&LocalVideoEncodeAcceleratorClient::Initialize, | 333 weak_factory_.GetWeakPtr(), |
370 video_accelerator_client_, | 334 create_video_encode_mem_cb)); |
371 video_config)); | |
372 } | 335 } |
373 | 336 |
374 ExternalVideoEncoder::~ExternalVideoEncoder() { | 337 ExternalVideoEncoder::~ExternalVideoEncoder() { |
375 encoder_task_runner_->PostTask( | 338 encoder_task_runner_->PostTask( |
376 FROM_HERE, | 339 FROM_HERE, |
377 base::Bind(&LocalVideoEncodeAcceleratorClient::Destroy, | 340 base::Bind(&LocalVideoEncodeAcceleratorClient::Destroy, |
378 video_accelerator_client_)); | 341 video_accelerator_client_)); |
379 } | 342 } |
380 | 343 |
381 void ExternalVideoEncoder::EncoderInitialized() { | 344 void ExternalVideoEncoder::EncoderInitialized() { |
382 DCHECK(cast_environment_->CurrentlyOn(CastEnvironment::MAIN)); | 345 DCHECK(cast_environment_->CurrentlyOn(CastEnvironment::MAIN)); |
383 encoder_active_ = true; | 346 encoder_active_ = true; |
384 } | 347 } |
385 | 348 |
386 void ExternalVideoEncoder::EncoderError() { | 349 void ExternalVideoEncoder::EncoderError() { |
387 DCHECK(cast_environment_->CurrentlyOn(CastEnvironment::MAIN)); | 350 DCHECK(cast_environment_->CurrentlyOn(CastEnvironment::MAIN)); |
388 encoder_active_ = false; | 351 encoder_active_ = false; |
389 } | 352 } |
390 | 353 |
| 354 void ExternalVideoEncoder::OnCreateVideoEncodeAccelerator( |
| 355 const CreateVideoEncodeMemoryCallback& create_video_encode_mem_cb, |
| 356 scoped_refptr<base::SingleThreadTaskRunner> encoder_task_runner, |
| 357 scoped_ptr<media::VideoEncodeAccelerator> vea) { |
| 358 DCHECK(cast_environment_->CurrentlyOn(CastEnvironment::MAIN)); |
| 359 encoder_task_runner_ = encoder_task_runner; |
| 360 |
| 361 video_accelerator_client_ = |
| 362 new LocalVideoEncodeAcceleratorClient(cast_environment_, |
| 363 encoder_task_runner, |
| 364 vea.Pass(), |
| 365 create_video_encode_mem_cb, |
| 366 weak_factory_.GetWeakPtr()); |
| 367 encoder_task_runner_->PostTask( |
| 368 FROM_HERE, |
| 369 base::Bind(&LocalVideoEncodeAcceleratorClient::Initialize, |
| 370 video_accelerator_client_, |
| 371 video_config_)); |
| 372 } |
| 373 |
391 bool ExternalVideoEncoder::EncodeVideoFrame( | 374 bool ExternalVideoEncoder::EncodeVideoFrame( |
392 const scoped_refptr<media::VideoFrame>& video_frame, | 375 const scoped_refptr<media::VideoFrame>& video_frame, |
393 const base::TimeTicks& capture_time, | 376 const base::TimeTicks& capture_time, |
394 const FrameEncodedCallback& frame_encoded_callback) { | 377 const FrameEncodedCallback& frame_encoded_callback) { |
395 DCHECK(cast_environment_->CurrentlyOn(CastEnvironment::MAIN)); | 378 DCHECK(cast_environment_->CurrentlyOn(CastEnvironment::MAIN)); |
396 | 379 |
397 if (!encoder_active_) | 380 if (!encoder_active_) |
398 return false; | 381 return false; |
399 | 382 |
400 if (skip_next_frame_) { | 383 if (skip_next_frame_) { |
(...skipping 48 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
449 // Do nothing not supported. | 432 // Do nothing not supported. |
450 } | 433 } |
451 | 434 |
452 int ExternalVideoEncoder::NumberOfSkippedFrames() const { | 435 int ExternalVideoEncoder::NumberOfSkippedFrames() const { |
453 DCHECK(cast_environment_->CurrentlyOn(CastEnvironment::MAIN)); | 436 DCHECK(cast_environment_->CurrentlyOn(CastEnvironment::MAIN)); |
454 return skip_count_; | 437 return skip_count_; |
455 } | 438 } |
456 | 439 |
457 } // namespace cast | 440 } // namespace cast |
458 } // namespace media | 441 } // namespace media |
OLD | NEW |