Remove Unused AsTextButtonBorder RTTI helper.
[chromium-blink-merge.git] / media / cast / video_receiver / codecs / vp8 / vp8_decoder.cc
blob1792eafbdcb96c0129a6e7159799a4a0a11e96bf
1 // Copyright 2013 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
5 #include "media/cast/video_receiver/codecs/vp8/vp8_decoder.h"
7 #include "base/bind.h"
8 #include "base/logging.h"
9 #include "base/message_loop/message_loop.h"
10 #include "media/base/video_frame.h"
11 #include "media/base/video_util.h"
12 #include "third_party/libvpx/source/libvpx/vpx/vp8dx.h"
13 #include "ui/gfx/size.h"
15 namespace media {
16 namespace cast {
18 void LogFrameDecodedEvent(CastEnvironment* const cast_environment,
19 uint32 rtp_timestamp,
20 uint32 frame_id) {
21 cast_environment->Logging()->InsertFrameEvent(
22 cast_environment->Clock()->NowTicks(),
23 kVideoFrameDecoded,
24 rtp_timestamp,
25 frame_id);
28 Vp8Decoder::Vp8Decoder(scoped_refptr<CastEnvironment> cast_environment)
29 : cast_environment_(cast_environment) {
30 // Make sure that we initialize the decoder from the correct thread.
31 cast_environment_->PostTask(
32 CastEnvironment::VIDEO_DECODER,
33 FROM_HERE,
34 base::Bind(&Vp8Decoder::InitDecoder, base::Unretained(this)));
37 Vp8Decoder::~Vp8Decoder() {
38 if (decoder_) {
39 vpx_codec_err_t ret = vpx_codec_destroy(decoder_.get());
40 CHECK_EQ(VPX_CODEC_OK, ret) << "vpx_codec_destroy() failed.";
44 void Vp8Decoder::InitDecoder() {
45 vpx_codec_dec_cfg_t cfg;
46 // Initializing to use one core.
47 cfg.threads = 1;
48 vpx_codec_flags_t flags = VPX_CODEC_USE_POSTPROC;
50 DCHECK(!decoder_);
51 decoder_.reset(new vpx_dec_ctx_t());
52 vpx_codec_err_t ret =
53 vpx_codec_dec_init(decoder_.get(), vpx_codec_vp8_dx(), &cfg, flags);
54 if (ret != VPX_CODEC_OK) {
55 DCHECK(false) << "vpx_codec_dec_init() failed.";
56 decoder_.reset();
60 bool Vp8Decoder::Decode(const transport::EncodedVideoFrame* encoded_frame,
61 const base::TimeTicks render_time,
62 const VideoFrameDecodedCallback& frame_decoded_cb) {
63 DCHECK(cast_environment_->CurrentlyOn(CastEnvironment::VIDEO_DECODER));
64 const int frame_id_int = static_cast<int>(encoded_frame->frame_id);
65 VLOG(1) << "VP8 decode frame:" << frame_id_int
66 << " sized:" << encoded_frame->data.size();
68 if (encoded_frame->data.empty())
69 return false;
71 vpx_codec_iter_t iter = NULL;
72 vpx_image_t* img;
73 const int real_time_decoding = 1;
74 if (vpx_codec_decode(
75 decoder_.get(),
76 reinterpret_cast<const uint8*>(encoded_frame->data.data()),
77 static_cast<unsigned int>(encoded_frame->data.size()),
79 real_time_decoding)) {
80 VLOG(1) << "Failed to decode VP8 frame.";
81 return false;
84 img = vpx_codec_get_frame(decoder_.get(), &iter);
85 if (img == NULL) {
86 VLOG(1) << "Skip rendering VP8 frame:" << frame_id_int;
87 return false;
90 gfx::Size visible_size(img->d_w, img->d_h);
91 gfx::Size full_size(img->stride[VPX_PLANE_Y], img->d_h);
92 DCHECK(VideoFrame::IsValidConfig(
93 VideoFrame::I420, visible_size, gfx::Rect(visible_size), full_size));
94 // Temp timing setting - will sort out timing in a follow up cl.
95 scoped_refptr<VideoFrame> decoded_frame =
96 VideoFrame::CreateFrame(VideoFrame::I420,
97 visible_size,
98 gfx::Rect(visible_size),
99 full_size,
100 base::TimeDelta());
102 // Copy each plane individually (need to account for stride).
103 // TODO(mikhal): Eliminate copy once http://crbug.com/321856 is resolved.
104 CopyPlane(VideoFrame::kYPlane,
105 img->planes[VPX_PLANE_Y],
106 img->stride[VPX_PLANE_Y],
107 img->d_h,
108 decoded_frame.get());
109 CopyPlane(VideoFrame::kUPlane,
110 img->planes[VPX_PLANE_U],
111 img->stride[VPX_PLANE_U],
112 (img->d_h + 1) / 2,
113 decoded_frame.get());
114 CopyPlane(VideoFrame::kVPlane,
115 img->planes[VPX_PLANE_V],
116 img->stride[VPX_PLANE_V],
117 (img->d_h + 1) / 2,
118 decoded_frame.get());
120 VLOG(1) << "Decoded frame " << frame_id_int;
122 // Update logging from the main thread.
123 cast_environment_->PostTask(CastEnvironment::MAIN,
124 FROM_HERE,
125 base::Bind(LogFrameDecodedEvent,
126 cast_environment_,
127 encoded_frame->rtp_timestamp,
128 encoded_frame->frame_id));
129 // Frame decoded - return frame to the user via callback.
130 cast_environment_->PostTask(
131 CastEnvironment::MAIN,
132 FROM_HERE,
133 base::Bind(frame_decoded_cb, decoded_frame, render_time));
135 return true;
138 } // namespace cast
139 } // namespace media