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

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

Issue 1913503002: Memory copy the VideoFrame to match the requirement for HW encoders. (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Addressed comments. Created 4 years, 7 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 <cmath> 7 #include <cmath>
8 #include <utility> 8 #include <utility>
9 9
10 #include "base/bind.h" 10 #include "base/bind.h"
11 #include "base/debug/crash_logging.h" 11 #include "base/debug/crash_logging.h"
12 #include "base/debug/dump_without_crashing.h" 12 #include "base/debug/dump_without_crashing.h"
13 #include "base/format_macros.h" 13 #include "base/format_macros.h"
14 #include "base/logging.h" 14 #include "base/logging.h"
15 #include "base/macros.h" 15 #include "base/macros.h"
16 #include "base/memory/scoped_vector.h"
17 #include "base/memory/shared_memory.h" 16 #include "base/memory/shared_memory.h"
18 #include "base/message_loop/message_loop.h" 17 #include "base/message_loop/message_loop.h"
19 #include "base/metrics/histogram.h" 18 #include "base/metrics/histogram.h"
20 #include "base/strings/stringprintf.h" 19 #include "base/strings/stringprintf.h"
21 #include "build/build_config.h" 20 #include "build/build_config.h"
21 #include "media/base/bind_to_current_loop.h"
22 #include "media/base/video_frame.h" 22 #include "media/base/video_frame.h"
23 #include "media/base/video_types.h" 23 #include "media/base/video_types.h"
24 #include "media/base/video_util.h" 24 #include "media/base/video_util.h"
25 #include "media/cast/cast_config.h" 25 #include "media/cast/cast_config.h"
26 #include "media/cast/cast_defines.h" 26 #include "media/cast/cast_defines.h"
27 #include "media/cast/common/rtp_time.h" 27 #include "media/cast/common/rtp_time.h"
28 #include "media/cast/logging/logging_defines.h" 28 #include "media/cast/logging/logging_defines.h"
29 #include "media/cast/net/cast_transport_config.h" 29 #include "media/cast/net/cast_transport_config.h"
30 #include "media/cast/sender/vp8_quantizer_parser.h" 30 #include "media/cast/sender/vp8_quantizer_parser.h"
31 #include "media/filters/h264_parser.h" 31 #include "media/filters/h264_parser.h"
32 32
33 namespace { 33 namespace {
34 34
35 enum { MAX_H264_QUANTIZER = 51 }; 35 enum { MAX_H264_QUANTIZER = 51 };
36
37 // Number of buffers for encoded bit stream.
36 static const size_t kOutputBufferCount = 3; 38 static const size_t kOutputBufferCount = 3;
37 39
40 // Maximum number of extra input buffers for encoder. The input buffers are only
41 // used when copy is needed to match the required coded size.
42 static const size_t kExtraInputBufferCount = 2;
miu 2016/05/03 19:05:43 Note: They've just allowed the use of constexpr, a
xjz 2016/05/03 23:30:15 Done.
43
38 } // namespace 44 } // namespace
39 45
40 namespace media { 46 namespace media {
41 namespace cast { 47 namespace cast {
42 48
43 // Container for the associated data of a video frame being processed. 49 // Container for the associated data of a video frame being processed.
44 struct InProgressFrameEncode { 50 struct InProgressFrameEncode {
45 // The source content to encode. 51 // The source content to encode.
46 const scoped_refptr<VideoFrame> video_frame; 52 const scoped_refptr<VideoFrame> video_frame;
47 53
(...skipping 42 matching lines...) Expand 10 before | Expand all | Expand 10 after
90 max_frame_rate_(max_frame_rate), 96 max_frame_rate_(max_frame_rate),
91 status_change_cb_(status_change_cb), 97 status_change_cb_(status_change_cb),
92 create_video_encode_memory_cb_(create_video_encode_memory_cb), 98 create_video_encode_memory_cb_(create_video_encode_memory_cb),
93 video_encode_accelerator_(std::move(vea)), 99 video_encode_accelerator_(std::move(vea)),
94 encoder_active_(false), 100 encoder_active_(false),
95 next_frame_id_(0u), 101 next_frame_id_(0u),
96 key_frame_encountered_(false), 102 key_frame_encountered_(false),
97 codec_profile_(media::VIDEO_CODEC_PROFILE_UNKNOWN), 103 codec_profile_(media::VIDEO_CODEC_PROFILE_UNKNOWN),
98 key_frame_quantizer_parsable_(false), 104 key_frame_quantizer_parsable_(false),
99 requested_bit_rate_(-1), 105 requested_bit_rate_(-1),
100 has_seen_zero_length_encoded_frame_(false) {} 106 has_seen_zero_length_encoded_frame_(false),
107 max_allowed_input_buffers_(0) {}
101 108
102 base::SingleThreadTaskRunner* task_runner() const { 109 base::SingleThreadTaskRunner* task_runner() const {
103 return task_runner_.get(); 110 return task_runner_.get();
104 } 111 }
105 112
106 void Initialize(const gfx::Size& frame_size, 113 void Initialize(const gfx::Size& frame_size,
107 VideoCodecProfile codec_profile, 114 VideoCodecProfile codec_profile,
108 int start_bit_rate, 115 int start_bit_rate,
109 uint32_t first_frame_id) { 116 uint32_t first_frame_id) {
110 DCHECK(task_runner_->RunsTasksOnCurrentThread()); 117 DCHECK(task_runner_->RunsTasksOnCurrentThread());
(...skipping 17 matching lines...) Expand all
128 } 135 }
129 136
130 void SetBitRate(int bit_rate) { 137 void SetBitRate(int bit_rate) {
131 DCHECK(task_runner_->RunsTasksOnCurrentThread()); 138 DCHECK(task_runner_->RunsTasksOnCurrentThread());
132 139
133 requested_bit_rate_ = bit_rate; 140 requested_bit_rate_ = bit_rate;
134 video_encode_accelerator_->RequestEncodingParametersChange(bit_rate, 141 video_encode_accelerator_->RequestEncodingParametersChange(bit_rate,
135 max_frame_rate_); 142 max_frame_rate_);
136 } 143 }
137 144
145 // The destruction call back of the copied video frame to free its use of
146 // the input buffer.
147 void ReturnInputBufferToPool(int index) {
148 DCHECK(task_runner_->RunsTasksOnCurrentThread());
149 DCHECK_GE(index, 0);
150 DCHECK_LT(index, static_cast<int>(input_buffers_.size()));
151 free_input_buffer_index_.push_back(index);
152 }
153
138 void EncodeVideoFrame( 154 void EncodeVideoFrame(
139 const scoped_refptr<media::VideoFrame>& video_frame, 155 const scoped_refptr<media::VideoFrame>& video_frame,
140 const base::TimeTicks& reference_time, 156 const base::TimeTicks& reference_time,
141 bool key_frame_requested, 157 bool key_frame_requested,
142 const VideoEncoder::FrameEncodedCallback& frame_encoded_callback) { 158 const VideoEncoder::FrameEncodedCallback& frame_encoded_callback) {
143 DCHECK(task_runner_->RunsTasksOnCurrentThread()); 159 DCHECK(task_runner_->RunsTasksOnCurrentThread());
144 160
145 if (!encoder_active_) 161 if (!encoder_active_)
146 return; 162 return;
147 163
148 in_progress_frame_encodes_.push_back(InProgressFrameEncode( 164 in_progress_frame_encodes_.push_back(InProgressFrameEncode(
149 video_frame, reference_time, frame_encoded_callback, 165 video_frame, reference_time, frame_encoded_callback,
150 requested_bit_rate_)); 166 requested_bit_rate_));
151 167
168 scoped_refptr<media::VideoFrame> frame = video_frame;
169 if (video_frame->coded_size() != frame_coded_size_) {
170 DCHECK_GE(frame_coded_size_.width(), video_frame->visible_rect().width());
171 DCHECK_GE(frame_coded_size_.height(),
172 video_frame->visible_rect().height());
173
174 if (free_input_buffer_index_.empty()) {
175 if (input_buffers_.size() < max_allowed_input_buffers_) {
miu 2016/05/03 19:05:43 It's unlikely, but possible, for this method to be
xjz 2016/05/03 23:30:15 Done. Changed to only allocate one buffer at one t
176 create_video_encode_memory_cb_.Run(
177 media::VideoFrame::AllocationSize(media::PIXEL_FORMAT_I420,
178 frame_coded_size_),
179 base::Bind(&VEAClientImpl::OnCreateInputSharedMemory, this));
180 }
181 ExitEncodingWithErrors();
182 return;
183 }
184
185 int index = free_input_buffer_index_.back();
186 base::SharedMemory* input_buffer = input_buffers_[index].get();
187 frame = VideoFrame::WrapExternalSharedMemory(
188 video_frame->format(), frame_coded_size_, video_frame->visible_rect(),
189 video_frame->visible_rect().size(),
190 static_cast<uint8_t*>(input_buffer->memory()),
191 input_buffer->mapped_size(), input_buffer->handle(), 0,
192 video_frame->timestamp());
193 if (!frame || !media::I420CopyWithPadding(*video_frame, frame.get())) {
194 LOG(DFATAL) << "Error: ExternalVideoEncoder: copy failed.";
195 ExitEncodingWithErrors();
196 return;
197 }
198
199 frame->AddDestructionObserver(media::BindToCurrentLoop(base::Bind(
200 &ExternalVideoEncoder::VEAClientImpl::ReturnInputBufferToPool, this,
201 index)));
202 free_input_buffer_index_.pop_back();
203 }
204
152 // BitstreamBufferReady will be called once the encoder is done. 205 // BitstreamBufferReady will be called once the encoder is done.
153 video_encode_accelerator_->Encode(video_frame, key_frame_requested); 206 video_encode_accelerator_->Encode(frame, key_frame_requested);
154 } 207 }
155 208
156 protected: 209 protected:
157 void NotifyError(VideoEncodeAccelerator::Error error) final { 210 void NotifyError(VideoEncodeAccelerator::Error error) final {
158 DCHECK(task_runner_->RunsTasksOnCurrentThread()); 211 DCHECK(task_runner_->RunsTasksOnCurrentThread());
159 212
160 DCHECK(error != VideoEncodeAccelerator::kInvalidArgumentError && 213 DCHECK(error != VideoEncodeAccelerator::kInvalidArgumentError &&
161 error != VideoEncodeAccelerator::kIllegalStateError); 214 error != VideoEncodeAccelerator::kIllegalStateError);
162 215
163 encoder_active_ = false; 216 encoder_active_ = false;
164 217
165 cast_environment_->PostTask( 218 cast_environment_->PostTask(
166 CastEnvironment::MAIN, 219 CastEnvironment::MAIN,
167 FROM_HERE, 220 FROM_HERE,
168 base::Bind(status_change_cb_, STATUS_CODEC_RUNTIME_ERROR)); 221 base::Bind(status_change_cb_, STATUS_CODEC_RUNTIME_ERROR));
169 222
170 // TODO(miu): Force-flush all |in_progress_frame_encodes_| immediately so 223 // TODO(miu): Force-flush all |in_progress_frame_encodes_| immediately so
171 // pending frames do not become stuck, freezing VideoSender. 224 // pending frames do not become stuck, freezing VideoSender.
172 } 225 }
173 226
174 // Called to allocate the input and output buffers. 227 // Called to allocate the input and output buffers.
175 void RequireBitstreamBuffers(unsigned int input_count, 228 void RequireBitstreamBuffers(unsigned int input_count,
176 const gfx::Size& input_coded_size, 229 const gfx::Size& input_coded_size,
177 size_t output_buffer_size) final { 230 size_t output_buffer_size) final {
178 DCHECK(task_runner_->RunsTasksOnCurrentThread()); 231 DCHECK(task_runner_->RunsTasksOnCurrentThread());
179 232
180 // TODO(miu): Investigate why we are ignoring |input_count| (4) and instead 233 frame_coded_size_ = input_coded_size;
181 // using |kOutputBufferCount| (3) here. 234
235 max_allowed_input_buffers_ = input_count + kExtraInputBufferCount;
236
182 for (size_t j = 0; j < kOutputBufferCount; ++j) { 237 for (size_t j = 0; j < kOutputBufferCount; ++j) {
183 create_video_encode_memory_cb_.Run( 238 create_video_encode_memory_cb_.Run(
184 output_buffer_size, 239 output_buffer_size,
185 base::Bind(&VEAClientImpl::OnCreateSharedMemory, this)); 240 base::Bind(&VEAClientImpl::OnCreateSharedMemory, this));
186 } 241 }
187 } 242 }
188 243
189 // Encoder has encoded a frame and it's available in one of the output 244 // Encoder has encoded a frame and it's available in one of the output
190 // buffers. Package the result in a media::cast::EncodedFrame and post it 245 // buffers. Package the result in a media::cast::EncodedFrame and post it
191 // to the Cast MAIN thread via the supplied callback. 246 // to the Cast MAIN thread via the supplied callback.
192 void BitstreamBufferReady(int32_t bitstream_buffer_id, 247 void BitstreamBufferReady(int32_t bitstream_buffer_id,
193 size_t payload_size, 248 size_t payload_size,
194 bool key_frame) final { 249 bool key_frame) final {
195 DCHECK(task_runner_->RunsTasksOnCurrentThread()); 250 DCHECK(task_runner_->RunsTasksOnCurrentThread());
196 if (bitstream_buffer_id < 0 || 251 if (bitstream_buffer_id < 0 ||
197 bitstream_buffer_id >= static_cast<int32_t>(output_buffers_.size())) { 252 bitstream_buffer_id >= static_cast<int32_t>(output_buffers_.size())) {
198 NOTREACHED(); 253 NOTREACHED();
199 VLOG(1) << "BitstreamBufferReady(): invalid bitstream_buffer_id=" 254 VLOG(1) << "BitstreamBufferReady(): invalid bitstream_buffer_id="
200 << bitstream_buffer_id; 255 << bitstream_buffer_id;
201 NotifyError(media::VideoEncodeAccelerator::kPlatformFailureError); 256 NotifyError(media::VideoEncodeAccelerator::kPlatformFailureError);
202 return; 257 return;
203 } 258 }
204 base::SharedMemory* output_buffer = output_buffers_[bitstream_buffer_id]; 259 base::SharedMemory* output_buffer =
260 output_buffers_[bitstream_buffer_id].get();
205 if (payload_size > output_buffer->mapped_size()) { 261 if (payload_size > output_buffer->mapped_size()) {
206 NOTREACHED(); 262 NOTREACHED();
207 VLOG(1) << "BitstreamBufferReady(): invalid payload_size = " 263 VLOG(1) << "BitstreamBufferReady(): invalid payload_size = "
208 << payload_size; 264 << payload_size;
209 NotifyError(media::VideoEncodeAccelerator::kPlatformFailureError); 265 NotifyError(media::VideoEncodeAccelerator::kPlatformFailureError);
210 return; 266 return;
211 } 267 }
212 if (key_frame) 268 if (key_frame)
213 key_frame_encountered_ = true; 269 key_frame_encountered_ = true;
214 if (!key_frame_encountered_) { 270 if (!key_frame_encountered_) {
215 // Do not send video until we have encountered the first key frame. 271 // Do not send video until we have encountered the first key frame.
216 // Save the bitstream buffer in |stream_header_| to be sent later along 272 // Save the bitstream buffer in |stream_header_| to be sent later along
217 // with the first key frame. 273 // with the first key frame.
218 // 274 //
219 // TODO(miu): Should |stream_header_| be an std::ostringstream for 275 // TODO(miu): Should |stream_header_| be an std::ostringstream for
220 // performance reasons? 276 // performance reasons?
221 stream_header_.append(static_cast<const char*>(output_buffer->memory()), 277 stream_header_.append(static_cast<const char*>(output_buffer->memory()),
222 payload_size); 278 payload_size);
223 } else if (!in_progress_frame_encodes_.empty()) { 279 } else if (!in_progress_frame_encodes_.empty()) {
224 const InProgressFrameEncode& request = in_progress_frame_encodes_.front(); 280 const InProgressFrameEncode& request = in_progress_frame_encodes_.front();
225 281
226 scoped_ptr<SenderEncodedFrame> encoded_frame(new SenderEncodedFrame()); 282 std::unique_ptr<SenderEncodedFrame> encoded_frame(
283 new SenderEncodedFrame());
227 encoded_frame->dependency = key_frame ? EncodedFrame::KEY : 284 encoded_frame->dependency = key_frame ? EncodedFrame::KEY :
228 EncodedFrame::DEPENDENT; 285 EncodedFrame::DEPENDENT;
229 encoded_frame->frame_id = next_frame_id_++; 286 encoded_frame->frame_id = next_frame_id_++;
230 if (key_frame) 287 if (key_frame)
231 encoded_frame->referenced_frame_id = encoded_frame->frame_id; 288 encoded_frame->referenced_frame_id = encoded_frame->frame_id;
232 else 289 else
233 encoded_frame->referenced_frame_id = encoded_frame->frame_id - 1; 290 encoded_frame->referenced_frame_id = encoded_frame->frame_id - 1;
234 encoded_frame->rtp_timestamp = RtpTimeTicks::FromTimeDelta( 291 encoded_frame->rtp_timestamp = RtpTimeTicks::FromTimeDelta(
235 request.video_frame->timestamp(), kVideoFrequency); 292 request.video_frame->timestamp(), kVideoFrequency);
236 encoded_frame->reference_time = request.reference_time; 293 encoded_frame->reference_time = request.reference_time;
(...skipping 117 matching lines...) Expand 10 before | Expand all | Expand 10 after
354 ~VEAClientImpl() final { 411 ~VEAClientImpl() final {
355 // According to the media::VideoEncodeAccelerator interface, Destroy() 412 // According to the media::VideoEncodeAccelerator interface, Destroy()
356 // should be called instead of invoking its private destructor. 413 // should be called instead of invoking its private destructor.
357 task_runner_->PostTask( 414 task_runner_->PostTask(
358 FROM_HERE, 415 FROM_HERE,
359 base::Bind(&media::VideoEncodeAccelerator::Destroy, 416 base::Bind(&media::VideoEncodeAccelerator::Destroy,
360 base::Unretained(video_encode_accelerator_.release()))); 417 base::Unretained(video_encode_accelerator_.release())));
361 } 418 }
362 419
363 // Note: This method can be called on any thread. 420 // Note: This method can be called on any thread.
364 void OnCreateSharedMemory(scoped_ptr<base::SharedMemory> memory) { 421 void OnCreateSharedMemory(std::unique_ptr<base::SharedMemory> memory) {
365 task_runner_->PostTask(FROM_HERE, 422 task_runner_->PostTask(FROM_HERE,
366 base::Bind(&VEAClientImpl::OnReceivedSharedMemory, 423 base::Bind(&VEAClientImpl::OnReceivedSharedMemory,
367 this, 424 this,
368 base::Passed(&memory))); 425 base::Passed(&memory)));
369 } 426 }
370 427
371 void OnReceivedSharedMemory(scoped_ptr<base::SharedMemory> memory) { 428 void OnCreateInputSharedMemory(std::unique_ptr<base::SharedMemory> memory) {
429 task_runner_->PostTask(
430 FROM_HERE, base::Bind(&VEAClientImpl::OnReceivedInputSharedMemory, this,
431 base::Passed(&memory)));
432 }
433
434 void OnReceivedSharedMemory(std::unique_ptr<base::SharedMemory> memory) {
372 DCHECK(task_runner_->RunsTasksOnCurrentThread()); 435 DCHECK(task_runner_->RunsTasksOnCurrentThread());
373 436
374 output_buffers_.push_back(std::move(memory)); 437 output_buffers_.push_back(std::move(memory));
375 438
376 // Wait until all requested buffers are received. 439 // Wait until all requested buffers are received.
377 if (output_buffers_.size() < kOutputBufferCount) 440 if (output_buffers_.size() < kOutputBufferCount)
378 return; 441 return;
379 442
380 // Immediately provide all output buffers to the VEA. 443 // Immediately provide all output buffers to the VEA.
381 for (size_t i = 0; i < output_buffers_.size(); ++i) { 444 for (size_t i = 0; i < output_buffers_.size(); ++i) {
382 video_encode_accelerator_->UseOutputBitstreamBuffer( 445 video_encode_accelerator_->UseOutputBitstreamBuffer(
383 media::BitstreamBuffer(static_cast<int32_t>(i), 446 media::BitstreamBuffer(static_cast<int32_t>(i),
384 output_buffers_[i]->handle(), 447 output_buffers_[i]->handle(),
385 output_buffers_[i]->mapped_size())); 448 output_buffers_[i]->mapped_size()));
386 } 449 }
387 } 450 }
388 451
452 void OnReceivedInputSharedMemory(std::unique_ptr<base::SharedMemory> memory) {
453 DCHECK(task_runner_->RunsTasksOnCurrentThread());
454
455 input_buffers_.push_back(std::move(memory));
456 free_input_buffer_index_.push_back(input_buffers_.size() - 1);
457 }
458
459 // This is called when copy errors occur in encoding process when there is
460 // need to copy the VideoFrames to match the required coded size for encoder.
461 void ExitEncodingWithErrors() {
462 DCHECK(task_runner_->RunsTasksOnCurrentThread());
463
464 std::unique_ptr<SenderEncodedFrame> no_result(nullptr);
465 cast_environment_->PostTask(
466 CastEnvironment::MAIN, FROM_HERE,
467 base::Bind(in_progress_frame_encodes_.back().frame_encoded_callback,
468 base::Passed(&no_result)));
469 in_progress_frame_encodes_.pop_back();
470 }
471
389 // Parse H264 SPS, PPS, and Slice header, and return the averaged frame 472 // Parse H264 SPS, PPS, and Slice header, and return the averaged frame
390 // quantizer in the range of [0, 51], or -1 on parse error. 473 // quantizer in the range of [0, 51], or -1 on parse error.
391 double GetH264FrameQuantizer(const uint8_t* encoded_data, off_t size) { 474 double GetH264FrameQuantizer(const uint8_t* encoded_data, off_t size) {
392 DCHECK(encoded_data); 475 DCHECK(encoded_data);
393 if (!size) 476 if (!size)
394 return -1; 477 return -1;
395 h264_parser_.SetStream(encoded_data, size); 478 h264_parser_.SetStream(encoded_data, size);
396 double total_quantizer = 0; 479 double total_quantizer = 0;
397 int num_slices = 0; 480 int num_slices = 0;
398 481
(...skipping 44 matching lines...) Expand 10 before | Expand all | Expand 10 after
443 } 526 }
444 } 527 }
445 return (num_slices == 0) ? -1 : (total_quantizer / num_slices); 528 return (num_slices == 0) ? -1 : (total_quantizer / num_slices);
446 } 529 }
447 530
448 const scoped_refptr<CastEnvironment> cast_environment_; 531 const scoped_refptr<CastEnvironment> cast_environment_;
449 const scoped_refptr<base::SingleThreadTaskRunner> task_runner_; 532 const scoped_refptr<base::SingleThreadTaskRunner> task_runner_;
450 const int max_frame_rate_; 533 const int max_frame_rate_;
451 const StatusChangeCallback status_change_cb_; // Must be run on MAIN thread. 534 const StatusChangeCallback status_change_cb_; // Must be run on MAIN thread.
452 const CreateVideoEncodeMemoryCallback create_video_encode_memory_cb_; 535 const CreateVideoEncodeMemoryCallback create_video_encode_memory_cb_;
453 scoped_ptr<media::VideoEncodeAccelerator> video_encode_accelerator_; 536 std::unique_ptr<media::VideoEncodeAccelerator> video_encode_accelerator_;
454 bool encoder_active_; 537 bool encoder_active_;
455 uint32_t next_frame_id_; 538 uint32_t next_frame_id_;
456 bool key_frame_encountered_; 539 bool key_frame_encountered_;
457 std::string stream_header_; 540 std::string stream_header_;
458 VideoCodecProfile codec_profile_; 541 VideoCodecProfile codec_profile_;
459 bool key_frame_quantizer_parsable_; 542 bool key_frame_quantizer_parsable_;
460 H264Parser h264_parser_; 543 H264Parser h264_parser_;
461 544
462 // Shared memory buffers for output with the VideoAccelerator. 545 // Shared memory buffers for output with the VideoAccelerator.
463 ScopedVector<base::SharedMemory> output_buffers_; 546 std::vector<std::unique_ptr<base::SharedMemory>> output_buffers_;
547
548 // Shared memory buffers for input video frames with the VideoAccelerator.
549 // These buffers will be allocated only when copy is needed to match the
550 // required coded size for encoder. They are allocated on-demand, up to
551 // |max_allowed_input_buffers_|.
552 std::vector<std::unique_ptr<base::SharedMemory>> input_buffers_;
553
554 // Available input buffer index. These buffers are used in FILO order.
555 std::vector<int> free_input_buffer_index_;
464 556
465 // FIFO list. 557 // FIFO list.
466 std::list<InProgressFrameEncode> in_progress_frame_encodes_; 558 std::list<InProgressFrameEncode> in_progress_frame_encodes_;
467 559
468 // The requested encode bit rate for the next frame. 560 // The requested encode bit rate for the next frame.
469 int requested_bit_rate_; 561 int requested_bit_rate_;
470 562
471 // Used to compute utilization metrics for each frame. 563 // Used to compute utilization metrics for each frame.
472 QuantizerEstimator quantizer_estimator_; 564 QuantizerEstimator quantizer_estimator_;
473 565
474 // Set to true once a frame with zero-length encoded data has been 566 // Set to true once a frame with zero-length encoded data has been
475 // encountered. 567 // encountered.
476 // TODO(miu): Remove after discovering cause. http://crbug.com/519022 568 // TODO(miu): Remove after discovering cause. http://crbug.com/519022
477 bool has_seen_zero_length_encoded_frame_; 569 bool has_seen_zero_length_encoded_frame_;
478 570
571 // The coded size of the video frame required by Encoder. This size is
572 // obtained from VEA through |RequireBitstreamBuffers()|.
573 gfx::Size frame_coded_size_;
574
575 // The maximum number of input buffers. These buffers are used to copy
576 // VideoFrames in order to match the required coded size for encoder.
577 uint32_t max_allowed_input_buffers_;
miu 2016/05/03 19:05:43 s/uint32_t/size_t/
xjz 2016/05/03 23:30:15 Done.
578
479 DISALLOW_COPY_AND_ASSIGN(VEAClientImpl); 579 DISALLOW_COPY_AND_ASSIGN(VEAClientImpl);
480 }; 580 };
481 581
482 // static 582 // static
483 bool ExternalVideoEncoder::IsSupported(const VideoSenderConfig& video_config) { 583 bool ExternalVideoEncoder::IsSupported(const VideoSenderConfig& video_config) {
484 if (video_config.codec != CODEC_VIDEO_VP8 && 584 if (video_config.codec != CODEC_VIDEO_VP8 &&
485 video_config.codec != CODEC_VIDEO_H264) 585 video_config.codec != CODEC_VIDEO_H264)
486 return false; 586 return false;
487 587
488 // TODO(miu): "Layering hooks" are needed to be able to query outside of 588 // TODO(miu): "Layering hooks" are needed to be able to query outside of
(...skipping 131 matching lines...) Expand 10 before | Expand all | Expand 10 after
620 const CreateVideoEncodeAcceleratorCallback& create_vea_cb, 720 const CreateVideoEncodeAcceleratorCallback& create_vea_cb,
621 const CreateVideoEncodeMemoryCallback& create_video_encode_memory_cb) 721 const CreateVideoEncodeMemoryCallback& create_video_encode_memory_cb)
622 : SizeAdaptableVideoEncoderBase(cast_environment, 722 : SizeAdaptableVideoEncoderBase(cast_environment,
623 video_config, 723 video_config,
624 status_change_cb), 724 status_change_cb),
625 create_vea_cb_(create_vea_cb), 725 create_vea_cb_(create_vea_cb),
626 create_video_encode_memory_cb_(create_video_encode_memory_cb) {} 726 create_video_encode_memory_cb_(create_video_encode_memory_cb) {}
627 727
628 SizeAdaptableExternalVideoEncoder::~SizeAdaptableExternalVideoEncoder() {} 728 SizeAdaptableExternalVideoEncoder::~SizeAdaptableExternalVideoEncoder() {}
629 729
630 scoped_ptr<VideoEncoder> SizeAdaptableExternalVideoEncoder::CreateEncoder() { 730 std::unique_ptr<VideoEncoder>
631 return scoped_ptr<VideoEncoder>(new ExternalVideoEncoder( 731 SizeAdaptableExternalVideoEncoder::CreateEncoder() {
632 cast_environment(), 732 return std::unique_ptr<VideoEncoder>(new ExternalVideoEncoder(
633 video_config(), 733 cast_environment(), video_config(), frame_size(), last_frame_id() + 1,
634 frame_size(), 734 CreateEncoderStatusChangeCallback(), create_vea_cb_,
635 last_frame_id() + 1,
636 CreateEncoderStatusChangeCallback(),
637 create_vea_cb_,
638 create_video_encode_memory_cb_)); 735 create_video_encode_memory_cb_));
639 } 736 }
640 737
641 QuantizerEstimator::QuantizerEstimator() {} 738 QuantizerEstimator::QuantizerEstimator() {}
642 739
643 QuantizerEstimator::~QuantizerEstimator() {} 740 QuantizerEstimator::~QuantizerEstimator() {}
644 741
645 void QuantizerEstimator::Reset() { 742 void QuantizerEstimator::Reset() {
646 last_frame_pixel_buffer_.reset(); 743 last_frame_pixel_buffer_.reset();
647 } 744 }
(...skipping 139 matching lines...) Expand 10 before | Expand all | Expand 10 after
787 const double kEntropyAtMaxQuantizer = 7.5; 884 const double kEntropyAtMaxQuantizer = 7.5;
788 const double slope = 885 const double slope =
789 (MAX_VP8_QUANTIZER - MIN_VP8_QUANTIZER) / kEntropyAtMaxQuantizer; 886 (MAX_VP8_QUANTIZER - MIN_VP8_QUANTIZER) / kEntropyAtMaxQuantizer;
790 const double quantizer = std::min<double>( 887 const double quantizer = std::min<double>(
791 MAX_VP8_QUANTIZER, MIN_VP8_QUANTIZER + slope * shannon_entropy); 888 MAX_VP8_QUANTIZER, MIN_VP8_QUANTIZER + slope * shannon_entropy);
792 return quantizer; 889 return quantizer;
793 } 890 }
794 891
795 } // namespace cast 892 } // namespace cast
796 } // namespace media 893 } // namespace media
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698