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

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

Issue 2011653002: Close bitstream buffer shared memory handles on Android. (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: moved BitstreamRecord code higher in avda.cc Created 4 years, 7 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 | « media/gpu/android_video_decode_accelerator.h ('k') | 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 (c) 2013 The Chromium Authors. All rights reserved. 1 // Copyright (c) 2013 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/android_video_decode_accelerator.h" 5 #include "media/gpu/android_video_decode_accelerator.h"
6 6
7 #include <stddef.h> 7 #include <stddef.h>
8 8
9 #include <memory> 9 #include <memory>
10 10
(...skipping 350 matching lines...) Expand 10 before | Expand all | Expand 10 after
361 DISALLOW_COPY_AND_ASSIGN(AVDATimerManager); 361 DISALLOW_COPY_AND_ASSIGN(AVDATimerManager);
362 }; 362 };
363 363
364 static base::LazyInstance<AVDATimerManager>::Leaky g_avda_timer = 364 static base::LazyInstance<AVDATimerManager>::Leaky g_avda_timer =
365 LAZY_INSTANCE_INITIALIZER; 365 LAZY_INSTANCE_INITIALIZER;
366 366
367 AndroidVideoDecodeAccelerator::CodecConfig::CodecConfig() {} 367 AndroidVideoDecodeAccelerator::CodecConfig::CodecConfig() {}
368 368
369 AndroidVideoDecodeAccelerator::CodecConfig::~CodecConfig() {} 369 AndroidVideoDecodeAccelerator::CodecConfig::~CodecConfig() {}
370 370
371 AndroidVideoDecodeAccelerator::BitstreamRecord::BitstreamRecord(
372 const media::BitstreamBuffer& bitstream_buffer)
373 : buffer(bitstream_buffer) {
374 if (buffer.id() != -1)
375 memory.reset(new SharedMemoryRegion(buffer, true));
376 }
377
378 AndroidVideoDecodeAccelerator::BitstreamRecord::BitstreamRecord(
379 BitstreamRecord&& other)
380 : buffer(std::move(other.buffer)), memory(std::move(other.memory)) {}
381
382 AndroidVideoDecodeAccelerator::BitstreamRecord::~BitstreamRecord() {}
383
371 AndroidVideoDecodeAccelerator::AndroidVideoDecodeAccelerator( 384 AndroidVideoDecodeAccelerator::AndroidVideoDecodeAccelerator(
372 const MakeGLContextCurrentCallback& make_context_current_cb, 385 const MakeGLContextCurrentCallback& make_context_current_cb,
373 const GetGLES2DecoderCallback& get_gles2_decoder_cb) 386 const GetGLES2DecoderCallback& get_gles2_decoder_cb)
374 : client_(NULL), 387 : client_(NULL),
375 make_context_current_cb_(make_context_current_cb), 388 make_context_current_cb_(make_context_current_cb),
376 get_gles2_decoder_cb_(get_gles2_decoder_cb), 389 get_gles2_decoder_cb_(get_gles2_decoder_cb),
377 state_(NO_ERROR), 390 state_(NO_ERROR),
378 picturebuffers_requested_(false), 391 picturebuffers_requested_(false),
379 drain_type_(DRAIN_TYPE_NONE), 392 drain_type_(DRAIN_TYPE_NONE),
380 media_drm_bridge_cdm_context_(nullptr), 393 media_drm_bridge_cdm_context_(nullptr),
(...skipping 184 matching lines...) Expand 10 before | Expand all | Expand 10 after
565 578
566 ManageTimer(did_work || start_timer); 579 ManageTimer(did_work || start_timer);
567 } 580 }
568 581
569 bool AndroidVideoDecodeAccelerator::QueueInput() { 582 bool AndroidVideoDecodeAccelerator::QueueInput() {
570 DCHECK(thread_checker_.CalledOnValidThread()); 583 DCHECK(thread_checker_.CalledOnValidThread());
571 TRACE_EVENT0("media", "AVDA::QueueInput"); 584 TRACE_EVENT0("media", "AVDA::QueueInput");
572 base::AutoReset<bool> auto_reset(&defer_errors_, true); 585 base::AutoReset<bool> auto_reset(&defer_errors_, true);
573 if (bitstreams_notified_in_advance_.size() > kMaxBitstreamsNotifiedInAdvance) 586 if (bitstreams_notified_in_advance_.size() > kMaxBitstreamsNotifiedInAdvance)
574 return false; 587 return false;
575 if (pending_bitstream_buffers_.empty()) 588 if (pending_bitstream_records_.empty())
576 return false; 589 return false;
577 if (state_ == WAITING_FOR_KEY) 590 if (state_ == WAITING_FOR_KEY)
578 return false; 591 return false;
579 592
580 int input_buf_index = pending_input_buf_index_; 593 int input_buf_index = pending_input_buf_index_;
581 594
582 // Do not dequeue a new input buffer if we failed with MEDIA_CODEC_NO_KEY. 595 // Do not dequeue a new input buffer if we failed with MEDIA_CODEC_NO_KEY.
583 // That status does not return this buffer back to the pool of 596 // That status does not return this buffer back to the pool of
584 // available input buffers. We have to reuse it in QueueSecureInputBuffer(). 597 // available input buffers. We have to reuse it in QueueSecureInputBuffer().
585 if (input_buf_index == -1) { 598 if (input_buf_index == -1) {
586 media::MediaCodecStatus status = 599 media::MediaCodecStatus status =
587 media_codec_->DequeueInputBuffer(NoWaitTimeOut(), &input_buf_index); 600 media_codec_->DequeueInputBuffer(NoWaitTimeOut(), &input_buf_index);
588 switch (status) { 601 switch (status) {
589 case media::MEDIA_CODEC_DEQUEUE_INPUT_AGAIN_LATER: 602 case media::MEDIA_CODEC_DEQUEUE_INPUT_AGAIN_LATER:
590 return false; 603 return false;
591 case media::MEDIA_CODEC_ERROR: 604 case media::MEDIA_CODEC_ERROR:
592 POST_ERROR(PLATFORM_FAILURE, "Failed to DequeueInputBuffer"); 605 POST_ERROR(PLATFORM_FAILURE, "Failed to DequeueInputBuffer");
593 return false; 606 return false;
594 case media::MEDIA_CODEC_OK: 607 case media::MEDIA_CODEC_OK:
595 break; 608 break;
596 default: 609 default:
597 NOTREACHED() << "Unknown DequeueInputBuffer status " << status; 610 NOTREACHED() << "Unknown DequeueInputBuffer status " << status;
598 return false; 611 return false;
599 } 612 }
600 } 613 }
601 614
602 DCHECK_NE(input_buf_index, -1); 615 DCHECK_NE(input_buf_index, -1);
603 616
604 media::BitstreamBuffer bitstream_buffer = pending_bitstream_buffers_.front(); 617 media::BitstreamBuffer bitstream_buffer =
618 pending_bitstream_records_.front().buffer;
605 619
606 if (bitstream_buffer.id() == -1) { 620 if (bitstream_buffer.id() == -1) {
607 pending_bitstream_buffers_.pop(); 621 pending_bitstream_records_.pop();
608 TRACE_COUNTER1("media", "AVDA::PendingBitstreamBufferCount", 622 TRACE_COUNTER1("media", "AVDA::PendingBitstreamBufferCount",
609 pending_bitstream_buffers_.size()); 623 pending_bitstream_records_.size());
610 624
611 media_codec_->QueueEOS(input_buf_index); 625 media_codec_->QueueEOS(input_buf_index);
612 return true; 626 return true;
613 } 627 }
614 628
615 std::unique_ptr<SharedMemoryRegion> shm; 629 std::unique_ptr<SharedMemoryRegion> shm;
616 630
617 if (pending_input_buf_index_ == -1) { 631 if (pending_input_buf_index_ == -1) {
618 // When |pending_input_buf_index_| is not -1, the buffer is already dequeued 632 // When |pending_input_buf_index_| is not -1, the buffer is already dequeued
619 // from MediaCodec, filled with data and bitstream_buffer.handle() is 633 // from MediaCodec, filled with data and bitstream_buffer.handle() is
620 // closed. 634 // closed.
621 shm.reset(new SharedMemoryRegion(bitstream_buffer, true)); 635 shm = std::move(pending_bitstream_records_.front().memory);
622 636
623 if (!shm->Map()) { 637 if (!shm->Map()) {
624 POST_ERROR(UNREADABLE_INPUT, "Failed to SharedMemoryRegion::Map()"); 638 POST_ERROR(UNREADABLE_INPUT, "Failed to SharedMemoryRegion::Map()");
625 return false; 639 return false;
626 } 640 }
627 } 641 }
628 642
629 const base::TimeDelta presentation_timestamp = 643 const base::TimeDelta presentation_timestamp =
630 bitstream_buffer.presentation_timestamp(); 644 bitstream_buffer.presentation_timestamp();
631 DCHECK(presentation_timestamp != media::kNoTimestamp()) 645 DCHECK(presentation_timestamp != media::kNoTimestamp())
(...skipping 34 matching lines...) Expand 10 before | Expand all | Expand 10 after
666 if (status == media::MEDIA_CODEC_NO_KEY) { 680 if (status == media::MEDIA_CODEC_NO_KEY) {
667 // Keep trying to enqueue the same input buffer. 681 // Keep trying to enqueue the same input buffer.
668 // The buffer is owned by us (not the MediaCodec) and is filled with data. 682 // The buffer is owned by us (not the MediaCodec) and is filled with data.
669 DVLOG(1) << "QueueSecureInputBuffer failed: NO_KEY"; 683 DVLOG(1) << "QueueSecureInputBuffer failed: NO_KEY";
670 pending_input_buf_index_ = input_buf_index; 684 pending_input_buf_index_ = input_buf_index;
671 state_ = WAITING_FOR_KEY; 685 state_ = WAITING_FOR_KEY;
672 return false; 686 return false;
673 } 687 }
674 688
675 pending_input_buf_index_ = -1; 689 pending_input_buf_index_ = -1;
676 pending_bitstream_buffers_.pop(); 690 pending_bitstream_records_.pop();
677 TRACE_COUNTER1("media", "AVDA::PendingBitstreamBufferCount", 691 TRACE_COUNTER1("media", "AVDA::PendingBitstreamBufferCount",
678 pending_bitstream_buffers_.size()); 692 pending_bitstream_records_.size());
679 // We should call NotifyEndOfBitstreamBuffer(), when no more decoded output 693 // We should call NotifyEndOfBitstreamBuffer(), when no more decoded output
680 // will be returned from the bitstream buffer. However, MediaCodec API is 694 // will be returned from the bitstream buffer. However, MediaCodec API is
681 // not enough to guarantee it. 695 // not enough to guarantee it.
682 // So, here, we calls NotifyEndOfBitstreamBuffer() in advance in order to 696 // So, here, we calls NotifyEndOfBitstreamBuffer() in advance in order to
683 // keep getting more bitstreams from the client, and throttle them by using 697 // keep getting more bitstreams from the client, and throttle them by using
684 // |bitstreams_notified_in_advance_|. 698 // |bitstreams_notified_in_advance_|.
685 // TODO(dwkang): check if there is a way to remove this workaround. 699 // TODO(dwkang): check if there is a way to remove this workaround.
686 base::MessageLoop::current()->PostTask( 700 base::MessageLoop::current()->PostTask(
687 FROM_HERE, 701 FROM_HERE,
688 base::Bind(&AndroidVideoDecodeAccelerator::NotifyEndOfBitstreamBuffer, 702 base::Bind(&AndroidVideoDecodeAccelerator::NotifyEndOfBitstreamBuffer,
(...skipping 225 matching lines...) Expand 10 before | Expand all | Expand 10 after
914 } else { 928 } else {
915 base::MessageLoop::current()->PostTask( 929 base::MessageLoop::current()->PostTask(
916 FROM_HERE, 930 FROM_HERE,
917 base::Bind(&AndroidVideoDecodeAccelerator::NotifyEndOfBitstreamBuffer, 931 base::Bind(&AndroidVideoDecodeAccelerator::NotifyEndOfBitstreamBuffer,
918 weak_this_factory_.GetWeakPtr(), bitstream_buffer.id())); 932 weak_this_factory_.GetWeakPtr(), bitstream_buffer.id()));
919 } 933 }
920 } 934 }
921 935
922 void AndroidVideoDecodeAccelerator::DecodeBuffer( 936 void AndroidVideoDecodeAccelerator::DecodeBuffer(
923 const media::BitstreamBuffer& bitstream_buffer) { 937 const media::BitstreamBuffer& bitstream_buffer) {
924 pending_bitstream_buffers_.push(bitstream_buffer); 938 pending_bitstream_records_.push(BitstreamRecord(bitstream_buffer));
925 TRACE_COUNTER1("media", "AVDA::PendingBitstreamBufferCount", 939 TRACE_COUNTER1("media", "AVDA::PendingBitstreamBufferCount",
926 pending_bitstream_buffers_.size()); 940 pending_bitstream_records_.size());
927 941
928 DoIOTask(true); 942 DoIOTask(true);
929 } 943 }
930 944
931 void AndroidVideoDecodeAccelerator::RequestPictureBuffers() { 945 void AndroidVideoDecodeAccelerator::RequestPictureBuffers() {
932 if (client_) { 946 if (client_) {
933 client_->ProvidePictureBuffers(kNumPictureBuffers, 1, 947 client_->ProvidePictureBuffers(kNumPictureBuffers, 1,
934 strategy_->GetPictureBufferSize(), 948 strategy_->GetPictureBufferSize(),
935 strategy_->GetTextureTarget()); 949 strategy_->GetTextureTarget());
936 } 950 }
(...skipping 226 matching lines...) Expand 10 before | Expand all | Expand 10 after
1163 if (!done_cb.is_null()) 1177 if (!done_cb.is_null())
1164 done_cb.Run(); 1178 done_cb.Run();
1165 return; 1179 return;
1166 } 1180 }
1167 1181
1168 bitstream_buffers_in_decoder_.clear(); 1182 bitstream_buffers_in_decoder_.clear();
1169 1183
1170 if (pending_input_buf_index_ != -1) { 1184 if (pending_input_buf_index_ != -1) {
1171 // The data for that index exists in the input buffer, but corresponding 1185 // The data for that index exists in the input buffer, but corresponding
1172 // shm block been deleted. Check that it is safe to flush the coec, i.e. 1186 // shm block been deleted. Check that it is safe to flush the coec, i.e.
1173 // |pending_bitstream_buffers_| is empty. 1187 // |pending_bitstream_records_| is empty.
1174 // TODO(timav): keep shm block for that buffer and remove this restriction. 1188 // TODO(timav): keep shm block for that buffer and remove this restriction.
1175 DCHECK(pending_bitstream_buffers_.empty()); 1189 DCHECK(pending_bitstream_records_.empty());
1176 pending_input_buf_index_ = -1; 1190 pending_input_buf_index_ = -1;
1177 } 1191 }
1178 1192
1179 const bool did_codec_error_happen = state_ == ERROR; 1193 const bool did_codec_error_happen = state_ == ERROR;
1180 state_ = NO_ERROR; 1194 state_ = NO_ERROR;
1181 1195
1182 // We might increment error_sequence_token here to cancel any delayed errors, 1196 // We might increment error_sequence_token here to cancel any delayed errors,
1183 // but right now it's unclear that it's safe to do so. If we are in an error 1197 // but right now it's unclear that it's safe to do so. If we are in an error
1184 // state because of a codec error, then it would be okay. Otherwise, it's 1198 // state because of a codec error, then it would be okay. Otherwise, it's
1185 // less obvious that we are exiting the error state. Since deferred errors 1199 // less obvious that we are exiting the error state. Since deferred errors
(...skipping 24 matching lines...) Expand all
1210 1224
1211 if (!done_cb.is_null()) 1225 if (!done_cb.is_null())
1212 done_cb.Run(); 1226 done_cb.Run();
1213 } 1227 }
1214 1228
1215 void AndroidVideoDecodeAccelerator::Reset() { 1229 void AndroidVideoDecodeAccelerator::Reset() {
1216 DVLOG(1) << __FUNCTION__; 1230 DVLOG(1) << __FUNCTION__;
1217 DCHECK(thread_checker_.CalledOnValidThread()); 1231 DCHECK(thread_checker_.CalledOnValidThread());
1218 TRACE_EVENT0("media", "AVDA::Reset"); 1232 TRACE_EVENT0("media", "AVDA::Reset");
1219 1233
1220 while (!pending_bitstream_buffers_.empty()) { 1234 while (!pending_bitstream_records_.empty()) {
1221 int32_t bitstream_buffer_id = pending_bitstream_buffers_.front().id(); 1235 int32_t bitstream_buffer_id =
1222 pending_bitstream_buffers_.pop(); 1236 pending_bitstream_records_.front().buffer.id();
1237 pending_bitstream_records_.pop();
1223 1238
1224 if (bitstream_buffer_id != -1) { 1239 if (bitstream_buffer_id != -1) {
1225 base::MessageLoop::current()->PostTask( 1240 base::MessageLoop::current()->PostTask(
1226 FROM_HERE, 1241 FROM_HERE,
1227 base::Bind(&AndroidVideoDecodeAccelerator::NotifyEndOfBitstreamBuffer, 1242 base::Bind(&AndroidVideoDecodeAccelerator::NotifyEndOfBitstreamBuffer,
1228 weak_this_factory_.GetWeakPtr(), bitstream_buffer_id)); 1243 weak_this_factory_.GetWeakPtr(), bitstream_buffer_id));
1229 } 1244 }
1230 } 1245 }
1231 TRACE_COUNTER1("media", "AVDA::PendingBitstreamBufferCount", 0); 1246 TRACE_COUNTER1("media", "AVDA::PendingBitstreamBufferCount", 0);
1232 bitstreams_notified_in_advance_.clear(); 1247 bitstreams_notified_in_advance_.clear();
(...skipping 31 matching lines...) Expand 10 before | Expand all | Expand 10 after
1264 if (on_frame_available_handler_) { 1279 if (on_frame_available_handler_) {
1265 on_frame_available_handler_->ClearOwner(); 1280 on_frame_available_handler_->ClearOwner();
1266 on_frame_available_handler_ = nullptr; 1281 on_frame_available_handler_ = nullptr;
1267 } 1282 }
1268 1283
1269 client_ = nullptr; 1284 client_ = nullptr;
1270 1285
1271 // Some VP8 files require complete MediaCodec drain before we can call 1286 // Some VP8 files require complete MediaCodec drain before we can call
1272 // MediaCodec.flush() or MediaCodec.reset(). http://crbug.com/598963. 1287 // MediaCodec.flush() or MediaCodec.reset(). http://crbug.com/598963.
1273 if (media_codec_ && codec_config_->codec_ == media::kCodecVP8) { 1288 if (media_codec_ && codec_config_->codec_ == media::kCodecVP8) {
1274 // Clear pending_bitstream_buffers_. 1289 // Clear pending_bitstream_records_.
1275 while (!pending_bitstream_buffers_.empty()) 1290 while (!pending_bitstream_records_.empty())
1276 pending_bitstream_buffers_.pop(); 1291 pending_bitstream_records_.pop();
1277 1292
1278 // Postpone ActualDestroy after the drain. 1293 // Postpone ActualDestroy after the drain.
1279 StartCodecDrain(DRAIN_FOR_DESTROY); 1294 StartCodecDrain(DRAIN_FOR_DESTROY);
1280 } else { 1295 } else {
1281 ActualDestroy(); 1296 ActualDestroy();
1282 } 1297 }
1283 } 1298 }
1284 1299
1285 void AndroidVideoDecodeAccelerator::ActualDestroy() { 1300 void AndroidVideoDecodeAccelerator::ActualDestroy() {
1286 DVLOG(1) << __FUNCTION__; 1301 DVLOG(1) << __FUNCTION__;
(...skipping 307 matching lines...) Expand 10 before | Expand all | Expand 10 after
1594 if (media::MediaCodecUtil::IsSurfaceViewOutputSupported()) { 1609 if (media::MediaCodecUtil::IsSurfaceViewOutputSupported()) {
1595 capabilities.flags |= media::VideoDecodeAccelerator::Capabilities:: 1610 capabilities.flags |= media::VideoDecodeAccelerator::Capabilities::
1596 SUPPORTS_EXTERNAL_OUTPUT_SURFACE; 1611 SUPPORTS_EXTERNAL_OUTPUT_SURFACE;
1597 } 1612 }
1598 } 1613 }
1599 1614
1600 return capabilities; 1615 return capabilities;
1601 } 1616 }
1602 1617
1603 } // namespace media 1618 } // namespace media
OLDNEW
« no previous file with comments | « media/gpu/android_video_decode_accelerator.h ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698