| OLD | NEW |
| 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" |
| 11 #include "base/cpu.h" | 11 #include "base/cpu.h" |
| 12 #include "base/message_loop.h" | 12 #include "base/message_loop.h" |
| 13 #include "base/stl_util.h" | 13 #include "base/stl_util.h" |
| 14 #include "base/task_runner_util.h" | 14 #include "base/task_runner_util.h" |
| 15 #include "media/base/bind_to_loop.h" | 15 #include "media/base/bind_to_loop.h" |
| 16 #include "media/base/decoder_buffer.h" | 16 #include "media/base/decoder_buffer.h" |
| 17 #include "media/base/pipeline.h" | 17 #include "media/base/pipeline.h" |
| 18 #include "media/base/pipeline_status.h" | 18 #include "media/base/pipeline_status.h" |
| 19 #include "media/base/video_decoder_config.h" | 19 #include "media/base/video_decoder_config.h" |
| 20 | 20 |
| 21 namespace media { | 21 namespace media { |
| 22 | 22 |
| 23 // Proxies calls to a VideoDecodeAccelerator::Client from the calling thread to | |
| 24 // the client's thread. | |
| 25 // | |
| 26 // TODO(scherkus): VDAClientProxy should hold onto GpuVideoDecoder::Factories | |
| 27 // and take care of some of the work that GpuVideoDecoder does to minimize | |
| 28 // thread hopping. See following for discussion: | |
| 29 // | |
| 30 // https://codereview.chromium.org/12989009/diff/27035/media/filters/gpu_video_d
ecoder.cc#newcode23 | |
| 31 class VDAClientProxy | |
| 32 : public base::RefCountedThreadSafe<VDAClientProxy>, | |
| 33 public VideoDecodeAccelerator::Client { | |
| 34 public: | |
| 35 explicit VDAClientProxy(VideoDecodeAccelerator::Client* client); | |
| 36 | |
| 37 // Detaches the proxy. |weak_client_| will no longer be called and can be | |
| 38 // safely deleted. Any pending/future calls will be discarded. | |
| 39 // | |
| 40 // Must be called on |client_loop_|. | |
| 41 void Detach(); | |
| 42 | |
| 43 // VideoDecodeAccelerator::Client implementation. | |
| 44 virtual void NotifyInitializeDone() OVERRIDE; | |
| 45 virtual void ProvidePictureBuffers(uint32 count, | |
| 46 const gfx::Size& size, | |
| 47 uint32 texture_target) OVERRIDE; | |
| 48 virtual void DismissPictureBuffer(int32 id) OVERRIDE; | |
| 49 virtual void PictureReady(const media::Picture& picture) OVERRIDE; | |
| 50 virtual void NotifyEndOfBitstreamBuffer(int32 id) OVERRIDE; | |
| 51 virtual void NotifyFlushDone() OVERRIDE; | |
| 52 virtual void NotifyResetDone() OVERRIDE; | |
| 53 virtual void NotifyError(media::VideoDecodeAccelerator::Error error) OVERRIDE; | |
| 54 | |
| 55 private: | |
| 56 friend class base::RefCountedThreadSafe<VDAClientProxy>; | |
| 57 virtual ~VDAClientProxy(); | |
| 58 | |
| 59 scoped_refptr<base::MessageLoopProxy> client_loop_; | |
| 60 | |
| 61 // Weak pointers are used to invalidate tasks posted to |client_loop_| after | |
| 62 // Detach() has been called. | |
| 63 base::WeakPtrFactory<VideoDecodeAccelerator::Client> weak_client_factory_; | |
| 64 base::WeakPtr<VideoDecodeAccelerator::Client> weak_client_; | |
| 65 | |
| 66 DISALLOW_COPY_AND_ASSIGN(VDAClientProxy); | |
| 67 }; | |
| 68 | |
| 69 VDAClientProxy::VDAClientProxy(VideoDecodeAccelerator::Client* client) | |
| 70 : client_loop_(base::MessageLoopProxy::current()), | |
| 71 weak_client_factory_(client), | |
| 72 weak_client_(weak_client_factory_.GetWeakPtr()) { | |
| 73 DCHECK(weak_client_.get()); | |
| 74 } | |
| 75 | |
| 76 VDAClientProxy::~VDAClientProxy() {} | |
| 77 | |
| 78 void VDAClientProxy::Detach() { | |
| 79 DCHECK(client_loop_->BelongsToCurrentThread()); | |
| 80 DCHECK(weak_client_.get()) << "Detach() already called"; | |
| 81 weak_client_factory_.InvalidateWeakPtrs(); | |
| 82 } | |
| 83 | |
| 84 void VDAClientProxy::NotifyInitializeDone() { | |
| 85 client_loop_->PostTask(FROM_HERE, base::Bind( | |
| 86 &VideoDecodeAccelerator::Client::NotifyInitializeDone, weak_client_)); | |
| 87 } | |
| 88 | |
| 89 void VDAClientProxy::ProvidePictureBuffers(uint32 count, | |
| 90 const gfx::Size& size, | |
| 91 uint32 texture_target) { | |
| 92 client_loop_->PostTask(FROM_HERE, base::Bind( | |
| 93 &VideoDecodeAccelerator::Client::ProvidePictureBuffers, weak_client_, | |
| 94 count, size, texture_target)); | |
| 95 } | |
| 96 | |
| 97 void VDAClientProxy::DismissPictureBuffer(int32 id) { | |
| 98 client_loop_->PostTask(FROM_HERE, base::Bind( | |
| 99 &VideoDecodeAccelerator::Client::DismissPictureBuffer, weak_client_, id)); | |
| 100 } | |
| 101 | |
| 102 void VDAClientProxy::PictureReady(const media::Picture& picture) { | |
| 103 client_loop_->PostTask(FROM_HERE, base::Bind( | |
| 104 &VideoDecodeAccelerator::Client::PictureReady, weak_client_, picture)); | |
| 105 } | |
| 106 | |
| 107 void VDAClientProxy::NotifyEndOfBitstreamBuffer(int32 id) { | |
| 108 client_loop_->PostTask(FROM_HERE, base::Bind( | |
| 109 &VideoDecodeAccelerator::Client::NotifyEndOfBitstreamBuffer, weak_client_, | |
| 110 id)); | |
| 111 } | |
| 112 | |
| 113 void VDAClientProxy::NotifyFlushDone() { | |
| 114 client_loop_->PostTask(FROM_HERE, base::Bind( | |
| 115 &VideoDecodeAccelerator::Client::NotifyFlushDone, weak_client_)); | |
| 116 } | |
| 117 | |
| 118 void VDAClientProxy::NotifyResetDone() { | |
| 119 client_loop_->PostTask(FROM_HERE, base::Bind( | |
| 120 &VideoDecodeAccelerator::Client::NotifyResetDone, weak_client_)); | |
| 121 } | |
| 122 | |
| 123 void VDAClientProxy::NotifyError(media::VideoDecodeAccelerator::Error error) { | |
| 124 client_loop_->PostTask(FROM_HERE, base::Bind( | |
| 125 &VideoDecodeAccelerator::Client::NotifyError, weak_client_, error)); | |
| 126 } | |
| 127 | |
| 128 | |
| 129 // Maximum number of concurrent VDA::Decode() operations GVD will maintain. | 23 // Maximum number of concurrent VDA::Decode() operations GVD will maintain. |
| 130 // Higher values allow better pipelining in the GPU, but also require more | 24 // Higher values allow better pipelining in the GPU, but also require more |
| 131 // resources. | 25 // resources. |
| 132 enum { kMaxInFlightDecodes = 4 }; | 26 enum { kMaxInFlightDecodes = 4 }; |
| 133 | 27 |
| 134 GpuVideoDecoder::Factories::~Factories() {} | 28 GpuVideoDecoder::Factories::~Factories() {} |
| 135 | 29 |
| 136 // Size of shared-memory segments we allocate. Since we reuse them we let them | 30 // Size of shared-memory segments we allocate. Since we reuse them we let them |
| 137 // be on the beefy side. | 31 // be on the beefy side. |
| 138 static const size_t kSharedMemorySegmentBytes = 100 << 10; | 32 static const size_t kSharedMemorySegmentBytes = 100 << 10; |
| (...skipping 12 matching lines...) Expand all Loading... |
| 151 GpuVideoDecoder::BufferPair::~BufferPair() {} | 45 GpuVideoDecoder::BufferPair::~BufferPair() {} |
| 152 | 46 |
| 153 GpuVideoDecoder::BufferData::BufferData( | 47 GpuVideoDecoder::BufferData::BufferData( |
| 154 int32 bbid, base::TimeDelta ts, const gfx::Rect& vr, const gfx::Size& ns) | 48 int32 bbid, base::TimeDelta ts, const gfx::Rect& vr, const gfx::Size& ns) |
| 155 : bitstream_buffer_id(bbid), timestamp(ts), visible_rect(vr), | 49 : bitstream_buffer_id(bbid), timestamp(ts), visible_rect(vr), |
| 156 natural_size(ns) { | 50 natural_size(ns) { |
| 157 } | 51 } |
| 158 | 52 |
| 159 GpuVideoDecoder::BufferData::~BufferData() {} | 53 GpuVideoDecoder::BufferData::~BufferData() {} |
| 160 | 54 |
| 161 GpuVideoDecoder::GpuVideoDecoder( | 55 GpuVideoDecoder::GpuVideoDecoder(const scoped_refptr<Factories>& factories) |
| 162 const scoped_refptr<base::MessageLoopProxy>& message_loop, | |
| 163 const scoped_refptr<Factories>& factories) | |
| 164 : needs_bitstream_conversion_(false), | 56 : needs_bitstream_conversion_(false), |
| 165 gvd_loop_proxy_(message_loop), | 57 gvd_loop_proxy_(factories->GetMessageLoop()), |
| 166 weak_factory_(this), | 58 weak_factory_(this), |
| 167 vda_loop_proxy_(factories->GetMessageLoop()), | |
| 168 factories_(factories), | 59 factories_(factories), |
| 169 state_(kNormal), | 60 state_(kNormal), |
| 170 decoder_texture_target_(0), | 61 decoder_texture_target_(0), |
| 171 next_picture_buffer_id_(0), | 62 next_picture_buffer_id_(0), |
| 172 next_bitstream_buffer_id_(0), | 63 next_bitstream_buffer_id_(0), |
| 173 available_pictures_(0) { | 64 available_pictures_(0) { |
| 174 DCHECK(factories_.get()); | 65 DCHECK(factories_.get()); |
| 175 } | 66 } |
| 176 | 67 |
| 177 void GpuVideoDecoder::Reset(const base::Closure& closure) { | 68 void GpuVideoDecoder::Reset(const base::Closure& closure) { |
| (...skipping 17 matching lines...) Expand all Loading... |
| 195 gvd_loop_proxy_->PostTask(FROM_HERE, closure); | 86 gvd_loop_proxy_->PostTask(FROM_HERE, closure); |
| 196 return; | 87 return; |
| 197 } | 88 } |
| 198 | 89 |
| 199 if (!pending_read_cb_.is_null()) | 90 if (!pending_read_cb_.is_null()) |
| 200 EnqueueFrameAndTriggerFrameDelivery(VideoFrame::CreateEmptyFrame()); | 91 EnqueueFrameAndTriggerFrameDelivery(VideoFrame::CreateEmptyFrame()); |
| 201 | 92 |
| 202 DCHECK(pending_reset_cb_.is_null()); | 93 DCHECK(pending_reset_cb_.is_null()); |
| 203 pending_reset_cb_ = BindToCurrentLoop(closure); | 94 pending_reset_cb_ = BindToCurrentLoop(closure); |
| 204 | 95 |
| 205 vda_loop_proxy_->PostTask(FROM_HERE, base::Bind( | 96 vda_->Reset(); |
| 206 &VideoDecodeAccelerator::Reset, weak_vda_)); | |
| 207 } | 97 } |
| 208 | 98 |
| 209 void GpuVideoDecoder::Stop(const base::Closure& closure) { | 99 void GpuVideoDecoder::Stop(const base::Closure& closure) { |
| 210 DCHECK(gvd_loop_proxy_->BelongsToCurrentThread()); | 100 DCHECK(gvd_loop_proxy_->BelongsToCurrentThread()); |
| 211 if (vda_) | 101 if (vda_) |
| 212 DestroyVDA(); | 102 DestroyVDA(); |
| 213 if (!pending_read_cb_.is_null()) | 103 if (!pending_read_cb_.is_null()) |
| 214 EnqueueFrameAndTriggerFrameDelivery(VideoFrame::CreateEmptyFrame()); | 104 EnqueueFrameAndTriggerFrameDelivery(VideoFrame::CreateEmptyFrame()); |
| 215 if (!pending_reset_cb_.is_null()) | 105 if (!pending_reset_cb_.is_null()) |
| 216 base::ResetAndReturn(&pending_reset_cb_).Run(); | 106 base::ResetAndReturn(&pending_reset_cb_).Run(); |
| (...skipping 35 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 252 DVLOG(1) << "GpuVideoDecoder reinitialization not supported."; | 142 DVLOG(1) << "GpuVideoDecoder reinitialization not supported."; |
| 253 status_cb.Run(DECODER_ERROR_NOT_SUPPORTED); | 143 status_cb.Run(DECODER_ERROR_NOT_SUPPORTED); |
| 254 return; | 144 return; |
| 255 } | 145 } |
| 256 | 146 |
| 257 if (!IsCodedSizeSupported(config.coded_size())) { | 147 if (!IsCodedSizeSupported(config.coded_size())) { |
| 258 status_cb.Run(DECODER_ERROR_NOT_SUPPORTED); | 148 status_cb.Run(DECODER_ERROR_NOT_SUPPORTED); |
| 259 return; | 149 return; |
| 260 } | 150 } |
| 261 | 151 |
| 262 client_proxy_ = new VDAClientProxy(this); | 152 VideoDecodeAccelerator* vda = |
| 263 VideoDecodeAccelerator* vda = factories_->CreateVideoDecodeAccelerator( | 153 factories_->CreateVideoDecodeAccelerator(config.profile(), this); |
| 264 config.profile(), client_proxy_.get()); | |
| 265 if (!vda) { | 154 if (!vda) { |
| 266 status_cb.Run(DECODER_ERROR_NOT_SUPPORTED); | 155 status_cb.Run(DECODER_ERROR_NOT_SUPPORTED); |
| 267 return; | 156 return; |
| 268 } | 157 } |
| 269 | 158 |
| 270 config_ = config; | 159 config_ = config; |
| 271 needs_bitstream_conversion_ = (config.codec() == kCodecH264); | 160 needs_bitstream_conversion_ = (config.codec() == kCodecH264); |
| 272 | 161 |
| 273 DVLOG(3) << "GpuVideoDecoder::Initialize() succeeded."; | 162 DVLOG(3) << "GpuVideoDecoder::Initialize() succeeded."; |
| 274 PostTaskAndReplyWithResult( | |
| 275 vda_loop_proxy_.get(), | |
| 276 FROM_HERE, | |
| 277 base::Bind(&VideoDecodeAccelerator::AsWeakPtr, base::Unretained(vda)), | |
| 278 base::Bind(&GpuVideoDecoder::SetVDA, weak_this_, status_cb, vda)); | |
| 279 } | |
| 280 | |
| 281 void GpuVideoDecoder::SetVDA( | |
| 282 const PipelineStatusCB& status_cb, | |
| 283 VideoDecodeAccelerator* vda, | |
| 284 base::WeakPtr<VideoDecodeAccelerator> weak_vda) { | |
| 285 DCHECK(gvd_loop_proxy_->BelongsToCurrentThread()); | |
| 286 DCHECK(!vda_.get()); | |
| 287 vda_.reset(vda); | 163 vda_.reset(vda); |
| 288 weak_vda_ = weak_vda; | |
| 289 status_cb.Run(PIPELINE_OK); | 164 status_cb.Run(PIPELINE_OK); |
| 290 } | 165 } |
| 291 | 166 |
| 292 void GpuVideoDecoder::DestroyTextures() { | 167 void GpuVideoDecoder::DestroyTextures() { |
| 293 std::map<int32, PictureBuffer>::iterator it; | 168 std::map<int32, PictureBuffer>::iterator it; |
| 294 | 169 |
| 295 for (it = assigned_picture_buffers_.begin(); | 170 for (it = assigned_picture_buffers_.begin(); |
| 296 it != assigned_picture_buffers_.end(); ++it) { | 171 it != assigned_picture_buffers_.end(); ++it) { |
| 297 factories_->DeleteTexture(it->second.texture_id()); | 172 factories_->DeleteTexture(it->second.texture_id()); |
| 298 } | 173 } |
| 299 assigned_picture_buffers_.clear(); | 174 assigned_picture_buffers_.clear(); |
| 300 | 175 |
| 301 for (it = dismissed_picture_buffers_.begin(); | 176 for (it = dismissed_picture_buffers_.begin(); |
| 302 it != dismissed_picture_buffers_.end(); ++it) { | 177 it != dismissed_picture_buffers_.end(); ++it) { |
| 303 factories_->DeleteTexture(it->second.texture_id()); | 178 factories_->DeleteTexture(it->second.texture_id()); |
| 304 } | 179 } |
| 305 dismissed_picture_buffers_.clear(); | 180 dismissed_picture_buffers_.clear(); |
| 306 } | 181 } |
| 307 | 182 |
| 308 static void DestroyVDAWithClientProxy( | |
| 309 const scoped_refptr<VDAClientProxy>& client_proxy, | |
| 310 base::WeakPtr<VideoDecodeAccelerator> weak_vda) { | |
| 311 if (weak_vda.get()) { | |
| 312 weak_vda->Destroy(); | |
| 313 DCHECK(!weak_vda.get()); // Check VDA::Destroy() contract. | |
| 314 } | |
| 315 } | |
| 316 | |
| 317 void GpuVideoDecoder::DestroyVDA() { | 183 void GpuVideoDecoder::DestroyVDA() { |
| 318 DCHECK(gvd_loop_proxy_->BelongsToCurrentThread()); | 184 DCHECK(gvd_loop_proxy_->BelongsToCurrentThread()); |
| 319 | 185 |
| 320 // |client_proxy| must stay alive until |weak_vda_| has been destroyed. | 186 if (vda_) |
| 321 vda_loop_proxy_->PostTask(FROM_HERE, base::Bind( | 187 vda_.release()->Destroy(); |
| 322 &DestroyVDAWithClientProxy, client_proxy_, weak_vda_)); | |
| 323 | |
| 324 VideoDecodeAccelerator* vda ALLOW_UNUSED = vda_.release(); | |
| 325 client_proxy_->Detach(); | |
| 326 client_proxy_ = NULL; | |
| 327 | 188 |
| 328 DestroyTextures(); | 189 DestroyTextures(); |
| 329 } | 190 } |
| 330 | 191 |
| 331 void GpuVideoDecoder::Decode(const scoped_refptr<DecoderBuffer>& buffer, | 192 void GpuVideoDecoder::Decode(const scoped_refptr<DecoderBuffer>& buffer, |
| 332 const ReadCB& read_cb) { | 193 const ReadCB& read_cb) { |
| 333 DCHECK(gvd_loop_proxy_->BelongsToCurrentThread()); | 194 DCHECK(gvd_loop_proxy_->BelongsToCurrentThread()); |
| 334 DCHECK(pending_reset_cb_.is_null()); | 195 DCHECK(pending_reset_cb_.is_null()); |
| 335 DCHECK(pending_read_cb_.is_null()); | 196 DCHECK(pending_read_cb_.is_null()); |
| 336 | 197 |
| (...skipping 20 matching lines...) Expand all Loading... |
| 357 // NotifyFlushDone below. | 218 // NotifyFlushDone below. |
| 358 return; | 219 return; |
| 359 case kError: | 220 case kError: |
| 360 NOTREACHED(); | 221 NOTREACHED(); |
| 361 return; | 222 return; |
| 362 } | 223 } |
| 363 | 224 |
| 364 if (buffer->IsEndOfStream()) { | 225 if (buffer->IsEndOfStream()) { |
| 365 if (state_ == kNormal) { | 226 if (state_ == kNormal) { |
| 366 state_ = kDrainingDecoder; | 227 state_ = kDrainingDecoder; |
| 367 vda_loop_proxy_->PostTask(FROM_HERE, base::Bind( | 228 vda_->Flush(); |
| 368 &VideoDecodeAccelerator::Flush, weak_vda_)); | |
| 369 } | 229 } |
| 370 return; | 230 return; |
| 371 } | 231 } |
| 372 | 232 |
| 373 size_t size = buffer->GetDataSize(); | 233 size_t size = buffer->GetDataSize(); |
| 374 SHMBuffer* shm_buffer = GetSHM(size); | 234 SHMBuffer* shm_buffer = GetSHM(size); |
| 375 if (!shm_buffer) { | 235 if (!shm_buffer) { |
| 376 base::ResetAndReturn(&pending_read_cb_).Run(kDecodeError, NULL); | 236 base::ResetAndReturn(&pending_read_cb_).Run(kDecodeError, NULL); |
| 377 return; | 237 return; |
| 378 } | 238 } |
| 379 | 239 |
| 380 memcpy(shm_buffer->shm->memory(), buffer->GetData(), size); | 240 memcpy(shm_buffer->shm->memory(), buffer->GetData(), size); |
| 381 BitstreamBuffer bitstream_buffer( | 241 BitstreamBuffer bitstream_buffer( |
| 382 next_bitstream_buffer_id_, shm_buffer->shm->handle(), size); | 242 next_bitstream_buffer_id_, shm_buffer->shm->handle(), size); |
| 383 // Mask against 30 bits, to avoid (undefined) wraparound on signed integer. | 243 // Mask against 30 bits, to avoid (undefined) wraparound on signed integer. |
| 384 next_bitstream_buffer_id_ = (next_bitstream_buffer_id_ + 1) & 0x3FFFFFFF; | 244 next_bitstream_buffer_id_ = (next_bitstream_buffer_id_ + 1) & 0x3FFFFFFF; |
| 385 bool inserted = bitstream_buffers_in_decoder_.insert(std::make_pair( | 245 bool inserted = bitstream_buffers_in_decoder_.insert(std::make_pair( |
| 386 bitstream_buffer.id(), BufferPair(shm_buffer, buffer))).second; | 246 bitstream_buffer.id(), BufferPair(shm_buffer, buffer))).second; |
| 387 DCHECK(inserted); | 247 DCHECK(inserted); |
| 388 RecordBufferData(bitstream_buffer, *buffer.get()); | 248 RecordBufferData(bitstream_buffer, *buffer.get()); |
| 389 | 249 |
| 390 vda_loop_proxy_->PostTask(FROM_HERE, base::Bind( | 250 vda_->Decode(bitstream_buffer); |
| 391 &VideoDecodeAccelerator::Decode, weak_vda_, bitstream_buffer)); | |
| 392 | 251 |
| 393 if (!ready_video_frames_.empty()) { | 252 if (!ready_video_frames_.empty()) { |
| 394 EnqueueFrameAndTriggerFrameDelivery(NULL); | 253 EnqueueFrameAndTriggerFrameDelivery(NULL); |
| 395 return; | 254 return; |
| 396 } | 255 } |
| 397 | 256 |
| 398 if (CanMoreDecodeWorkBeDone()) | 257 if (CanMoreDecodeWorkBeDone()) |
| 399 base::ResetAndReturn(&pending_read_cb_).Run(kNotEnoughData, NULL); | 258 base::ResetAndReturn(&pending_read_cb_).Run(kNotEnoughData, NULL); |
| 400 } | 259 } |
| 401 | 260 |
| (...skipping 82 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 484 for (size_t i = 0; i < texture_ids.size(); ++i) { | 343 for (size_t i = 0; i < texture_ids.size(); ++i) { |
| 485 picture_buffers.push_back(PictureBuffer( | 344 picture_buffers.push_back(PictureBuffer( |
| 486 next_picture_buffer_id_++, size, texture_ids[i], texture_mailboxes[i])); | 345 next_picture_buffer_id_++, size, texture_ids[i], texture_mailboxes[i])); |
| 487 bool inserted = assigned_picture_buffers_.insert(std::make_pair( | 346 bool inserted = assigned_picture_buffers_.insert(std::make_pair( |
| 488 picture_buffers.back().id(), picture_buffers.back())).second; | 347 picture_buffers.back().id(), picture_buffers.back())).second; |
| 489 DCHECK(inserted); | 348 DCHECK(inserted); |
| 490 } | 349 } |
| 491 | 350 |
| 492 available_pictures_ += count; | 351 available_pictures_ += count; |
| 493 | 352 |
| 494 vda_loop_proxy_->PostTask(FROM_HERE, base::Bind( | 353 vda_->AssignPictureBuffers(picture_buffers); |
| 495 &VideoDecodeAccelerator::AssignPictureBuffers, weak_vda_, | |
| 496 picture_buffers)); | |
| 497 } | 354 } |
| 498 | 355 |
| 499 void GpuVideoDecoder::DismissPictureBuffer(int32 id) { | 356 void GpuVideoDecoder::DismissPictureBuffer(int32 id) { |
| 500 DVLOG(3) << "DismissPictureBuffer(" << id << ")"; | 357 DVLOG(3) << "DismissPictureBuffer(" << id << ")"; |
| 501 DCHECK(gvd_loop_proxy_->BelongsToCurrentThread()); | 358 DCHECK(gvd_loop_proxy_->BelongsToCurrentThread()); |
| 502 | 359 |
| 503 std::map<int32, PictureBuffer>::iterator it = | 360 std::map<int32, PictureBuffer>::iterator it = |
| 504 assigned_picture_buffers_.find(id); | 361 assigned_picture_buffers_.find(id); |
| 505 if (it == assigned_picture_buffers_.end()) { | 362 if (it == assigned_picture_buffers_.end()) { |
| 506 NOTREACHED() << "Missing picture buffer: " << id; | 363 NOTREACHED() << "Missing picture buffer: " << id; |
| (...skipping 106 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 613 it = dismissed_picture_buffers_.find(picture_buffer_id); | 470 it = dismissed_picture_buffers_.find(picture_buffer_id); |
| 614 DCHECK(it != dismissed_picture_buffers_.end()); | 471 DCHECK(it != dismissed_picture_buffers_.end()); |
| 615 factories_->DeleteTexture(it->second.texture_id()); | 472 factories_->DeleteTexture(it->second.texture_id()); |
| 616 dismissed_picture_buffers_.erase(it); | 473 dismissed_picture_buffers_.erase(it); |
| 617 return; | 474 return; |
| 618 } | 475 } |
| 619 | 476 |
| 620 factories_->WaitSyncPoint(sync_point); | 477 factories_->WaitSyncPoint(sync_point); |
| 621 ++available_pictures_; | 478 ++available_pictures_; |
| 622 | 479 |
| 623 vda_loop_proxy_->PostTask(FROM_HERE, base::Bind( | 480 vda_->ReusePictureBuffer(picture_buffer_id); |
| 624 &VideoDecodeAccelerator::ReusePictureBuffer, weak_vda_, | |
| 625 picture_buffer_id)); | |
| 626 } | 481 } |
| 627 | 482 |
| 628 GpuVideoDecoder::SHMBuffer* GpuVideoDecoder::GetSHM(size_t min_size) { | 483 GpuVideoDecoder::SHMBuffer* GpuVideoDecoder::GetSHM(size_t min_size) { |
| 629 DCHECK(gvd_loop_proxy_->BelongsToCurrentThread()); | 484 DCHECK(gvd_loop_proxy_->BelongsToCurrentThread()); |
| 630 if (available_shm_segments_.empty() || | 485 if (available_shm_segments_.empty() || |
| 631 available_shm_segments_.back()->size < min_size) { | 486 available_shm_segments_.back()->size < min_size) { |
| 632 size_t size_to_allocate = std::max(min_size, kSharedMemorySegmentBytes); | 487 size_t size_to_allocate = std::max(min_size, kSharedMemorySegmentBytes); |
| 633 base::SharedMemory* shm = factories_->CreateSharedMemory(size_to_allocate); | 488 base::SharedMemory* shm = factories_->CreateSharedMemory(size_to_allocate); |
| 634 // CreateSharedMemory() can return NULL during Shutdown. | 489 // CreateSharedMemory() can return NULL during Shutdown. |
| 635 if (!shm) | 490 if (!shm) |
| (...skipping 83 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 719 | 574 |
| 720 state_ = kError; | 575 state_ = kError; |
| 721 | 576 |
| 722 if (!pending_read_cb_.is_null()) { | 577 if (!pending_read_cb_.is_null()) { |
| 723 base::ResetAndReturn(&pending_read_cb_).Run(kDecodeError, NULL); | 578 base::ResetAndReturn(&pending_read_cb_).Run(kDecodeError, NULL); |
| 724 return; | 579 return; |
| 725 } | 580 } |
| 726 } | 581 } |
| 727 | 582 |
| 728 } // namespace media | 583 } // namespace media |
| OLD | NEW |