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

Side by Side Diff: media/cast/sender/external_video_encoder.cc

Issue 901833004: [Cast] Repurpose CastInitializationStatus for variable frame size support. (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Compile fixes. Created 5 years, 10 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
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 45 matching lines...) Expand 10 before | Expand all | Expand 10 after
56 // SingleThreadTaskRunner, except for the task_runner() accessor. 56 // SingleThreadTaskRunner, except for the task_runner() accessor.
57 class ExternalVideoEncoder::VEAClientImpl 57 class ExternalVideoEncoder::VEAClientImpl
58 : public VideoEncodeAccelerator::Client, 58 : public VideoEncodeAccelerator::Client,
59 public base::RefCountedThreadSafe<VEAClientImpl> { 59 public base::RefCountedThreadSafe<VEAClientImpl> {
60 public: 60 public:
61 VEAClientImpl( 61 VEAClientImpl(
62 const scoped_refptr<CastEnvironment>& cast_environment, 62 const scoped_refptr<CastEnvironment>& cast_environment,
63 const scoped_refptr<base::SingleThreadTaskRunner>& encoder_task_runner, 63 const scoped_refptr<base::SingleThreadTaskRunner>& encoder_task_runner,
64 scoped_ptr<media::VideoEncodeAccelerator> vea, 64 scoped_ptr<media::VideoEncodeAccelerator> vea,
65 int max_frame_rate, 65 int max_frame_rate,
66 const StatusChangeCallback& status_change_cb,
66 const CreateVideoEncodeMemoryCallback& create_video_encode_memory_cb) 67 const CreateVideoEncodeMemoryCallback& create_video_encode_memory_cb)
67 : cast_environment_(cast_environment), 68 : cast_environment_(cast_environment),
68 task_runner_(encoder_task_runner), 69 task_runner_(encoder_task_runner),
69 max_frame_rate_(max_frame_rate), 70 max_frame_rate_(max_frame_rate),
71 status_change_cb_(status_change_cb),
70 create_video_encode_memory_cb_(create_video_encode_memory_cb), 72 create_video_encode_memory_cb_(create_video_encode_memory_cb),
71 video_encode_accelerator_(vea.Pass()), 73 video_encode_accelerator_(vea.Pass()),
72 encoder_active_(false), 74 encoder_active_(false),
73 last_encoded_frame_id_(kStartFrameId), 75 last_encoded_frame_id_(kStartFrameId),
74 key_frame_encountered_(false) { 76 key_frame_encountered_(false) {
75 } 77 }
76 78
77 base::SingleThreadTaskRunner* task_runner() const { 79 base::SingleThreadTaskRunner* task_runner() const {
78 return task_runner_.get(); 80 return task_runner_.get();
79 } 81 }
80 82
81 void Initialize(const gfx::Size& frame_size, 83 void Initialize(const gfx::Size& frame_size,
82 VideoCodecProfile codec_profile, 84 VideoCodecProfile codec_profile,
83 int start_bit_rate, 85 int start_bit_rate) {
84 const CastInitializationCallback& initialization_cb) {
85 DCHECK(task_runner_->RunsTasksOnCurrentThread()); 86 DCHECK(task_runner_->RunsTasksOnCurrentThread());
86 DCHECK(!frame_size.IsEmpty()); 87 DCHECK(!frame_size.IsEmpty());
87 88
88 encoder_active_ = video_encode_accelerator_->Initialize( 89 encoder_active_ = video_encode_accelerator_->Initialize(
89 media::VideoFrame::I420, 90 media::VideoFrame::I420,
90 frame_size, 91 frame_size,
91 codec_profile, 92 codec_profile,
92 start_bit_rate, 93 start_bit_rate,
93 this); 94 this);
94 95
95 UMA_HISTOGRAM_BOOLEAN("Cast.Sender.VideoEncodeAcceleratorInitializeSuccess", 96 UMA_HISTOGRAM_BOOLEAN("Cast.Sender.VideoEncodeAcceleratorInitializeSuccess",
96 encoder_active_); 97 encoder_active_);
97 98
98 if (!initialization_cb.is_null()) { 99 cast_environment_->PostTask(
99 cast_environment_->PostTask( 100 CastEnvironment::MAIN,
100 CastEnvironment::MAIN, 101 FROM_HERE,
101 FROM_HERE, 102 base::Bind(status_change_cb_,
102 base::Bind(initialization_cb, 103 encoder_active_ ? STATUS_INITIALIZED :
103 encoder_active_ ? STATUS_VIDEO_INITIALIZED : 104 STATUS_CODEC_INIT_FAILED));
104 STATUS_HW_VIDEO_ENCODER_NOT_SUPPORTED));
105 }
106 } 105 }
107 106
108 void SetBitRate(int bit_rate) { 107 void SetBitRate(int bit_rate) {
109 DCHECK(task_runner_->RunsTasksOnCurrentThread()); 108 DCHECK(task_runner_->RunsTasksOnCurrentThread());
110 109
111 video_encode_accelerator_->RequestEncodingParametersChange(bit_rate, 110 video_encode_accelerator_->RequestEncodingParametersChange(bit_rate,
112 max_frame_rate_); 111 max_frame_rate_);
113 } 112 }
114 113
115 void EncodeVideoFrame( 114 void EncodeVideoFrame(
(...skipping 11 matching lines...) Expand all
127 reference_time, 126 reference_time,
128 frame_encoded_callback)); 127 frame_encoded_callback));
129 128
130 // BitstreamBufferReady will be called once the encoder is done. 129 // BitstreamBufferReady will be called once the encoder is done.
131 video_encode_accelerator_->Encode(video_frame, key_frame_requested); 130 video_encode_accelerator_->Encode(video_frame, key_frame_requested);
132 } 131 }
133 132
134 protected: 133 protected:
135 void NotifyError(VideoEncodeAccelerator::Error error) override { 134 void NotifyError(VideoEncodeAccelerator::Error error) override {
136 DCHECK(task_runner_->RunsTasksOnCurrentThread()); 135 DCHECK(task_runner_->RunsTasksOnCurrentThread());
137 VLOG(1) << "ExternalVideoEncoder NotifyError: " << error; 136
137 DCHECK(error != VideoEncodeAccelerator::kInvalidArgumentError &&
138 error != VideoEncodeAccelerator::kIllegalStateError);
138 139
139 encoder_active_ = false; 140 encoder_active_ = false;
140 // TODO(miu): Plumbing is required to bubble this up to the CastSession and 141
141 // beyond. 142 cast_environment_->PostTask(
143 CastEnvironment::MAIN,
144 FROM_HERE,
145 base::Bind(status_change_cb_, STATUS_CODEC_RUNTIME_ERROR));
146
142 // TODO(miu): Force-flush all |in_progress_frame_encodes_| immediately so 147 // TODO(miu): Force-flush all |in_progress_frame_encodes_| immediately so
143 // pending frames do not become stuck, freezing VideoSender. 148 // pending frames do not become stuck, freezing VideoSender.
144 } 149 }
145 150
146 // Called to allocate the input and output buffers. 151 // Called to allocate the input and output buffers.
147 void RequireBitstreamBuffers(unsigned int input_count, 152 void RequireBitstreamBuffers(unsigned int input_count,
148 const gfx::Size& input_coded_size, 153 const gfx::Size& input_coded_size,
149 size_t output_buffer_size) override { 154 size_t output_buffer_size) override {
150 DCHECK(task_runner_->RunsTasksOnCurrentThread()); 155 DCHECK(task_runner_->RunsTasksOnCurrentThread());
151 156
(...skipping 122 matching lines...) Expand 10 before | Expand all | Expand 10 after
274 video_encode_accelerator_->UseOutputBitstreamBuffer( 279 video_encode_accelerator_->UseOutputBitstreamBuffer(
275 media::BitstreamBuffer(static_cast<int32>(i), 280 media::BitstreamBuffer(static_cast<int32>(i),
276 output_buffers_[i]->handle(), 281 output_buffers_[i]->handle(),
277 output_buffers_[i]->mapped_size())); 282 output_buffers_[i]->mapped_size()));
278 } 283 }
279 } 284 }
280 285
281 const scoped_refptr<CastEnvironment> cast_environment_; 286 const scoped_refptr<CastEnvironment> cast_environment_;
282 const scoped_refptr<base::SingleThreadTaskRunner> task_runner_; 287 const scoped_refptr<base::SingleThreadTaskRunner> task_runner_;
283 const int max_frame_rate_; 288 const int max_frame_rate_;
289 const StatusChangeCallback status_change_cb_; // Must be run on MAIN thread.
284 const CreateVideoEncodeMemoryCallback create_video_encode_memory_cb_; 290 const CreateVideoEncodeMemoryCallback create_video_encode_memory_cb_;
285 scoped_ptr<media::VideoEncodeAccelerator> video_encode_accelerator_; 291 scoped_ptr<media::VideoEncodeAccelerator> video_encode_accelerator_;
286 bool encoder_active_; 292 bool encoder_active_;
287 uint32 last_encoded_frame_id_; 293 uint32 last_encoded_frame_id_;
288 bool key_frame_encountered_; 294 bool key_frame_encountered_;
289 std::string stream_header_; 295 std::string stream_header_;
290 296
291 // Shared memory buffers for output with the VideoAccelerator. 297 // Shared memory buffers for output with the VideoAccelerator.
292 ScopedVector<base::SharedMemory> output_buffers_; 298 ScopedVector<base::SharedMemory> output_buffers_;
293 299
294 // FIFO list. 300 // FIFO list.
295 std::list<InProgressFrameEncode> in_progress_frame_encodes_; 301 std::list<InProgressFrameEncode> in_progress_frame_encodes_;
296 302
297 DISALLOW_COPY_AND_ASSIGN(VEAClientImpl); 303 DISALLOW_COPY_AND_ASSIGN(VEAClientImpl);
298 }; 304 };
299 305
300 ExternalVideoEncoder::ExternalVideoEncoder( 306 ExternalVideoEncoder::ExternalVideoEncoder(
301 const scoped_refptr<CastEnvironment>& cast_environment, 307 const scoped_refptr<CastEnvironment>& cast_environment,
302 const VideoSenderConfig& video_config, 308 const VideoSenderConfig& video_config,
303 const gfx::Size& frame_size, 309 const gfx::Size& frame_size,
304 const CastInitializationCallback& initialization_cb, 310 const StatusChangeCallback& status_change_cb,
305 const CreateVideoEncodeAcceleratorCallback& create_vea_cb, 311 const CreateVideoEncodeAcceleratorCallback& create_vea_cb,
306 const CreateVideoEncodeMemoryCallback& create_video_encode_memory_cb) 312 const CreateVideoEncodeMemoryCallback& create_video_encode_memory_cb)
307 : cast_environment_(cast_environment), 313 : cast_environment_(cast_environment),
308 create_video_encode_memory_cb_(create_video_encode_memory_cb), 314 create_video_encode_memory_cb_(create_video_encode_memory_cb),
309 bit_rate_(video_config.start_bitrate), 315 bit_rate_(video_config.start_bitrate),
310 key_frame_requested_(false), 316 key_frame_requested_(false),
311 weak_factory_(this) { 317 weak_factory_(this) {
312 DCHECK(cast_environment_->CurrentlyOn(CastEnvironment::MAIN)); 318 DCHECK(cast_environment_->CurrentlyOn(CastEnvironment::MAIN));
313 DCHECK_GT(video_config.max_frame_rate, 0); 319 DCHECK_GT(video_config.max_frame_rate, 0);
314 DCHECK(!frame_size.IsEmpty()); 320 DCHECK(!frame_size.IsEmpty());
321 DCHECK(!status_change_cb.is_null());
315 DCHECK(!create_vea_cb.is_null()); 322 DCHECK(!create_vea_cb.is_null());
316 DCHECK(!create_video_encode_memory_cb_.is_null()); 323 DCHECK(!create_video_encode_memory_cb_.is_null());
317 DCHECK_GT(bit_rate_, 0); 324 DCHECK_GT(bit_rate_, 0);
318 325
319 VideoCodecProfile codec_profile; 326 VideoCodecProfile codec_profile;
320 switch (video_config.codec) { 327 switch (video_config.codec) {
321 case CODEC_VIDEO_VP8: 328 case CODEC_VIDEO_VP8:
322 codec_profile = media::VP8PROFILE_ANY; 329 codec_profile = media::VP8PROFILE_ANY;
323 break; 330 break;
324 case CODEC_VIDEO_H264: 331 case CODEC_VIDEO_H264:
325 codec_profile = media::H264PROFILE_MAIN; 332 codec_profile = media::H264PROFILE_MAIN;
326 break; 333 break;
327 case CODEC_VIDEO_FAKE: 334 case CODEC_VIDEO_FAKE:
328 NOTREACHED() << "Fake software video encoder cannot be external"; 335 NOTREACHED() << "Fake software video encoder cannot be external";
329 // ...flow through to next case... 336 // ...flow through to next case...
330 default: 337 default:
331 cast_environment_->PostTask( 338 cast_environment_->PostTask(
332 CastEnvironment::MAIN, 339 CastEnvironment::MAIN,
333 FROM_HERE, 340 FROM_HERE,
334 base::Bind(initialization_cb, STATUS_HW_VIDEO_ENCODER_NOT_SUPPORTED)); 341 base::Bind(status_change_cb, STATUS_UNSUPPORTED_CODEC));
335 return; 342 return;
336 } 343 }
337 344
338 create_vea_cb.Run( 345 create_vea_cb.Run(
339 base::Bind(&ExternalVideoEncoder::OnCreateVideoEncodeAccelerator, 346 base::Bind(&ExternalVideoEncoder::OnCreateVideoEncodeAccelerator,
340 weak_factory_.GetWeakPtr(), 347 weak_factory_.GetWeakPtr(),
341 frame_size, 348 frame_size,
342 codec_profile, 349 codec_profile,
343 video_config.max_frame_rate, 350 video_config.max_frame_rate,
344 initialization_cb)); 351 status_change_cb));
345 } 352 }
346 353
347 ExternalVideoEncoder::~ExternalVideoEncoder() { 354 ExternalVideoEncoder::~ExternalVideoEncoder() {
348 } 355 }
349 356
350 bool ExternalVideoEncoder::CanEncodeVariedFrameSizes() const { 357 bool ExternalVideoEncoder::CanEncodeVariedFrameSizes() const {
351 return false; 358 return false;
352 } 359 }
353 360
354 bool ExternalVideoEncoder::EncodeVideoFrame( 361 bool ExternalVideoEncoder::EncodeVideoFrame(
(...skipping 35 matching lines...) Expand 10 before | Expand all | Expand 10 after
390 } 397 }
391 398
392 void ExternalVideoEncoder::LatestFrameIdToReference(uint32 /*frame_id*/) { 399 void ExternalVideoEncoder::LatestFrameIdToReference(uint32 /*frame_id*/) {
393 // Do nothing. Not supported. 400 // Do nothing. Not supported.
394 } 401 }
395 402
396 void ExternalVideoEncoder::OnCreateVideoEncodeAccelerator( 403 void ExternalVideoEncoder::OnCreateVideoEncodeAccelerator(
397 const gfx::Size& frame_size, 404 const gfx::Size& frame_size,
398 VideoCodecProfile codec_profile, 405 VideoCodecProfile codec_profile,
399 int max_frame_rate, 406 int max_frame_rate,
400 const CastInitializationCallback& initialization_cb, 407 const StatusChangeCallback& status_change_cb,
401 scoped_refptr<base::SingleThreadTaskRunner> encoder_task_runner, 408 scoped_refptr<base::SingleThreadTaskRunner> encoder_task_runner,
402 scoped_ptr<media::VideoEncodeAccelerator> vea) { 409 scoped_ptr<media::VideoEncodeAccelerator> vea) {
403 DCHECK(cast_environment_->CurrentlyOn(CastEnvironment::MAIN)); 410 DCHECK(cast_environment_->CurrentlyOn(CastEnvironment::MAIN));
404 411
405 // The callback will be invoked with null pointers in the case where the 412 // The callback will be invoked with null pointers in the case where the
406 // system does not support or lacks the resources to provide GPU-accelerated 413 // system does not support or lacks the resources to provide GPU-accelerated
407 // video encoding. 414 // video encoding.
408 if (!encoder_task_runner || !vea) { 415 if (!encoder_task_runner || !vea) {
409 if (!initialization_cb.is_null()) { 416 cast_environment_->PostTask(
410 cast_environment_->PostTask( 417 CastEnvironment::MAIN,
411 CastEnvironment::MAIN, 418 FROM_HERE,
412 FROM_HERE, 419 base::Bind(status_change_cb, STATUS_CODEC_INIT_FAILED));
413 base::Bind(initialization_cb, STATUS_INVALID_VIDEO_CONFIGURATION));
414 }
415 return; 420 return;
416 } 421 }
417 422
418 DCHECK(!client_); 423 DCHECK(!client_);
419 client_ = new VEAClientImpl(cast_environment_, 424 client_ = new VEAClientImpl(cast_environment_,
420 encoder_task_runner, 425 encoder_task_runner,
421 vea.Pass(), 426 vea.Pass(),
422 max_frame_rate, 427 max_frame_rate,
428 status_change_cb,
423 create_video_encode_memory_cb_); 429 create_video_encode_memory_cb_);
424 client_->task_runner()->PostTask(FROM_HERE, 430 client_->task_runner()->PostTask(FROM_HERE,
425 base::Bind(&VEAClientImpl::Initialize, 431 base::Bind(&VEAClientImpl::Initialize,
426 client_, 432 client_,
427 frame_size, 433 frame_size,
428 codec_profile, 434 codec_profile,
429 bit_rate_, 435 bit_rate_));
430 initialization_cb));
431 } 436 }
432 437
433 } // namespace cast 438 } // namespace cast
434 } // namespace media 439 } // namespace media
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698