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

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

Issue 9331003: Improving the decoder pipeline. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Integer ScaleRect Created 8 years, 10 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
« no previous file with comments | « remoting/base/decoder_row_based.h ('k') | remoting/base/decoder_vp8.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) 2012 The Chromium Authors. All rights reserved. 1 // Copyright (c) 2012 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 "remoting/base/decoder_row_based.h" 5 #include "remoting/base/decoder_row_based.h"
6 6
7 #include "base/logging.h" 7 #include "base/logging.h"
8 #include "remoting/base/decompressor.h" 8 #include "remoting/base/decompressor.h"
9 #include "remoting/base/decompressor_zlib.h" 9 #include "remoting/base/decompressor_zlib.h"
10 #include "remoting/base/decompressor_verbatim.h" 10 #include "remoting/base/decompressor_verbatim.h"
(...skipping 16 matching lines...) Expand all
27 VideoPacketFormat::ENCODING_VERBATIM); 27 VideoPacketFormat::ENCODING_VERBATIM);
28 } 28 }
29 29
30 DecoderRowBased::DecoderRowBased(Decompressor* decompressor, 30 DecoderRowBased::DecoderRowBased(Decompressor* decompressor,
31 VideoPacketFormat::Encoding encoding) 31 VideoPacketFormat::Encoding encoding)
32 : state_(kUninitialized), 32 : state_(kUninitialized),
33 clip_(SkIRect::MakeEmpty()), 33 clip_(SkIRect::MakeEmpty()),
34 decompressor_(decompressor), 34 decompressor_(decompressor),
35 encoding_(encoding), 35 encoding_(encoding),
36 row_pos_(0), 36 row_pos_(0),
37 row_y_(0) { 37 row_y_(0),
38 screen_size_(SkISize::Make(0, 0)) {
38 } 39 }
39 40
40 DecoderRowBased::~DecoderRowBased() { 41 DecoderRowBased::~DecoderRowBased() {
41 } 42 }
42 43
43 void DecoderRowBased::Reset() {
44 frame_ = NULL;
45 decompressor_->Reset();
46 state_ = kUninitialized;
47 updated_region_.setEmpty();
48 }
49
50 bool DecoderRowBased::IsReadyForData() { 44 bool DecoderRowBased::IsReadyForData() {
51 switch (state_) { 45 switch (state_) {
52 case kUninitialized: 46 case kUninitialized:
53 case kError: 47 case kError:
54 return false; 48 return false;
55 case kReady: 49 case kReady:
56 case kProcessing: 50 case kProcessing:
57 case kPartitionDone: 51 case kPartitionDone:
58 case kDone: 52 case kDone:
59 return true; 53 return true;
60 } 54 }
61 NOTREACHED(); 55 NOTREACHED();
62 return false; 56 return false;
63 } 57 }
64 58
65 void DecoderRowBased::Initialize(scoped_refptr<media::VideoFrame> frame) { 59 void DecoderRowBased::Initialize(const SkISize& screen_size) {
66 // Make sure we are not currently initialized. 60 decompressor_->Reset();
67 CHECK_EQ(kUninitialized, state_); 61 updated_region_.setEmpty();
62 screen_buffer_.reset(NULL);
68 63
69 if (frame->format() != media::VideoFrame::RGB32) { 64 screen_size_ = screen_size;
70 LOG(WARNING) << "DecoderRowBased only supports RGB32."; 65 // Allocate the screen buffer, if necessary.
71 state_ = kError; 66 if (!screen_size_.isEmpty()) {
72 return; 67 screen_buffer_.reset(new uint8[
68 screen_size_.width() * screen_size_.height() * kBytesPerPixel]);
73 } 69 }
74 70
75 frame_ = frame;
76 state_ = kReady; 71 state_ = kReady;
77 } 72 }
78 73
79 Decoder::DecodeResult DecoderRowBased::DecodePacket(const VideoPacket* packet) { 74 Decoder::DecodeResult DecoderRowBased::DecodePacket(const VideoPacket* packet) {
80 UpdateStateForPacket(packet); 75 UpdateStateForPacket(packet);
81 76
82 if (state_ == kError) { 77 if (state_ == kError) {
83 return DECODE_ERROR; 78 return DECODE_ERROR;
84 } 79 }
85 80
86 const uint8* in = reinterpret_cast<const uint8*>(packet->data().data()); 81 const uint8* in = reinterpret_cast<const uint8*>(packet->data().data());
87 const int in_size = packet->data().size(); 82 const int in_size = packet->data().size();
83 const int row_size = clip_.width() * kBytesPerPixel;
88 84
89 const int row_size = clip_.width() * kBytesPerPixel; 85 int out_stride = screen_size_.width() * kBytesPerPixel;
90 int stride = frame_->stride(media::VideoFrame::kRGBPlane); 86 uint8* out = screen_buffer_.get() + out_stride * (clip_.top() + row_y_) +
91 uint8* rect_begin = frame_->data(media::VideoFrame::kRGBPlane); 87 kBytesPerPixel * clip_.left();
92
93 uint8* out = rect_begin + stride * (clip_.fTop + row_y_) +
94 kBytesPerPixel * clip_.fLeft;
95 88
96 // Consume all the data in the message. 89 // Consume all the data in the message.
97 bool decompress_again = true; 90 bool decompress_again = true;
98 int used = 0; 91 int used = 0;
99 while (decompress_again && used < in_size) { 92 while (decompress_again && used < in_size) {
100 if (row_y_ >= clip_.height()) { 93 if (row_y_ >= clip_.height()) {
101 state_ = kError; 94 state_ = kError;
102 LOG(WARNING) << "Too much data is received for the given rectangle."; 95 LOG(WARNING) << "Too much data is received for the given rectangle.";
103 return DECODE_ERROR; 96 return DECODE_ERROR;
104 } 97 }
105 98
106 int written = 0; 99 int written = 0;
107 int consumed = 0; 100 int consumed = 0;
108 // TODO(ajwong): This assume source and dest stride are the same, which is
109 // incorrect.
110 decompress_again = decompressor_->Process( 101 decompress_again = decompressor_->Process(
111 in + used, in_size - used, out + row_pos_, row_size - row_pos_, 102 in + used, in_size - used, out + row_pos_, row_size - row_pos_,
112 &consumed, &written); 103 &consumed, &written);
113 used += consumed; 104 used += consumed;
114 row_pos_ += written; 105 row_pos_ += written;
115 106
116 // If this row is completely filled then move onto the next row. 107 // If this row is completely filled then move onto the next row.
117 if (row_pos_ == row_size) { 108 if (row_pos_ == row_size) {
118 ++row_y_; 109 ++row_y_;
119 row_pos_ = 0; 110 row_pos_ = 0;
120 out += stride; 111 out += out_stride;
121 } 112 }
122 } 113 }
123 114
124 if (state_ == kPartitionDone || state_ == kDone) { 115 if (state_ == kPartitionDone || state_ == kDone) {
125 if (row_y_ < clip_.height()) { 116 if (row_y_ < clip_.height()) {
126 state_ = kError; 117 state_ = kError;
127 LOG(WARNING) << "Received LAST_PACKET, but didn't get enough data."; 118 LOG(WARNING) << "Received LAST_PACKET, but didn't get enough data.";
128 return DECODE_ERROR; 119 return DECODE_ERROR;
129 } 120 }
130 121
(...skipping 12 matching lines...) Expand all
143 if (state_ == kError) { 134 if (state_ == kError) {
144 return; 135 return;
145 } 136 }
146 137
147 if (packet->flags() & VideoPacket::FIRST_PACKET) { 138 if (packet->flags() & VideoPacket::FIRST_PACKET) {
148 if (state_ != kReady && state_ != kDone && state_ != kPartitionDone) { 139 if (state_ != kReady && state_ != kDone && state_ != kPartitionDone) {
149 state_ = kError; 140 state_ = kError;
150 LOG(WARNING) << "Received unexpected FIRST_PACKET."; 141 LOG(WARNING) << "Received unexpected FIRST_PACKET.";
151 return; 142 return;
152 } 143 }
153 state_ = kProcessing;
154 144
155 // Reset the buffer location status variables on the first packet. 145 // Reset the buffer location status variables on the first packet.
156 clip_.setXYWH(packet->format().x(), packet->format().y(), 146 clip_.setXYWH(packet->format().x(), packet->format().y(),
157 packet->format().width(), packet->format().height()); 147 packet->format().width(), packet->format().height());
148 if (!SkIRect::MakeSize(screen_size_).contains(clip_)) {
149 state_ = kError;
150 LOG(WARNING) << "Invalid clipping area received.";
151 return;
152 }
153
154 state_ = kProcessing;
158 row_pos_ = 0; 155 row_pos_ = 0;
159 row_y_ = 0; 156 row_y_ = 0;
160 } 157 }
161 158
162 if (state_ != kProcessing) { 159 if (state_ != kProcessing) {
163 state_ = kError; 160 state_ = kError;
164 LOG(WARNING) << "Received unexpected packet."; 161 LOG(WARNING) << "Received unexpected packet.";
165 return; 162 return;
166 } 163 }
167 164
(...skipping 11 matching lines...) Expand all
179 state_ = kError; 176 state_ = kError;
180 LOG(WARNING) << "Received unexpected LAST_PARTITION."; 177 LOG(WARNING) << "Received unexpected LAST_PARTITION.";
181 return; 178 return;
182 } 179 }
183 state_ = kDone; 180 state_ = kDone;
184 } 181 }
185 182
186 return; 183 return;
187 } 184 }
188 185
189 void DecoderRowBased::GetUpdatedRegion(SkRegion* region) {
190 region->swap(updated_region_);
191 updated_region_.setEmpty();
192 }
193
194 VideoPacketFormat::Encoding DecoderRowBased::Encoding() { 186 VideoPacketFormat::Encoding DecoderRowBased::Encoding() {
195 return encoding_; 187 return encoding_;
196 } 188 }
197 189
190 void DecoderRowBased::Invalidate(const SkISize& view_size,
191 const SkRegion& region) {
192 updated_region_.op(region, SkRegion::kUnion_Op);
193 }
194
195 void DecoderRowBased::RenderFrame(const SkISize& view_size,
196 const SkIRect& clip_area,
197 uint8* image_buffer,
198 int image_stride,
199 SkRegion* output_region) {
200 output_region->setEmpty();
201
202 // TODO(alexeypa): scaling is not implemented.
203 SkIRect clip_rect = SkIRect::MakeSize(screen_size_);
204 if (!clip_rect.intersect(clip_area))
205 return;
206
207 int screen_stride = screen_size_.width() * kBytesPerPixel;
208
209 for (SkRegion::Iterator i(updated_region_); !i.done(); i.next()) {
210 SkIRect rect(i.rect());
211 if (!rect.intersect(clip_rect))
212 continue;
213
214 CopyRGB32Rect(screen_buffer_.get(), screen_stride,
215 clip_rect,
216 image_buffer, image_stride,
217 clip_area,
218 rect);
219 output_region->op(rect, SkRegion::kUnion_Op);
220 }
221
222 updated_region_.setEmpty();
223 }
224
198 } // namespace remoting 225 } // namespace remoting
OLDNEW
« no previous file with comments | « remoting/base/decoder_row_based.h ('k') | remoting/base/decoder_vp8.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698