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

Side by Side Diff: media/gpu/vt_video_decode_accelerator_mac.cc

Issue 2345633006: VTVDA: Fix reorder queue size. (Closed)
Patch Set: Reduce spam at level 1. Created 4 years, 3 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
« no previous file with comments | « no previous file | no next file » | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
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/gpu/vt_video_decode_accelerator_mac.h" 5 #include "media/gpu/vt_video_decode_accelerator_mac.h"
6 6
7 #include <CoreVideo/CoreVideo.h> 7 #include <CoreVideo/CoreVideo.h>
8 #include <OpenGL/CGLIOSurface.h> 8 #include <OpenGL/CGLIOSurface.h>
9 #include <OpenGL/gl.h> 9 #include <OpenGL/gl.h>
10 #include <stddef.h> 10 #include <stddef.h>
(...skipping 48 matching lines...) Expand 10 before | Expand all | Expand 10 after
59 59
60 // Size to use for NALU length headers in AVC format (can be 1, 2, or 4). 60 // Size to use for NALU length headers in AVC format (can be 1, 2, or 4).
61 const int kNALUHeaderLength = 4; 61 const int kNALUHeaderLength = 4;
62 62
63 // We request 5 picture buffers from the client, each of which has a texture ID 63 // We request 5 picture buffers from the client, each of which has a texture ID
64 // that we can bind decoded frames to. We need enough to satisfy preroll, and 64 // that we can bind decoded frames to. We need enough to satisfy preroll, and
65 // enough to avoid unnecessary stalling, but no more than that. The resource 65 // enough to avoid unnecessary stalling, but no more than that. The resource
66 // requirements are low, as we don't need the textures to be backed by storage. 66 // requirements are low, as we don't need the textures to be backed by storage.
67 const int kNumPictureBuffers = limits::kMaxVideoFrames + 1; 67 const int kNumPictureBuffers = limits::kMaxVideoFrames + 1;
68 68
69 // Maximum number of frames to queue for reordering before we stop asking for 69 // Maximum number of frames to queue for reordering. (Also controls the maximum
70 // more. (NotifyEndOfBitstreamBuffer() is called when frames are moved into the 70 // number of in-flight frames, since NotifyEndOfBitstreamBuffer() is called when
71 // reorder queue.) 71 // frames are moved into the reorder queue.)
72 const int kMaxReorderQueueSize = 16; 72 //
73 // Since the maximum possible |reorder_window| is 16 for H.264, 17 is the
74 // minimum safe (static) size of the reorder queue.
75 const int kMaxReorderQueueSize = 17;
73 76
74 // Build an |image_config| dictionary for VideoToolbox initialization. 77 // Build an |image_config| dictionary for VideoToolbox initialization.
75 base::ScopedCFTypeRef<CFMutableDictionaryRef> BuildImageConfig( 78 base::ScopedCFTypeRef<CFMutableDictionaryRef> BuildImageConfig(
76 CMVideoDimensions coded_dimensions) { 79 CMVideoDimensions coded_dimensions) {
77 base::ScopedCFTypeRef<CFMutableDictionaryRef> image_config; 80 base::ScopedCFTypeRef<CFMutableDictionaryRef> image_config;
78 81
79 // Note that 4:2:0 textures cannot be used directly as RGBA in OpenGL, but are 82 // Note that 4:2:0 textures cannot be used directly as RGBA in OpenGL, but are
80 // lower power than 4:2:2 when composited directly by CoreAnimation. 83 // lower power than 4:2:2 when composited directly by CoreAnimation.
81 int32_t pixel_format = kCVPixelFormatType_420YpCbCr8BiPlanarVideoRange; 84 int32_t pixel_format = kCVPixelFormatType_420YpCbCr8BiPlanarVideoRange;
82 #define CFINT(i) CFNumberCreate(kCFAllocatorDefault, kCFNumberSInt32Type, &i) 85 #define CFINT(i) CFNumberCreate(kCFAllocatorDefault, kCFNumberSInt32Type, &i)
(...skipping 128 matching lines...) Expand 10 before | Expand all | Expand 10 after
211 DLOG(WARNING) << "Failed to create software VideoToolbox session"; 214 DLOG(WARNING) << "Failed to create software VideoToolbox session";
212 return false; 215 return false;
213 } 216 }
214 217
215 return true; 218 return true;
216 } 219 }
217 220
218 // TODO(sandersd): Share this computation with the VAAPI decoder. 221 // TODO(sandersd): Share this computation with the VAAPI decoder.
219 int32_t ComputeReorderWindow(const H264SPS* sps) { 222 int32_t ComputeReorderWindow(const H264SPS* sps) {
220 // TODO(sandersd): Compute MaxDpbFrames. 223 // TODO(sandersd): Compute MaxDpbFrames.
221 int32_t max_dpb_frames = kMaxReorderQueueSize; 224 int32_t max_dpb_frames = 16;
222 225
223 // See AVC spec section E.2.1 definition of |max_num_reorder_frames|. 226 // See AVC spec section E.2.1 definition of |max_num_reorder_frames|.
224 if (sps->vui_parameters_present_flag && sps->bitstream_restriction_flag) { 227 if (sps->vui_parameters_present_flag && sps->bitstream_restriction_flag) {
225 return std::min(sps->max_num_reorder_frames, max_dpb_frames); 228 return std::min(sps->max_num_reorder_frames, max_dpb_frames);
226 } else if (sps->constraint_set3_flag) { 229 } else if (sps->constraint_set3_flag) {
227 if (sps->profile_idc == 44 || sps->profile_idc == 86 || 230 if (sps->profile_idc == 44 || sps->profile_idc == 86 ||
228 sps->profile_idc == 100 || sps->profile_idc == 110 || 231 sps->profile_idc == 100 || sps->profile_idc == 110 ||
229 sps->profile_idc == 122 || sps->profile_idc == 244) { 232 sps->profile_idc == 122 || sps->profile_idc == 244) {
230 return 0; 233 return 0;
231 } 234 }
(...skipping 77 matching lines...) Expand 10 before | Expand all | Expand 10 after
309 missing_idr_logged_(false), 312 missing_idr_logged_(false),
310 gpu_task_runner_(base::ThreadTaskRunnerHandle::Get()), 313 gpu_task_runner_(base::ThreadTaskRunnerHandle::Get()),
311 decoder_thread_("VTDecoderThread"), 314 decoder_thread_("VTDecoderThread"),
312 weak_this_factory_(this) { 315 weak_this_factory_(this) {
313 callback_.decompressionOutputCallback = OutputThunk; 316 callback_.decompressionOutputCallback = OutputThunk;
314 callback_.decompressionOutputRefCon = this; 317 callback_.decompressionOutputRefCon = this;
315 weak_this_ = weak_this_factory_.GetWeakPtr(); 318 weak_this_ = weak_this_factory_.GetWeakPtr();
316 } 319 }
317 320
318 VTVideoDecodeAccelerator::~VTVideoDecodeAccelerator() { 321 VTVideoDecodeAccelerator::~VTVideoDecodeAccelerator() {
322 DVLOG(1) << __func__;
319 DCHECK(gpu_thread_checker_.CalledOnValidThread()); 323 DCHECK(gpu_thread_checker_.CalledOnValidThread());
320 } 324 }
321 325
322 bool VTVideoDecodeAccelerator::Initialize(const Config& config, 326 bool VTVideoDecodeAccelerator::Initialize(const Config& config,
323 Client* client) { 327 Client* client) {
328 DVLOG(1) << __func__;
324 DCHECK(gpu_thread_checker_.CalledOnValidThread()); 329 DCHECK(gpu_thread_checker_.CalledOnValidThread());
325 330
326 if (make_context_current_cb_.is_null() || bind_image_cb_.is_null()) { 331 if (make_context_current_cb_.is_null() || bind_image_cb_.is_null()) {
327 NOTREACHED() << "GL callbacks are required for this VDA"; 332 NOTREACHED() << "GL callbacks are required for this VDA";
328 return false; 333 return false;
329 } 334 }
330 335
331 if (config.is_encrypted) { 336 if (config.is_encrypted) {
332 NOTREACHED() << "Encrypted streams are not supported for this VDA"; 337 NOTREACHED() << "Encrypted streams are not supported for this VDA";
333 return false; 338 return false;
(...skipping 23 matching lines...) Expand all
357 if (!decoder_thread_.Start()) 362 if (!decoder_thread_.Start())
358 return false; 363 return false;
359 364
360 // Count the session as successfully initialized. 365 // Count the session as successfully initialized.
361 UMA_HISTOGRAM_ENUMERATION("Media.VTVDA.SessionFailureReason", 366 UMA_HISTOGRAM_ENUMERATION("Media.VTVDA.SessionFailureReason",
362 SFT_SUCCESSFULLY_INITIALIZED, SFT_MAX + 1); 367 SFT_SUCCESSFULLY_INITIALIZED, SFT_MAX + 1);
363 return true; 368 return true;
364 } 369 }
365 370
366 bool VTVideoDecodeAccelerator::FinishDelayedFrames() { 371 bool VTVideoDecodeAccelerator::FinishDelayedFrames() {
372 DVLOG(3) << __func__;
367 DCHECK(decoder_thread_.task_runner()->BelongsToCurrentThread()); 373 DCHECK(decoder_thread_.task_runner()->BelongsToCurrentThread());
368 if (session_) { 374 if (session_) {
369 OSStatus status = VTDecompressionSessionWaitForAsynchronousFrames(session_); 375 OSStatus status = VTDecompressionSessionWaitForAsynchronousFrames(session_);
370 if (status) { 376 if (status) {
371 NOTIFY_STATUS("VTDecompressionSessionWaitForAsynchronousFrames()", status, 377 NOTIFY_STATUS("VTDecompressionSessionWaitForAsynchronousFrames()", status,
372 SFT_PLATFORM_ERROR); 378 SFT_PLATFORM_ERROR);
373 return false; 379 return false;
374 } 380 }
375 } 381 }
376 return true; 382 return true;
377 } 383 }
378 384
379 bool VTVideoDecodeAccelerator::ConfigureDecoder() { 385 bool VTVideoDecodeAccelerator::ConfigureDecoder() {
386 DVLOG(2) << __func__;
380 DCHECK(decoder_thread_.task_runner()->BelongsToCurrentThread()); 387 DCHECK(decoder_thread_.task_runner()->BelongsToCurrentThread());
381 DCHECK(!last_sps_.empty()); 388 DCHECK(!last_sps_.empty());
382 DCHECK(!last_pps_.empty()); 389 DCHECK(!last_pps_.empty());
383 390
384 // Build the configuration records. 391 // Build the configuration records.
385 std::vector<const uint8_t*> nalu_data_ptrs; 392 std::vector<const uint8_t*> nalu_data_ptrs;
386 std::vector<size_t> nalu_data_sizes; 393 std::vector<size_t> nalu_data_sizes;
387 nalu_data_ptrs.reserve(3); 394 nalu_data_ptrs.reserve(3);
388 nalu_data_sizes.reserve(3); 395 nalu_data_sizes.reserve(3);
389 nalu_data_ptrs.push_back(&last_sps_.front()); 396 nalu_data_ptrs.push_back(&last_sps_.front());
(...skipping 82 matching lines...) Expand 10 before | Expand all | Expand 10 after
472 cf_using_hardware.InitializeInto()) == 0) { 479 cf_using_hardware.InitializeInto()) == 0) {
473 using_hardware = CFBooleanGetValue(cf_using_hardware); 480 using_hardware = CFBooleanGetValue(cf_using_hardware);
474 } 481 }
475 UMA_HISTOGRAM_BOOLEAN("Media.VTVDA.HardwareAccelerated", using_hardware); 482 UMA_HISTOGRAM_BOOLEAN("Media.VTVDA.HardwareAccelerated", using_hardware);
476 483
477 return true; 484 return true;
478 } 485 }
479 486
480 void VTVideoDecodeAccelerator::DecodeTask(const BitstreamBuffer& bitstream, 487 void VTVideoDecodeAccelerator::DecodeTask(const BitstreamBuffer& bitstream,
481 Frame* frame) { 488 Frame* frame) {
489 DVLOG(2) << __func__ << "(" << frame->bitstream_id << ")";
482 DCHECK(decoder_thread_.task_runner()->BelongsToCurrentThread()); 490 DCHECK(decoder_thread_.task_runner()->BelongsToCurrentThread());
483 491
484 // Map the bitstream buffer. 492 // Map the bitstream buffer.
485 SharedMemoryRegion memory(bitstream, true); 493 SharedMemoryRegion memory(bitstream, true);
486 if (!memory.Map()) { 494 if (!memory.Map()) {
487 DLOG(ERROR) << "Failed to map bitstream buffer"; 495 DLOG(ERROR) << "Failed to map bitstream buffer";
488 NotifyError(PLATFORM_FAILURE, SFT_PLATFORM_ERROR); 496 NotifyError(PLATFORM_FAILURE, SFT_PLATFORM_ERROR);
489 return; 497 return;
490 } 498 }
491 const uint8_t* buf = static_cast<uint8_t*>(memory.memory()); 499 const uint8_t* buf = static_cast<uint8_t*>(memory.memory());
(...skipping 309 matching lines...) Expand 10 before | Expand all | Expand 10 after
801 } 809 }
802 810
803 Frame* frame = reinterpret_cast<Frame*>(source_frame_refcon); 811 Frame* frame = reinterpret_cast<Frame*>(source_frame_refcon);
804 frame->image.reset(image_buffer, base::scoped_policy::RETAIN); 812 frame->image.reset(image_buffer, base::scoped_policy::RETAIN);
805 gpu_task_runner_->PostTask( 813 gpu_task_runner_->PostTask(
806 FROM_HERE, 814 FROM_HERE,
807 base::Bind(&VTVideoDecodeAccelerator::DecodeDone, weak_this_, frame)); 815 base::Bind(&VTVideoDecodeAccelerator::DecodeDone, weak_this_, frame));
808 } 816 }
809 817
810 void VTVideoDecodeAccelerator::DecodeDone(Frame* frame) { 818 void VTVideoDecodeAccelerator::DecodeDone(Frame* frame) {
819 DVLOG(3) << __func__ << "(" << frame->bitstream_id << ")";
811 DCHECK(gpu_thread_checker_.CalledOnValidThread()); 820 DCHECK(gpu_thread_checker_.CalledOnValidThread());
821
812 DCHECK_EQ(1u, pending_frames_.count(frame->bitstream_id)); 822 DCHECK_EQ(1u, pending_frames_.count(frame->bitstream_id));
813 Task task(TASK_FRAME); 823 Task task(TASK_FRAME);
814 task.frame = pending_frames_[frame->bitstream_id]; 824 task.frame = pending_frames_[frame->bitstream_id];
815 pending_frames_.erase(frame->bitstream_id); 825 pending_frames_.erase(frame->bitstream_id);
816 task_queue_.push(task); 826 task_queue_.push(task);
817 ProcessWorkQueues(); 827 ProcessWorkQueues();
818 } 828 }
819 829
820 void VTVideoDecodeAccelerator::FlushTask(TaskType type) { 830 void VTVideoDecodeAccelerator::FlushTask(TaskType type) {
831 DVLOG(3) << __func__;
821 DCHECK(decoder_thread_.task_runner()->BelongsToCurrentThread()); 832 DCHECK(decoder_thread_.task_runner()->BelongsToCurrentThread());
833
822 FinishDelayedFrames(); 834 FinishDelayedFrames();
823 835
824 // Always queue a task, even if FinishDelayedFrames() fails, so that 836 // Always queue a task, even if FinishDelayedFrames() fails, so that
825 // destruction always completes. 837 // destruction always completes.
826 gpu_task_runner_->PostTask( 838 gpu_task_runner_->PostTask(
827 FROM_HERE, 839 FROM_HERE,
828 base::Bind(&VTVideoDecodeAccelerator::FlushDone, weak_this_, type)); 840 base::Bind(&VTVideoDecodeAccelerator::FlushDone, weak_this_, type));
829 } 841 }
830 842
831 void VTVideoDecodeAccelerator::FlushDone(TaskType type) { 843 void VTVideoDecodeAccelerator::FlushDone(TaskType type) {
844 DVLOG(3) << __func__;
832 DCHECK(gpu_thread_checker_.CalledOnValidThread()); 845 DCHECK(gpu_thread_checker_.CalledOnValidThread());
833 task_queue_.push(Task(type)); 846 task_queue_.push(Task(type));
834 ProcessWorkQueues(); 847 ProcessWorkQueues();
835 } 848 }
836 849
837 void VTVideoDecodeAccelerator::Decode(const BitstreamBuffer& bitstream) { 850 void VTVideoDecodeAccelerator::Decode(const BitstreamBuffer& bitstream) {
851 DVLOG(2) << __func__ << "(" << bitstream.id() << ")";
838 DCHECK(gpu_thread_checker_.CalledOnValidThread()); 852 DCHECK(gpu_thread_checker_.CalledOnValidThread());
853
839 if (bitstream.id() < 0) { 854 if (bitstream.id() < 0) {
840 DLOG(ERROR) << "Invalid bitstream, id: " << bitstream.id(); 855 DLOG(ERROR) << "Invalid bitstream, id: " << bitstream.id();
841 if (base::SharedMemory::IsHandleValid(bitstream.handle())) 856 if (base::SharedMemory::IsHandleValid(bitstream.handle()))
842 base::SharedMemory::CloseHandle(bitstream.handle()); 857 base::SharedMemory::CloseHandle(bitstream.handle());
843 NotifyError(INVALID_ARGUMENT, SFT_INVALID_STREAM); 858 NotifyError(INVALID_ARGUMENT, SFT_INVALID_STREAM);
844 return; 859 return;
845 } 860 }
861
846 DCHECK_EQ(0u, assigned_bitstream_ids_.count(bitstream.id())); 862 DCHECK_EQ(0u, assigned_bitstream_ids_.count(bitstream.id()));
847 assigned_bitstream_ids_.insert(bitstream.id()); 863 assigned_bitstream_ids_.insert(bitstream.id());
864
848 Frame* frame = new Frame(bitstream.id()); 865 Frame* frame = new Frame(bitstream.id());
849 pending_frames_[frame->bitstream_id] = make_linked_ptr(frame); 866 pending_frames_[frame->bitstream_id] = make_linked_ptr(frame);
850 decoder_thread_.task_runner()->PostTask( 867 decoder_thread_.task_runner()->PostTask(
851 FROM_HERE, base::Bind(&VTVideoDecodeAccelerator::DecodeTask, 868 FROM_HERE, base::Bind(&VTVideoDecodeAccelerator::DecodeTask,
852 base::Unretained(this), bitstream, frame)); 869 base::Unretained(this), bitstream, frame));
853 } 870 }
854 871
855 void VTVideoDecodeAccelerator::AssignPictureBuffers( 872 void VTVideoDecodeAccelerator::AssignPictureBuffers(
856 const std::vector<PictureBuffer>& pictures) { 873 const std::vector<PictureBuffer>& pictures) {
874 DVLOG(1) << __func__;
857 DCHECK(gpu_thread_checker_.CalledOnValidThread()); 875 DCHECK(gpu_thread_checker_.CalledOnValidThread());
858 876
859 for (const PictureBuffer& picture : pictures) { 877 for (const PictureBuffer& picture : pictures) {
860 DCHECK(!picture_info_map_.count(picture.id())); 878 DCHECK(!picture_info_map_.count(picture.id()));
861 assigned_picture_ids_.insert(picture.id()); 879 assigned_picture_ids_.insert(picture.id());
862 available_picture_ids_.push_back(picture.id()); 880 available_picture_ids_.push_back(picture.id());
863 DCHECK_LE(1u, picture.internal_texture_ids().size()); 881 DCHECK_LE(1u, picture.internal_texture_ids().size());
864 DCHECK_LE(1u, picture.texture_ids().size()); 882 DCHECK_LE(1u, picture.texture_ids().size());
865 picture_info_map_.insert(std::make_pair( 883 picture_info_map_.insert(std::make_pair(
866 picture.id(), 884 picture.id(),
867 base::MakeUnique<PictureInfo>(picture.internal_texture_ids()[0], 885 base::MakeUnique<PictureInfo>(picture.internal_texture_ids()[0],
868 picture.texture_ids()[0]))); 886 picture.texture_ids()[0])));
869 } 887 }
870 888
871 // Pictures are not marked as uncleared until after this method returns, and 889 // Pictures are not marked as uncleared until after this method returns, and
872 // they will be broken if they are used before that happens. So, schedule 890 // they will be broken if they are used before that happens. So, schedule
873 // future work after that happens. 891 // future work after that happens.
874 gpu_task_runner_->PostTask( 892 gpu_task_runner_->PostTask(
875 FROM_HERE, 893 FROM_HERE,
876 base::Bind(&VTVideoDecodeAccelerator::ProcessWorkQueues, weak_this_)); 894 base::Bind(&VTVideoDecodeAccelerator::ProcessWorkQueues, weak_this_));
877 } 895 }
878 896
879 void VTVideoDecodeAccelerator::ReusePictureBuffer(int32_t picture_id) { 897 void VTVideoDecodeAccelerator::ReusePictureBuffer(int32_t picture_id) {
898 DVLOG(2) << __func__ << "(" << picture_id << ")";
880 DCHECK(gpu_thread_checker_.CalledOnValidThread()); 899 DCHECK(gpu_thread_checker_.CalledOnValidThread());
881 900
882 auto it = picture_info_map_.find(picture_id); 901 auto it = picture_info_map_.find(picture_id);
883 if (it != picture_info_map_.end()) { 902 if (it != picture_info_map_.end()) {
884 PictureInfo* picture_info = it->second.get(); 903 PictureInfo* picture_info = it->second.get();
885 picture_info->cv_image.reset(); 904 picture_info->cv_image.reset();
886 picture_info->gl_image->Destroy(false); 905 picture_info->gl_image->Destroy(false);
887 picture_info->gl_image = nullptr; 906 picture_info->gl_image = nullptr;
888 } 907 }
889 908
890 if (assigned_picture_ids_.count(picture_id)) { 909 if (assigned_picture_ids_.count(picture_id)) {
891 available_picture_ids_.push_back(picture_id); 910 available_picture_ids_.push_back(picture_id);
892 ProcessWorkQueues(); 911 ProcessWorkQueues();
893 } else { 912 } else {
894 client_->DismissPictureBuffer(picture_id); 913 client_->DismissPictureBuffer(picture_id);
895 } 914 }
896 } 915 }
897 916
898 void VTVideoDecodeAccelerator::ProcessWorkQueues() { 917 void VTVideoDecodeAccelerator::ProcessWorkQueues() {
918 DVLOG(3) << __func__;
899 DCHECK(gpu_thread_checker_.CalledOnValidThread()); 919 DCHECK(gpu_thread_checker_.CalledOnValidThread());
900 switch (state_) { 920 switch (state_) {
901 case STATE_DECODING: 921 case STATE_DECODING:
902 // TODO(sandersd): Batch where possible. 922 // TODO(sandersd): Batch where possible.
903 while (state_ == STATE_DECODING) { 923 while (state_ == STATE_DECODING) {
904 if (!ProcessReorderQueue() && !ProcessTaskQueue()) 924 if (!ProcessReorderQueue() && !ProcessTaskQueue())
905 break; 925 break;
906 } 926 }
907 return; 927 return;
908 928
909 case STATE_ERROR: 929 case STATE_ERROR:
910 // Do nothing until Destroy() is called. 930 // Do nothing until Destroy() is called.
911 return; 931 return;
912 932
913 case STATE_DESTROYING: 933 case STATE_DESTROYING:
914 // Drop tasks until we are ready to destruct. 934 // Drop tasks until we are ready to destruct.
915 while (!task_queue_.empty()) { 935 while (!task_queue_.empty()) {
916 if (task_queue_.front().type == TASK_DESTROY) { 936 if (task_queue_.front().type == TASK_DESTROY) {
917 delete this; 937 delete this;
918 return; 938 return;
919 } 939 }
920 task_queue_.pop(); 940 task_queue_.pop();
921 } 941 }
922 return; 942 return;
923 } 943 }
924 } 944 }
925 945
926 bool VTVideoDecodeAccelerator::ProcessTaskQueue() { 946 bool VTVideoDecodeAccelerator::ProcessTaskQueue() {
947 DVLOG(3) << __func__ << " size=" << task_queue_.size();
927 DCHECK(gpu_thread_checker_.CalledOnValidThread()); 948 DCHECK(gpu_thread_checker_.CalledOnValidThread());
928 DCHECK_EQ(state_, STATE_DECODING); 949 DCHECK_EQ(state_, STATE_DECODING);
929 950
930 if (task_queue_.empty()) 951 if (task_queue_.empty())
931 return false; 952 return false;
932 953
933 const Task& task = task_queue_.front(); 954 const Task& task = task_queue_.front();
934 switch (task.type) { 955 switch (task.type) {
935 case TASK_FRAME: 956 case TASK_FRAME:
936 if (reorder_queue_.size() < kMaxReorderQueueSize && 957 if (reorder_queue_.size() < kMaxReorderQueueSize &&
937 (!task.frame->is_idr || reorder_queue_.empty())) { 958 (!task.frame->is_idr || reorder_queue_.empty())) {
959 DVLOG(2) << "Decode(" << task.frame->bitstream_id << ") complete";
938 assigned_bitstream_ids_.erase(task.frame->bitstream_id); 960 assigned_bitstream_ids_.erase(task.frame->bitstream_id);
939 client_->NotifyEndOfBitstreamBuffer(task.frame->bitstream_id); 961 client_->NotifyEndOfBitstreamBuffer(task.frame->bitstream_id);
940 reorder_queue_.push(task.frame); 962 reorder_queue_.push(task.frame);
941 task_queue_.pop(); 963 task_queue_.pop();
942 return true; 964 return true;
943 } 965 }
944 return false; 966 return false;
945 967
946 case TASK_FLUSH: 968 case TASK_FLUSH:
947 DCHECK_EQ(task.type, pending_flush_tasks_.front()); 969 DCHECK_EQ(task.type, pending_flush_tasks_.front());
948 if (reorder_queue_.size() == 0) { 970 if (reorder_queue_.size() == 0) {
971 DVLOG(1) << "Flush complete";
949 pending_flush_tasks_.pop(); 972 pending_flush_tasks_.pop();
950 client_->NotifyFlushDone(); 973 client_->NotifyFlushDone();
951 task_queue_.pop(); 974 task_queue_.pop();
952 return true; 975 return true;
953 } 976 }
954 return false; 977 return false;
955 978
956 case TASK_RESET: 979 case TASK_RESET:
957 DCHECK_EQ(task.type, pending_flush_tasks_.front()); 980 DCHECK_EQ(task.type, pending_flush_tasks_.front());
958 if (reorder_queue_.size() == 0) { 981 if (reorder_queue_.size() == 0) {
982 DVLOG(1) << "Reset complete";
959 waiting_for_idr_ = true; 983 waiting_for_idr_ = true;
960 pending_flush_tasks_.pop(); 984 pending_flush_tasks_.pop();
961 client_->NotifyResetDone(); 985 client_->NotifyResetDone();
962 task_queue_.pop(); 986 task_queue_.pop();
963 return true; 987 return true;
964 } 988 }
965 return false; 989 return false;
966 990
967 case TASK_DESTROY: 991 case TASK_DESTROY:
968 NOTREACHED() << "Can't destroy while in STATE_DECODING"; 992 NOTREACHED() << "Can't destroy while in STATE_DECODING";
(...skipping 10 matching lines...) Expand all
979 return false; 1003 return false;
980 1004
981 // If the next task is a flush (because there is a pending flush or becuase 1005 // If the next task is a flush (because there is a pending flush or becuase
982 // the next frame is an IDR), then we don't need a full reorder buffer to send 1006 // the next frame is an IDR), then we don't need a full reorder buffer to send
983 // the next frame. 1007 // the next frame.
984 bool flushing = 1008 bool flushing =
985 !task_queue_.empty() && (task_queue_.front().type != TASK_FRAME || 1009 !task_queue_.empty() && (task_queue_.front().type != TASK_FRAME ||
986 task_queue_.front().frame->is_idr); 1010 task_queue_.front().frame->is_idr);
987 1011
988 size_t reorder_window = std::max(0, reorder_queue_.top()->reorder_window); 1012 size_t reorder_window = std::max(0, reorder_queue_.top()->reorder_window);
1013 DVLOG(3) << __func__ << " size=" << reorder_queue_.size()
1014 << " window=" << reorder_window << " flushing=" << flushing;
989 if (flushing || reorder_queue_.size() > reorder_window) { 1015 if (flushing || reorder_queue_.size() > reorder_window) {
990 if (ProcessFrame(*reorder_queue_.top())) { 1016 if (ProcessFrame(*reorder_queue_.top())) {
991 reorder_queue_.pop(); 1017 reorder_queue_.pop();
992 return true; 1018 return true;
993 } 1019 }
994 } 1020 }
995 1021
996 return false; 1022 return false;
997 } 1023 }
998 1024
999 bool VTVideoDecodeAccelerator::ProcessFrame(const Frame& frame) { 1025 bool VTVideoDecodeAccelerator::ProcessFrame(const Frame& frame) {
1026 DVLOG(3) << __func__ << "(" << frame.bitstream_id << ")";
1000 DCHECK(gpu_thread_checker_.CalledOnValidThread()); 1027 DCHECK(gpu_thread_checker_.CalledOnValidThread());
1001 DCHECK_EQ(state_, STATE_DECODING); 1028 DCHECK_EQ(state_, STATE_DECODING);
1002 1029
1003 // If the next pending flush is for a reset, then the frame will be dropped. 1030 // If the next pending flush is for a reset, then the frame will be dropped.
1004 bool resetting = !pending_flush_tasks_.empty() && 1031 bool resetting = !pending_flush_tasks_.empty() &&
1005 pending_flush_tasks_.front() == TASK_RESET; 1032 pending_flush_tasks_.front() == TASK_RESET;
1006 1033
1007 if (!resetting && frame.image.get()) { 1034 if (!resetting && frame.image.get()) {
1008 // If the |coded_size| has changed, request new picture buffers and then 1035 // If the |coded_size| has changed, request new picture buffers and then
1009 // wait for them. 1036 // wait for them.
(...skipping 15 matching lines...) Expand all
1025 return false; 1052 return false;
1026 } 1053 }
1027 if (!SendFrame(frame)) 1054 if (!SendFrame(frame))
1028 return false; 1055 return false;
1029 } 1056 }
1030 1057
1031 return true; 1058 return true;
1032 } 1059 }
1033 1060
1034 bool VTVideoDecodeAccelerator::SendFrame(const Frame& frame) { 1061 bool VTVideoDecodeAccelerator::SendFrame(const Frame& frame) {
1062 DVLOG(2) << __func__ << "(" << frame.bitstream_id << ")";
1035 DCHECK(gpu_thread_checker_.CalledOnValidThread()); 1063 DCHECK(gpu_thread_checker_.CalledOnValidThread());
1036 DCHECK_EQ(state_, STATE_DECODING); 1064 DCHECK_EQ(state_, STATE_DECODING);
1037 1065
1038 if (available_picture_ids_.empty()) 1066 if (available_picture_ids_.empty())
1039 return false; 1067 return false;
1040 1068
1041 int32_t picture_id = available_picture_ids_.back(); 1069 int32_t picture_id = available_picture_ids_.back();
1042 auto it = picture_info_map_.find(picture_id); 1070 auto it = picture_info_map_.find(picture_id);
1043 DCHECK(it != picture_info_map_.end()); 1071 DCHECK(it != picture_info_map_.end());
1044 PictureInfo* picture_info = it->second.get(); 1072 PictureInfo* picture_info = it->second.get();
(...skipping 60 matching lines...) Expand 10 before | Expand all | Expand 10 after
1105 decoder_thread_.task_runner()->PostTask( 1133 decoder_thread_.task_runner()->PostTask(
1106 FROM_HERE, base::Bind(&VTVideoDecodeAccelerator::FlushTask, 1134 FROM_HERE, base::Bind(&VTVideoDecodeAccelerator::FlushTask,
1107 base::Unretained(this), type)); 1135 base::Unretained(this), type));
1108 1136
1109 // If this is a new flush request, see if we can make progress. 1137 // If this is a new flush request, see if we can make progress.
1110 if (pending_flush_tasks_.size() == 1) 1138 if (pending_flush_tasks_.size() == 1)
1111 ProcessWorkQueues(); 1139 ProcessWorkQueues();
1112 } 1140 }
1113 1141
1114 void VTVideoDecodeAccelerator::Flush() { 1142 void VTVideoDecodeAccelerator::Flush() {
1143 DVLOG(1) << __func__;
1115 DCHECK(gpu_thread_checker_.CalledOnValidThread()); 1144 DCHECK(gpu_thread_checker_.CalledOnValidThread());
1116 QueueFlush(TASK_FLUSH); 1145 QueueFlush(TASK_FLUSH);
1117 } 1146 }
1118 1147
1119 void VTVideoDecodeAccelerator::Reset() { 1148 void VTVideoDecodeAccelerator::Reset() {
1149 DVLOG(1) << __func__;
1120 DCHECK(gpu_thread_checker_.CalledOnValidThread()); 1150 DCHECK(gpu_thread_checker_.CalledOnValidThread());
1121 QueueFlush(TASK_RESET); 1151 QueueFlush(TASK_RESET);
1122 } 1152 }
1123 1153
1124 void VTVideoDecodeAccelerator::Destroy() { 1154 void VTVideoDecodeAccelerator::Destroy() {
1155 DVLOG(1) << __func__;
1125 DCHECK(gpu_thread_checker_.CalledOnValidThread()); 1156 DCHECK(gpu_thread_checker_.CalledOnValidThread());
1126 1157
1127 // In a forceful shutdown, the decoder thread may be dead already. 1158 // In a forceful shutdown, the decoder thread may be dead already.
1128 if (!decoder_thread_.IsRunning()) { 1159 if (!decoder_thread_.IsRunning()) {
1129 delete this; 1160 delete this;
1130 return; 1161 return;
1131 } 1162 }
1132 1163
1133 // For a graceful shutdown, return assigned buffers and flush before 1164 // For a graceful shutdown, return assigned buffers and flush before
1134 // destructing |this|. 1165 // destructing |this|.
(...skipping 20 matching lines...) Expand all
1155 SupportedProfile profile; 1186 SupportedProfile profile;
1156 profile.profile = supported_profile; 1187 profile.profile = supported_profile;
1157 profile.min_resolution.SetSize(16, 16); 1188 profile.min_resolution.SetSize(16, 16);
1158 profile.max_resolution.SetSize(4096, 2160); 1189 profile.max_resolution.SetSize(4096, 2160);
1159 profiles.push_back(profile); 1190 profiles.push_back(profile);
1160 } 1191 }
1161 return profiles; 1192 return profiles;
1162 } 1193 }
1163 1194
1164 } // namespace media 1195 } // namespace media
OLDNEW
« no previous file with comments | « no previous file | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698