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

Side by Side Diff: remoting/base/encoder_vp8.cc

Issue 4255001: Revert 64672 - Cleanups in the video encoding decoding code. Reenable VP8.... (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src/
Patch Set: Created 10 years, 1 month 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
« no previous file with comments | « remoting/base/encoder_verbatim.cc ('k') | remoting/base/encoder_zlib.h » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright (c) 2010 The Chromium Authors. All rights reserved. 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 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 "base/logging.h" 5 #include "base/logging.h"
6 #include "media/base/callback.h" 6 #include "media/base/callback.h"
7 #include "media/base/data_buffer.h" 7 #include "media/base/data_buffer.h"
8 #include "media/base/media.h" 8 #include "media/base/media.h"
9 #include "remoting/base/capture_data.h" 9 #include "remoting/base/capture_data.h"
10 #include "remoting/base/encoder_vp8.h" 10 #include "remoting/base/encoder_vp8.h"
(...skipping 30 matching lines...) Expand all
41 41
42 // libvpx seems to require both to be assigned. 42 // libvpx seems to require both to be assigned.
43 image_->d_w = width; 43 image_->d_w = width;
44 image_->w = width; 44 image_->w = width;
45 image_->d_h = height; 45 image_->d_h = height;
46 image_->h = height; 46 image_->h = height;
47 47
48 vpx_codec_enc_cfg_t config; 48 vpx_codec_enc_cfg_t config;
49 const vpx_codec_iface_t* algo = 49 const vpx_codec_iface_t* algo =
50 (const vpx_codec_iface_t*)media::GetVp8CxAlgoAddress(); 50 (const vpx_codec_iface_t*)media::GetVp8CxAlgoAddress();
51 CHECK(algo);
52 vpx_codec_err_t ret = vpx_codec_enc_config_default(algo, &config, 0); 51 vpx_codec_err_t ret = vpx_codec_enc_config_default(algo, &config, 0);
53 if (ret != VPX_CODEC_OK) 52 if (ret != VPX_CODEC_OK)
54 return false; 53 return false;
55 54
56 // TODO(hclam): Tune the parameters to better suit the application. 55 // TODO(hclam): Tune the parameters to better suit the application.
57 config.rc_target_bitrate = width * height * config.rc_target_bitrate 56 config.rc_target_bitrate = width * height * config.rc_target_bitrate
58 / config.g_w / config.g_h; 57 / config.g_w / config.g_h;
59 config.g_w = width; 58 config.g_w = width;
60 config.g_h = height; 59 config.g_h = height;
61 config.g_pass = VPX_RC_ONE_PASS; 60 config.g_pass = VPX_RC_ONE_PASS;
62 config.g_profile = 1; 61 config.g_profile = 1;
63 config.g_threads = 2; 62 config.g_threads = 2;
64 config.rc_min_quantizer = 0; 63 config.rc_min_quantizer = 0;
65 config.rc_max_quantizer = 15; 64 config.rc_max_quantizer = 15;
66 config.g_timebase.num = 1; 65 config.g_timebase.num = 1;
67 config.g_timebase.den = 30; 66 config.g_timebase.den = 30;
68 67
69 if (vpx_codec_enc_init(codec_.get(), algo, &config, 0)) 68 if (vpx_codec_enc_init(codec_.get(), algo, &config, 0))
70 return false; 69 return false;
71 return true; 70 return true;
72 } 71 }
73 72
74 static int clip_byte(int x) {
75 if (x > 255)
76 return 255;
77 else if (x < 0)
78 return 0;
79 else
80 return x;
81 }
82
83 bool EncoderVp8::PrepareImage(scoped_refptr<CaptureData> capture_data) { 73 bool EncoderVp8::PrepareImage(scoped_refptr<CaptureData> capture_data) {
84 const int plane_size = capture_data->width() * capture_data->height();
85
86 if (!yuv_image_.get()) { 74 if (!yuv_image_.get()) {
75 const int plane_size = capture_data->width() * capture_data->height();
87 76
88 // YUV image size is 1.5 times of a plane. Multiplication is performed first 77 // YUV image size is 1.5 times of a plane. Multiplication is performed first
89 // to avoid rounding error. 78 // to avoid rounding error.
90 const int size = plane_size * 3 / 2; 79 const int size = plane_size * 3 / 2;
91 80
92 yuv_image_.reset(new uint8[size]); 81 yuv_image_.reset(new uint8[size]);
93 82
94 // Reset image value to 128 so we just need to fill in the y plane. 83 // Reset image value to 128 so we just need to fill in the y plane.
95 memset(yuv_image_.get(), 128, size); 84 memset(yuv_image_.get(), 128, size);
96 85
97 // Fill in the information for |image_|. 86 // Fill in the information for |image_|.
98 unsigned char* image = reinterpret_cast<unsigned char*>(yuv_image_.get()); 87 unsigned char* image = reinterpret_cast<unsigned char*>(yuv_image_.get());
99 image_->planes[0] = image; 88 image_->planes[0] = image;
100 image_->planes[1] = image + plane_size; 89 image_->planes[1] = image + plane_size;
101 90
102 // The V plane starts from 1.25 of the plane size. 91 // The V plane starts from 1.25 of the plane size.
103 image_->planes[2] = image + plane_size + plane_size / 4; 92 image_->planes[2] = image + plane_size + plane_size / 4;
104 93
105 // In YV12 Y plane has full width, UV plane has half width because of 94 // In YV12 Y plane has full width, UV plane has half width because of
106 // subsampling. 95 // subsampling.
107 image_->stride[0] = image_->w; 96 image_->stride[0] = image_->w;
108 image_->stride[1] = image_->w / 2; 97 image_->stride[1] = image_->w / 2;
109 image_->stride[2] = image_->w / 2; 98 image_->stride[2] = image_->w / 2;
110 } 99 }
111 100
112 // And then do RGB->YUV conversion. 101 // And then do RGB->YUV conversion.
113 // Currently we just produce the Y channel as the average of RGB. This will 102 // Currently we just produce the Y channel as the average of RGB. This will
114 // giv ae gray scale image after conversion. 103 // give a gray scale image after conversion.
115 // TODO(sergeyu): Move this code to a separate routine. 104 // TODO(hclam): Implement the actual color space conversion.
116 // TODO(sergeyu): Optimize this code. 105 DCHECK(capture_data->pixel_format() == PixelFormatRgb32)
117 DCHECK(capture_data->pixel_format() == PIXEL_FORMAT_RGB32)
118 << "Only RGB32 is supported"; 106 << "Only RGB32 is supported";
119 uint8* in = capture_data->data_planes().data[0]; 107 uint8* in = capture_data->data_planes().data[0];
120 const int in_stride = capture_data->data_planes().strides[0]; 108 const int in_stride = capture_data->data_planes().strides[0];
121 uint8* y_out = yuv_image_.get(); 109 uint8* out = yuv_image_.get();
122 uint8* u_out = yuv_image_.get() + plane_size;
123 uint8* v_out = yuv_image_.get() + plane_size + plane_size / 4;
124 const int out_stride = image_->stride[0]; 110 const int out_stride = image_->stride[0];
125 for (int i = 0; i < capture_data->height(); ++i) { 111 for (int i = 0; i < capture_data->height(); ++i) {
126 for (int j = 0; j < capture_data->width(); ++j) { 112 for (int j = 0; j < capture_data->width(); ++j) {
127 // Since the input pixel format is RGB32, there are 4 bytes per pixel. 113 // Since the input pixel format is RGB32, there are 4 bytes per pixel.
128 uint8* pixel = in + 4 * j; 114 uint8* pixel = in + 4 * j;
129 y_out[j] = clip_byte(((pixel[0] * 66 + pixel[1] * 129 + 115 out[j] = (pixel[0] + pixel[1] + pixel[2]) / 3;
130 pixel[2] * 25 + 128) >> 8) + 16);
131 if (i % 2 == 0 && j % 2 == 0) {
132 u_out[j / 2] = clip_byte(((pixel[0] * -38 + pixel[1] * -74 +
133 pixel[2] * 112 + 128) >> 8) + 128);
134 v_out[j / 2] = clip_byte(((pixel[0] * 112 + pixel[1] * -94 +
135 pixel[2] * -18 + 128) >> 8) + 128);
136 }
137 } 116 }
138 in += in_stride; 117 in += in_stride;
139 y_out += out_stride; 118 out += out_stride;
140 if (i % 2 == 0) {
141 u_out += out_stride / 2;
142 v_out += out_stride / 2;
143 }
144 } 119 }
145 return true; 120 return true;
146 } 121 }
147 122
148 void EncoderVp8::Encode(scoped_refptr<CaptureData> capture_data, 123 void EncoderVp8::Encode(scoped_refptr<CaptureData> capture_data,
149 bool key_frame, 124 bool key_frame,
150 DataAvailableCallback* data_available_callback) { 125 DataAvailableCallback* data_available_callback) {
151 if (!initialized_) { 126 if (!initialized_) {
152 bool ret = Init(capture_data->width(), capture_data->height()); 127 bool ret = Init(capture_data->width(), capture_data->height());
153 // TODO(hclam): Handle error better. 128 // TODO(hclam): Handle error better.
154 DCHECK(ret) << "Initialization of encoder failed"; 129 DCHECK(ret) << "Initialization of encoder failed";
155 initialized_ = ret; 130 initialized_ = ret;
156 } 131 }
157 132
158 if (!PrepareImage(capture_data)) { 133 if (!PrepareImage(capture_data)) {
159 NOTREACHED() << "Can't image data for encoding"; 134 NOTREACHED() << "Can't image data for encoding";
160 } 135 }
161 136
162 // Do the actual encoding. 137 // Do the actual encoding.
163 vpx_codec_err_t ret = vpx_codec_encode(codec_.get(), image_.get(), 138 vpx_codec_err_t ret = vpx_codec_encode(codec_.get(), image_.get(),
164 last_timestamp_, 139 last_timestamp_,
165 1, 0, VPX_DL_REALTIME); 140 1, 0, VPX_DL_REALTIME);
166 DCHECK_EQ(ret, VPX_CODEC_OK) 141 DCHECK(ret == VPX_CODEC_OK) << "Encoding error: "
167 << "Encoding error: " << vpx_codec_err_to_string(ret) << "\n" 142 << vpx_codec_err_to_string(ret)
168 << "Details: " << vpx_codec_error(codec_.get()) << "\n" 143 << "\n"
169 << vpx_codec_error_detail(codec_.get()); 144 << "Details: "
145 << vpx_codec_error(codec_.get())
146 << "\n"
147 << vpx_codec_error_detail(codec_.get());
170 148
171 // TODO(hclam): fix this. 149 // TODO(hclam): fix this.
172 last_timestamp_ += 100; 150 last_timestamp_ += 100;
173 151
174 // Read the encoded data. 152 // Read the encoded data.
175 vpx_codec_iter_t iter = NULL; 153 vpx_codec_iter_t iter = NULL;
176 bool got_data = false; 154 bool got_data = false;
177 155
178 // TODO(hclam): Make sure we get exactly one frame from the packet. 156 // TODO(hclam): Make sure we get exactly one frame from the packet.
179 // TODO(hclam): We should provide the output buffer to avoid one copy. 157 // TODO(hclam): We should provide the output buffer to avoid one copy.
180 VideoPacket* message = new VideoPacket(); 158 ChromotingHostMessage* message = new ChromotingHostMessage();
159 UpdateStreamPacketMessage* packet = message->mutable_update_stream_packet();
160
161 // Prepare the begin rect.
162 packet->mutable_begin_rect()->set_x(0);
163 packet->mutable_begin_rect()->set_y(0);
164 packet->mutable_begin_rect()->set_width(capture_data->width());
165 packet->mutable_begin_rect()->set_height(capture_data->height());
166 packet->mutable_begin_rect()->set_encoding(EncodingVp8);
167 packet->mutable_begin_rect()->set_pixel_format(PixelFormatYv12);
181 168
182 while (!got_data) { 169 while (!got_data) {
183 const vpx_codec_cx_pkt_t* packet = vpx_codec_get_cx_data(codec_.get(), 170 const vpx_codec_cx_pkt_t* packet = vpx_codec_get_cx_data(codec_.get(),
184 &iter); 171 &iter);
185 if (!packet) 172 if (!packet)
186 continue; 173 continue;
187 174
188 switch (packet->kind) { 175 switch (packet->kind) {
189 case VPX_CODEC_CX_FRAME_PKT: 176 case VPX_CODEC_CX_FRAME_PKT:
190 got_data = true; 177 got_data = true;
191 message->set_data( 178 message->mutable_update_stream_packet()->mutable_rect_data()->set_data(
192 packet->data.frame.buf, packet->data.frame.sz); 179 packet->data.frame.buf, packet->data.frame.sz);
193 break; 180 break;
194 default: 181 default:
195 break; 182 break;
196 } 183 }
197 } 184 }
198 185
199 message->mutable_format()->set_encoding(VideoPacketFormat::ENCODING_VP8); 186 // Enter the end rect.
200 message->set_flags(VideoPacket::FIRST_PACKET | VideoPacket::LAST_PACKET); 187 message->mutable_update_stream_packet()->mutable_end_rect();
201 message->mutable_format()->set_pixel_format(PIXEL_FORMAT_RGB32); 188 data_available_callback->Run(
202 message->mutable_format()->set_x(0); 189 message,
203 message->mutable_format()->set_y(0); 190 EncodingStarting | EncodingInProgress | EncodingEnded);
204 message->mutable_format()->set_width(capture_data->width());
205 message->mutable_format()->set_height(capture_data->height());
206
207 data_available_callback->Run(message);
208 delete data_available_callback; 191 delete data_available_callback;
209 } 192 }
210 193
211 } // namespace remoting 194 } // namespace remoting
OLDNEW
« no previous file with comments | « remoting/base/encoder_verbatim.cc ('k') | remoting/base/encoder_zlib.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698