OLD | NEW |
---|---|
1 // Copyright 2013 The Chromium Authors. All rights reserved. | 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 | 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/cast/video_receiver/codecs/vp8/vp8_decoder.h" | 5 #include "media/cast/video_receiver/codecs/vp8/vp8_decoder.h" |
6 | 6 |
7 #include "base/bind.h" | |
7 #include "base/logging.h" | 8 #include "base/logging.h" |
9 #include "base/message_loop/message_loop.h" | |
8 #include "third_party/libvpx/source/libvpx/vpx/vp8dx.h" | 10 #include "third_party/libvpx/source/libvpx/vpx/vp8dx.h" |
9 | 11 |
10 namespace media { | 12 namespace media { |
11 namespace cast { | 13 namespace cast { |
12 | 14 |
13 Vp8Decoder::Vp8Decoder(int number_of_cores) { | 15 Vp8Decoder::Vp8Decoder(int number_of_cores, |
14 decoder_.reset(new vpx_dec_ctx_t()); | 16 scoped_refptr<CastEnvironment> cast_environment) |
17 : decoder_(new vpx_dec_ctx_t()), | |
18 cast_environment_(cast_environment) { | |
15 InitDecode(number_of_cores); | 19 InitDecode(number_of_cores); |
16 } | 20 } |
17 | 21 |
18 Vp8Decoder::~Vp8Decoder() {} | 22 Vp8Decoder::~Vp8Decoder() {} |
19 | 23 |
20 void Vp8Decoder::InitDecode(int number_of_cores) { | 24 void Vp8Decoder::InitDecode(int number_of_cores) { |
21 vpx_codec_dec_cfg_t cfg; | 25 vpx_codec_dec_cfg_t cfg; |
22 cfg.threads = number_of_cores; | 26 cfg.threads = number_of_cores; |
23 vpx_codec_flags_t flags = VPX_CODEC_USE_POSTPROC; | 27 vpx_codec_flags_t flags = VPX_CODEC_USE_POSTPROC; |
24 | 28 |
25 if (vpx_codec_dec_init(decoder_.get(), vpx_codec_vp8_dx(), &cfg, flags)) { | 29 if (vpx_codec_dec_init(decoder_.get(), vpx_codec_vp8_dx(), &cfg, flags)) { |
26 DCHECK(false) << "VP8 decode error"; | 30 DCHECK(false) << "VP8 decode error"; |
27 } | 31 } |
28 } | 32 } |
29 | 33 |
30 bool Vp8Decoder::Decode(const EncodedVideoFrame& input_image, | 34 bool Vp8Decoder::Decode(const EncodedVideoFrame* encoded_frame, |
31 I420VideoFrame* decoded_frame) { | 35 const base::TimeTicks render_time, |
32 VLOG(1) << "VP8 decode frame:" << static_cast<int>(input_image.frame_id) | 36 const VideoFrameDecodedCallback& |
33 << " sized:" << input_image.data.size(); | 37 frame_decoded_callback) { |
38 VLOG(1) << "VP8 decode frame:" << static_cast<int>(encoded_frame->frame_id) | |
Alpha Left Google
2013/11/06 02:22:06
There's 3 static_cast<int> for the frame id. I'd d
mikhal
2013/11/06 18:29:16
Done.
| |
39 << " sized:" << encoded_frame->data.size(); | |
34 | 40 |
35 if (input_image.data.empty()) return false; | 41 if (encoded_frame->data.empty()) return false; |
36 | 42 |
37 vpx_codec_iter_t iter = NULL; | 43 vpx_codec_iter_t iter = NULL; |
38 vpx_image_t* img; | 44 vpx_image_t* img; |
39 if (vpx_codec_decode(decoder_.get(), | 45 if (vpx_codec_decode(decoder_.get(), |
40 input_image.data.data(), | 46 encoded_frame->data.data(), |
41 static_cast<unsigned int>(input_image.data.size()), | 47 static_cast<unsigned int>(encoded_frame->data.size()), |
42 0, | 48 0, |
43 1 /* real time*/)) { | 49 1 /* real time*/)) { |
44 VLOG(1) << "Failed to decode VP8 frame."; | 50 VLOG(1) << "Failed to decode VP8 frame."; |
45 return false; | 51 return false; |
46 } | 52 } |
47 | 53 |
48 img = vpx_codec_get_frame(decoder_.get(), &iter); | 54 img = vpx_codec_get_frame(decoder_.get(), &iter); |
49 if (img == NULL) { | 55 if (img == NULL) { |
50 VLOG(1) << "Skip rendering VP8 frame:" | 56 VLOG(1) << "Skip rendering VP8 frame:" |
51 << static_cast<int>(input_image.frame_id); | 57 << static_cast<int>(encoded_frame->frame_id); |
52 return false; | 58 return false; |
53 } | 59 } |
54 | 60 |
61 scoped_ptr<I420VideoFrame> decoded_frame(new I420VideoFrame()); | |
62 | |
55 // The img is only valid until the next call to vpx_codec_decode. | 63 // The img is only valid until the next call to vpx_codec_decode. |
56 // Populate the decoded image. | 64 // Populate the decoded image. |
57 decoded_frame->width = img->d_w; | 65 decoded_frame->width = img->d_w; |
58 decoded_frame->height = img->d_h; | 66 decoded_frame->height = img->d_h; |
59 | 67 |
60 decoded_frame->y_plane.stride = img->stride[VPX_PLANE_Y]; | 68 decoded_frame->y_plane.stride = img->stride[VPX_PLANE_Y]; |
61 decoded_frame->y_plane.length = img->stride[VPX_PLANE_Y] * img->d_h; | 69 decoded_frame->y_plane.length = img->stride[VPX_PLANE_Y] * img->d_h; |
62 decoded_frame->y_plane.data = new uint8[decoded_frame->y_plane.length]; | 70 decoded_frame->y_plane.data = new uint8[decoded_frame->y_plane.length]; |
63 memcpy(decoded_frame->y_plane.data, img->planes[VPX_PLANE_Y], | 71 memcpy(decoded_frame->y_plane.data, img->planes[VPX_PLANE_Y], |
64 decoded_frame->y_plane.length); | 72 decoded_frame->y_plane.length); |
65 | 73 |
66 decoded_frame->u_plane.stride = img->stride[VPX_PLANE_U]; | 74 decoded_frame->u_plane.stride = img->stride[VPX_PLANE_U]; |
67 decoded_frame->u_plane.length = img->stride[VPX_PLANE_U] * (img->d_h + 1) / 2; | 75 decoded_frame->u_plane.length = img->stride[VPX_PLANE_U] * (img->d_h + 1) / 2; |
68 decoded_frame->u_plane.data = new uint8[decoded_frame->u_plane.length]; | 76 decoded_frame->u_plane.data = new uint8[decoded_frame->u_plane.length]; |
69 memcpy(decoded_frame->u_plane.data, img->planes[VPX_PLANE_U], | 77 memcpy(decoded_frame->u_plane.data, img->planes[VPX_PLANE_U], |
70 decoded_frame->u_plane.length); | 78 decoded_frame->u_plane.length); |
71 | 79 |
72 decoded_frame->v_plane.stride = img->stride[VPX_PLANE_V]; | 80 decoded_frame->v_plane.stride = img->stride[VPX_PLANE_V]; |
73 decoded_frame->v_plane.length = img->stride[VPX_PLANE_V] * (img->d_h + 1) / 2; | 81 decoded_frame->v_plane.length = img->stride[VPX_PLANE_V] * (img->d_h + 1) / 2; |
74 decoded_frame->v_plane.data = new uint8[decoded_frame->v_plane.length]; | 82 decoded_frame->v_plane.data = new uint8[decoded_frame->v_plane.length]; |
75 | 83 |
76 memcpy(decoded_frame->v_plane.data, img->planes[VPX_PLANE_V], | 84 memcpy(decoded_frame->v_plane.data, img->planes[VPX_PLANE_V], |
77 decoded_frame->v_plane.length); | 85 decoded_frame->v_plane.length); |
78 | 86 |
87 // Return frame. | |
88 VLOG(1) << "Decoded frame " << static_cast<int>(encoded_frame->frame_id); | |
89 // Frame decoded - return frame to the user via callback. | |
90 cast_environment_->PostTask(CastEnvironment::MAIN, FROM_HERE, | |
91 base::Bind(frame_decoded_callback, | |
92 base::Passed(&decoded_frame), render_time)); | |
93 | |
79 return true; | 94 return true; |
80 } | 95 } |
81 | 96 |
82 } // namespace cast | 97 } // namespace cast |
83 } // namespace media | 98 } // namespace media |
84 | 99 |
OLD | NEW |