OLD | NEW |
---|---|
1 // Copyright 2015 The Chromium Authors. All rights reserved. | 1 // Copyright 2015 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/base/android/media_codec_video_decoder.h" | 5 #include "media/base/android/media_codec_video_decoder.h" |
6 | 6 |
7 #include "base/bind.h" | 7 #include "base/bind.h" |
8 #include "base/logging.h" | 8 #include "base/logging.h" |
9 #include "media/base/android/media_codec_bridge.h" | 9 #include "media/base/android/media_codec_bridge.h" |
10 #include "media/base/buffers.h" | 10 #include "media/base/buffers.h" |
(...skipping 57 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
68 void MediaCodecVideoDecoder::ReleaseDecoderResources() { | 68 void MediaCodecVideoDecoder::ReleaseDecoderResources() { |
69 DCHECK(media_task_runner_->BelongsToCurrentThread()); | 69 DCHECK(media_task_runner_->BelongsToCurrentThread()); |
70 | 70 |
71 DVLOG(1) << class_name() << "::" << __FUNCTION__; | 71 DVLOG(1) << class_name() << "::" << __FUNCTION__; |
72 | 72 |
73 MediaCodecDecoder::ReleaseDecoderResources(); | 73 MediaCodecDecoder::ReleaseDecoderResources(); |
74 surface_ = gfx::ScopedJavaSurface(); | 74 surface_ = gfx::ScopedJavaSurface(); |
75 delayed_buffers_.clear(); | 75 delayed_buffers_.clear(); |
76 } | 76 } |
77 | 77 |
78 void MediaCodecVideoDecoder::SetPendingSurface(gfx::ScopedJavaSurface surface) { | 78 void MediaCodecVideoDecoder::SetVideoSurface(gfx::ScopedJavaSurface surface) { |
79 DCHECK(media_task_runner_->BelongsToCurrentThread()); | 79 DCHECK(media_task_runner_->BelongsToCurrentThread()); |
80 | 80 |
81 DVLOG(1) << class_name() << "::" << __FUNCTION__ | |
82 << (surface.IsEmpty() ? " empty" : " non-empty"); | |
83 | |
81 surface_ = surface.Pass(); | 84 surface_ = surface.Pass(); |
82 | 85 |
83 if (surface_.IsEmpty()) { | 86 needs_reconfigure_ = true; |
84 // Synchronously stop decoder thread and release MediaCodec | |
85 ReleaseDecoderResources(); | |
86 } | |
87 } | 87 } |
88 | 88 |
89 bool MediaCodecVideoDecoder::HasPendingSurface() const { | 89 bool MediaCodecVideoDecoder::HasVideoSurface() const { |
90 DCHECK(media_task_runner_->BelongsToCurrentThread()); | 90 DCHECK(media_task_runner_->BelongsToCurrentThread()); |
91 | 91 |
92 return !surface_.IsEmpty(); | 92 return !surface_.IsEmpty(); |
93 } | 93 } |
94 | 94 |
95 bool MediaCodecVideoDecoder::IsCodecReconfigureNeeded( | 95 bool MediaCodecVideoDecoder::IsCodecReconfigureNeeded( |
96 const DemuxerConfigs& curr, | 96 const DemuxerConfigs& curr, |
97 const DemuxerConfigs& next) const { | 97 const DemuxerConfigs& next) const { |
98 if (curr.video_codec != next.video_codec || | 98 if (curr.video_codec != next.video_codec || |
99 curr.is_video_encrypted != next.is_video_encrypted) { | 99 curr.is_video_encrypted != next.is_video_encrypted) { |
(...skipping 13 matching lines...) Expand all Loading... | |
113 } | 113 } |
114 | 114 |
115 MediaCodecDecoder::ConfigStatus MediaCodecVideoDecoder::ConfigureInternal() { | 115 MediaCodecDecoder::ConfigStatus MediaCodecVideoDecoder::ConfigureInternal() { |
116 DCHECK(media_task_runner_->BelongsToCurrentThread()); | 116 DCHECK(media_task_runner_->BelongsToCurrentThread()); |
117 | 117 |
118 DVLOG(1) << class_name() << "::" << __FUNCTION__; | 118 DVLOG(1) << class_name() << "::" << __FUNCTION__; |
119 | 119 |
120 // If we cannot find a key frame in cache, the browser seek is needed. | 120 // If we cannot find a key frame in cache, the browser seek is needed. |
121 if (!au_queue_.RewindToLastKeyFrame()) { | 121 if (!au_queue_.RewindToLastKeyFrame()) { |
122 DVLOG(1) << class_name() << "::" << __FUNCTION__ << " key frame required"; | 122 DVLOG(1) << class_name() << "::" << __FUNCTION__ << " key frame required"; |
123 return CONFIG_KEY_FRAME_REQUIRED; | |
124 } | |
123 | 125 |
124 // The processing of CONFIG_KEY_FRAME_REQUIRED is not implemented yet, | 126 if (configs_.video_codec == kUnknownVideoCodec) { |
125 // return error for now. | 127 DVLOG(0) << class_name() << "::" << __FUNCTION__ |
126 // TODO(timav): Replace this with the following line together with | 128 << " configuration parameters are required"; |
127 // implementing the browser seek: | |
128 // return CONFIG_KEY_FRAME_REQUIRED; | |
129 return CONFIG_FAILURE; | 129 return CONFIG_FAILURE; |
130 } | 130 } |
131 | 131 |
132 // TODO(timav): implement DRM. | 132 // TODO(timav): implement DRM. |
133 // bool is_secure = is_content_encrypted() && drm_bridge() && | 133 // bool is_secure = is_content_encrypted() && drm_bridge() && |
134 // drm_bridge()->IsProtectedSurfaceRequired(); | 134 // drm_bridge()->IsProtectedSurfaceRequired(); |
135 | 135 |
136 bool is_secure = false; // DRM is not implemented | 136 bool is_secure = false; // DRM is not implemented |
137 | 137 |
138 if (surface_.IsEmpty()) { | 138 if (surface_.IsEmpty()) { |
(...skipping 98 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
237 } | 237 } |
238 | 238 |
239 void MediaCodecVideoDecoder::ReleaseDelayedBuffers() { | 239 void MediaCodecVideoDecoder::ReleaseDelayedBuffers() { |
240 // Media thread | 240 // Media thread |
241 // Called when there is no decoder thread | 241 // Called when there is no decoder thread |
242 for (int index : delayed_buffers_) | 242 for (int index : delayed_buffers_) |
243 media_codec_bridge_->ReleaseOutputBuffer(index, false); | 243 media_codec_bridge_->ReleaseOutputBuffer(index, false); |
244 delayed_buffers_.clear(); | 244 delayed_buffers_.clear(); |
245 } | 245 } |
246 | 246 |
247 void MediaCodecVideoDecoder::ClearDelayedBuffers() { | |
qinmin
2015/07/22 17:30:33
I think you can merge this function with ReleaseDe
Tima Vaisburd
2015/07/23 00:37:49
Done.
| |
248 // Media thread | |
249 delayed_buffers_.clear(); | |
250 } | |
251 | |
247 #ifndef NDEBUG | 252 #ifndef NDEBUG |
248 void MediaCodecVideoDecoder::VerifyUnitIsKeyFrame( | 253 void MediaCodecVideoDecoder::VerifyUnitIsKeyFrame( |
249 const AccessUnit* unit) const { | 254 const AccessUnit* unit) const { |
250 // The first video frame in a sequence must be a key frame or stand-alone EOS. | 255 // The first video frame in a sequence must be a key frame or stand-alone EOS. |
251 DCHECK(unit); | 256 DCHECK(unit); |
252 bool stand_alone_eos = unit->is_end_of_stream && unit->data.empty(); | 257 bool stand_alone_eos = unit->is_end_of_stream && unit->data.empty(); |
253 DCHECK(stand_alone_eos || unit->is_key_frame); | 258 DCHECK(stand_alone_eos || unit->is_key_frame); |
254 } | 259 } |
255 #endif | 260 #endif |
256 | 261 |
(...skipping 14 matching lines...) Expand all Loading... | |
271 | 276 |
272 // |update_current_time_cb_| might be null if there is audio stream. | 277 // |update_current_time_cb_| might be null if there is audio stream. |
273 // Do not update current time for stand-alone EOS frames. | 278 // Do not update current time for stand-alone EOS frames. |
274 if (!update_current_time_cb_.is_null() && !(eos_encountered && !size)) { | 279 if (!update_current_time_cb_.is_null() && !(eos_encountered && !size)) { |
275 media_task_runner_->PostTask(FROM_HERE, | 280 media_task_runner_->PostTask(FROM_HERE, |
276 base::Bind(update_current_time_cb_, pts, pts)); | 281 base::Bind(update_current_time_cb_, pts, pts)); |
277 } | 282 } |
278 } | 283 } |
279 | 284 |
280 } // namespace media | 285 } // namespace media |
OLD | NEW |