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

Side by Side Diff: media/base/android/media_codec_video_decoder.cc

Issue 1242913004: MediaCodecPlayer implementation (stage 3 - browser seek and surface change) (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@mtplayer-seek
Patch Set: Rebased, changed DCHECKs. Created 5 years, 4 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/base/android/media_codec_video_decoder.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 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
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
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 kConfigKeyFrameRequired;
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: 129 return kConfigFailure;
128 // return CONFIG_KEY_FRAME_REQUIRED;
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()) {
139 DVLOG(0) << class_name() << "::" << __FUNCTION__ << " surface required"; 139 DVLOG(0) << class_name() << "::" << __FUNCTION__ << " surface required";
140 return CONFIG_FAILURE; 140 return kConfigFailure;
141 } 141 }
142 142
143 media_codec_bridge_.reset(VideoCodecBridge::CreateDecoder( 143 media_codec_bridge_.reset(VideoCodecBridge::CreateDecoder(
144 configs_.video_codec, 144 configs_.video_codec,
145 is_secure, 145 is_secure,
146 configs_.video_size, 146 configs_.video_size,
147 surface_.j_surface().obj(), 147 surface_.j_surface().obj(),
148 GetMediaCrypto().obj())); 148 GetMediaCrypto().obj()));
149 149
150 if (!media_codec_bridge_) { 150 if (!media_codec_bridge_) {
151 DVLOG(1) << class_name() << "::" << __FUNCTION__ << " failed"; 151 DVLOG(1) << class_name() << "::" << __FUNCTION__ << " failed";
152 return CONFIG_FAILURE; 152 return kConfigFailure;
153 } 153 }
154 154
155 DVLOG(1) << class_name() << "::" << __FUNCTION__ << " succeeded"; 155 DVLOG(1) << class_name() << "::" << __FUNCTION__ << " succeeded";
156 156
157 media_task_runner_->PostTask(FROM_HERE, codec_created_cb_); 157 media_task_runner_->PostTask(FROM_HERE, codec_created_cb_);
158 158
159 return CONFIG_OK; 159 return kConfigOk;
160 } 160 }
161 161
162 void MediaCodecVideoDecoder::SynchronizePTSWithTime( 162 void MediaCodecVideoDecoder::SynchronizePTSWithTime(
163 base::TimeDelta current_time) { 163 base::TimeDelta current_time) {
164 DCHECK(media_task_runner_->BelongsToCurrentThread()); 164 DCHECK(media_task_runner_->BelongsToCurrentThread());
165 165
166 start_time_ticks_ = base::TimeTicks::Now(); 166 start_time_ticks_ = base::TimeTicks::Now();
167 start_pts_ = current_time; 167 start_pts_ = current_time;
168 last_seen_pts_ = current_time; 168 last_seen_pts_ = current_time;
169 } 169 }
(...skipping 59 matching lines...) Expand 10 before | Expand all | Expand 10 after
229 size, do_render, eos_encountered), 229 size, do_render, eos_encountered),
230 time_to_render); 230 time_to_render);
231 } 231 }
232 232
233 int MediaCodecVideoDecoder::NumDelayedRenderTasks() const { 233 int MediaCodecVideoDecoder::NumDelayedRenderTasks() const {
234 DCHECK(decoder_thread_.task_runner()->BelongsToCurrentThread()); 234 DCHECK(decoder_thread_.task_runner()->BelongsToCurrentThread());
235 235
236 return delayed_buffers_.size(); 236 return delayed_buffers_.size();
237 } 237 }
238 238
239 void MediaCodecVideoDecoder::ReleaseDelayedBuffers() { 239 void MediaCodecVideoDecoder::ClearDelayedBuffers(bool release) {
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 if (release) {
243 media_codec_bridge_->ReleaseOutputBuffer(index, false); 243 for (int index : delayed_buffers_)
244 media_codec_bridge_->ReleaseOutputBuffer(index, false);
245 }
246
244 delayed_buffers_.clear(); 247 delayed_buffers_.clear();
245 } 248 }
246 249
247 #ifndef NDEBUG 250 #ifndef NDEBUG
248 void MediaCodecVideoDecoder::VerifyUnitIsKeyFrame( 251 void MediaCodecVideoDecoder::VerifyUnitIsKeyFrame(
249 const AccessUnit* unit) const { 252 const AccessUnit* unit) const {
250 // The first video frame in a sequence must be a key frame or stand-alone EOS. 253 // The first video frame in a sequence must be a key frame or stand-alone EOS.
251 DCHECK(unit); 254 DCHECK(unit);
252 bool stand_alone_eos = unit->is_end_of_stream && unit->data.empty(); 255 bool stand_alone_eos = unit->is_end_of_stream && unit->data.empty();
253 DCHECK(stand_alone_eos || unit->is_key_frame); 256 DCHECK(stand_alone_eos || unit->is_key_frame);
(...skipping 17 matching lines...) Expand all
271 274
272 // |update_current_time_cb_| might be null if there is audio stream. 275 // |update_current_time_cb_| might be null if there is audio stream.
273 // Do not update current time for stand-alone EOS frames. 276 // Do not update current time for stand-alone EOS frames.
274 if (!update_current_time_cb_.is_null() && !(eos_encountered && !size)) { 277 if (!update_current_time_cb_.is_null() && !(eos_encountered && !size)) {
275 media_task_runner_->PostTask(FROM_HERE, 278 media_task_runner_->PostTask(FROM_HERE,
276 base::Bind(update_current_time_cb_, pts, pts)); 279 base::Bind(update_current_time_cb_, pts, pts));
277 } 280 }
278 } 281 }
279 282
280 } // namespace media 283 } // namespace media
OLDNEW
« no previous file with comments | « media/base/android/media_codec_video_decoder.h ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698