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

Side by Side Diff: media/filters/skcanvas_video_renderer.cc

Issue 624633002: Fix potential use-after-free bug in VideoImageGenerator::onGetYUV8Planes. (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: give up removing |generator_| Created 6 years, 2 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 | 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) 2012 The Chromium Authors. All rights reserved. 1 // Copyright (c) 2012 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/filters/skcanvas_video_renderer.h" 5 #include "media/filters/skcanvas_video_renderer.h"
6 6
7 #include "base/logging.h" 7 #include "base/logging.h"
8 #include "media/base/video_frame.h" 8 #include "media/base/video_frame.h"
9 #include "media/base/yuv_convert.h" 9 #include "media/base/yuv_convert.h"
10 #include "third_party/libyuv/include/libyuv.h" 10 #include "third_party/libyuv/include/libyuv.h"
(...skipping 190 matching lines...) Expand 10 before | Expand all | Expand 10 after
201 } 201 }
202 default: 202 default:
203 NOTREACHED(); 203 NOTREACHED();
204 break; 204 break;
205 } 205 }
206 } 206 }
207 207
208 // Generates an RGB image from a VideoFrame. 208 // Generates an RGB image from a VideoFrame.
209 class VideoImageGenerator : public SkImageGenerator { 209 class VideoImageGenerator : public SkImageGenerator {
210 public: 210 public:
211 VideoImageGenerator(const scoped_refptr<VideoFrame>& frame) : frame_(frame) {} 211 VideoImageGenerator(const scoped_refptr<VideoFrame>& frame) : frame_(frame) {
212 DCHECK(frame_.get());
213 }
212 virtual ~VideoImageGenerator() {} 214 virtual ~VideoImageGenerator() {}
213 215
214 void set_frame(const scoped_refptr<VideoFrame>& frame) { frame_ = frame; } 216 void set_frame(const scoped_refptr<VideoFrame>& frame) { frame_ = frame; }
215 217
216 protected: 218 protected:
217 virtual bool onGetInfo(SkImageInfo* info) override { 219 virtual bool onGetInfo(SkImageInfo* info) override {
218 info->fWidth = frame_->visible_rect().width(); 220 info->fWidth = frame_->visible_rect().width();
219 info->fHeight = frame_->visible_rect().height(); 221 info->fHeight = frame_->visible_rect().height();
220 info->fColorType = kN32_SkColorType; 222 info->fColorType = kN32_SkColorType;
221 info->fAlphaType = kPremul_SkAlphaType; 223 info->fAlphaType = kPremul_SkAlphaType;
222 return true; 224 return true;
223 } 225 }
224 226
225 virtual bool onGetPixels(const SkImageInfo& info, 227 virtual bool onGetPixels(const SkImageInfo& info,
226 void* pixels, 228 void* pixels,
227 size_t row_bytes, 229 size_t row_bytes,
228 SkPMColor ctable[], 230 SkPMColor ctable[],
229 int* ctable_count) override { 231 int* ctable_count) override {
230 if (!frame_.get()) 232 if (!frame_.get())
231 return false; 233 return false;
232 if (!pixels) 234 if (!pixels)
233 return true; 235 return false;
234 // If skia couldn't do the YUV conversion, we will. 236 // If skia couldn't do the YUV conversion, we will.
235 ConvertVideoFrameToRGBPixels(frame_, pixels, row_bytes); 237 ConvertVideoFrameToRGBPixels(frame_, pixels, row_bytes);
236 frame_ = NULL;
237 return true; 238 return true;
238 } 239 }
239 240
240 virtual bool onGetYUV8Planes(SkISize sizes[3], 241 virtual bool onGetYUV8Planes(SkISize sizes[3],
241 void* planes[3], 242 void* planes[3],
242 size_t row_bytes[3], 243 size_t row_bytes[3],
243 SkYUVColorSpace* color_space) override { 244 SkYUVColorSpace* color_space) override {
244 if (!frame_.get() || !IsYUV(frame_->format())) 245 if (!frame_.get() || !IsYUV(frame_->format()))
245 return false; 246 return false;
246 247
(...skipping 24 matching lines...) Expand all
271 frame_->visible_rect().x(); 272 frame_->visible_rect().x();
272 } else { 273 } else {
273 offset = (frame_->stride(media::VideoFrame::kUPlane) * 274 offset = (frame_->stride(media::VideoFrame::kUPlane) *
274 (frame_->visible_rect().y() >> y_shift)) + 275 (frame_->visible_rect().y() >> y_shift)) +
275 (frame_->visible_rect().x() >> 1); 276 (frame_->visible_rect().x() >> 1);
276 } 277 }
277 row_bytes[plane] = static_cast<size_t>(frame_->stride(plane)); 278 row_bytes[plane] = static_cast<size_t>(frame_->stride(plane));
278 planes[plane] = frame_->data(plane) + offset; 279 planes[plane] = frame_->data(plane) + offset;
279 } 280 }
280 } 281 }
281 if (planes && row_bytes)
282 frame_ = NULL;
283 return true; 282 return true;
284 } 283 }
285 284
286 private: 285 private:
287 scoped_refptr<VideoFrame> frame_; 286 scoped_refptr<VideoFrame> frame_;
287
288 DISALLOW_IMPLICIT_CONSTRUCTORS(VideoImageGenerator);
288 }; 289 };
289 290
290 SkCanvasVideoRenderer::SkCanvasVideoRenderer() 291 SkCanvasVideoRenderer::SkCanvasVideoRenderer()
291 : generator_(NULL), last_frame_timestamp_(media::kNoTimestamp()) { 292 : generator_(NULL), last_frame_timestamp_(media::kNoTimestamp()) {
292 last_frame_.setIsVolatile(true); 293 last_frame_.setIsVolatile(true);
293 } 294 }
294 295
295 SkCanvasVideoRenderer::~SkCanvasVideoRenderer() {} 296 SkCanvasVideoRenderer::~SkCanvasVideoRenderer() {}
296 297
297 void SkCanvasVideoRenderer::Paint(const scoped_refptr<VideoFrame>& video_frame, 298 void SkCanvasVideoRenderer::Paint(const scoped_refptr<VideoFrame>& video_frame,
(...skipping 27 matching lines...) Expand all
325 326
326 // Note: This takes ownership of |generator_|. 327 // Note: This takes ownership of |generator_|.
327 if (!SkInstallDiscardablePixelRef(generator_, &last_frame_)) { 328 if (!SkInstallDiscardablePixelRef(generator_, &last_frame_)) {
328 NOTREACHED(); 329 NOTREACHED();
329 } 330 }
330 DCHECK(video_frame->visible_rect().width() == last_frame_.width() && 331 DCHECK(video_frame->visible_rect().width() == last_frame_.width() &&
331 video_frame->visible_rect().height() == last_frame_.height()); 332 video_frame->visible_rect().height() == last_frame_.height());
332 333
333 last_frame_timestamp_ = video_frame->timestamp(); 334 last_frame_timestamp_ = video_frame->timestamp();
334 } else if (generator_) { 335 } else if (generator_) {
335 generator_->set_frame(video_frame); 336 generator_->set_frame(video_frame);
dshwang 2014/10/10 16:50:20 This line is needed because |generator_| generates
336 } 337 }
337 338
338 paint.setXfermodeMode(mode); 339 paint.setXfermodeMode(mode);
339 paint.setFilterLevel(SkPaint::kLow_FilterLevel); 340 paint.setFilterLevel(SkPaint::kLow_FilterLevel);
340 341
341 bool need_transform = 342 bool need_transform =
342 video_rotation != VIDEO_ROTATION_0 || 343 video_rotation != VIDEO_ROTATION_0 ||
343 dest_rect.size() != video_frame->visible_rect().size() || 344 dest_rect.size() != video_frame->visible_rect().size() ||
344 !dest_rect.origin().IsOrigin(); 345 !dest_rect.origin().IsOrigin();
345 if (need_transform) { 346 if (need_transform) {
(...skipping 26 matching lines...) Expand all
372 canvas->scale( 373 canvas->scale(
373 SkFloatToScalar(rotated_dest_size.width() / last_frame_.width()), 374 SkFloatToScalar(rotated_dest_size.width() / last_frame_.width()),
374 SkFloatToScalar(rotated_dest_size.height() / last_frame_.height())); 375 SkFloatToScalar(rotated_dest_size.height() / last_frame_.height()));
375 canvas->translate(-SkFloatToScalar(last_frame_.width() * 0.5f), 376 canvas->translate(-SkFloatToScalar(last_frame_.width() * 0.5f),
376 -SkFloatToScalar(last_frame_.height() * 0.5f)); 377 -SkFloatToScalar(last_frame_.height() * 0.5f));
377 } 378 }
378 canvas->drawBitmap(last_frame_, 0, 0, &paint); 379 canvas->drawBitmap(last_frame_, 0, 0, &paint);
379 if (need_transform) 380 if (need_transform)
380 canvas->restore(); 381 canvas->restore();
381 canvas->flush(); 382 canvas->flush();
383 // SkCanvas::flush() causes the generator to generate SkImage, so delete
384 // |video_frame| not to be outlived.
385 if (generator_)
386 generator_->set_frame(NULL);
382 } 387 }
383 388
384 void SkCanvasVideoRenderer::Copy(const scoped_refptr<VideoFrame>& video_frame, 389 void SkCanvasVideoRenderer::Copy(const scoped_refptr<VideoFrame>& video_frame,
385 SkCanvas* canvas) { 390 SkCanvas* canvas) {
386 Paint(video_frame, 391 Paint(video_frame,
387 canvas, 392 canvas,
388 video_frame->visible_rect(), 393 video_frame->visible_rect(),
389 0xff, 394 0xff,
390 SkXfermode::kSrc_Mode, 395 SkXfermode::kSrc_Mode,
391 media::VIDEO_ROTATION_0); 396 media::VIDEO_ROTATION_0);
392 } 397 }
393 398
394 } // namespace media 399 } // namespace media
OLDNEW
« no previous file with comments | « no previous file | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698