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

Side by Side Diff: media/cast/video_receiver/codecs/vp8/vp8_decoder.cc

Issue 225023010: [Cast] Refactor/clean-up VideoReceiver to match AudioReceiver as closely as possible. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: rebase Created 6 years, 8 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 | Annotate | Revision Log
OLDNEW
(Empty)
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.
4
5 #include "media/cast/video_receiver/codecs/vp8/vp8_decoder.h"
6
7 #include "base/bind.h"
8 #include "base/debug/trace_event.h"
9 #include "base/logging.h"
10 #include "base/message_loop/message_loop.h"
11 #include "media/base/video_frame.h"
12 #include "media/base/video_util.h"
13 #include "media/cast/logging/logging_defines.h"
14 #include "third_party/libvpx/source/libvpx/vpx/vp8dx.h"
15 #include "ui/gfx/size.h"
16
17 namespace {
18
19 void LogFrameDecodedEvent(
20 const scoped_refptr<media::cast::CastEnvironment>& cast_environment,
21 base::TimeTicks event_time,
22 media::cast::RtpTimestamp rtp_timestamp,
23 uint32 frame_id) {
24 cast_environment->Logging()->InsertFrameEvent(
25 event_time, media::cast::kVideoFrameDecoded, rtp_timestamp, frame_id);
26 }
27
28 } // namespace
29
30 namespace media {
31 namespace cast {
32
33 Vp8Decoder::Vp8Decoder(scoped_refptr<CastEnvironment> cast_environment)
34 : cast_environment_(cast_environment) {
35 // Make sure that we initialize the decoder from the correct thread.
36 cast_environment_->PostTask(
37 CastEnvironment::VIDEO,
38 FROM_HERE,
39 base::Bind(&Vp8Decoder::InitDecoder, base::Unretained(this)));
40 }
41
42 Vp8Decoder::~Vp8Decoder() {
43 if (decoder_) {
44 vpx_codec_err_t ret = vpx_codec_destroy(decoder_.get());
45 CHECK_EQ(VPX_CODEC_OK, ret) << "vpx_codec_destroy() failed.";
46 }
47 }
48
49 void Vp8Decoder::InitDecoder() {
50 vpx_codec_dec_cfg_t cfg;
51 // Initializing to use one core.
52 cfg.threads = 1;
53 vpx_codec_flags_t flags = VPX_CODEC_USE_POSTPROC;
54
55 DCHECK(!decoder_);
56 decoder_.reset(new vpx_dec_ctx_t());
57 vpx_codec_err_t ret =
58 vpx_codec_dec_init(decoder_.get(), vpx_codec_vp8_dx(), &cfg, flags);
59 if (ret != VPX_CODEC_OK) {
60 DCHECK(false) << "vpx_codec_dec_init() failed.";
61 decoder_.reset();
62 }
63 }
64
65 bool Vp8Decoder::Decode(const transport::EncodedVideoFrame* encoded_frame,
66 const base::TimeTicks render_time,
67 const VideoFrameDecodedCallback& frame_decoded_cb) {
68 DCHECK(cast_environment_->CurrentlyOn(CastEnvironment::VIDEO));
69 const int frame_id_int = static_cast<int>(encoded_frame->frame_id);
70 VLOG(2) << "VP8 decode frame:" << frame_id_int
71 << " sized:" << encoded_frame->data.size();
72
73 if (encoded_frame->data.empty())
74 return false;
75
76 vpx_codec_iter_t iter = NULL;
77 vpx_image_t* img;
78 const int real_time_decoding = 1;
79 if (vpx_codec_decode(
80 decoder_.get(),
81 reinterpret_cast<const uint8*>(encoded_frame->data.data()),
82 static_cast<unsigned int>(encoded_frame->data.size()),
83 0,
84 real_time_decoding)) {
85 VLOG(1) << "Failed to decode VP8 frame:" << frame_id_int;
86 return false;
87 }
88
89 img = vpx_codec_get_frame(decoder_.get(), &iter);
90 if (img == NULL) {
91 VLOG(1) << "Skip rendering VP8 frame:" << frame_id_int;
92 return false;
93 }
94
95 gfx::Size visible_size(img->d_w, img->d_h);
96 gfx::Size full_size(img->stride[VPX_PLANE_Y], img->d_h);
97 DCHECK(VideoFrame::IsValidConfig(
98 VideoFrame::I420, visible_size, gfx::Rect(visible_size), full_size));
99 // Temp timing setting - will sort out timing in a follow up cl.
100 scoped_refptr<VideoFrame> decoded_frame =
101 VideoFrame::CreateFrame(VideoFrame::I420,
102 visible_size,
103 gfx::Rect(visible_size),
104 full_size,
105 base::TimeDelta());
106
107 // Copy each plane individually (need to account for stride).
108 // TODO(mikhal): Eliminate copy once http://crbug.com/321856 is resolved.
109 CopyPlane(VideoFrame::kYPlane,
110 img->planes[VPX_PLANE_Y],
111 img->stride[VPX_PLANE_Y],
112 img->d_h,
113 decoded_frame.get());
114 CopyPlane(VideoFrame::kUPlane,
115 img->planes[VPX_PLANE_U],
116 img->stride[VPX_PLANE_U],
117 (img->d_h + 1) / 2,
118 decoded_frame.get());
119 CopyPlane(VideoFrame::kVPlane,
120 img->planes[VPX_PLANE_V],
121 img->stride[VPX_PLANE_V],
122 (img->d_h + 1) / 2,
123 decoded_frame.get());
124
125 VLOG(2) << "Decoded frame " << frame_id_int;
126
127 // Update logging from the main thread.
128 cast_environment_->PostTask(CastEnvironment::MAIN,
129 FROM_HERE,
130 base::Bind(&LogFrameDecodedEvent,
131 cast_environment_,
132 cast_environment_->Clock()->NowTicks(),
133 encoded_frame->rtp_timestamp,
134 encoded_frame->frame_id));
135
136 // Used by chrome/browser/extension/api/cast_streaming/performance_test.cc
137 TRACE_EVENT_INSTANT1(
138 "cast_perf_test", "FrameDecoded",
139 TRACE_EVENT_SCOPE_THREAD,
140 "rtp_timestamp", encoded_frame->rtp_timestamp);
141
142 // Frame decoded - return frame to the user via callback.
143 cast_environment_->PostTask(
144 CastEnvironment::MAIN,
145 FROM_HERE,
146 base::Bind(frame_decoded_cb, decoded_frame, render_time));
147
148 return true;
149 }
150
151 } // namespace cast
152 } // namespace media
OLDNEW
« no previous file with comments | « media/cast/video_receiver/codecs/vp8/vp8_decoder.h ('k') | media/cast/video_receiver/codecs/vp8/vp8_decoder.gyp » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698