OLD | NEW |
---|---|
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 213 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
224 | 224 |
225 AndroidVideoDecodeAccelerator::AndroidVideoDecodeAccelerator( | 225 AndroidVideoDecodeAccelerator::AndroidVideoDecodeAccelerator( |
226 const MakeGLContextCurrentCallback& make_context_current_cb, | 226 const MakeGLContextCurrentCallback& make_context_current_cb, |
227 const GetGLES2DecoderCallback& get_gles2_decoder_cb) | 227 const GetGLES2DecoderCallback& get_gles2_decoder_cb) |
228 : client_(NULL), | 228 : client_(NULL), |
229 make_context_current_cb_(make_context_current_cb), | 229 make_context_current_cb_(make_context_current_cb), |
230 get_gles2_decoder_cb_(get_gles2_decoder_cb), | 230 get_gles2_decoder_cb_(get_gles2_decoder_cb), |
231 state_(NO_ERROR), | 231 state_(NO_ERROR), |
232 picturebuffers_requested_(false), | 232 picturebuffers_requested_(false), |
233 picture_buffer_manager_(this), | 233 picture_buffer_manager_(this), |
234 drain_type_(DRAIN_TYPE_NONE), | |
235 media_drm_bridge_cdm_context_(nullptr), | 234 media_drm_bridge_cdm_context_(nullptr), |
236 cdm_registration_id_(0), | 235 cdm_registration_id_(0), |
237 pending_input_buf_index_(-1), | 236 pending_input_buf_index_(-1), |
238 deferred_initialization_pending_(false), | 237 deferred_initialization_pending_(false), |
239 codec_needs_reset_(false), | 238 codec_needs_reset_(false), |
240 defer_surface_creation_(false), | 239 defer_surface_creation_(false), |
241 weak_this_factory_(this) {} | 240 weak_this_factory_(this) {} |
242 | 241 |
243 AndroidVideoDecodeAccelerator::~AndroidVideoDecodeAccelerator() { | 242 AndroidVideoDecodeAccelerator::~AndroidVideoDecodeAccelerator() { |
244 DCHECK(thread_checker_.CalledOnValidThread()); | 243 DCHECK(thread_checker_.CalledOnValidThread()); |
(...skipping 341 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
586 MediaCodecStatus status = media_codec_->DequeueOutputBuffer( | 585 MediaCodecStatus status = media_codec_->DequeueOutputBuffer( |
587 NoWaitTimeOut, &buf_index, &offset, &size, &presentation_timestamp, | 586 NoWaitTimeOut, &buf_index, &offset, &size, &presentation_timestamp, |
588 &eos, NULL); | 587 &eos, NULL); |
589 TRACE_EVENT_END2("media", "AVDA::DequeueOutput", "status", status, | 588 TRACE_EVENT_END2("media", "AVDA::DequeueOutput", "status", status, |
590 "presentation_timestamp (ms)", | 589 "presentation_timestamp (ms)", |
591 presentation_timestamp.InMilliseconds()); | 590 presentation_timestamp.InMilliseconds()); |
592 | 591 |
593 switch (status) { | 592 switch (status) { |
594 case MEDIA_CODEC_ERROR: | 593 case MEDIA_CODEC_ERROR: |
595 // Do not post an error if we are draining for reset and destroy. | 594 // Do not post an error if we are draining for reset and destroy. |
596 // Instead, run the drain completion task. | 595 // Instead, signal completion of the drain. |
597 if (IsDrainingForResetOrDestroy()) { | 596 if (IsDrainingForResetOrDestroy()) { |
598 DVLOG(1) << __func__ << ": error while codec draining"; | 597 DVLOG(1) << __func__ << ": error while draining"; |
599 state_ = ERROR; | 598 state_ = ERROR; |
600 OnDrainCompleted(); | 599 OnDrainCompleted(); |
601 } else { | 600 } else { |
602 NOTIFY_ERROR(PLATFORM_FAILURE, "DequeueOutputBuffer failed."); | 601 NOTIFY_ERROR(PLATFORM_FAILURE, "DequeueOutputBuffer failed."); |
603 } | 602 } |
604 return false; | 603 return false; |
605 | 604 |
606 case MEDIA_CODEC_DEQUEUE_OUTPUT_AGAIN_LATER: | 605 case MEDIA_CODEC_DEQUEUE_OUTPUT_AGAIN_LATER: |
607 return false; | 606 return false; |
608 | 607 |
(...skipping 155 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
764 | 763 |
765 if (defer_surface_creation_ && !InitializePictureBufferManager()) { | 764 if (defer_surface_creation_ && !InitializePictureBufferManager()) { |
766 NOTIFY_ERROR(PLATFORM_FAILURE, | 765 NOTIFY_ERROR(PLATFORM_FAILURE, |
767 "Failed deferred surface and MediaCodec initialization."); | 766 "Failed deferred surface and MediaCodec initialization."); |
768 return; | 767 return; |
769 } | 768 } |
770 | 769 |
771 // If we previously deferred a codec restart, take care of it now. This can | 770 // If we previously deferred a codec restart, take care of it now. This can |
772 // happen on older devices where configuration changes require a codec reset. | 771 // happen on older devices where configuration changes require a codec reset. |
773 if (codec_needs_reset_) { | 772 if (codec_needs_reset_) { |
774 DCHECK_EQ(drain_type_, DRAIN_TYPE_NONE); | 773 DCHECK(!drain_type_); |
775 ResetCodecState(); | 774 ResetCodecState(); |
776 } | 775 } |
777 | 776 |
778 if (bitstream_buffer.id() >= 0 && bitstream_buffer.size() > 0) { | 777 if (bitstream_buffer.id() >= 0 && bitstream_buffer.size() > 0) { |
779 DecodeBuffer(bitstream_buffer); | 778 DecodeBuffer(bitstream_buffer); |
780 return; | 779 return; |
781 } | 780 } |
782 | 781 |
783 if (base::SharedMemory::IsHandleValid(bitstream_buffer.handle())) | 782 if (base::SharedMemory::IsHandleValid(bitstream_buffer.handle())) |
784 base::SharedMemory::CloseHandle(bitstream_buffer.handle()); | 783 base::SharedMemory::CloseHandle(bitstream_buffer.handle()); |
(...skipping 72 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
857 return; | 856 return; |
858 } | 857 } |
859 | 858 |
860 picture_buffer_manager_.ReuseOnePictureBuffer(it->second); | 859 picture_buffer_manager_.ReuseOnePictureBuffer(it->second); |
861 DoIOTask(true); | 860 DoIOTask(true); |
862 } | 861 } |
863 | 862 |
864 void AndroidVideoDecodeAccelerator::Flush() { | 863 void AndroidVideoDecodeAccelerator::Flush() { |
865 DVLOG(1) << __func__; | 864 DVLOG(1) << __func__; |
866 DCHECK(thread_checker_.CalledOnValidThread()); | 865 DCHECK(thread_checker_.CalledOnValidThread()); |
867 | 866 StartCodecDrain(DRAIN_FOR_FLUSH); |
868 if (state_ == SURFACE_DESTROYED || defer_surface_creation_) | |
watk
2016/12/07 23:30:32
These both imply media_codec == nullptr so I used
| |
869 NotifyFlushDone(); | |
870 else | |
871 StartCodecDrain(DRAIN_FOR_FLUSH); | |
872 } | 867 } |
873 | 868 |
874 void AndroidVideoDecodeAccelerator::ConfigureMediaCodecAsynchronously() { | 869 void AndroidVideoDecodeAccelerator::ConfigureMediaCodecAsynchronously() { |
875 DCHECK(thread_checker_.CalledOnValidThread()); | 870 DCHECK(thread_checker_.CalledOnValidThread()); |
876 | 871 |
877 DCHECK_NE(state_, WAITING_FOR_CODEC); | 872 DCHECK_NE(state_, WAITING_FOR_CODEC); |
878 state_ = WAITING_FOR_CODEC; | 873 state_ = WAITING_FOR_CODEC; |
879 | 874 |
880 if (media_codec_) { | 875 if (media_codec_) { |
881 AVDACodecAllocator::Instance()->ReleaseMediaCodec( | 876 AVDACodecAllocator::Instance()->ReleaseMediaCodec( |
(...skipping 73 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
955 | 950 |
956 state_ = NO_ERROR; | 951 state_ = NO_ERROR; |
957 | 952 |
958 ManageTimer(true); | 953 ManageTimer(true); |
959 } | 954 } |
960 | 955 |
961 void AndroidVideoDecodeAccelerator::StartCodecDrain(DrainType drain_type) { | 956 void AndroidVideoDecodeAccelerator::StartCodecDrain(DrainType drain_type) { |
962 DVLOG(2) << __func__ << " drain_type:" << drain_type; | 957 DVLOG(2) << __func__ << " drain_type:" << drain_type; |
963 DCHECK(thread_checker_.CalledOnValidThread()); | 958 DCHECK(thread_checker_.CalledOnValidThread()); |
964 | 959 |
965 // We assume that DRAIN_FOR_FLUSH and DRAIN_FOR_RESET cannot come while | 960 auto previous_drain_type = drain_type_; |
966 // another drain request is present, but DRAIN_FOR_DESTROY can. | |
967 DCHECK_NE(drain_type, DRAIN_TYPE_NONE); | |
968 DCHECK(drain_type_ == DRAIN_TYPE_NONE || drain_type == DRAIN_FOR_DESTROY) | |
969 << "Unexpected StartCodecDrain() with drain type " << drain_type | |
970 << " while already draining with drain type " << drain_type_; | |
971 | |
972 const bool enqueue_eos = drain_type_ == DRAIN_TYPE_NONE; | |
973 drain_type_ = drain_type; | 961 drain_type_ = drain_type; |
974 | 962 |
975 if (enqueue_eos) | 963 // Only DRAIN_FOR_DESTROY is allowed while a drain is already in progress. |
964 DCHECK(!previous_drain_type || drain_type == DRAIN_FOR_DESTROY) | |
965 << "StartCodecDrain(" << drain_type | |
966 << ") while already draining with type " << previous_drain_type.value(); | |
967 | |
968 // Skip the drain if possible. We still need to drain VP8 for destroy and | |
969 // reset because MediaCodec might hang in release() or flush() if we don't. | |
DaleCurtis
2016/12/08 00:11:13
Comment is a bit misleading, code skips drain if t
| |
970 // http://crbug.com/598963 | |
971 if (!media_codec_ || (pending_bitstream_records_.empty() && | |
DaleCurtis
2016/12/08 00:11:14
Maybe clarify that in the case of Reset() pending
| |
972 bitstream_buffers_in_decoder_.empty()) || | |
973 (drain_type != DRAIN_FOR_FLUSH && codec_config_->codec != kCodecVP8)) { | |
974 OnDrainCompleted(); | |
975 return; | |
976 } | |
977 | |
978 // Queue EOS if one is not already queued. | |
979 if (!previous_drain_type) | |
976 DecodeBuffer(BitstreamBuffer(-1, base::SharedMemoryHandle(), 0)); | 980 DecodeBuffer(BitstreamBuffer(-1, base::SharedMemoryHandle(), 0)); |
977 } | 981 } |
978 | 982 |
979 bool AndroidVideoDecodeAccelerator::IsDrainingForResetOrDestroy() const { | 983 bool AndroidVideoDecodeAccelerator::IsDrainingForResetOrDestroy() const { |
980 return drain_type_ == DRAIN_FOR_RESET || drain_type_ == DRAIN_FOR_DESTROY; | 984 return drain_type_ == DRAIN_FOR_RESET || drain_type_ == DRAIN_FOR_DESTROY; |
981 } | 985 } |
982 | 986 |
983 void AndroidVideoDecodeAccelerator::OnDrainCompleted() { | 987 void AndroidVideoDecodeAccelerator::OnDrainCompleted() { |
984 DVLOG(2) << __func__; | 988 DVLOG(2) << __func__; |
985 DCHECK(thread_checker_.CalledOnValidThread()); | 989 DCHECK(thread_checker_.CalledOnValidThread()); |
986 | 990 |
987 // If we were waiting for an EOS, clear the state and reset the MediaCodec | 991 // Sometimes MediaCodec returns an EOS buffer even if we didn't queue one. |
988 // as normal. | 992 // Consider it an error. http://crbug.com/585959. |
989 // | 993 if (!drain_type_) { |
990 // Some Android platforms seem to send an EOS buffer even when we're not | 994 state_ = ERROR; |
991 // expecting it. In this case, destroy and reset the codec but don't notify | 995 ResetCodecState(); |
992 // flush done since it violates the state machine. http://crbug.com/585959. | 996 return; |
997 } | |
993 | 998 |
994 switch (drain_type_) { | 999 ResetCodecState(); |
995 case DRAIN_TYPE_NONE: | 1000 switch (*drain_type_) { |
996 // Unexpected EOS. | |
997 state_ = ERROR; | |
998 ResetCodecState(); | |
999 break; | |
1000 case DRAIN_FOR_FLUSH: | 1001 case DRAIN_FOR_FLUSH: |
1001 ResetCodecState(); | |
1002 base::ThreadTaskRunnerHandle::Get()->PostTask( | 1002 base::ThreadTaskRunnerHandle::Get()->PostTask( |
1003 FROM_HERE, base::Bind(&AndroidVideoDecodeAccelerator::NotifyFlushDone, | 1003 FROM_HERE, base::Bind(&AndroidVideoDecodeAccelerator::NotifyFlushDone, |
1004 weak_this_factory_.GetWeakPtr())); | 1004 weak_this_factory_.GetWeakPtr())); |
1005 break; | 1005 break; |
1006 case DRAIN_FOR_RESET: | 1006 case DRAIN_FOR_RESET: |
1007 ResetCodecState(); | |
1008 base::ThreadTaskRunnerHandle::Get()->PostTask( | 1007 base::ThreadTaskRunnerHandle::Get()->PostTask( |
1009 FROM_HERE, base::Bind(&AndroidVideoDecodeAccelerator::NotifyResetDone, | 1008 FROM_HERE, base::Bind(&AndroidVideoDecodeAccelerator::NotifyResetDone, |
1010 weak_this_factory_.GetWeakPtr())); | 1009 weak_this_factory_.GetWeakPtr())); |
1011 break; | 1010 break; |
1012 case DRAIN_FOR_DESTROY: | 1011 case DRAIN_FOR_DESTROY: |
1013 ResetCodecState(); | |
1014 base::ThreadTaskRunnerHandle::Get()->PostTask( | 1012 base::ThreadTaskRunnerHandle::Get()->PostTask( |
1015 FROM_HERE, base::Bind(&AndroidVideoDecodeAccelerator::ActualDestroy, | 1013 FROM_HERE, base::Bind(&AndroidVideoDecodeAccelerator::ActualDestroy, |
1016 weak_this_factory_.GetWeakPtr())); | 1014 weak_this_factory_.GetWeakPtr())); |
1017 break; | 1015 break; |
1018 } | 1016 } |
1019 drain_type_ = DRAIN_TYPE_NONE; | 1017 drain_type_.reset(); |
1020 } | 1018 } |
1021 | 1019 |
1022 void AndroidVideoDecodeAccelerator::ResetCodecState() { | 1020 void AndroidVideoDecodeAccelerator::ResetCodecState() { |
1023 DCHECK(thread_checker_.CalledOnValidThread()); | 1021 DCHECK(thread_checker_.CalledOnValidThread()); |
1024 | 1022 |
1025 // If there is already a reset in flight, then that counts. This can really | 1023 // If there is already a reset in flight, then that counts. This can really |
1026 // only happen if somebody calls Reset. | 1024 // only happen if somebody calls Reset. |
1027 // If the surface is destroyed there's nothing to do. | 1025 // If the surface is destroyed there's nothing to do. |
1028 if (state_ == WAITING_FOR_CODEC || state_ == SURFACE_DESTROYED) | 1026 if (state_ == WAITING_FOR_CODEC || state_ == SURFACE_DESTROYED) |
1029 return; | 1027 return; |
(...skipping 60 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
1090 base::ThreadTaskRunnerHandle::Get()->PostTask( | 1088 base::ThreadTaskRunnerHandle::Get()->PostTask( |
1091 FROM_HERE, | 1089 FROM_HERE, |
1092 base::Bind(&AndroidVideoDecodeAccelerator::NotifyEndOfBitstreamBuffer, | 1090 base::Bind(&AndroidVideoDecodeAccelerator::NotifyEndOfBitstreamBuffer, |
1093 weak_this_factory_.GetWeakPtr(), bitstream_buffer_id)); | 1091 weak_this_factory_.GetWeakPtr(), bitstream_buffer_id)); |
1094 } | 1092 } |
1095 } | 1093 } |
1096 TRACE_COUNTER1("media", "AVDA::PendingBitstreamBufferCount", 0); | 1094 TRACE_COUNTER1("media", "AVDA::PendingBitstreamBufferCount", 0); |
1097 bitstreams_notified_in_advance_.clear(); | 1095 bitstreams_notified_in_advance_.clear(); |
1098 | 1096 |
1099 picture_buffer_manager_.ReleaseCodecBuffers(output_picture_buffers_); | 1097 picture_buffer_manager_.ReleaseCodecBuffers(output_picture_buffers_); |
1100 | 1098 StartCodecDrain(DRAIN_FOR_RESET); |
1101 // Some VP8 files require complete MediaCodec drain before we can call | |
1102 // MediaCodec.flush() or MediaCodec.reset(). http://crbug.com/598963. | |
1103 if (media_codec_ && codec_config_->codec == kCodecVP8 && | |
1104 !bitstream_buffers_in_decoder_.empty()) { | |
1105 // Postpone ResetCodecState() after the drain. | |
1106 StartCodecDrain(DRAIN_FOR_RESET); | |
1107 } else { | |
1108 ResetCodecState(); | |
1109 base::ThreadTaskRunnerHandle::Get()->PostTask( | |
1110 FROM_HERE, base::Bind(&AndroidVideoDecodeAccelerator::NotifyResetDone, | |
1111 weak_this_factory_.GetWeakPtr())); | |
1112 } | |
1113 } | 1099 } |
1114 | 1100 |
1115 void AndroidVideoDecodeAccelerator::SetSurface(int32_t surface_id) { | 1101 void AndroidVideoDecodeAccelerator::SetSurface(int32_t surface_id) { |
1116 DVLOG(1) << __func__; | 1102 DVLOG(1) << __func__; |
1117 DCHECK(thread_checker_.CalledOnValidThread()); | 1103 DCHECK(thread_checker_.CalledOnValidThread()); |
1118 | 1104 |
1119 if (surface_id == config_.surface_id) { | 1105 if (surface_id == config_.surface_id) { |
1120 pending_surface_id_.reset(); | 1106 pending_surface_id_.reset(); |
1121 return; | 1107 return; |
1122 } | 1108 } |
1123 | 1109 |
1124 // Surface changes never take effect immediately, they will be handled during | 1110 // Surface changes never take effect immediately, they will be handled during |
1125 // DequeOutput() once we get to a good switch point or immediately during an | 1111 // DequeOutput() once we get to a good switch point or immediately during an |
1126 // OnSurfaceDestroyed() call. | 1112 // OnSurfaceDestroyed() call. |
1127 pending_surface_id_ = surface_id; | 1113 pending_surface_id_ = surface_id; |
1128 } | 1114 } |
1129 | 1115 |
1130 void AndroidVideoDecodeAccelerator::Destroy() { | 1116 void AndroidVideoDecodeAccelerator::Destroy() { |
1131 DVLOG(1) << __func__; | 1117 DVLOG(1) << __func__; |
1132 DCHECK(thread_checker_.CalledOnValidThread()); | 1118 DCHECK(thread_checker_.CalledOnValidThread()); |
1133 | 1119 |
1134 picture_buffer_manager_.Destroy(output_picture_buffers_); | 1120 picture_buffer_manager_.Destroy(output_picture_buffers_); |
1135 | 1121 |
1136 client_ = nullptr; | 1122 client_ = nullptr; |
1137 | 1123 |
1138 // Some VP8 files require a complete MediaCodec drain before we can call | 1124 // We don't want to queue more inputs while draining. |
1139 // MediaCodec.flush() or MediaCodec.release(). http://crbug.com/598963. In | 1125 while (!pending_bitstream_records_.empty()) |
DaleCurtis
2016/12/08 00:29:35
Because I was curious and have been benchmarking t
| |
1140 // that case, postpone ActualDestroy() until after the drain. | 1126 pending_bitstream_records_.pop(); |
1141 if (media_codec_ && codec_config_->codec == kCodecVP8) { | 1127 StartCodecDrain(DRAIN_FOR_DESTROY); |
1142 // Clear |pending_bitstream_records_|. | |
1143 while (!pending_bitstream_records_.empty()) | |
1144 pending_bitstream_records_.pop(); | |
1145 | |
1146 StartCodecDrain(DRAIN_FOR_DESTROY); | |
1147 } else { | |
1148 ActualDestroy(); | |
1149 } | |
1150 } | 1128 } |
1151 | 1129 |
1152 void AndroidVideoDecodeAccelerator::ActualDestroy() { | 1130 void AndroidVideoDecodeAccelerator::ActualDestroy() { |
1153 DVLOG(1) << __func__; | 1131 DVLOG(1) << __func__; |
1154 DCHECK(thread_checker_.CalledOnValidThread()); | 1132 DCHECK(thread_checker_.CalledOnValidThread()); |
1155 | 1133 |
1156 // Note that async codec construction might still be in progress. In that | 1134 // Note that async codec construction might still be in progress. In that |
1157 // case, the codec will be deleted when it completes once we invalidate all | 1135 // case, the codec will be deleted when it completes once we invalidate all |
1158 // our weak refs. | 1136 // our weak refs. |
1159 weak_this_factory_.InvalidateWeakPtrs(); | 1137 weak_this_factory_.InvalidateWeakPtrs(); |
(...skipping 55 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
1215 // SURFACE_DESTROYED. | 1193 // SURFACE_DESTROYED. |
1216 state_ = SURFACE_DESTROYED; | 1194 state_ = SURFACE_DESTROYED; |
1217 if (media_codec_) { | 1195 if (media_codec_) { |
1218 AVDACodecAllocator::Instance()->ReleaseMediaCodec( | 1196 AVDACodecAllocator::Instance()->ReleaseMediaCodec( |
1219 std::move(media_codec_), codec_config_->task_type, config_.surface_id); | 1197 std::move(media_codec_), codec_config_->task_type, config_.surface_id); |
1220 picture_buffer_manager_.CodecChanged(nullptr); | 1198 picture_buffer_manager_.CodecChanged(nullptr); |
1221 } | 1199 } |
1222 | 1200 |
1223 // If we're draining, signal completion now because the drain can no longer | 1201 // If we're draining, signal completion now because the drain can no longer |
1224 // proceed. | 1202 // proceed. |
1225 if (drain_type_ != DRAIN_TYPE_NONE) | 1203 if (drain_type_) |
1226 OnDrainCompleted(); | 1204 OnDrainCompleted(); |
1227 } | 1205 } |
1228 | 1206 |
1229 void AndroidVideoDecodeAccelerator::InitializeCdm() { | 1207 void AndroidVideoDecodeAccelerator::InitializeCdm() { |
1230 DVLOG(2) << __func__ << ": " << config_.cdm_id; | 1208 DVLOG(2) << __func__ << ": " << config_.cdm_id; |
1231 | 1209 |
1232 #if !defined(ENABLE_MOJO_MEDIA_IN_GPU_PROCESS) | 1210 #if !defined(ENABLE_MOJO_MEDIA_IN_GPU_PROCESS) |
1233 NOTIMPLEMENTED(); | 1211 NOTIMPLEMENTED(); |
1234 NotifyInitializationComplete(false); | 1212 NotifyInitializationComplete(false); |
1235 #else | 1213 #else |
(...skipping 274 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
1510 AVDACodecAllocator::Instance()->DeallocateSurface(this, new_surface_id); | 1488 AVDACodecAllocator::Instance()->DeallocateSurface(this, new_surface_id); |
1511 } | 1489 } |
1512 | 1490 |
1513 // Regardless of whether we succeeded, we no longer own the previous surface. | 1491 // Regardless of whether we succeeded, we no longer own the previous surface. |
1514 AVDACodecAllocator::Instance()->DeallocateSurface(this, previous_surface_id); | 1492 AVDACodecAllocator::Instance()->DeallocateSurface(this, previous_surface_id); |
1515 | 1493 |
1516 return success; | 1494 return success; |
1517 } | 1495 } |
1518 | 1496 |
1519 } // namespace media | 1497 } // namespace media |
OLD | NEW |