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

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

Issue 114853002: media: Enabling direct rendering for VP9 (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: adding some comments. Created 7 years 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
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/vpx_video_decoder.h" 5 #include "media/filters/vpx_video_decoder.h"
6 6
7 #include <algorithm> 7 #include <algorithm>
8 #include <string> 8 #include <string>
9 9
10 #include "base/bind.h" 10 #include "base/bind.h"
(...skipping 13 matching lines...) Expand all
24 #include "media/base/video_frame.h" 24 #include "media/base/video_frame.h"
25 #include "media/base/video_util.h" 25 #include "media/base/video_util.h"
26 26
27 // Include libvpx header files. 27 // Include libvpx header files.
28 // VPX_CODEC_DISABLE_COMPAT excludes parts of the libvpx API that provide 28 // VPX_CODEC_DISABLE_COMPAT excludes parts of the libvpx API that provide
29 // backwards compatibility for legacy applications using the library. 29 // backwards compatibility for legacy applications using the library.
30 #define VPX_CODEC_DISABLE_COMPAT 1 30 #define VPX_CODEC_DISABLE_COMPAT 1
31 extern "C" { 31 extern "C" {
32 #include "third_party/libvpx/source/libvpx/vpx/vpx_decoder.h" 32 #include "third_party/libvpx/source/libvpx/vpx/vpx_decoder.h"
33 #include "third_party/libvpx/source/libvpx/vpx/vp8dx.h" 33 #include "third_party/libvpx/source/libvpx/vpx/vp8dx.h"
34 #include "third_party/libvpx/source/libvpx/vpx/vpx_external_frame_buffer.h"
fgalligan1 2013/12/16 19:38:43 This include should be before vp8dx
vignesh 2013/12/16 21:10:57 Done.
34 } 35 }
35 36
36 namespace media { 37 namespace media {
37 38
38 // Always try to use three threads for video decoding. There is little reason 39 // Always try to use three threads for video decoding. There is little reason
39 // not to since current day CPUs tend to be multi-core and we measured 40 // not to since current day CPUs tend to be multi-core and we measured
40 // performance benefits on older machines such as P4s with hyperthreading. 41 // performance benefits on older machines such as P4s with hyperthreading.
41 static const int kDecodeThreads = 2; 42 static const int kDecodeThreads = 2;
42 static const int kMaxDecodeThreads = 16; 43 static const int kMaxDecodeThreads = 16;
43 44
(...skipping 22 matching lines...) Expand all
66 decode_threads = std::min(decode_threads, kMaxDecodeThreads); 67 decode_threads = std::min(decode_threads, kMaxDecodeThreads);
67 return decode_threads; 68 return decode_threads;
68 } 69 }
69 70
70 VpxVideoDecoder::VpxVideoDecoder( 71 VpxVideoDecoder::VpxVideoDecoder(
71 const scoped_refptr<base::MessageLoopProxy>& message_loop) 72 const scoped_refptr<base::MessageLoopProxy>& message_loop)
72 : message_loop_(message_loop), 73 : message_loop_(message_loop),
73 weak_factory_(this), 74 weak_factory_(this),
74 state_(kUninitialized), 75 state_(kUninitialized),
75 vpx_codec_(NULL), 76 vpx_codec_(NULL),
76 vpx_codec_alpha_(NULL) { 77 vpx_codec_alpha_(NULL),
78 frame_buffers_(NULL) {
77 } 79 }
78 80
79 VpxVideoDecoder::~VpxVideoDecoder() { 81 VpxVideoDecoder::~VpxVideoDecoder() {
80 DCHECK_EQ(kUninitialized, state_); 82 DCHECK_EQ(kUninitialized, state_);
81 CloseDecoder(); 83 CloseDecoder();
82 } 84 }
83 85
84 void VpxVideoDecoder::Initialize(const VideoDecoderConfig& config, 86 void VpxVideoDecoder::Initialize(const VideoDecoderConfig& config,
85 const PipelineStatusCB& status_cb) { 87 const PipelineStatusCB& status_cb) {
86 DCHECK(message_loop_->BelongsToCurrentThread()); 88 DCHECK(message_loop_->BelongsToCurrentThread());
(...skipping 30 matching lines...) Expand all
117 &vpx_config, 119 &vpx_config,
118 0); 120 0);
119 if (status != VPX_CODEC_OK) { 121 if (status != VPX_CODEC_OK) {
120 LOG(ERROR) << "vpx_codec_dec_init failed, status=" << status; 122 LOG(ERROR) << "vpx_codec_dec_init failed, status=" << status;
121 delete context; 123 delete context;
122 return NULL; 124 return NULL;
123 } 125 }
124 return context; 126 return context;
125 } 127 }
126 128
129 int32 VpxVideoDecoder::ReallocVP9FrameBuffer(void *user_priv, size_t new_size,
130 vpx_codec_frame_buffer *fb) {
131 if (!fb)
132 return -1;
133 if (fb->data)
134 delete[] fb->data;
135 fb->data = new uint8[new_size];
136 if (!fb->data) {
137 fb->size = 0;
138 return -1;
139 }
140 fb->size = new_size;
141 return VPX_CODEC_OK;
142 }
143
127 bool VpxVideoDecoder::ConfigureDecoder(const VideoDecoderConfig& config) { 144 bool VpxVideoDecoder::ConfigureDecoder(const VideoDecoderConfig& config) {
128 const CommandLine* cmd_line = CommandLine::ForCurrentProcess(); 145 const CommandLine* cmd_line = CommandLine::ForCurrentProcess();
129 bool can_handle = false; 146 bool can_handle = false;
130 if (config.codec() == kCodecVP9) 147 if (config.codec() == kCodecVP9)
131 can_handle = true; 148 can_handle = true;
132 if (!cmd_line->HasSwitch(switches::kDisableVp8AlphaPlayback) && 149 if (!cmd_line->HasSwitch(switches::kDisableVp8AlphaPlayback) &&
133 config.codec() == kCodecVP8 && config.format() == VideoFrame::YV12A) { 150 config.codec() == kCodecVP8 && config.format() == VideoFrame::YV12A) {
134 can_handle = true; 151 can_handle = true;
135 } 152 }
136 if (!can_handle) 153 if (!can_handle)
137 return false; 154 return false;
138 155
139 CloseDecoder(); 156 CloseDecoder();
140 157
141 vpx_codec_ = InitializeVpxContext(vpx_codec_, config); 158 vpx_codec_ = InitializeVpxContext(vpx_codec_, config);
142 if (!vpx_codec_) 159 if (!vpx_codec_)
143 return false; 160 return false;
144 161
162 // We use our own buffers for VP9 so that there is no need to copy data after
163 // decoding.
164 if (config.codec() == kCodecVP9) {
fgalligan1 2013/12/16 19:38:43 You are going to have to add a check of the ABI he
vignesh 2013/12/16 21:10:57 Done.
165 frame_buffers_ = new vpx_codec_frame_buffer[kVP9MaxFrameBuffers]();
fgalligan1 2013/12/16 19:38:43 parenthesis are not needed.
vignesh 2013/12/16 21:10:57 new operator without paranthesis will not zero ini
166 if (vpx_codec_set_frame_buffers(vpx_codec_,
167 frame_buffers_,
168 kVP9MaxFrameBuffers,
169 VpxVideoDecoder::ReallocVP9FrameBuffer,
170 NULL)) {
171 LOG(ERROR) << "Failed to configure external buffers.";
172 return false;
173 }
174 }
175
145 if (config.format() == VideoFrame::YV12A) { 176 if (config.format() == VideoFrame::YV12A) {
146 vpx_codec_alpha_ = InitializeVpxContext(vpx_codec_alpha_, config); 177 vpx_codec_alpha_ = InitializeVpxContext(vpx_codec_alpha_, config);
147 if (!vpx_codec_alpha_) 178 if (!vpx_codec_alpha_)
148 return false; 179 return false;
149 } 180 }
150 181
151 return true; 182 return true;
152 } 183 }
153 184
154 void VpxVideoDecoder::CloseDecoder() { 185 void VpxVideoDecoder::CloseDecoder() {
155 if (vpx_codec_) { 186 if (vpx_codec_) {
156 vpx_codec_destroy(vpx_codec_); 187 vpx_codec_destroy(vpx_codec_);
157 delete vpx_codec_; 188 delete vpx_codec_;
158 vpx_codec_ = NULL; 189 vpx_codec_ = NULL;
190 if (frame_buffers_) {
191 for (int i = 0; i < kVP9MaxFrameBuffers; i++)
192 delete[] frame_buffers_[i].data;
193 delete[] frame_buffers_;
194 frame_buffers_ = NULL;
195 }
159 } 196 }
160 if (vpx_codec_alpha_) { 197 if (vpx_codec_alpha_) {
161 vpx_codec_destroy(vpx_codec_alpha_); 198 vpx_codec_destroy(vpx_codec_alpha_);
162 delete vpx_codec_alpha_; 199 delete vpx_codec_alpha_;
163 vpx_codec_alpha_ = NULL; 200 vpx_codec_alpha_ = NULL;
164 } 201 }
165 } 202 }
166 203
167 void VpxVideoDecoder::Decode(const scoped_refptr<DecoderBuffer>& buffer, 204 void VpxVideoDecoder::Decode(const scoped_refptr<DecoderBuffer>& buffer,
168 const DecodeCB& decode_cb) { 205 const DecodeCB& decode_cb) {
(...skipping 166 matching lines...) Expand 10 before | Expand all | Expand 10 after
335 372
336 void VpxVideoDecoder::CopyVpxImageTo(const vpx_image* vpx_image, 373 void VpxVideoDecoder::CopyVpxImageTo(const vpx_image* vpx_image,
337 const struct vpx_image* vpx_image_alpha, 374 const struct vpx_image* vpx_image_alpha,
338 scoped_refptr<VideoFrame>* video_frame) { 375 scoped_refptr<VideoFrame>* video_frame) {
339 CHECK(vpx_image); 376 CHECK(vpx_image);
340 CHECK(vpx_image->fmt == VPX_IMG_FMT_I420 || 377 CHECK(vpx_image->fmt == VPX_IMG_FMT_I420 ||
341 vpx_image->fmt == VPX_IMG_FMT_YV12); 378 vpx_image->fmt == VPX_IMG_FMT_YV12);
342 379
343 gfx::Size size(vpx_image->d_w, vpx_image->d_h); 380 gfx::Size size(vpx_image->d_w, vpx_image->d_h);
344 381
382 if (!vpx_codec_alpha_) {
383 *video_frame = VideoFrame::WrapExternalYuvData(
384 VideoFrame::YV12,
385 size, gfx::Rect(size), config_.natural_size(),
386 vpx_image->stride[VPX_PLANE_Y],
387 vpx_image->stride[VPX_PLANE_U],
388 vpx_image->stride[VPX_PLANE_V],
389 vpx_image->planes[VPX_PLANE_Y],
390 vpx_image->planes[VPX_PLANE_U],
391 vpx_image->planes[VPX_PLANE_V],
392 kNoTimestamp(),
393 base::Closure());
394 return;
395 }
396
345 *video_frame = frame_pool_.CreateFrame( 397 *video_frame = frame_pool_.CreateFrame(
346 vpx_codec_alpha_ ? VideoFrame::YV12A : VideoFrame::YV12, 398 vpx_codec_alpha_ ? VideoFrame::YV12A : VideoFrame::YV12,
347 size, 399 size,
348 gfx::Rect(size), 400 gfx::Rect(size),
349 config_.natural_size(), 401 config_.natural_size(),
350 kNoTimestamp()); 402 kNoTimestamp());
351 403
352 CopyYPlane(vpx_image->planes[VPX_PLANE_Y], 404 CopyYPlane(vpx_image->planes[VPX_PLANE_Y],
353 vpx_image->stride[VPX_PLANE_Y], 405 vpx_image->stride[VPX_PLANE_Y],
354 vpx_image->d_h, 406 vpx_image->d_h,
355 video_frame->get()); 407 video_frame->get());
356 CopyUPlane(vpx_image->planes[VPX_PLANE_U], 408 CopyUPlane(vpx_image->planes[VPX_PLANE_U],
357 vpx_image->stride[VPX_PLANE_U], 409 vpx_image->stride[VPX_PLANE_U],
358 (vpx_image->d_h + 1) / 2, 410 (vpx_image->d_h + 1) / 2,
359 video_frame->get()); 411 video_frame->get());
360 CopyVPlane(vpx_image->planes[VPX_PLANE_V], 412 CopyVPlane(vpx_image->planes[VPX_PLANE_V],
361 vpx_image->stride[VPX_PLANE_V], 413 vpx_image->stride[VPX_PLANE_V],
362 (vpx_image->d_h + 1) / 2, 414 (vpx_image->d_h + 1) / 2,
363 video_frame->get()); 415 video_frame->get());
364 if (!vpx_codec_alpha_)
365 return;
366 if (!vpx_image_alpha) { 416 if (!vpx_image_alpha) {
367 MakeOpaqueAPlane( 417 MakeOpaqueAPlane(
368 vpx_image->stride[VPX_PLANE_Y], vpx_image->d_h, video_frame->get()); 418 vpx_image->stride[VPX_PLANE_Y], vpx_image->d_h, video_frame->get());
369 return; 419 return;
370 } 420 }
371 CopyAPlane(vpx_image_alpha->planes[VPX_PLANE_Y], 421 CopyAPlane(vpx_image_alpha->planes[VPX_PLANE_Y],
372 vpx_image->stride[VPX_PLANE_Y], 422 vpx_image->stride[VPX_PLANE_Y],
373 vpx_image->d_h, 423 vpx_image->d_h,
374 video_frame->get()); 424 video_frame->get());
375 } 425 }
376 426
377 } // namespace media 427 } // namespace media
OLDNEW
« media/filters/vpx_video_decoder.h ('K') | « media/filters/vpx_video_decoder.h ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698