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