| Index: media/gpu/vt_video_decode_accelerator_mac.cc
|
| diff --git a/media/gpu/vt_video_decode_accelerator_mac.cc b/media/gpu/vt_video_decode_accelerator_mac.cc
|
| index ac424e321ca6bdbb95e968f816ee2d719e24b817..65f00d77f5b88c1c99f00450fb9b716babb8f699 100644
|
| --- a/media/gpu/vt_video_decode_accelerator_mac.cc
|
| +++ b/media/gpu/vt_video_decode_accelerator_mac.cc
|
| @@ -66,10 +66,13 @@ const int kNALUHeaderLength = 4;
|
| // requirements are low, as we don't need the textures to be backed by storage.
|
| const int kNumPictureBuffers = limits::kMaxVideoFrames + 1;
|
|
|
| -// Maximum number of frames to queue for reordering before we stop asking for
|
| -// more. (NotifyEndOfBitstreamBuffer() is called when frames are moved into the
|
| -// reorder queue.)
|
| -const int kMaxReorderQueueSize = 16;
|
| +// Maximum number of frames to queue for reordering. (Also controls the maximum
|
| +// number of in-flight frames, since NotifyEndOfBitstreamBuffer() is called when
|
| +// frames are moved into the reorder queue.)
|
| +//
|
| +// Since the maximum possible |reorder_window| is 16 for H.264, 17 is the
|
| +// minimum safe (static) size of the reorder queue.
|
| +const int kMaxReorderQueueSize = 17;
|
|
|
| // Build an |image_config| dictionary for VideoToolbox initialization.
|
| base::ScopedCFTypeRef<CFMutableDictionaryRef> BuildImageConfig(
|
| @@ -218,7 +221,7 @@ bool InitializeVideoToolboxInternal() {
|
| // TODO(sandersd): Share this computation with the VAAPI decoder.
|
| int32_t ComputeReorderWindow(const H264SPS* sps) {
|
| // TODO(sandersd): Compute MaxDpbFrames.
|
| - int32_t max_dpb_frames = kMaxReorderQueueSize;
|
| + int32_t max_dpb_frames = 16;
|
|
|
| // See AVC spec section E.2.1 definition of |max_num_reorder_frames|.
|
| if (sps->vui_parameters_present_flag && sps->bitstream_restriction_flag) {
|
| @@ -316,11 +319,13 @@ VTVideoDecodeAccelerator::VTVideoDecodeAccelerator(
|
| }
|
|
|
| VTVideoDecodeAccelerator::~VTVideoDecodeAccelerator() {
|
| + DVLOG(1) << __func__;
|
| DCHECK(gpu_thread_checker_.CalledOnValidThread());
|
| }
|
|
|
| bool VTVideoDecodeAccelerator::Initialize(const Config& config,
|
| Client* client) {
|
| + DVLOG(1) << __func__;
|
| DCHECK(gpu_thread_checker_.CalledOnValidThread());
|
|
|
| if (make_context_current_cb_.is_null() || bind_image_cb_.is_null()) {
|
| @@ -364,6 +369,7 @@ bool VTVideoDecodeAccelerator::Initialize(const Config& config,
|
| }
|
|
|
| bool VTVideoDecodeAccelerator::FinishDelayedFrames() {
|
| + DVLOG(3) << __func__;
|
| DCHECK(decoder_thread_.task_runner()->BelongsToCurrentThread());
|
| if (session_) {
|
| OSStatus status = VTDecompressionSessionWaitForAsynchronousFrames(session_);
|
| @@ -377,6 +383,7 @@ bool VTVideoDecodeAccelerator::FinishDelayedFrames() {
|
| }
|
|
|
| bool VTVideoDecodeAccelerator::ConfigureDecoder() {
|
| + DVLOG(2) << __func__;
|
| DCHECK(decoder_thread_.task_runner()->BelongsToCurrentThread());
|
| DCHECK(!last_sps_.empty());
|
| DCHECK(!last_pps_.empty());
|
| @@ -479,6 +486,7 @@ bool VTVideoDecodeAccelerator::ConfigureDecoder() {
|
|
|
| void VTVideoDecodeAccelerator::DecodeTask(const BitstreamBuffer& bitstream,
|
| Frame* frame) {
|
| + DVLOG(2) << __func__ << "(" << frame->bitstream_id << ")";
|
| DCHECK(decoder_thread_.task_runner()->BelongsToCurrentThread());
|
|
|
| // Map the bitstream buffer.
|
| @@ -808,7 +816,9 @@ void VTVideoDecodeAccelerator::Output(void* source_frame_refcon,
|
| }
|
|
|
| void VTVideoDecodeAccelerator::DecodeDone(Frame* frame) {
|
| + DVLOG(3) << __func__ << "(" << frame->bitstream_id << ")";
|
| DCHECK(gpu_thread_checker_.CalledOnValidThread());
|
| +
|
| DCHECK_EQ(1u, pending_frames_.count(frame->bitstream_id));
|
| Task task(TASK_FRAME);
|
| task.frame = pending_frames_[frame->bitstream_id];
|
| @@ -818,7 +828,9 @@ void VTVideoDecodeAccelerator::DecodeDone(Frame* frame) {
|
| }
|
|
|
| void VTVideoDecodeAccelerator::FlushTask(TaskType type) {
|
| + DVLOG(3) << __func__;
|
| DCHECK(decoder_thread_.task_runner()->BelongsToCurrentThread());
|
| +
|
| FinishDelayedFrames();
|
|
|
| // Always queue a task, even if FinishDelayedFrames() fails, so that
|
| @@ -829,13 +841,16 @@ void VTVideoDecodeAccelerator::FlushTask(TaskType type) {
|
| }
|
|
|
| void VTVideoDecodeAccelerator::FlushDone(TaskType type) {
|
| + DVLOG(3) << __func__;
|
| DCHECK(gpu_thread_checker_.CalledOnValidThread());
|
| task_queue_.push(Task(type));
|
| ProcessWorkQueues();
|
| }
|
|
|
| void VTVideoDecodeAccelerator::Decode(const BitstreamBuffer& bitstream) {
|
| + DVLOG(2) << __func__ << "(" << bitstream.id() << ")";
|
| DCHECK(gpu_thread_checker_.CalledOnValidThread());
|
| +
|
| if (bitstream.id() < 0) {
|
| DLOG(ERROR) << "Invalid bitstream, id: " << bitstream.id();
|
| if (base::SharedMemory::IsHandleValid(bitstream.handle()))
|
| @@ -843,8 +858,10 @@ void VTVideoDecodeAccelerator::Decode(const BitstreamBuffer& bitstream) {
|
| NotifyError(INVALID_ARGUMENT, SFT_INVALID_STREAM);
|
| return;
|
| }
|
| +
|
| DCHECK_EQ(0u, assigned_bitstream_ids_.count(bitstream.id()));
|
| assigned_bitstream_ids_.insert(bitstream.id());
|
| +
|
| Frame* frame = new Frame(bitstream.id());
|
| pending_frames_[frame->bitstream_id] = make_linked_ptr(frame);
|
| decoder_thread_.task_runner()->PostTask(
|
| @@ -854,6 +871,7 @@ void VTVideoDecodeAccelerator::Decode(const BitstreamBuffer& bitstream) {
|
|
|
| void VTVideoDecodeAccelerator::AssignPictureBuffers(
|
| const std::vector<PictureBuffer>& pictures) {
|
| + DVLOG(1) << __func__;
|
| DCHECK(gpu_thread_checker_.CalledOnValidThread());
|
|
|
| for (const PictureBuffer& picture : pictures) {
|
| @@ -877,6 +895,7 @@ void VTVideoDecodeAccelerator::AssignPictureBuffers(
|
| }
|
|
|
| void VTVideoDecodeAccelerator::ReusePictureBuffer(int32_t picture_id) {
|
| + DVLOG(2) << __func__ << "(" << picture_id << ")";
|
| DCHECK(gpu_thread_checker_.CalledOnValidThread());
|
|
|
| auto it = picture_info_map_.find(picture_id);
|
| @@ -896,6 +915,7 @@ void VTVideoDecodeAccelerator::ReusePictureBuffer(int32_t picture_id) {
|
| }
|
|
|
| void VTVideoDecodeAccelerator::ProcessWorkQueues() {
|
| + DVLOG(3) << __func__;
|
| DCHECK(gpu_thread_checker_.CalledOnValidThread());
|
| switch (state_) {
|
| case STATE_DECODING:
|
| @@ -924,6 +944,7 @@ void VTVideoDecodeAccelerator::ProcessWorkQueues() {
|
| }
|
|
|
| bool VTVideoDecodeAccelerator::ProcessTaskQueue() {
|
| + DVLOG(3) << __func__ << " size=" << task_queue_.size();
|
| DCHECK(gpu_thread_checker_.CalledOnValidThread());
|
| DCHECK_EQ(state_, STATE_DECODING);
|
|
|
| @@ -935,6 +956,7 @@ bool VTVideoDecodeAccelerator::ProcessTaskQueue() {
|
| case TASK_FRAME:
|
| if (reorder_queue_.size() < kMaxReorderQueueSize &&
|
| (!task.frame->is_idr || reorder_queue_.empty())) {
|
| + DVLOG(2) << "Decode(" << task.frame->bitstream_id << ") complete";
|
| assigned_bitstream_ids_.erase(task.frame->bitstream_id);
|
| client_->NotifyEndOfBitstreamBuffer(task.frame->bitstream_id);
|
| reorder_queue_.push(task.frame);
|
| @@ -946,6 +968,7 @@ bool VTVideoDecodeAccelerator::ProcessTaskQueue() {
|
| case TASK_FLUSH:
|
| DCHECK_EQ(task.type, pending_flush_tasks_.front());
|
| if (reorder_queue_.size() == 0) {
|
| + DVLOG(1) << "Flush complete";
|
| pending_flush_tasks_.pop();
|
| client_->NotifyFlushDone();
|
| task_queue_.pop();
|
| @@ -956,6 +979,7 @@ bool VTVideoDecodeAccelerator::ProcessTaskQueue() {
|
| case TASK_RESET:
|
| DCHECK_EQ(task.type, pending_flush_tasks_.front());
|
| if (reorder_queue_.size() == 0) {
|
| + DVLOG(1) << "Reset complete";
|
| waiting_for_idr_ = true;
|
| pending_flush_tasks_.pop();
|
| client_->NotifyResetDone();
|
| @@ -986,6 +1010,8 @@ bool VTVideoDecodeAccelerator::ProcessReorderQueue() {
|
| task_queue_.front().frame->is_idr);
|
|
|
| size_t reorder_window = std::max(0, reorder_queue_.top()->reorder_window);
|
| + DVLOG(3) << __func__ << " size=" << reorder_queue_.size()
|
| + << " window=" << reorder_window << " flushing=" << flushing;
|
| if (flushing || reorder_queue_.size() > reorder_window) {
|
| if (ProcessFrame(*reorder_queue_.top())) {
|
| reorder_queue_.pop();
|
| @@ -997,6 +1023,7 @@ bool VTVideoDecodeAccelerator::ProcessReorderQueue() {
|
| }
|
|
|
| bool VTVideoDecodeAccelerator::ProcessFrame(const Frame& frame) {
|
| + DVLOG(3) << __func__ << "(" << frame.bitstream_id << ")";
|
| DCHECK(gpu_thread_checker_.CalledOnValidThread());
|
| DCHECK_EQ(state_, STATE_DECODING);
|
|
|
| @@ -1032,6 +1059,7 @@ bool VTVideoDecodeAccelerator::ProcessFrame(const Frame& frame) {
|
| }
|
|
|
| bool VTVideoDecodeAccelerator::SendFrame(const Frame& frame) {
|
| + DVLOG(2) << __func__ << "(" << frame.bitstream_id << ")";
|
| DCHECK(gpu_thread_checker_.CalledOnValidThread());
|
| DCHECK_EQ(state_, STATE_DECODING);
|
|
|
| @@ -1112,16 +1140,19 @@ void VTVideoDecodeAccelerator::QueueFlush(TaskType type) {
|
| }
|
|
|
| void VTVideoDecodeAccelerator::Flush() {
|
| + DVLOG(1) << __func__;
|
| DCHECK(gpu_thread_checker_.CalledOnValidThread());
|
| QueueFlush(TASK_FLUSH);
|
| }
|
|
|
| void VTVideoDecodeAccelerator::Reset() {
|
| + DVLOG(1) << __func__;
|
| DCHECK(gpu_thread_checker_.CalledOnValidThread());
|
| QueueFlush(TASK_RESET);
|
| }
|
|
|
| void VTVideoDecodeAccelerator::Destroy() {
|
| + DVLOG(1) << __func__;
|
| DCHECK(gpu_thread_checker_.CalledOnValidThread());
|
|
|
| // In a forceful shutdown, the decoder thread may be dead already.
|
|
|