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

Side by Side Diff: media/filters/gpu_video_decoder.cc

Issue 297553002: Add callback in VideoDecoder and AudioDecoder to return decoded frames. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Created 6 years, 6 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
« no previous file with comments | « media/filters/gpu_video_decoder.h ('k') | media/filters/opus_audio_decoder.h » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
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 "media/filters/gpu_video_decoder.h" 5 #include "media/filters/gpu_video_decoder.h"
6 6
7 #include <algorithm> 7 #include <algorithm>
8 8
9 #include "base/bind.h" 9 #include "base/bind.h"
10 #include "base/callback_helpers.h" 10 #include "base/callback_helpers.h"
(...skipping 25 matching lines...) Expand all
36 // Size of shared-memory segments we allocate. Since we reuse them we let them 36 // Size of shared-memory segments we allocate. Since we reuse them we let them
37 // be on the beefy side. 37 // be on the beefy side.
38 static const size_t kSharedMemorySegmentBytes = 100 << 10; 38 static const size_t kSharedMemorySegmentBytes = 100 << 10;
39 39
40 GpuVideoDecoder::SHMBuffer::SHMBuffer(base::SharedMemory* m, size_t s) 40 GpuVideoDecoder::SHMBuffer::SHMBuffer(base::SharedMemory* m, size_t s)
41 : shm(m), size(s) { 41 : shm(m), size(s) {
42 } 42 }
43 43
44 GpuVideoDecoder::SHMBuffer::~SHMBuffer() {} 44 GpuVideoDecoder::SHMBuffer::~SHMBuffer() {}
45 45
46 GpuVideoDecoder::BufferPair::BufferPair( 46 GpuVideoDecoder::PendingDecoderBuffer::PendingDecoderBuffer(
47 SHMBuffer* s, const scoped_refptr<DecoderBuffer>& b) 47 SHMBuffer* s,
48 : shm_buffer(s), buffer(b) { 48 const scoped_refptr<DecoderBuffer>& b,
49 const DecodeCB& done_cb)
50 : shm_buffer(s), buffer(b), done_cb(done_cb) {
49 } 51 }
50 52
51 GpuVideoDecoder::BufferPair::~BufferPair() {} 53 GpuVideoDecoder::PendingDecoderBuffer::~PendingDecoderBuffer() {}
52 54
53 GpuVideoDecoder::BufferData::BufferData( 55 GpuVideoDecoder::BufferData::BufferData(
54 int32 bbid, base::TimeDelta ts, const gfx::Rect& vr, const gfx::Size& ns) 56 int32 bbid, base::TimeDelta ts, const gfx::Rect& vr, const gfx::Size& ns)
55 : bitstream_buffer_id(bbid), timestamp(ts), visible_rect(vr), 57 : bitstream_buffer_id(bbid), timestamp(ts), visible_rect(vr),
56 natural_size(ns) { 58 natural_size(ns) {
57 } 59 }
58 60
59 GpuVideoDecoder::BufferData::~BufferData() {} 61 GpuVideoDecoder::BufferData::~BufferData() {}
60 62
61 GpuVideoDecoder::GpuVideoDecoder( 63 GpuVideoDecoder::GpuVideoDecoder(
(...skipping 13 matching lines...) Expand all
75 77
76 void GpuVideoDecoder::Reset(const base::Closure& closure) { 78 void GpuVideoDecoder::Reset(const base::Closure& closure) {
77 DVLOG(3) << "Reset()"; 79 DVLOG(3) << "Reset()";
78 DCheckGpuVideoAcceleratorFactoriesTaskRunnerIsCurrent(); 80 DCheckGpuVideoAcceleratorFactoriesTaskRunnerIsCurrent();
79 81
80 if (state_ == kDrainingDecoder) { 82 if (state_ == kDrainingDecoder) {
81 base::MessageLoop::current()->PostTask( 83 base::MessageLoop::current()->PostTask(
82 FROM_HERE, 84 FROM_HERE,
83 base::Bind( 85 base::Bind(
84 &GpuVideoDecoder::Reset, weak_factory_.GetWeakPtr(), closure)); 86 &GpuVideoDecoder::Reset, weak_factory_.GetWeakPtr(), closure));
85 // NOTE: if we're deferring Reset() until a Flush() completes, return
86 // queued pictures to the VDA so they can be used to finish that Flush().
87 if (pending_decode_cb_.is_null())
88 ready_video_frames_.clear();
89 return; 87 return;
90 } 88 }
91 89
92 // Throw away any already-decoded, not-yet-delivered frames.
93 ready_video_frames_.clear();
94
95 if (!vda_) { 90 if (!vda_) {
96 base::MessageLoop::current()->PostTask(FROM_HERE, closure); 91 base::MessageLoop::current()->PostTask(FROM_HERE, closure);
97 return; 92 return;
98 } 93 }
99 94
100 if (!pending_decode_cb_.is_null())
101 EnqueueFrameAndTriggerFrameDelivery(VideoFrame::CreateEOSFrame());
102
103 DCHECK(pending_reset_cb_.is_null()); 95 DCHECK(pending_reset_cb_.is_null());
104 pending_reset_cb_ = BindToCurrentLoop(closure); 96 pending_reset_cb_ = BindToCurrentLoop(closure);
105 97
106 vda_->Reset(); 98 vda_->Reset();
107 } 99 }
108 100
109 void GpuVideoDecoder::Stop() { 101 void GpuVideoDecoder::Stop() {
110 DCheckGpuVideoAcceleratorFactoriesTaskRunnerIsCurrent(); 102 DCheckGpuVideoAcceleratorFactoriesTaskRunnerIsCurrent();
111 if (vda_) 103 if (vda_)
112 DestroyVDA(); 104 DestroyVDA();
113 if (!pending_decode_cb_.is_null()) 105 DCHECK(bitstream_buffers_in_decoder_.empty());
114 EnqueueFrameAndTriggerFrameDelivery(VideoFrame::CreateEOSFrame());
115 if (!pending_reset_cb_.is_null()) 106 if (!pending_reset_cb_.is_null())
116 base::ResetAndReturn(&pending_reset_cb_).Run(); 107 base::ResetAndReturn(&pending_reset_cb_).Run();
117 } 108 }
118 109
119 static bool IsCodedSizeSupported(const gfx::Size& coded_size) { 110 static bool IsCodedSizeSupported(const gfx::Size& coded_size) {
120 #if defined(OS_WIN) 111 #if defined(OS_WIN)
121 // Windows Media Foundation H.264 decoding does not support decoding videos 112 // Windows Media Foundation H.264 decoding does not support decoding videos
122 // with any dimension smaller than 48 pixels: 113 // with any dimension smaller than 48 pixels:
123 // http://msdn.microsoft.com/en-us/library/windows/desktop/dd797815 114 // http://msdn.microsoft.com/en-us/library/windows/desktop/dd797815
124 if (coded_size.width() < 48 || coded_size.height() < 48) 115 if (coded_size.width() < 48 || coded_size.height() < 48)
(...skipping 26 matching lines...) Expand all
151 static void ReportGpuVideoDecoderInitializeStatusToUMAAndRunCB( 142 static void ReportGpuVideoDecoderInitializeStatusToUMAAndRunCB(
152 const PipelineStatusCB& cb, 143 const PipelineStatusCB& cb,
153 PipelineStatus status) { 144 PipelineStatus status) {
154 UMA_HISTOGRAM_ENUMERATION( 145 UMA_HISTOGRAM_ENUMERATION(
155 "Media.GpuVideoDecoderInitializeStatus", status, PIPELINE_STATUS_MAX + 1); 146 "Media.GpuVideoDecoderInitializeStatus", status, PIPELINE_STATUS_MAX + 1);
156 cb.Run(status); 147 cb.Run(status);
157 } 148 }
158 149
159 void GpuVideoDecoder::Initialize(const VideoDecoderConfig& config, 150 void GpuVideoDecoder::Initialize(const VideoDecoderConfig& config,
160 bool live_mode, 151 bool live_mode,
161 const PipelineStatusCB& orig_status_cb) { 152 const PipelineStatusCB& orig_status_cb,
153 const OutputCB& output_cb) {
162 DVLOG(3) << "Initialize()"; 154 DVLOG(3) << "Initialize()";
163 DCheckGpuVideoAcceleratorFactoriesTaskRunnerIsCurrent(); 155 DCheckGpuVideoAcceleratorFactoriesTaskRunnerIsCurrent();
164 DCHECK(config.IsValidConfig()); 156 DCHECK(config.IsValidConfig());
165 DCHECK(!config.is_encrypted()); 157 DCHECK(!config.is_encrypted());
166 158
167 PipelineStatusCB status_cb = 159 PipelineStatusCB status_cb =
168 base::Bind(&ReportGpuVideoDecoderInitializeStatusToUMAAndRunCB, 160 base::Bind(&ReportGpuVideoDecoderInitializeStatusToUMAAndRunCB,
169 BindToCurrentLoop(orig_status_cb)); 161 BindToCurrentLoop(orig_status_cb));
170 162
171 bool previously_initialized = config_.IsValidConfig(); 163 bool previously_initialized = config_.IsValidConfig();
172 DVLOG(1) << "(Re)initializing GVD with config: " 164 DVLOG(1) << "(Re)initializing GVD with config: "
173 << config.AsHumanReadableString(); 165 << config.AsHumanReadableString();
174 166
175 // TODO(posciak): destroy and create a new VDA on codec/profile change 167 // TODO(posciak): destroy and create a new VDA on codec/profile change
176 // (http://crbug.com/260224). 168 // (http://crbug.com/260224).
177 if (previously_initialized && (config_.profile() != config.profile())) { 169 if (previously_initialized && (config_.profile() != config.profile())) {
178 DVLOG(1) << "Codec or profile changed, cannot reinitialize."; 170 DVLOG(1) << "Codec or profile changed, cannot reinitialize.";
179 status_cb.Run(DECODER_ERROR_NOT_SUPPORTED); 171 status_cb.Run(DECODER_ERROR_NOT_SUPPORTED);
180 return; 172 return;
181 } 173 }
182 174
183 if (!IsCodedSizeSupported(config.coded_size())) { 175 if (!IsCodedSizeSupported(config.coded_size())) {
184 status_cb.Run(DECODER_ERROR_NOT_SUPPORTED); 176 status_cb.Run(DECODER_ERROR_NOT_SUPPORTED);
185 return; 177 return;
186 } 178 }
187 179
188 config_ = config; 180 config_ = config;
189 needs_bitstream_conversion_ = (config.codec() == kCodecH264); 181 needs_bitstream_conversion_ = (config.codec() == kCodecH264);
182 output_cb_ = BindToCurrentLoop(output_cb);
190 183
191 if (previously_initialized) { 184 if (previously_initialized) {
192 // Reinitialization with a different config (but same codec and profile). 185 // Reinitialization with a different config (but same codec and profile).
193 // VDA should handle it by detecting this in-stream by itself, 186 // VDA should handle it by detecting this in-stream by itself,
194 // no need to notify it. 187 // no need to notify it.
195 status_cb.Run(PIPELINE_OK); 188 status_cb.Run(PIPELINE_OK);
196 return; 189 return;
197 } 190 }
198 191
199 vda_ = factories_->CreateVideoDecodeAccelerator().Pass(); 192 vda_ = factories_->CreateVideoDecodeAccelerator().Pass();
(...skipping 30 matching lines...) Expand all
230 ++it) { 223 ++it) {
231 assigned_picture_buffers_.erase(it->first); 224 assigned_picture_buffers_.erase(it->first);
232 } 225 }
233 DestroyPictureBuffers(&assigned_picture_buffers_); 226 DestroyPictureBuffers(&assigned_picture_buffers_);
234 } 227 }
235 228
236 void GpuVideoDecoder::Decode(const scoped_refptr<DecoderBuffer>& buffer, 229 void GpuVideoDecoder::Decode(const scoped_refptr<DecoderBuffer>& buffer,
237 const DecodeCB& decode_cb) { 230 const DecodeCB& decode_cb) {
238 DCheckGpuVideoAcceleratorFactoriesTaskRunnerIsCurrent(); 231 DCheckGpuVideoAcceleratorFactoriesTaskRunnerIsCurrent();
239 DCHECK(pending_reset_cb_.is_null()); 232 DCHECK(pending_reset_cb_.is_null());
240 DCHECK(pending_decode_cb_.is_null());
241 233
242 pending_decode_cb_ = BindToCurrentLoop(decode_cb); 234 DecodeCB bound_decode_cb = BindToCurrentLoop(decode_cb);
243 235
244 if (state_ == kError || !vda_) { 236 if (state_ == kError || !vda_) {
245 base::ResetAndReturn(&pending_decode_cb_).Run(kDecodeError, NULL); 237 bound_decode_cb.Run(kDecodeError);
246 return; 238 return;
247 } 239 }
248 240
249 switch (state_) { 241 switch (state_) {
250 case kDecoderDrained: 242 case kDecoderDrained:
251 if (!ready_video_frames_.empty()) {
252 EnqueueFrameAndTriggerFrameDelivery(NULL);
253 return;
254 }
255 state_ = kNormal; 243 state_ = kNormal;
256 // Fall-through. 244 // Fall-through.
257 case kNormal: 245 case kNormal:
258 break; 246 break;
259 case kDrainingDecoder: 247 case kDrainingDecoder:
260 DCHECK(buffer->end_of_stream());
261 // Do nothing. Will be satisfied either by a PictureReady or
262 // NotifyFlushDone below.
263 return;
264 case kError: 248 case kError:
265 NOTREACHED(); 249 NOTREACHED();
266 return; 250 return;
267 } 251 }
268 252
253 DCHECK_EQ(state_, kNormal);
254
269 if (buffer->end_of_stream()) { 255 if (buffer->end_of_stream()) {
270 if (state_ == kNormal) { 256 state_ = kDrainingDecoder;
271 state_ = kDrainingDecoder; 257 eos_decode_cb_ = bound_decode_cb;
272 vda_->Flush(); 258 vda_->Flush();
273 // If we have ready frames, go ahead and process them to ensure that the
274 // Flush operation does not block in the VDA due to lack of picture
275 // buffers.
276 if (!ready_video_frames_.empty())
277 EnqueueFrameAndTriggerFrameDelivery(NULL);
278 }
279 return; 259 return;
280 } 260 }
281 261
282 size_t size = buffer->data_size(); 262 size_t size = buffer->data_size();
283 SHMBuffer* shm_buffer = GetSHM(size); 263 SHMBuffer* shm_buffer = GetSHM(size);
284 if (!shm_buffer) { 264 if (!shm_buffer) {
285 base::ResetAndReturn(&pending_decode_cb_).Run(kDecodeError, NULL); 265 bound_decode_cb.Run(kDecodeError);
286 return; 266 return;
287 } 267 }
288 268
289 memcpy(shm_buffer->shm->memory(), buffer->data(), size); 269 memcpy(shm_buffer->shm->memory(), buffer->data(), size);
290 BitstreamBuffer bitstream_buffer( 270 BitstreamBuffer bitstream_buffer(
291 next_bitstream_buffer_id_, shm_buffer->shm->handle(), size); 271 next_bitstream_buffer_id_, shm_buffer->shm->handle(), size);
292 // Mask against 30 bits, to avoid (undefined) wraparound on signed integer. 272 // Mask against 30 bits, to avoid (undefined) wraparound on signed integer.
293 next_bitstream_buffer_id_ = (next_bitstream_buffer_id_ + 1) & 0x3FFFFFFF; 273 next_bitstream_buffer_id_ = (next_bitstream_buffer_id_ + 1) & 0x3FFFFFFF;
294 bool inserted = bitstream_buffers_in_decoder_.insert(std::make_pair( 274 DCHECK(!ContainsKey(bitstream_buffers_in_decoder_, bitstream_buffer.id()));
295 bitstream_buffer.id(), BufferPair(shm_buffer, buffer))).second; 275 bitstream_buffers_in_decoder_.insert(
296 DCHECK(inserted); 276 std::make_pair(bitstream_buffer.id(),
277 PendingDecoderBuffer(shm_buffer, buffer, decode_cb)));
278 DCHECK_LE(static_cast<int>(bitstream_buffers_in_decoder_.size()),
279 kMaxInFlightDecodes);
297 RecordBufferData(bitstream_buffer, *buffer.get()); 280 RecordBufferData(bitstream_buffer, *buffer.get());
298 281
299 vda_->Decode(bitstream_buffer); 282 vda_->Decode(bitstream_buffer);
300
301 if (!ready_video_frames_.empty()) {
302 EnqueueFrameAndTriggerFrameDelivery(NULL);
303 return;
304 }
305
306 if (CanMoreDecodeWorkBeDone())
307 base::ResetAndReturn(&pending_decode_cb_).Run(kNotEnoughData, NULL);
308 }
309
310 bool GpuVideoDecoder::CanMoreDecodeWorkBeDone() {
311 return bitstream_buffers_in_decoder_.size() < kMaxInFlightDecodes;
312 } 283 }
313 284
314 void GpuVideoDecoder::RecordBufferData(const BitstreamBuffer& bitstream_buffer, 285 void GpuVideoDecoder::RecordBufferData(const BitstreamBuffer& bitstream_buffer,
315 const DecoderBuffer& buffer) { 286 const DecoderBuffer& buffer) {
316 input_buffer_data_.push_front(BufferData(bitstream_buffer.id(), 287 input_buffer_data_.push_front(BufferData(bitstream_buffer.id(),
317 buffer.timestamp(), 288 buffer.timestamp(),
318 config_.visible_rect(), 289 config_.visible_rect(),
319 config_.natural_size())); 290 config_.natural_size()));
320 // Why this value? Because why not. avformat.h:MAX_REORDER_DELAY is 16, but 291 // Why this value? Because why not. avformat.h:MAX_REORDER_DELAY is 16, but
321 // that's too small for some pathological B-frame test videos. The cost of 292 // that's too small for some pathological B-frame test videos. The cost of
(...skipping 23 matching lines...) Expand all
345 316
346 bool GpuVideoDecoder::NeedsBitstreamConversion() const { 317 bool GpuVideoDecoder::NeedsBitstreamConversion() const {
347 DCheckGpuVideoAcceleratorFactoriesTaskRunnerIsCurrent(); 318 DCheckGpuVideoAcceleratorFactoriesTaskRunnerIsCurrent();
348 return needs_bitstream_conversion_; 319 return needs_bitstream_conversion_;
349 } 320 }
350 321
351 bool GpuVideoDecoder::CanReadWithoutStalling() const { 322 bool GpuVideoDecoder::CanReadWithoutStalling() const {
352 DCheckGpuVideoAcceleratorFactoriesTaskRunnerIsCurrent(); 323 DCheckGpuVideoAcceleratorFactoriesTaskRunnerIsCurrent();
353 return 324 return
354 next_picture_buffer_id_ == 0 || // Decode() will ProvidePictureBuffers(). 325 next_picture_buffer_id_ == 0 || // Decode() will ProvidePictureBuffers().
355 available_pictures_ > 0 || !ready_video_frames_.empty(); 326 available_pictures_ > 0;
327 }
328
329 int GpuVideoDecoder::GetMaxDecodeRequests() const {
330 return kMaxInFlightDecodes;
356 } 331 }
357 332
358 void GpuVideoDecoder::ProvidePictureBuffers(uint32 count, 333 void GpuVideoDecoder::ProvidePictureBuffers(uint32 count,
359 const gfx::Size& size, 334 const gfx::Size& size,
360 uint32 texture_target) { 335 uint32 texture_target) {
361 DVLOG(3) << "ProvidePictureBuffers(" << count << ", " 336 DVLOG(3) << "ProvidePictureBuffers(" << count << ", "
362 << size.width() << "x" << size.height() << ")"; 337 << size.width() << "x" << size.height() << ")";
363 DCheckGpuVideoAcceleratorFactoriesTaskRunnerIsCurrent(); 338 DCheckGpuVideoAcceleratorFactoriesTaskRunnerIsCurrent();
364 339
365 std::vector<uint32> texture_ids; 340 std::vector<uint32> texture_ids;
(...skipping 112 matching lines...) Expand 10 before | Expand all | Expand 10 after
478 timestamp, 453 timestamp,
479 base::Bind(&ReadPixelsSync, factories_, pb.texture_id(), visible_rect))); 454 base::Bind(&ReadPixelsSync, factories_, pb.texture_id(), visible_rect)));
480 CHECK_GT(available_pictures_, 0); 455 CHECK_GT(available_pictures_, 0);
481 --available_pictures_; 456 --available_pictures_;
482 bool inserted = 457 bool inserted =
483 picture_buffers_at_display_.insert(std::make_pair( 458 picture_buffers_at_display_.insert(std::make_pair(
484 picture.picture_buffer_id(), 459 picture.picture_buffer_id(),
485 pb.texture_id())).second; 460 pb.texture_id())).second;
486 DCHECK(inserted); 461 DCHECK(inserted);
487 462
488 EnqueueFrameAndTriggerFrameDelivery(frame); 463 DeliverFrame(frame);
489 } 464 }
490 465
491 void GpuVideoDecoder::EnqueueFrameAndTriggerFrameDelivery( 466 void GpuVideoDecoder::DeliverFrame(
492 const scoped_refptr<VideoFrame>& frame) { 467 const scoped_refptr<VideoFrame>& frame) {
493 DCheckGpuVideoAcceleratorFactoriesTaskRunnerIsCurrent(); 468 DCheckGpuVideoAcceleratorFactoriesTaskRunnerIsCurrent();
494 469
495 // During a pending vda->Reset(), we don't accumulate frames. Drop it on the 470 // During a pending vda->Reset(), we don't accumulate frames. Drop it on the
496 // floor and return. 471 // floor and return.
497 if (!pending_reset_cb_.is_null()) 472 if (!pending_reset_cb_.is_null())
498 return; 473 return;
499 474
500 if (frame.get()) 475 output_cb_.Run(frame);
501 ready_video_frames_.push_back(frame);
502 else
503 DCHECK(!ready_video_frames_.empty());
504
505 if (pending_decode_cb_.is_null())
506 return;
507
508 base::ResetAndReturn(&pending_decode_cb_)
509 .Run(kOk, ready_video_frames_.front());
510 ready_video_frames_.pop_front();
511 } 476 }
512 477
513 // static 478 // static
514 void GpuVideoDecoder::ReleaseMailbox( 479 void GpuVideoDecoder::ReleaseMailbox(
515 base::WeakPtr<GpuVideoDecoder> decoder, 480 base::WeakPtr<GpuVideoDecoder> decoder,
516 const scoped_refptr<media::GpuVideoAcceleratorFactories>& factories, 481 const scoped_refptr<media::GpuVideoAcceleratorFactories>& factories,
517 int64 picture_buffer_id, 482 int64 picture_buffer_id,
518 uint32 texture_id, 483 uint32 texture_id,
519 const std::vector<uint32>& release_sync_points) { 484 const std::vector<uint32>& release_sync_points) {
520 DCHECK(factories->GetTaskRunner()->BelongsToCurrentThread()); 485 DCHECK(factories->GetTaskRunner()->BelongsToCurrentThread());
(...skipping 52 matching lines...) Expand 10 before | Expand all | Expand 10 after
573 538
574 void GpuVideoDecoder::PutSHM(SHMBuffer* shm_buffer) { 539 void GpuVideoDecoder::PutSHM(SHMBuffer* shm_buffer) {
575 DCheckGpuVideoAcceleratorFactoriesTaskRunnerIsCurrent(); 540 DCheckGpuVideoAcceleratorFactoriesTaskRunnerIsCurrent();
576 available_shm_segments_.push_back(shm_buffer); 541 available_shm_segments_.push_back(shm_buffer);
577 } 542 }
578 543
579 void GpuVideoDecoder::NotifyEndOfBitstreamBuffer(int32 id) { 544 void GpuVideoDecoder::NotifyEndOfBitstreamBuffer(int32 id) {
580 DVLOG(3) << "NotifyEndOfBitstreamBuffer(" << id << ")"; 545 DVLOG(3) << "NotifyEndOfBitstreamBuffer(" << id << ")";
581 DCheckGpuVideoAcceleratorFactoriesTaskRunnerIsCurrent(); 546 DCheckGpuVideoAcceleratorFactoriesTaskRunnerIsCurrent();
582 547
583 std::map<int32, BufferPair>::iterator it = 548 std::map<int32, PendingDecoderBuffer>::iterator it =
584 bitstream_buffers_in_decoder_.find(id); 549 bitstream_buffers_in_decoder_.find(id);
585 if (it == bitstream_buffers_in_decoder_.end()) { 550 if (it == bitstream_buffers_in_decoder_.end()) {
586 NotifyError(VideoDecodeAccelerator::PLATFORM_FAILURE); 551 NotifyError(VideoDecodeAccelerator::PLATFORM_FAILURE);
587 NOTREACHED() << "Missing bitstream buffer: " << id; 552 NOTREACHED() << "Missing bitstream buffer: " << id;
588 return; 553 return;
589 } 554 }
590 555
591 PutSHM(it->second.shm_buffer); 556 PutSHM(it->second.shm_buffer);
557 it->second.done_cb.Run(state_ == kError ? kDecodeError : kOk);
592 bitstream_buffers_in_decoder_.erase(it); 558 bitstream_buffers_in_decoder_.erase(it);
593
594 if (pending_reset_cb_.is_null() && state_ != kDrainingDecoder &&
595 CanMoreDecodeWorkBeDone() && !pending_decode_cb_.is_null()) {
596 base::ResetAndReturn(&pending_decode_cb_).Run(kNotEnoughData, NULL);
597 }
598 } 559 }
599 560
600 GpuVideoDecoder::~GpuVideoDecoder() { 561 GpuVideoDecoder::~GpuVideoDecoder() {
601 DCheckGpuVideoAcceleratorFactoriesTaskRunnerIsCurrent(); 562 DCheckGpuVideoAcceleratorFactoriesTaskRunnerIsCurrent();
602 // Stop should have been already called. 563 // Stop should have been already called.
603 DCHECK(!vda_.get() && assigned_picture_buffers_.empty()); 564 DCHECK(!vda_.get() && assigned_picture_buffers_.empty());
604 DCHECK(pending_decode_cb_.is_null()); 565 DCHECK(bitstream_buffers_in_decoder_.empty());
605 for (size_t i = 0; i < available_shm_segments_.size(); ++i) { 566 for (size_t i = 0; i < available_shm_segments_.size(); ++i) {
606 available_shm_segments_[i]->shm->Close(); 567 available_shm_segments_[i]->shm->Close();
607 delete available_shm_segments_[i]; 568 delete available_shm_segments_[i];
608 } 569 }
609 available_shm_segments_.clear(); 570 available_shm_segments_.clear();
610 for (std::map<int32, BufferPair>::iterator it = 571 for (std::map<int32, PendingDecoderBuffer>::iterator it =
611 bitstream_buffers_in_decoder_.begin(); 572 bitstream_buffers_in_decoder_.begin();
612 it != bitstream_buffers_in_decoder_.end(); ++it) { 573 it != bitstream_buffers_in_decoder_.end(); ++it) {
613 it->second.shm_buffer->shm->Close(); 574 it->second.shm_buffer->shm->Close();
614 } 575 }
615 bitstream_buffers_in_decoder_.clear(); 576 bitstream_buffers_in_decoder_.clear();
616 } 577 }
617 578
618 void GpuVideoDecoder::NotifyFlushDone() { 579 void GpuVideoDecoder::NotifyFlushDone() {
619 DVLOG(3) << "NotifyFlushDone()"; 580 DVLOG(3) << "NotifyFlushDone()";
620 DCheckGpuVideoAcceleratorFactoriesTaskRunnerIsCurrent(); 581 DCheckGpuVideoAcceleratorFactoriesTaskRunnerIsCurrent();
621 DCHECK_EQ(state_, kDrainingDecoder); 582 DCHECK_EQ(state_, kDrainingDecoder);
622 state_ = kDecoderDrained; 583 state_ = kDecoderDrained;
623 EnqueueFrameAndTriggerFrameDelivery(VideoFrame::CreateEOSFrame()); 584 DeliverFrame(VideoFrame::CreateEOSFrame());
585 base::ResetAndReturn(&eos_decode_cb_).Run(kOk);
624 } 586 }
625 587
626 void GpuVideoDecoder::NotifyResetDone() { 588 void GpuVideoDecoder::NotifyResetDone() {
627 DVLOG(3) << "NotifyResetDone()"; 589 DVLOG(3) << "NotifyResetDone()";
628 DCheckGpuVideoAcceleratorFactoriesTaskRunnerIsCurrent(); 590 DCheckGpuVideoAcceleratorFactoriesTaskRunnerIsCurrent();
629 DCHECK(ready_video_frames_.empty()); 591 DCHECK(bitstream_buffers_in_decoder_.empty());
630 592
631 // This needs to happen after the Reset() on vda_ is done to ensure pictures 593 // This needs to happen after the Reset() on vda_ is done to ensure pictures
632 // delivered during the reset can find their time data. 594 // delivered during the reset can find their time data.
633 input_buffer_data_.clear(); 595 input_buffer_data_.clear();
634 596
635 if (!pending_reset_cb_.is_null()) 597 if (!pending_reset_cb_.is_null())
636 base::ResetAndReturn(&pending_reset_cb_).Run(); 598 base::ResetAndReturn(&pending_reset_cb_).Run();
637
638 if (!pending_decode_cb_.is_null())
639 EnqueueFrameAndTriggerFrameDelivery(VideoFrame::CreateEOSFrame());
640 } 599 }
641 600
642 void GpuVideoDecoder::NotifyError(media::VideoDecodeAccelerator::Error error) { 601 void GpuVideoDecoder::NotifyError(media::VideoDecodeAccelerator::Error error) {
643 DCheckGpuVideoAcceleratorFactoriesTaskRunnerIsCurrent(); 602 DCheckGpuVideoAcceleratorFactoriesTaskRunnerIsCurrent();
644 if (!vda_) 603 if (!vda_)
645 return; 604 return;
646 605
606 state_ = kError;
607
647 DLOG(ERROR) << "VDA Error: " << error; 608 DLOG(ERROR) << "VDA Error: " << error;
648 DestroyVDA(); 609 DestroyVDA();
649
650 state_ = kError;
651
652 if (!pending_decode_cb_.is_null()) {
653 base::ResetAndReturn(&pending_decode_cb_).Run(kDecodeError, NULL);
654 return;
655 }
656 } 610 }
657 611
658 void GpuVideoDecoder::DCheckGpuVideoAcceleratorFactoriesTaskRunnerIsCurrent() 612 void GpuVideoDecoder::DCheckGpuVideoAcceleratorFactoriesTaskRunnerIsCurrent()
659 const { 613 const {
660 DCHECK(factories_->GetTaskRunner()->BelongsToCurrentThread()); 614 DCHECK(factories_->GetTaskRunner()->BelongsToCurrentThread());
661 } 615 }
662 616
663 } // namespace media 617 } // namespace media
OLDNEW
« no previous file with comments | « media/filters/gpu_video_decoder.h ('k') | media/filters/opus_audio_decoder.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698