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

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

Issue 4476003: Add VideoPacket struct for video packets. Refactor Decode interface to use it. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: merged 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/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) 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 "remoting/base/decoder_row_based.h" 5 #include "remoting/base/decoder_row_based.h"
6 6
7 #include "remoting/base/decompressor.h" 7 #include "remoting/base/decompressor.h"
8 #include "remoting/base/decompressor_zlib.h" 8 #include "remoting/base/decompressor_zlib.h"
9 #include "remoting/base/decompressor_verbatim.h" 9 #include "remoting/base/decompressor_verbatim.h"
10 #include "remoting/base/util.h" 10 #include "remoting/base/util.h"
11 11
12 namespace remoting { 12 namespace remoting {
13 13
14 namespace {
15 // Both input and output data are assumed to be RGBA32.
16 const int kBytesPerPixel = 4;
17 }
18
14 DecoderRowBased* DecoderRowBased::CreateZlibDecoder() { 19 DecoderRowBased* DecoderRowBased::CreateZlibDecoder() {
15 return new DecoderRowBased(new DecompressorZlib(), 20 return new DecoderRowBased(new DecompressorZlib(),
16 VideoPacketFormat::ENCODING_ZLIB); 21 VideoPacketFormat::ENCODING_ZLIB);
17 } 22 }
18 23
19 DecoderRowBased* DecoderRowBased::CreateVerbatimDecoder() { 24 DecoderRowBased* DecoderRowBased::CreateVerbatimDecoder() {
20 return new DecoderRowBased(new DecompressorVerbatim(), 25 return new DecoderRowBased(new DecompressorVerbatim(),
21 VideoPacketFormat::ENCODING_VERBATIM); 26 VideoPacketFormat::ENCODING_VERBATIM);
22 } 27 }
23 28
24 DecoderRowBased::DecoderRowBased(Decompressor* decompressor, 29 DecoderRowBased::DecoderRowBased(Decompressor* decompressor,
25 VideoPacketFormat::Encoding encoding) 30 VideoPacketFormat::Encoding encoding)
26 : state_(kUninitialized), 31 : state_(kUninitialized),
27 decompressor_(decompressor), 32 decompressor_(decompressor),
28 encoding_(encoding), 33 encoding_(encoding),
29 bytes_per_src_pixel_(0),
30 row_pos_(0), 34 row_pos_(0),
31 row_y_(0), 35 row_y_(0),
32 // TODO(hclam): We should use the information from the update stream 36 // TODO(hclam): We should use the information from the update stream
33 // to determine whether we should reverse the rows or not. 37 // to determine whether we should reverse the rows or not.
34 // But for simplicity we set to be always true. 38 // But for simplicity we set to be always true.
35 reverse_rows_(true) { 39 reverse_rows_(true) {
36 } 40 }
37 41
38 DecoderRowBased::~DecoderRowBased() { 42 DecoderRowBased::~DecoderRowBased() {
39 } 43 }
40 44
41 void DecoderRowBased::Reset() { 45 void DecoderRowBased::Reset() {
42 frame_ = NULL; 46 frame_ = NULL;
43 decompressor_->Reset(); 47 decompressor_->Reset();
44 state_ = kUninitialized; 48 state_ = kUninitialized;
45 } 49 }
46 50
47 bool DecoderRowBased::IsReadyForData() { 51 bool DecoderRowBased::IsReadyForData() {
48 return state_ == kReady; 52 return state_ == kReady || state_ == kProcessing || state_ == kDone;
49 } 53 }
50 54
51 void DecoderRowBased::Initialize(scoped_refptr<media::VideoFrame> frame, 55 void DecoderRowBased::Initialize(scoped_refptr<media::VideoFrame> frame) {
52 const gfx::Rect& clip,
53 int bytes_per_src_pixel) {
54 // Make sure we are not currently initialized. 56 // Make sure we are not currently initialized.
55 CHECK_EQ(kUninitialized, state_); 57 CHECK_EQ(kUninitialized, state_);
56 58
57 if (static_cast<PixelFormat>(frame->format()) != PIXEL_FORMAT_RGB32) { 59 if (frame->format() != media::VideoFrame::RGB32) {
58 LOG(WARNING) << "DecoderRowBased only supports RGB32."; 60 LOG(WARNING) << "DecoderRowBased only supports RGB32.";
59 state_ = kError; 61 state_ = kError;
60 return; 62 return;
61 } 63 }
62 64
63 frame_ = frame; 65 frame_ = frame;
64
65 // Reset the buffer location status variables.
66 clip_ = clip;
67 row_pos_ = 0;
68 row_y_ = 0;
69 bytes_per_src_pixel_ = bytes_per_src_pixel;
70
71 state_ = kReady; 66 state_ = kReady;
72 } 67 }
73 68
74 void DecoderRowBased::DecodeBytes(const std::string& encoded_bytes) { 69 Decoder::DecodeResult DecoderRowBased::DecodePacket(
75 DCHECK_EQ(kReady, state_); 70 const VideoPacket* packet) {
71 UpdateStateForPacket(packet);
76 72
77 const uint8* in = reinterpret_cast<const uint8*>(encoded_bytes.data()); 73 if (state_ == kError) {
78 const int in_size = encoded_bytes.size(); 74 return DECODE_ERROR;
79 const int row_size = clip_.width() * bytes_per_src_pixel_; 75 }
76
77 const uint8* in = reinterpret_cast<const uint8*>(packet->data().data());
78 const int in_size = packet->data().size();
79
80 const int row_size = clip_.width() * kBytesPerPixel;
80 int stride = frame_->stride(media::VideoFrame::kRGBPlane); 81 int stride = frame_->stride(media::VideoFrame::kRGBPlane);
81 uint8* rect_begin = frame_->data(media::VideoFrame::kRGBPlane); 82 uint8* rect_begin = frame_->data(media::VideoFrame::kRGBPlane);
82 83
83 if (reverse_rows_) { 84 if (reverse_rows_) {
84 // Advance the pointer to the last row. 85 // Advance the pointer to the last row.
85 rect_begin += (frame_->height() - 1) * stride; 86 rect_begin += (frame_->height() - 1) * stride;
86 87
87 // And then make the stride negative. 88 // And then make the stride negative.
88 stride = -stride; 89 stride = -stride;
89 } 90 }
90 91
91 // TODO(ajwong): This should be bytes_per_dst_pixel shouldn't this.? 92 uint8* out = rect_begin + stride * (clip_.y() + row_y_) +
92 uint8* out = rect_begin + 93 kBytesPerPixel * clip_.x();
93 stride * (clip_.y() + row_y_) +
94 bytes_per_src_pixel_ * clip_.x();
95 94
96 // Consume all the data in the message. 95 // Consume all the data in the message.
97 bool decompress_again = true; 96 bool decompress_again = true;
98 int used = 0; 97 int used = 0;
99 while (decompress_again && used < in_size) { 98 while (decompress_again && used < in_size) {
99 if (row_y_ >= clip_.height()) {
100 state_ = kError;
101 LOG(WARNING) << "Too much data is received for the given rectangle.";
102 return DECODE_ERROR;
103 }
104
100 int written = 0; 105 int written = 0;
101 int consumed = 0; 106 int consumed = 0;
102 // TODO(ajwong): This assume source and dest stride are the same, which is 107 // TODO(ajwong): This assume source and dest stride are the same, which is
103 // incorrect. 108 // incorrect.
104 decompress_again = decompressor_->Process( 109 decompress_again = decompressor_->Process(
105 in + used, in_size - used, out + row_pos_, row_size - row_pos_, 110 in + used, in_size - used, out + row_pos_, row_size - row_pos_,
106 &consumed, &written); 111 &consumed, &written);
107 used += consumed; 112 used += consumed;
108 row_pos_ += written; 113 row_pos_ += written;
109 114
110 // If this row is completely filled then move onto the next row. 115 // If this row is completely filled then move onto the next row.
111 if (row_pos_ == row_size) { 116 if (row_pos_ == row_size) {
112 ++row_y_; 117 ++row_y_;
113 row_pos_ = 0; 118 row_pos_ = 0;
114 out += stride; 119 out += stride;
115 } 120 }
116 } 121 }
122
123 if (state_ == kDone && row_y_ < clip_.height()) {
124 state_ = kError;
125 LOG(WARNING) << "Received LAST_PACKET, but didn't get enough data.";
126 return DECODE_ERROR;
127 }
128
129 return state_ == kDone ? DECODE_DONE : DECODE_IN_PROGRESS;
130 }
131
132 void DecoderRowBased::UpdateStateForPacket(const VideoPacket* packet) {
133 if (state_ == kError) {
134 return;
135 }
136
137 if (packet->flags() & VideoPacket::FIRST_PACKET) {
138 if (state_ != kReady && state_ != kDone) {
139 state_ = kError;
140 LOG(WARNING) << "Received unexpected FIRST_PACKET.";
141 return;
142 }
143 state_ = kProcessing;
144
145 // Reset the buffer location status variables on the first packet.
146 clip_.SetRect(packet->format().x(), packet->format().y(),
147 packet->format().width(), packet->format().height());
148 row_pos_ = 0;
149 row_y_ = 0;
150 }
151
152 if (state_ != kProcessing) {
153 state_ = kError;
154 LOG(WARNING) << "Received unexpected packet.";
155 return;
156 }
157
158 if (packet->flags() & VideoPacket::LAST_PACKET) {
159 if (state_ != kProcessing) {
160 state_ = kError;
161 LOG(WARNING) << "Received unexpected LAST_PACKET.";
162 return;
163 }
164 state_ = kDone;
165 }
166
167 return;
168 }
169
170 void DecoderRowBased::GetUpdatedRects(UpdatedRects* rects) {
171 rects->push_back(clip_);
172 }
173
174 VideoPacketFormat::Encoding DecoderRowBased::Encoding() {
175 return encoding_;
117 } 176 }
118 177
119 } // namespace remoting 178 } // 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