| 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 |