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

Side by Side Diff: content/renderer/pepper/video_decoder_shim.cc

Issue 805193006: Fix VideoDecoderShim to return correct decode_id for all codecs. (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Created 5 years, 11 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 | « no previous file | media/base/video_decoder.h » ('j') | media/base/video_decoder.h » ('J')
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright 2014 The Chromium Authors. All rights reserved. 1 // Copyright 2014 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 "content/renderer/pepper/video_decoder_shim.h" 5 #include "content/renderer/pepper/video_decoder_shim.h"
6 6
7 #include <GLES2/gl2.h> 7 #include <GLES2/gl2.h>
8 #include <GLES2/gl2ext.h> 8 #include <GLES2/gl2ext.h>
9 #include <GLES2/gl2extchromium.h> 9 #include <GLES2/gl2extchromium.h>
10 10
(...skipping 78 matching lines...) Expand 10 before | Expand all | Expand 10 after
89 ~DecoderImpl(); 89 ~DecoderImpl();
90 90
91 void Initialize(media::VideoDecoderConfig config); 91 void Initialize(media::VideoDecoderConfig config);
92 void Decode(uint32_t decode_id, scoped_refptr<media::DecoderBuffer> buffer); 92 void Decode(uint32_t decode_id, scoped_refptr<media::DecoderBuffer> buffer);
93 void Reset(); 93 void Reset();
94 void Stop(); 94 void Stop();
95 95
96 private: 96 private:
97 void OnPipelineStatus(media::PipelineStatus status); 97 void OnPipelineStatus(media::PipelineStatus status);
98 void DoDecode(); 98 void DoDecode();
99 void OnDecodeComplete(uint32_t decode_id, media::VideoDecoder::Status status); 99 void OnDecodeComplete(media::VideoDecoder::Status status);
100 void OnOutputComplete(const scoped_refptr<media::VideoFrame>& frame); 100 void OnOutputComplete(const scoped_refptr<media::VideoFrame>& frame);
101 void OnResetComplete(); 101 void OnResetComplete();
102 102
103 // WeakPtr is bound to main_message_loop_. Use only in shim callbacks. 103 // WeakPtr is bound to main_message_loop_. Use only in shim callbacks.
104 base::WeakPtr<VideoDecoderShim> shim_; 104 base::WeakPtr<VideoDecoderShim> shim_;
105 scoped_ptr<media::VideoDecoder> decoder_; 105 scoped_ptr<media::VideoDecoder> decoder_;
106 scoped_refptr<base::MessageLoopProxy> main_message_loop_; 106 scoped_refptr<base::MessageLoopProxy> main_message_loop_;
107 // Queue of decodes waiting for the decoder. 107 // Queue of decodes waiting for the decoder.
108 typedef std::queue<PendingDecode> PendingDecodeQueue; 108 typedef std::queue<PendingDecode> PendingDecodeQueue;
109 PendingDecodeQueue pending_decodes_; 109 PendingDecodeQueue pending_decodes_;
110 int max_decodes_at_decoder_; 110 bool waiting_decoder_;
bbudge 2015/01/15 21:21:00 nit: s/waiting/awaiting
Sergey Ulanov 2015/01/16 00:46:39 Done.
111 int num_decodes_at_decoder_;
112 // VideoDecoder returns pictures without information about the decode buffer 111 // VideoDecoder returns pictures without information about the decode buffer
113 // that generated it. Save the decode_id from the last decode that completed, 112 // that generated it, but software decoder always generate corresponding
bbudge 2015/01/15 21:21:00 nit: s/decoder/decoders
Sergey Ulanov 2015/01/16 00:46:39 Done.
114 // which is close for most decoders, which only decode one buffer at a time. 113 // frames before decode is finished.
115 uint32_t decode_id_; 114 uint32_t decode_id_;
116 }; 115 };
117 116
118 VideoDecoderShim::DecoderImpl::DecoderImpl( 117 VideoDecoderShim::DecoderImpl::DecoderImpl(
119 const base::WeakPtr<VideoDecoderShim>& proxy) 118 const base::WeakPtr<VideoDecoderShim>& proxy)
120 : shim_(proxy), 119 : shim_(proxy),
121 main_message_loop_(base::MessageLoopProxy::current()), 120 main_message_loop_(base::MessageLoopProxy::current()),
122 max_decodes_at_decoder_(0), 121 waiting_decoder_(0),
bbudge 2015/01/15 21:21:00 s/0/false
Sergey Ulanov 2015/01/16 00:46:39 Done.
123 num_decodes_at_decoder_(0),
124 decode_id_(0) { 122 decode_id_(0) {
125 } 123 }
126 124
127 VideoDecoderShim::DecoderImpl::~DecoderImpl() { 125 VideoDecoderShim::DecoderImpl::~DecoderImpl() {
128 DCHECK(pending_decodes_.empty()); 126 DCHECK(pending_decodes_.empty());
129 } 127 }
130 128
131 void VideoDecoderShim::DecoderImpl::Initialize( 129 void VideoDecoderShim::DecoderImpl::Initialize(
132 media::VideoDecoderConfig config) { 130 media::VideoDecoderConfig config) {
133 DCHECK(!decoder_); 131 DCHECK(!decoder_);
134 #if !defined(MEDIA_DISABLE_LIBVPX) 132 #if !defined(MEDIA_DISABLE_LIBVPX)
135 if (config.codec() == media::kCodecVP9) { 133 if (config.codec() == media::kCodecVP9) {
136 decoder_.reset( 134 decoder_.reset(
137 new media::VpxVideoDecoder(base::MessageLoopProxy::current())); 135 new media::VpxVideoDecoder(base::MessageLoopProxy::current()));
138 } else 136 } else
139 #endif 137 #endif
140 { 138 {
141 scoped_ptr<media::FFmpegVideoDecoder> ffmpeg_video_decoder( 139 scoped_ptr<media::FFmpegVideoDecoder> ffmpeg_video_decoder(
142 new media::FFmpegVideoDecoder(base::MessageLoopProxy::current())); 140 new media::FFmpegVideoDecoder(base::MessageLoopProxy::current()));
143 ffmpeg_video_decoder->set_decode_nalus(true); 141 ffmpeg_video_decoder->set_decode_nalus(true);
144 decoder_ = ffmpeg_video_decoder.Pass(); 142 decoder_ = ffmpeg_video_decoder.Pass();
145 } 143 }
146 max_decodes_at_decoder_ = decoder_->GetMaxDecodeRequests(); 144
145 // VpxVideoDecoder and FFmpegVideoDecoder support only one pending Decode()
146 // request.
147 DCHECK_EQ(decoder_->GetMaxDecodeRequests(), 1);
148
147 // We can use base::Unretained() safely in decoder callbacks because 149 // We can use base::Unretained() safely in decoder callbacks because
148 // |decoder_| is owned by DecoderImpl. During Stop(), the |decoder_| will be 150 // |decoder_| is owned by DecoderImpl. During Stop(), the |decoder_| will be
149 // destroyed and all outstanding callbacks will be fired. 151 // destroyed and all outstanding callbacks will be fired.
150 decoder_->Initialize( 152 decoder_->Initialize(
151 config, 153 config,
152 true /* low_delay */, 154 true /* low_delay */,
153 base::Bind(&VideoDecoderShim::DecoderImpl::OnPipelineStatus, 155 base::Bind(&VideoDecoderShim::DecoderImpl::OnPipelineStatus,
154 base::Unretained(this)), 156 base::Unretained(this)),
155 base::Bind(&VideoDecoderShim::DecoderImpl::OnOutputComplete, 157 base::Bind(&VideoDecoderShim::DecoderImpl::OnOutputComplete,
156 base::Unretained(this))); 158 base::Unretained(this)));
(...skipping 43 matching lines...) Expand 10 before | Expand all | Expand 10 after
200 break; 202 break;
201 case media::DECODER_ERROR_NOT_SUPPORTED: 203 case media::DECODER_ERROR_NOT_SUPPORTED:
202 result = PP_ERROR_NOTSUPPORTED; 204 result = PP_ERROR_NOTSUPPORTED;
203 break; 205 break;
204 default: 206 default:
205 result = PP_ERROR_FAILED; 207 result = PP_ERROR_FAILED;
206 break; 208 break;
207 } 209 }
208 210
209 // Calculate how many textures the shim should create. 211 // Calculate how many textures the shim should create.
210 uint32_t shim_texture_pool_size = 212 uint32_t shim_texture_pool_size = media::limits::kMaxVideoFrames + 1;
211 max_decodes_at_decoder_ + media::limits::kMaxVideoFrames;
212 main_message_loop_->PostTask( 213 main_message_loop_->PostTask(
213 FROM_HERE, 214 FROM_HERE,
214 base::Bind(&VideoDecoderShim::OnInitializeComplete, 215 base::Bind(&VideoDecoderShim::OnInitializeComplete,
215 shim_, 216 shim_,
216 result, 217 result,
217 shim_texture_pool_size)); 218 shim_texture_pool_size));
218 } 219 }
219 220
220 void VideoDecoderShim::DecoderImpl::DoDecode() { 221 void VideoDecoderShim::DecoderImpl::DoDecode() {
221 while (!pending_decodes_.empty() && 222 if (pending_decodes_.empty() || waiting_decoder_)
222 num_decodes_at_decoder_ < max_decodes_at_decoder_) { 223 return;
223 num_decodes_at_decoder_++; 224
224 const PendingDecode& decode = pending_decodes_.front(); 225 waiting_decoder_ = true;
225 decoder_->Decode( 226 const PendingDecode& decode = pending_decodes_.front();
226 decode.buffer, 227 decode_id_ = decode.decode_id;
227 base::Bind(&VideoDecoderShim::DecoderImpl::OnDecodeComplete, 228 decoder_->Decode(decode.buffer,
228 base::Unretained(this), 229 base::Bind(&VideoDecoderShim::DecoderImpl::OnDecodeComplete,
229 decode.decode_id)); 230 base::Unretained(this)));
230 pending_decodes_.pop(); 231 pending_decodes_.pop();
231 }
232 } 232 }
233 233
234 void VideoDecoderShim::DecoderImpl::OnDecodeComplete( 234 void VideoDecoderShim::DecoderImpl::OnDecodeComplete(
235 uint32_t decode_id,
236 media::VideoDecoder::Status status) { 235 media::VideoDecoder::Status status) {
237 num_decodes_at_decoder_--; 236 DCHECK(waiting_decoder_);
238 decode_id_ = decode_id; 237 waiting_decoder_ = false;
239 238
240 int32_t result; 239 int32_t result;
241 switch (status) { 240 switch (status) {
242 case media::VideoDecoder::kOk: 241 case media::VideoDecoder::kOk:
243 case media::VideoDecoder::kAborted: 242 case media::VideoDecoder::kAborted:
244 result = PP_OK; 243 result = PP_OK;
245 break; 244 break;
246 case media::VideoDecoder::kDecodeError: 245 case media::VideoDecoder::kDecodeError:
247 result = PP_ERROR_RESOURCE_FAILED; 246 result = PP_ERROR_RESOURCE_FAILED;
248 break; 247 break;
249 default: 248 default:
250 NOTREACHED(); 249 NOTREACHED();
251 result = PP_ERROR_FAILED; 250 result = PP_ERROR_FAILED;
252 break; 251 break;
253 } 252 }
254 253
255 main_message_loop_->PostTask( 254 main_message_loop_->PostTask(
256 FROM_HERE, 255 FROM_HERE,
257 base::Bind( 256 base::Bind(
258 &VideoDecoderShim::OnDecodeComplete, shim_, result, decode_id)); 257 &VideoDecoderShim::OnDecodeComplete, shim_, result, decode_id_));
259 258
260 DoDecode(); 259 DoDecode();
261 } 260 }
262 261
263 void VideoDecoderShim::DecoderImpl::OnOutputComplete( 262 void VideoDecoderShim::DecoderImpl::OnOutputComplete(
264 const scoped_refptr<media::VideoFrame>& frame) { 263 const scoped_refptr<media::VideoFrame>& frame) {
264 // Software decoders are expected to generated frames only when Decode() call
bbudge 2015/01/15 21:21:00 s/generated/generate s/Decode()/a Decode()
Sergey Ulanov 2015/01/16 00:46:39 Done.
265 // is pending.
266 DCHECK(waiting_decoder_);
267
265 scoped_ptr<PendingFrame> pending_frame; 268 scoped_ptr<PendingFrame> pending_frame;
266 if (!frame->end_of_stream()) { 269 if (!frame->end_of_stream()) {
267 pending_frame.reset(new PendingFrame( 270 pending_frame.reset(new PendingFrame(
268 decode_id_, frame->coded_size(), frame->visible_rect())); 271 decode_id_, frame->coded_size(), frame->visible_rect()));
269 // Convert the VideoFrame pixels to ABGR to match VideoDecodeAccelerator. 272 // Convert the VideoFrame pixels to ABGR to match VideoDecodeAccelerator.
270 libyuv::I420ToABGR(frame->data(media::VideoFrame::kYPlane), 273 libyuv::I420ToABGR(frame->data(media::VideoFrame::kYPlane),
271 frame->stride(media::VideoFrame::kYPlane), 274 frame->stride(media::VideoFrame::kYPlane),
272 frame->data(media::VideoFrame::kUPlane), 275 frame->data(media::VideoFrame::kUPlane),
273 frame->stride(media::VideoFrame::kUPlane), 276 frame->stride(media::VideoFrame::kUPlane),
274 frame->data(media::VideoFrame::kVPlane), 277 frame->data(media::VideoFrame::kVPlane),
(...skipping 313 matching lines...) Expand 10 before | Expand all | Expand 10 after
588 void VideoDecoderShim::DeleteTexture(uint32_t texture_id) { 591 void VideoDecoderShim::DeleteTexture(uint32_t texture_id) {
589 gpu::gles2::GLES2Interface* gles2 = context_provider_->ContextGL(); 592 gpu::gles2::GLES2Interface* gles2 = context_provider_->ContextGL();
590 gles2->DeleteTextures(1, &texture_id); 593 gles2->DeleteTextures(1, &texture_id);
591 } 594 }
592 595
593 void VideoDecoderShim::FlushCommandBuffer() { 596 void VideoDecoderShim::FlushCommandBuffer() {
594 context_provider_->ContextGL()->Flush(); 597 context_provider_->ContextGL()->Flush();
595 } 598 }
596 599
597 } // namespace content 600 } // namespace content
OLDNEW
« no previous file with comments | « no previous file | media/base/video_decoder.h » ('j') | media/base/video_decoder.h » ('J')

Powered by Google App Engine
This is Rietveld 408576698