- add sources.
[platform/framework/web/crosswalk.git] / src / media / cast / video_receiver / codecs / vp8 / vp8_decoder.cc
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/logging.h"
8 #include "third_party/libvpx/source/libvpx/vpx/vp8dx.h"
9
10 namespace media {
11 namespace cast {
12
13 Vp8Decoder::Vp8Decoder(int number_of_cores) {
14   decoder_.reset(new vpx_dec_ctx_t());
15   InitDecode(number_of_cores);
16 }
17
18 Vp8Decoder::~Vp8Decoder() {}
19
20 void Vp8Decoder::InitDecode(int number_of_cores) {
21   vpx_codec_dec_cfg_t  cfg;
22   cfg.threads = number_of_cores;
23   vpx_codec_flags_t flags = VPX_CODEC_USE_POSTPROC;
24
25   if (vpx_codec_dec_init(decoder_.get(), vpx_codec_vp8_dx(), &cfg, flags)) {
26     DCHECK(false) << "VP8 decode error";
27   }
28 }
29
30 bool Vp8Decoder::Decode(const EncodedVideoFrame& input_image,
31                         I420VideoFrame* decoded_frame) {
32   VLOG(1) << "VP8 decode frame:" << static_cast<int>(input_image.frame_id)
33           << " sized:" << input_image.data.size();
34
35   if (input_image.data.empty()) return false;
36
37   vpx_codec_iter_t iter = NULL;
38   vpx_image_t* img;
39   if (vpx_codec_decode(decoder_.get(),
40                        input_image.data.data(),
41                        static_cast<unsigned int>(input_image.data.size()),
42                        0,
43                        1 /* real time*/)) {
44     VLOG(1) << "Failed to decode VP8 frame.";
45     return false;
46   }
47
48   img = vpx_codec_get_frame(decoder_.get(), &iter);
49   if (img == NULL) {
50     VLOG(1) << "Skip rendering VP8 frame:"
51             << static_cast<int>(input_image.frame_id);
52     return false;
53   }
54
55   // The img is only valid until the next call to vpx_codec_decode.
56   // Populate the decoded image.
57   decoded_frame->width = img->d_w;
58   decoded_frame->height = img->d_h;
59
60   decoded_frame->y_plane.stride = img->stride[VPX_PLANE_Y];
61   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];
63   memcpy(decoded_frame->y_plane.data, img->planes[VPX_PLANE_Y],
64          decoded_frame->y_plane.length);
65
66   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;
68   decoded_frame->u_plane.data = new uint8[decoded_frame->u_plane.length];
69   memcpy(decoded_frame->u_plane.data, img->planes[VPX_PLANE_U],
70          decoded_frame->u_plane.length);
71
72   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;
74   decoded_frame->v_plane.data = new uint8[decoded_frame->v_plane.length];
75
76   memcpy(decoded_frame->v_plane.data, img->planes[VPX_PLANE_V],
77          decoded_frame->v_plane.length);
78
79   return true;
80 }
81
82 }  // namespace cast
83 }  // namespace media
84