| 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/sender/external_video_encoder.h" | 5 #include "media/cast/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" |
| (...skipping 66 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 77 // we can properly destroy the VEA. | 77 // we can properly destroy the VEA. |
| 78 create_vea_cb.Run(base::Bind( | 78 create_vea_cb.Run(base::Bind( |
| 79 &LocalVideoEncodeAcceleratorClient::OnCreateVideoEncodeAcceleratorProxy, | 79 &LocalVideoEncodeAcceleratorClient::OnCreateVideoEncodeAcceleratorProxy, |
| 80 client)); | 80 client)); |
| 81 | 81 |
| 82 return client; | 82 return client; |
| 83 } | 83 } |
| 84 | 84 |
| 85 // Initialize the real HW encoder. | 85 // Initialize the real HW encoder. |
| 86 void Initialize(const VideoSenderConfig& video_config) { | 86 void Initialize(const VideoSenderConfig& video_config) { |
| 87 DCHECK(encoder_task_runner_); | 87 DCHECK(encoder_task_runner_.get()); |
| 88 DCHECK(encoder_task_runner_->RunsTasksOnCurrentThread()); | 88 DCHECK(encoder_task_runner_->RunsTasksOnCurrentThread()); |
| 89 | 89 |
| 90 VideoCodecProfile output_profile = media::VIDEO_CODEC_PROFILE_UNKNOWN; | 90 VideoCodecProfile output_profile = media::VIDEO_CODEC_PROFILE_UNKNOWN; |
| 91 switch (video_config.codec) { | 91 switch (video_config.codec) { |
| 92 case CODEC_VIDEO_VP8: | 92 case CODEC_VIDEO_VP8: |
| 93 output_profile = media::VP8PROFILE_ANY; | 93 output_profile = media::VP8PROFILE_ANY; |
| 94 break; | 94 break; |
| 95 case CODEC_VIDEO_H264: | 95 case CODEC_VIDEO_H264: |
| 96 output_profile = media::H264PROFILE_MAIN; | 96 output_profile = media::H264PROFILE_MAIN; |
| 97 break; | 97 break; |
| (...skipping 19 matching lines...) Expand all Loading... |
| 117 NotifyError(VideoEncodeAccelerator::kInvalidArgumentError); | 117 NotifyError(VideoEncodeAccelerator::kInvalidArgumentError); |
| 118 return; | 118 return; |
| 119 } | 119 } |
| 120 | 120 |
| 121 // Wait until shared memory is allocated to indicate that encoder is | 121 // Wait until shared memory is allocated to indicate that encoder is |
| 122 // initialized. | 122 // initialized. |
| 123 } | 123 } |
| 124 | 124 |
| 125 // Destroy the VEA on the correct thread. | 125 // Destroy the VEA on the correct thread. |
| 126 void Destroy() { | 126 void Destroy() { |
| 127 DCHECK(encoder_task_runner_); | 127 DCHECK(encoder_task_runner_.get()); |
| 128 if (!video_encode_accelerator_) | 128 if (!video_encode_accelerator_) |
| 129 return; | 129 return; |
| 130 | 130 |
| 131 if (encoder_task_runner_->RunsTasksOnCurrentThread()) { | 131 if (encoder_task_runner_->RunsTasksOnCurrentThread()) { |
| 132 video_encode_accelerator_.reset(); | 132 video_encode_accelerator_.reset(); |
| 133 } else { | 133 } else { |
| 134 // We do this instead of just reposting to encoder_task_runner_, because | 134 // We do this instead of just reposting to encoder_task_runner_, because |
| 135 // we are called from the destructor. | 135 // we are called from the destructor. |
| 136 encoder_task_runner_->PostTask( | 136 encoder_task_runner_->PostTask( |
| 137 FROM_HERE, | 137 FROM_HERE, |
| 138 base::Bind(&DestroyVideoEncodeAcceleratorOnEncoderThread, | 138 base::Bind(&DestroyVideoEncodeAcceleratorOnEncoderThread, |
| 139 base::Passed(&video_encode_accelerator_))); | 139 base::Passed(&video_encode_accelerator_))); |
| 140 } | 140 } |
| 141 } | 141 } |
| 142 | 142 |
| 143 void SetBitRate(uint32 bit_rate) { | 143 void SetBitRate(uint32 bit_rate) { |
| 144 DCHECK(encoder_task_runner_); | 144 DCHECK(encoder_task_runner_.get()); |
| 145 DCHECK(encoder_task_runner_->RunsTasksOnCurrentThread()); | 145 DCHECK(encoder_task_runner_->RunsTasksOnCurrentThread()); |
| 146 | 146 |
| 147 video_encode_accelerator_->RequestEncodingParametersChange(bit_rate, | 147 video_encode_accelerator_->RequestEncodingParametersChange(bit_rate, |
| 148 max_frame_rate_); | 148 max_frame_rate_); |
| 149 } | 149 } |
| 150 | 150 |
| 151 void EncodeVideoFrame( | 151 void EncodeVideoFrame( |
| 152 const scoped_refptr<media::VideoFrame>& video_frame, | 152 const scoped_refptr<media::VideoFrame>& video_frame, |
| 153 const base::TimeTicks& capture_time, | 153 const base::TimeTicks& capture_time, |
| 154 bool key_frame_requested, | 154 bool key_frame_requested, |
| 155 const VideoEncoder::FrameEncodedCallback& frame_encoded_callback) { | 155 const VideoEncoder::FrameEncodedCallback& frame_encoded_callback) { |
| 156 DCHECK(encoder_task_runner_); | 156 DCHECK(encoder_task_runner_.get()); |
| 157 DCHECK(encoder_task_runner_->RunsTasksOnCurrentThread()); | 157 DCHECK(encoder_task_runner_->RunsTasksOnCurrentThread()); |
| 158 | 158 |
| 159 encoded_frame_data_storage_.push_back( | 159 encoded_frame_data_storage_.push_back( |
| 160 EncodedFrameReturnData(capture_time, frame_encoded_callback)); | 160 EncodedFrameReturnData(capture_time, frame_encoded_callback)); |
| 161 | 161 |
| 162 // BitstreamBufferReady will be called once the encoder is done. | 162 // BitstreamBufferReady will be called once the encoder is done. |
| 163 video_encode_accelerator_->Encode(video_frame, key_frame_requested); | 163 video_encode_accelerator_->Encode(video_frame, key_frame_requested); |
| 164 } | 164 } |
| 165 | 165 |
| 166 protected: | 166 protected: |
| 167 virtual void NotifyError(VideoEncodeAccelerator::Error error) OVERRIDE { | 167 virtual void NotifyError(VideoEncodeAccelerator::Error error) OVERRIDE { |
| 168 DCHECK(encoder_task_runner_); | 168 DCHECK(encoder_task_runner_.get()); |
| 169 DCHECK(encoder_task_runner_->RunsTasksOnCurrentThread()); | 169 DCHECK(encoder_task_runner_->RunsTasksOnCurrentThread()); |
| 170 VLOG(1) << "ExternalVideoEncoder NotifyError: " << error; | 170 VLOG(1) << "ExternalVideoEncoder NotifyError: " << error; |
| 171 | 171 |
| 172 cast_environment_->PostTask( | 172 cast_environment_->PostTask( |
| 173 CastEnvironment::MAIN, | 173 CastEnvironment::MAIN, |
| 174 FROM_HERE, | 174 FROM_HERE, |
| 175 base::Bind(&ExternalVideoEncoder::EncoderError, weak_owner_)); | 175 base::Bind(&ExternalVideoEncoder::EncoderError, weak_owner_)); |
| 176 } | 176 } |
| 177 | 177 |
| 178 // Called to allocate the input and output buffers. | 178 // Called to allocate the input and output buffers. |
| 179 virtual void RequireBitstreamBuffers(unsigned int input_count, | 179 virtual void RequireBitstreamBuffers(unsigned int input_count, |
| 180 const gfx::Size& input_coded_size, | 180 const gfx::Size& input_coded_size, |
| 181 size_t output_buffer_size) OVERRIDE { | 181 size_t output_buffer_size) OVERRIDE { |
| 182 DCHECK(encoder_task_runner_); | 182 DCHECK(encoder_task_runner_.get()); |
| 183 DCHECK(encoder_task_runner_->RunsTasksOnCurrentThread()); | 183 DCHECK(encoder_task_runner_->RunsTasksOnCurrentThread()); |
| 184 DCHECK(video_encode_accelerator_); | 184 DCHECK(video_encode_accelerator_); |
| 185 | 185 |
| 186 for (size_t j = 0; j < kOutputBufferCount; ++j) { | 186 for (size_t j = 0; j < kOutputBufferCount; ++j) { |
| 187 create_video_encode_memory_cb_.Run( | 187 create_video_encode_memory_cb_.Run( |
| 188 output_buffer_size, | 188 output_buffer_size, |
| 189 base::Bind(&LocalVideoEncodeAcceleratorClient::OnCreateSharedMemory, | 189 base::Bind(&LocalVideoEncodeAcceleratorClient::OnCreateSharedMemory, |
| 190 this)); | 190 this)); |
| 191 } | 191 } |
| 192 } | 192 } |
| 193 | 193 |
| 194 // Encoder has encoded a frame and it's available in one of out output | 194 // Encoder has encoded a frame and it's available in one of out output |
| 195 // buffers. | 195 // buffers. |
| 196 virtual void BitstreamBufferReady(int32 bitstream_buffer_id, | 196 virtual void BitstreamBufferReady(int32 bitstream_buffer_id, |
| 197 size_t payload_size, | 197 size_t payload_size, |
| 198 bool key_frame) OVERRIDE { | 198 bool key_frame) OVERRIDE { |
| 199 DCHECK(encoder_task_runner_); | 199 DCHECK(encoder_task_runner_.get()); |
| 200 DCHECK(encoder_task_runner_->RunsTasksOnCurrentThread()); | 200 DCHECK(encoder_task_runner_->RunsTasksOnCurrentThread()); |
| 201 if (bitstream_buffer_id < 0 || | 201 if (bitstream_buffer_id < 0 || |
| 202 bitstream_buffer_id >= static_cast<int32>(output_buffers_.size())) { | 202 bitstream_buffer_id >= static_cast<int32>(output_buffers_.size())) { |
| 203 NOTREACHED(); | 203 NOTREACHED(); |
| 204 VLOG(1) << "BitstreamBufferReady(): invalid bitstream_buffer_id=" | 204 VLOG(1) << "BitstreamBufferReady(): invalid bitstream_buffer_id=" |
| 205 << bitstream_buffer_id; | 205 << bitstream_buffer_id; |
| 206 NotifyError(media::VideoEncodeAccelerator::kPlatformFailureError); | 206 NotifyError(media::VideoEncodeAccelerator::kPlatformFailureError); |
| 207 return; | 207 return; |
| 208 } | 208 } |
| 209 base::SharedMemory* output_buffer = output_buffers_[bitstream_buffer_id]; | 209 base::SharedMemory* output_buffer = output_buffers_[bitstream_buffer_id]; |
| (...skipping 105 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 315 // Note: This method can be called on any thread. | 315 // Note: This method can be called on any thread. |
| 316 void OnCreateSharedMemory(scoped_ptr<base::SharedMemory> memory) { | 316 void OnCreateSharedMemory(scoped_ptr<base::SharedMemory> memory) { |
| 317 encoder_task_runner_->PostTask( | 317 encoder_task_runner_->PostTask( |
| 318 FROM_HERE, | 318 FROM_HERE, |
| 319 base::Bind(&LocalVideoEncodeAcceleratorClient::ReceivedSharedMemory, | 319 base::Bind(&LocalVideoEncodeAcceleratorClient::ReceivedSharedMemory, |
| 320 this, | 320 this, |
| 321 base::Passed(&memory))); | 321 base::Passed(&memory))); |
| 322 } | 322 } |
| 323 | 323 |
| 324 void ReceivedSharedMemory(scoped_ptr<base::SharedMemory> memory) { | 324 void ReceivedSharedMemory(scoped_ptr<base::SharedMemory> memory) { |
| 325 DCHECK(encoder_task_runner_); | 325 DCHECK(encoder_task_runner_.get()); |
| 326 DCHECK(encoder_task_runner_->RunsTasksOnCurrentThread()); | 326 DCHECK(encoder_task_runner_->RunsTasksOnCurrentThread()); |
| 327 | 327 |
| 328 output_buffers_.push_back(memory.release()); | 328 output_buffers_.push_back(memory.release()); |
| 329 | 329 |
| 330 // Wait until all requested buffers are received. | 330 // Wait until all requested buffers are received. |
| 331 if (output_buffers_.size() < kOutputBufferCount) | 331 if (output_buffers_.size() < kOutputBufferCount) |
| 332 return; | 332 return; |
| 333 | 333 |
| 334 // Immediately provide all output buffers to the VEA. | 334 // Immediately provide all output buffers to the VEA. |
| 335 for (size_t i = 0; i < output_buffers_.size(); ++i) { | 335 for (size_t i = 0; i < output_buffers_.size(); ++i) { |
| (...skipping 50 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 386 encoder_active_(false), | 386 encoder_active_(false), |
| 387 key_frame_requested_(false), | 387 key_frame_requested_(false), |
| 388 weak_factory_(this) { | 388 weak_factory_(this) { |
| 389 DCHECK(cast_environment_->CurrentlyOn(CastEnvironment::MAIN)); | 389 DCHECK(cast_environment_->CurrentlyOn(CastEnvironment::MAIN)); |
| 390 | 390 |
| 391 video_accelerator_client_ = | 391 video_accelerator_client_ = |
| 392 LocalVideoEncodeAcceleratorClient::Create(cast_environment_, | 392 LocalVideoEncodeAcceleratorClient::Create(cast_environment_, |
| 393 create_vea_cb, | 393 create_vea_cb, |
| 394 create_video_encode_mem_cb, | 394 create_video_encode_mem_cb, |
| 395 weak_factory_.GetWeakPtr()); | 395 weak_factory_.GetWeakPtr()); |
| 396 DCHECK(video_accelerator_client_); | 396 DCHECK(video_accelerator_client_.get()); |
| 397 } | 397 } |
| 398 | 398 |
| 399 ExternalVideoEncoder::~ExternalVideoEncoder() { | 399 ExternalVideoEncoder::~ExternalVideoEncoder() { |
| 400 } | 400 } |
| 401 | 401 |
| 402 void ExternalVideoEncoder::EncoderInitialized() { | 402 void ExternalVideoEncoder::EncoderInitialized() { |
| 403 DCHECK(cast_environment_->CurrentlyOn(CastEnvironment::MAIN)); | 403 DCHECK(cast_environment_->CurrentlyOn(CastEnvironment::MAIN)); |
| 404 encoder_active_ = true; | 404 encoder_active_ = true; |
| 405 } | 405 } |
| 406 | 406 |
| (...skipping 58 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 465 DCHECK(cast_environment_->CurrentlyOn(CastEnvironment::MAIN)); | 465 DCHECK(cast_environment_->CurrentlyOn(CastEnvironment::MAIN)); |
| 466 key_frame_requested_ = true; | 466 key_frame_requested_ = true; |
| 467 } | 467 } |
| 468 | 468 |
| 469 // Inform the encoder to only reference frames older or equal to frame_id; | 469 // Inform the encoder to only reference frames older or equal to frame_id; |
| 470 void ExternalVideoEncoder::LatestFrameIdToReference(uint32 /*frame_id*/) { | 470 void ExternalVideoEncoder::LatestFrameIdToReference(uint32 /*frame_id*/) { |
| 471 // Do nothing not supported. | 471 // Do nothing not supported. |
| 472 } | 472 } |
| 473 } // namespace cast | 473 } // namespace cast |
| 474 } // namespace media | 474 } // namespace media |
| OLD | NEW |