OLD | NEW |
(Empty) | |
| 1 // Copyright (c) 2010 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 "base/logging.h" |
| 6 #include "media/base/callback.h" |
| 7 #include "media/base/data_buffer.h" |
| 8 #include "remoting/host/encoder_vp8.h" |
| 9 |
| 10 extern "C" { |
| 11 // TODO(garykac): Rix with correct path to vp8 header. |
| 12 #include "remoting/third_party/on2/include/vp8cx.h" |
| 13 } |
| 14 |
| 15 namespace remoting { |
| 16 |
| 17 EncoderVp8::EncoderVp8() |
| 18 : initialized_(false), |
| 19 last_timestamp_(0) { |
| 20 } |
| 21 |
| 22 EncoderVp8::~EncoderVp8() { |
| 23 } |
| 24 |
| 25 bool EncoderVp8::Init() { |
| 26 // TODO(hclam): Now always assume we receive YV12. May need to extend this |
| 27 // so we can do color space conversion manually. |
| 28 image_.fmt = IMG_FMT_YV12; |
| 29 image_.w = width_; |
| 30 image_.h = height_; |
| 31 |
| 32 on2_codec_enc_cfg_t config; |
| 33 on2_codec_err_t result = on2_codec_enc_config_default(&on2_codec_vp8_cx_algo, |
| 34 &config, 0); |
| 35 |
| 36 // TODO(hclam): Adjust the parameters. |
| 37 config.g_w = width_; |
| 38 config.g_h = height_; |
| 39 config.g_pass = ON2_RC_ONE_PASS; |
| 40 config.g_profile = 1; |
| 41 config.g_threads = 2; |
| 42 config.rc_target_bitrate = 1000000; |
| 43 config.rc_min_quantizer = 0; |
| 44 config.rc_max_quantizer = 15; |
| 45 config.g_timebase.num = 1; |
| 46 config.g_timebase.den = 30; |
| 47 |
| 48 if (on2_codec_enc_init(&codec_, &on2_codec_vp8_cx_algo, &config, 0)) |
| 49 return false; |
| 50 |
| 51 on2_codec_control_(&codec_, VP8E_SET_CPUUSED, -15); |
| 52 return true; |
| 53 } |
| 54 |
| 55 void EncoderVp8::Encode(const DirtyRects& dirty_rects, |
| 56 const uint8** input_data, |
| 57 const int* strides, |
| 58 bool key_frame, |
| 59 chromotocol_pb::UpdateStreamPacketHeader* header, |
| 60 scoped_refptr<media::DataBuffer>* output_data, |
| 61 bool* encode_done, |
| 62 Task* data_available_task) { |
| 63 // This will allow the task be called when this method exits. |
| 64 media::AutoTaskRunner task(data_available_task); |
| 65 *encode_done = false; |
| 66 |
| 67 // TODO(hclam): We only initialize the encoder once. We may have to |
| 68 // allow encoder be initialized with difference sizes. |
| 69 if (!initialized_) { |
| 70 if (!Init()) { |
| 71 LOG(ERROR) << "Can't initialize VP8 encoder"; |
| 72 return; |
| 73 } |
| 74 initialized_ = true; |
| 75 } |
| 76 |
| 77 // Assume the capturer has done the color space conversion. |
| 78 if (!input_data || !strides) |
| 79 return; |
| 80 |
| 81 image_.planes[0] = (unsigned char*)input_data[0]; |
| 82 image_.planes[1] = (unsigned char*)input_data[1]; |
| 83 image_.planes[2] = (unsigned char*)input_data[2]; |
| 84 image_.stride[0] = strides[0]; |
| 85 image_.stride[1] = strides[1]; |
| 86 image_.stride[2] = strides[2]; |
| 87 |
| 88 // Do the actual encoding. |
| 89 if (on2_codec_encode(&codec_, &image_, |
| 90 last_timestamp_, 1, 0, ON2_DL_REALTIME)) { |
| 91 return; |
| 92 } |
| 93 |
| 94 // TODO(hclam): fix this. |
| 95 last_timestamp_ += 100; |
| 96 |
| 97 // Read the encoded data. |
| 98 on2_codec_iter_t iter = NULL; |
| 99 bool got_data = false; |
| 100 |
| 101 // TODO(hclam: We assume one frame of input will get exactly one frame of |
| 102 // output. This assumption may not be valid. |
| 103 while (!got_data) { |
| 104 on2_codec_cx_pkt_t* packet = on2_codec_get_cx_data(&codec_, &iter); |
| 105 if (!packet) |
| 106 continue; |
| 107 |
| 108 switch (packet->kind) { |
| 109 case ON2_CODEC_CX_FRAME_PKT: |
| 110 got_data = true; |
| 111 *encode_done = true; |
| 112 *output_data = new media::DataBuffer(packet->data.frame.sz); |
| 113 memcpy((*output_data)->GetWritableData(), |
| 114 packet->data.frame.buf, |
| 115 packet->data.frame.sz); |
| 116 break; |
| 117 default: |
| 118 break; |
| 119 } |
| 120 } |
| 121 return; |
| 122 } |
| 123 |
| 124 void EncoderVp8::SetSize(int width, int height) { |
| 125 width_ = width; |
| 126 height_ = height; |
| 127 } |
| 128 |
| 129 void EncoderVp8::SetPixelFormat(PixelFormat pixel_format) { |
| 130 pixel_format_ = pixel_format; |
| 131 } |
| 132 |
| 133 } // namespace remoting |
OLD | NEW |