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

Side by Side Diff: content/common/gpu/media/dxva_video_decode_accelerator.cc

Issue 185403020: Make VEA client of command buffer; move sync. IPC to VDA/VEA::Initialize() (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: 7da5b6ec Rebase. Created 6 years, 8 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 | Annotate | Revision Log
OLDNEW
1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. 1 // Copyright (c) 2012 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 "content/common/gpu/media/dxva_video_decode_accelerator.h" 5 #include "content/common/gpu/media/dxva_video_decode_accelerator.h"
6 6
7 #if !defined(OS_WIN) 7 #if !defined(OS_WIN)
8 #error This file should only be built on Windows. 8 #error This file should only be built on Windows.
9 #endif // !defined(OS_WIN) 9 #endif // !defined(OS_WIN)
10 10
(...skipping 412 matching lines...) Expand 10 before | Expand all | Expand 10 after
423 } 423 }
424 424
425 DXVAVideoDecodeAccelerator::DXVAVideoDecodeAccelerator( 425 DXVAVideoDecodeAccelerator::DXVAVideoDecodeAccelerator(
426 const base::Callback<bool(void)>& make_context_current) 426 const base::Callback<bool(void)>& make_context_current)
427 : client_(NULL), 427 : client_(NULL),
428 dev_manager_reset_token_(0), 428 dev_manager_reset_token_(0),
429 egl_config_(NULL), 429 egl_config_(NULL),
430 state_(kUninitialized), 430 state_(kUninitialized),
431 pictures_requested_(false), 431 pictures_requested_(false),
432 inputs_before_decode_(0), 432 inputs_before_decode_(0),
433 make_context_current_(make_context_current) { 433 make_context_current_(make_context_current),
434 weak_this_factory_(this) {
434 memset(&input_stream_info_, 0, sizeof(input_stream_info_)); 435 memset(&input_stream_info_, 0, sizeof(input_stream_info_));
435 memset(&output_stream_info_, 0, sizeof(output_stream_info_)); 436 memset(&output_stream_info_, 0, sizeof(output_stream_info_));
436 } 437 }
437 438
438 DXVAVideoDecodeAccelerator::~DXVAVideoDecodeAccelerator() { 439 DXVAVideoDecodeAccelerator::~DXVAVideoDecodeAccelerator() {
439 client_ = NULL; 440 client_ = NULL;
440 } 441 }
441 442
442 bool DXVAVideoDecodeAccelerator::Initialize(media::VideoCodecProfile profile, 443 bool DXVAVideoDecodeAccelerator::Initialize(media::VideoCodecProfile profile,
443 Client* client) { 444 Client* client) {
(...skipping 47 matching lines...) Expand 10 before | Expand all | Expand 10 after
491 SendMFTMessage(MFT_MESSAGE_NOTIFY_BEGIN_STREAMING, 0), 492 SendMFTMessage(MFT_MESSAGE_NOTIFY_BEGIN_STREAMING, 0),
492 "Send MFT_MESSAGE_NOTIFY_BEGIN_STREAMING notification failed", 493 "Send MFT_MESSAGE_NOTIFY_BEGIN_STREAMING notification failed",
493 PLATFORM_FAILURE, false); 494 PLATFORM_FAILURE, false);
494 495
495 RETURN_AND_NOTIFY_ON_FAILURE( 496 RETURN_AND_NOTIFY_ON_FAILURE(
496 SendMFTMessage(MFT_MESSAGE_NOTIFY_START_OF_STREAM, 0), 497 SendMFTMessage(MFT_MESSAGE_NOTIFY_START_OF_STREAM, 0),
497 "Send MFT_MESSAGE_NOTIFY_START_OF_STREAM notification failed", 498 "Send MFT_MESSAGE_NOTIFY_START_OF_STREAM notification failed",
498 PLATFORM_FAILURE, false); 499 PLATFORM_FAILURE, false);
499 500
500 state_ = kNormal; 501 state_ = kNormal;
501 base::MessageLoop::current()->PostTask(FROM_HERE, base::Bind(
502 &DXVAVideoDecodeAccelerator::NotifyInitializeDone,
503 base::AsWeakPtr(this)));
504 return true; 502 return true;
505 } 503 }
506 504
507 void DXVAVideoDecodeAccelerator::Decode( 505 void DXVAVideoDecodeAccelerator::Decode(
508 const media::BitstreamBuffer& bitstream_buffer) { 506 const media::BitstreamBuffer& bitstream_buffer) {
509 DCHECK(CalledOnValidThread()); 507 DCHECK(CalledOnValidThread());
510 508
511 RETURN_AND_NOTIFY_ON_FAILURE((state_ == kNormal || state_ == kStopped || 509 RETURN_AND_NOTIFY_ON_FAILURE((state_ == kNormal || state_ == kStopped ||
512 state_ == kFlushing), 510 state_ == kFlushing),
513 "Invalid state: " << state_, ILLEGAL_STATE,); 511 "Invalid state: " << state_, ILLEGAL_STATE,);
(...skipping 89 matching lines...) Expand 10 before | Expand all | Expand 10 after
603 601
604 state_ = kResetting; 602 state_ = kResetting;
605 603
606 pending_output_samples_.clear(); 604 pending_output_samples_.clear();
607 605
608 NotifyInputBuffersDropped(); 606 NotifyInputBuffersDropped();
609 607
610 RETURN_AND_NOTIFY_ON_FAILURE(SendMFTMessage(MFT_MESSAGE_COMMAND_FLUSH, 0), 608 RETURN_AND_NOTIFY_ON_FAILURE(SendMFTMessage(MFT_MESSAGE_COMMAND_FLUSH, 0),
611 "Reset: Failed to send message.", PLATFORM_FAILURE,); 609 "Reset: Failed to send message.", PLATFORM_FAILURE,);
612 610
613 base::MessageLoop::current()->PostTask(FROM_HERE, base::Bind( 611 base::MessageLoop::current()->PostTask(
614 &DXVAVideoDecodeAccelerator::NotifyResetDone, base::AsWeakPtr(this))); 612 FROM_HERE,
613 base::Bind(&DXVAVideoDecodeAccelerator::NotifyResetDone,
614 weak_this_factory_.GetWeakPtr()));
615 615
616 state_ = DXVAVideoDecodeAccelerator::kNormal; 616 state_ = DXVAVideoDecodeAccelerator::kNormal;
617 } 617 }
618 618
619 void DXVAVideoDecodeAccelerator::Destroy() { 619 void DXVAVideoDecodeAccelerator::Destroy() {
620 DCHECK(CalledOnValidThread()); 620 DCHECK(CalledOnValidThread());
621 Invalidate(); 621 Invalidate();
622 delete this; 622 delete this;
623 } 623 }
624 624
(...skipping 252 matching lines...) Expand 10 before | Expand all | Expand 10 after
877 } 877 }
878 878
879 // We only read the surface description, which contains its width/height when 879 // We only read the surface description, which contains its width/height when
880 // we need the picture buffers from the client. Once we have those, then they 880 // we need the picture buffers from the client. Once we have those, then they
881 // are reused. 881 // are reused.
882 D3DSURFACE_DESC surface_desc; 882 D3DSURFACE_DESC surface_desc;
883 hr = surface->GetDesc(&surface_desc); 883 hr = surface->GetDesc(&surface_desc);
884 RETURN_ON_HR_FAILURE(hr, "Failed to get surface description", false); 884 RETURN_ON_HR_FAILURE(hr, "Failed to get surface description", false);
885 885
886 // Go ahead and request picture buffers. 886 // Go ahead and request picture buffers.
887 base::MessageLoop::current()->PostTask(FROM_HERE, base::Bind( 887 base::MessageLoop::current()->PostTask(
888 &DXVAVideoDecodeAccelerator::RequestPictureBuffers, 888 FROM_HERE,
889 base::AsWeakPtr(this), surface_desc.Width, surface_desc.Height)); 889 base::Bind(&DXVAVideoDecodeAccelerator::RequestPictureBuffers,
890 weak_this_factory_.GetWeakPtr(),
891 surface_desc.Width,
892 surface_desc.Height));
890 893
891 pictures_requested_ = true; 894 pictures_requested_ = true;
892 return true; 895 return true;
893 } 896 }
894 897
895 void DXVAVideoDecodeAccelerator::ProcessPendingSamples() { 898 void DXVAVideoDecodeAccelerator::ProcessPendingSamples() {
896 RETURN_AND_NOTIFY_ON_FAILURE(make_context_current_.Run(), 899 RETURN_AND_NOTIFY_ON_FAILURE(make_context_current_.Run(),
897 "Failed to make context current", PLATFORM_FAILURE,); 900 "Failed to make context current", PLATFORM_FAILURE,);
898 901
899 OutputBuffers::iterator index; 902 OutputBuffers::iterator index;
(...skipping 31 matching lines...) Expand 10 before | Expand all | Expand 10 after
931 return; 934 return;
932 } 935 }
933 936
934 RETURN_AND_NOTIFY_ON_FAILURE( 937 RETURN_AND_NOTIFY_ON_FAILURE(
935 index->second->CopyOutputSampleDataToPictureBuffer(*this, surface), 938 index->second->CopyOutputSampleDataToPictureBuffer(*this, surface),
936 "Failed to copy output sample", 939 "Failed to copy output sample",
937 PLATFORM_FAILURE, ); 940 PLATFORM_FAILURE, );
938 941
939 media::Picture output_picture(index->second->id(), 942 media::Picture output_picture(index->second->id(),
940 sample_info.input_buffer_id); 943 sample_info.input_buffer_id);
941 base::MessageLoop::current()->PostTask(FROM_HERE, base::Bind( 944 base::MessageLoop::current()->PostTask(
942 &DXVAVideoDecodeAccelerator::NotifyPictureReady, 945 FROM_HERE,
943 base::AsWeakPtr(this), output_picture)); 946 base::Bind(&DXVAVideoDecodeAccelerator::NotifyPictureReady,
947 weak_this_factory_.GetWeakPtr(),
948 output_picture));
944 949
945 index->second->set_available(false); 950 index->second->set_available(false);
946 pending_output_samples_.pop_front(); 951 pending_output_samples_.pop_front();
947 } 952 }
948 } 953 }
949 954
950 if (!pending_input_buffers_.empty() && pending_output_samples_.empty()) { 955 if (!pending_input_buffers_.empty() && pending_output_samples_.empty()) {
951 base::MessageLoop::current()->PostTask(FROM_HERE, base::Bind( 956 base::MessageLoop::current()->PostTask(
952 &DXVAVideoDecodeAccelerator::DecodePendingInputBuffers, 957 FROM_HERE,
953 base::AsWeakPtr(this))); 958 base::Bind(&DXVAVideoDecodeAccelerator::DecodePendingInputBuffers,
959 weak_this_factory_.GetWeakPtr()));
954 } 960 }
955 } 961 }
956 962
957 void DXVAVideoDecodeAccelerator::StopOnError( 963 void DXVAVideoDecodeAccelerator::StopOnError(
958 media::VideoDecodeAccelerator::Error error) { 964 media::VideoDecodeAccelerator::Error error) {
959 DCHECK(CalledOnValidThread()); 965 DCHECK(CalledOnValidThread());
960 966
961 if (client_) 967 if (client_)
962 client_->NotifyError(error); 968 client_->NotifyError(error);
963 client_ = NULL; 969 client_ = NULL;
964 970
965 if (state_ != kUninitialized) { 971 if (state_ != kUninitialized) {
966 Invalidate(); 972 Invalidate();
967 } 973 }
968 } 974 }
969 975
970 void DXVAVideoDecodeAccelerator::Invalidate() { 976 void DXVAVideoDecodeAccelerator::Invalidate() {
971 if (state_ == kUninitialized) 977 if (state_ == kUninitialized)
972 return; 978 return;
979 weak_this_factory_.InvalidateWeakPtrs();
973 output_picture_buffers_.clear(); 980 output_picture_buffers_.clear();
974 pending_output_samples_.clear(); 981 pending_output_samples_.clear();
975 pending_input_buffers_.clear(); 982 pending_input_buffers_.clear();
976 decoder_.Release(); 983 decoder_.Release();
977 MFShutdown(); 984 MFShutdown();
978 state_ = kUninitialized; 985 state_ = kUninitialized;
979 } 986 }
980 987
981 void DXVAVideoDecodeAccelerator::NotifyInitializeDone() {
982 if (client_)
983 client_->NotifyInitializeDone();
984 }
985
986 void DXVAVideoDecodeAccelerator::NotifyInputBufferRead(int input_buffer_id) { 988 void DXVAVideoDecodeAccelerator::NotifyInputBufferRead(int input_buffer_id) {
987 if (client_) 989 if (client_)
988 client_->NotifyEndOfBitstreamBuffer(input_buffer_id); 990 client_->NotifyEndOfBitstreamBuffer(input_buffer_id);
989 } 991 }
990 992
991 void DXVAVideoDecodeAccelerator::NotifyFlushDone() { 993 void DXVAVideoDecodeAccelerator::NotifyFlushDone() {
992 if (client_) 994 if (client_)
993 client_->NotifyFlushDone(); 995 client_->NotifyFlushDone();
994 } 996 }
995 997
(...skipping 54 matching lines...) Expand 10 before | Expand all | Expand 10 after
1050 // MF_E_TRANSFORM_NEED_MORE_INPUT. 1052 // MF_E_TRANSFORM_NEED_MORE_INPUT.
1051 // The MFT decoder can buffer upto 30 frames worth of input before returning 1053 // The MFT decoder can buffer upto 30 frames worth of input before returning
1052 // an output frame. This loop here attempts to retrieve as many output frames 1054 // an output frame. This loop here attempts to retrieve as many output frames
1053 // as possible from the buffered set. 1055 // as possible from the buffered set.
1054 while (state_ != kStopped) { 1056 while (state_ != kStopped) {
1055 DoDecode(); 1057 DoDecode();
1056 if (!pending_output_samples_.empty()) 1058 if (!pending_output_samples_.empty())
1057 return; 1059 return;
1058 } 1060 }
1059 1061
1060 base::MessageLoop::current()->PostTask(FROM_HERE, base::Bind( 1062 base::MessageLoop::current()->PostTask(
1061 &DXVAVideoDecodeAccelerator::NotifyFlushDone, base::AsWeakPtr(this))); 1063 FROM_HERE,
1064 base::Bind(&DXVAVideoDecodeAccelerator::NotifyFlushDone,
1065 weak_this_factory_.GetWeakPtr()));
1062 1066
1063 state_ = kNormal; 1067 state_ = kNormal;
1064 } 1068 }
1065 1069
1066 void DXVAVideoDecodeAccelerator::DecodeInternal( 1070 void DXVAVideoDecodeAccelerator::DecodeInternal(
1067 const base::win::ScopedComPtr<IMFSample>& sample) { 1071 const base::win::ScopedComPtr<IMFSample>& sample) {
1068 DCHECK(CalledOnValidThread()); 1072 DCHECK(CalledOnValidThread());
1069 1073
1070 if (state_ == kUninitialized) 1074 if (state_ == kUninitialized)
1071 return; 1075 return;
(...skipping 29 matching lines...) Expand all
1101 // 2. If we don't have any output samples we post the 1105 // 2. If we don't have any output samples we post the
1102 // DecodePendingInputBuffers task to process the pending input samples. 1106 // DecodePendingInputBuffers task to process the pending input samples.
1103 // If we have an output sample then the above task is posted when the 1107 // If we have an output sample then the above task is posted when the
1104 // output samples are sent to the client. 1108 // output samples are sent to the client.
1105 // This is because we only support 1 pending output sample at any 1109 // This is because we only support 1 pending output sample at any
1106 // given time due to the limitation with the Microsoft media foundation 1110 // given time due to the limitation with the Microsoft media foundation
1107 // decoder where it recycles the output Decoder surfaces. 1111 // decoder where it recycles the output Decoder surfaces.
1108 if (hr == MF_E_NOTACCEPTING) { 1112 if (hr == MF_E_NOTACCEPTING) {
1109 pending_input_buffers_.push_back(sample); 1113 pending_input_buffers_.push_back(sample);
1110 if (pending_output_samples_.empty()) { 1114 if (pending_output_samples_.empty()) {
1111 base::MessageLoop::current()->PostTask(FROM_HERE, base::Bind( 1115 base::MessageLoop::current()->PostTask(
1112 &DXVAVideoDecodeAccelerator::DecodePendingInputBuffers, 1116 FROM_HERE,
1113 base::AsWeakPtr(this))); 1117 base::Bind(&DXVAVideoDecodeAccelerator::DecodePendingInputBuffers,
1118 weak_this_factory_.GetWeakPtr()));
1114 } 1119 }
1115 return; 1120 return;
1116 } 1121 }
1117 } 1122 }
1118 RETURN_AND_NOTIFY_ON_HR_FAILURE(hr, "Failed to process input sample", 1123 RETURN_AND_NOTIFY_ON_HR_FAILURE(hr, "Failed to process input sample",
1119 PLATFORM_FAILURE,); 1124 PLATFORM_FAILURE,);
1120 1125
1121 DoDecode(); 1126 DoDecode();
1122 1127
1123 RETURN_AND_NOTIFY_ON_FAILURE((state_ == kStopped || state_ == kNormal), 1128 RETURN_AND_NOTIFY_ON_FAILURE((state_ == kStopped || state_ == kNormal),
1124 "Failed to process output. Unexpected decoder state: " << state_, 1129 "Failed to process output. Unexpected decoder state: " << state_,
1125 ILLEGAL_STATE,); 1130 ILLEGAL_STATE,);
1126 1131
1127 LONGLONG input_buffer_id = 0; 1132 LONGLONG input_buffer_id = 0;
1128 RETURN_ON_HR_FAILURE(sample->GetSampleTime(&input_buffer_id), 1133 RETURN_ON_HR_FAILURE(sample->GetSampleTime(&input_buffer_id),
1129 "Failed to get input buffer id associated with sample",); 1134 "Failed to get input buffer id associated with sample",);
1130 // The Microsoft Media foundation decoder internally buffers up to 30 frames 1135 // The Microsoft Media foundation decoder internally buffers up to 30 frames
1131 // before returning a decoded frame. We need to inform the client that this 1136 // before returning a decoded frame. We need to inform the client that this
1132 // input buffer is processed as it may stop sending us further input. 1137 // input buffer is processed as it may stop sending us further input.
1133 // Note: This may break clients which expect every input buffer to be 1138 // Note: This may break clients which expect every input buffer to be
1134 // associated with a decoded output buffer. 1139 // associated with a decoded output buffer.
1135 // TODO(ananta) 1140 // TODO(ananta)
1136 // Do some more investigation into whether it is possible to get the MFT 1141 // Do some more investigation into whether it is possible to get the MFT
1137 // decoder to emit an output packet for every input packet. 1142 // decoder to emit an output packet for every input packet.
1138 // http://code.google.com/p/chromium/issues/detail?id=108121 1143 // http://code.google.com/p/chromium/issues/detail?id=108121
1139 // http://code.google.com/p/chromium/issues/detail?id=150925 1144 // http://code.google.com/p/chromium/issues/detail?id=150925
1140 base::MessageLoop::current()->PostTask(FROM_HERE, base::Bind( 1145 base::MessageLoop::current()->PostTask(
1141 &DXVAVideoDecodeAccelerator::NotifyInputBufferRead, 1146 FROM_HERE,
1142 base::AsWeakPtr(this), input_buffer_id)); 1147 base::Bind(&DXVAVideoDecodeAccelerator::NotifyInputBufferRead,
1148 weak_this_factory_.GetWeakPtr(),
1149 input_buffer_id));
1143 } 1150 }
1144 1151
1145 void DXVAVideoDecodeAccelerator::HandleResolutionChanged(int width, 1152 void DXVAVideoDecodeAccelerator::HandleResolutionChanged(int width,
1146 int height) { 1153 int height) {
1147 base::MessageLoop::current()->PostTask(FROM_HERE, base::Bind( 1154 base::MessageLoop::current()->PostTask(
1148 &DXVAVideoDecodeAccelerator::DismissStaleBuffers, 1155 FROM_HERE,
1149 base::AsWeakPtr(this), output_picture_buffers_)); 1156 base::Bind(&DXVAVideoDecodeAccelerator::DismissStaleBuffers,
1157 weak_this_factory_.GetWeakPtr(),
1158 output_picture_buffers_));
1150 1159
1151 base::MessageLoop::current()->PostTask(FROM_HERE, base::Bind( 1160 base::MessageLoop::current()->PostTask(
1152 &DXVAVideoDecodeAccelerator::RequestPictureBuffers, 1161 FROM_HERE,
1153 base::AsWeakPtr(this), width, height)); 1162 base::Bind(&DXVAVideoDecodeAccelerator::RequestPictureBuffers,
1163 weak_this_factory_.GetWeakPtr(),
1164 width,
1165 height));
1154 1166
1155 output_picture_buffers_.clear(); 1167 output_picture_buffers_.clear();
1156 } 1168 }
1157 1169
1158 void DXVAVideoDecodeAccelerator::DismissStaleBuffers( 1170 void DXVAVideoDecodeAccelerator::DismissStaleBuffers(
1159 const OutputBuffers& picture_buffers) { 1171 const OutputBuffers& picture_buffers) {
1160 OutputBuffers::const_iterator index; 1172 OutputBuffers::const_iterator index;
1161 1173
1162 for (index = picture_buffers.begin(); 1174 for (index = picture_buffers.begin();
1163 index != picture_buffers.end(); 1175 index != picture_buffers.end();
1164 ++index) { 1176 ++index) {
1165 DVLOG(1) << "Dismissing picture id: " << index->second->id(); 1177 DVLOG(1) << "Dismissing picture id: " << index->second->id();
1166 client_->DismissPictureBuffer(index->second->id()); 1178 client_->DismissPictureBuffer(index->second->id());
1167 } 1179 }
1168 } 1180 }
1169 1181
1170 } // namespace content 1182 } // namespace content
OLDNEW
« no previous file with comments | « content/common/gpu/media/dxva_video_decode_accelerator.h ('k') | content/common/gpu/media/exynos_video_encode_accelerator.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698