summaryrefslogtreecommitdiffstats
path: root/remoting/base/decoder_row_based.cc
diff options
context:
space:
mode:
authorsergeyu@chromium.org <sergeyu@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2010-11-09 23:22:20 +0000
committersergeyu@chromium.org <sergeyu@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2010-11-09 23:22:20 +0000
commit3adf1b2a65a85ff7d4b55cd57a4e400f104d27dd (patch)
tree235aee1f595583297e057b058a29d2ed24d9da92 /remoting/base/decoder_row_based.cc
parent9db9173baebf27623ce30770696f84a3fec74259 (diff)
downloadchromium_src-3adf1b2a65a85ff7d4b55cd57a4e400f104d27dd.zip
chromium_src-3adf1b2a65a85ff7d4b55cd57a4e400f104d27dd.tar.gz
chromium_src-3adf1b2a65a85ff7d4b55cd57a4e400f104d27dd.tar.bz2
Add VideoPacket struct for video packets. Refactor Decode interface to use it.
Various cleanups. BUG=None TEST=Unittests. Review URL: http://codereview.chromium.org/4476003 git-svn-id: svn://svn.chromium.org/chrome/trunk/src@65590 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'remoting/base/decoder_row_based.cc')
-rw-r--r--remoting/base/decoder_row_based.cc103
1 files changed, 81 insertions, 22 deletions
diff --git a/remoting/base/decoder_row_based.cc b/remoting/base/decoder_row_based.cc
index d378e96..1a0efad 100644
--- a/remoting/base/decoder_row_based.cc
+++ b/remoting/base/decoder_row_based.cc
@@ -11,6 +11,11 @@
namespace remoting {
+namespace {
+// Both input and output data are assumed to be RGBA32.
+const int kBytesPerPixel = 4;
+}
+
DecoderRowBased* DecoderRowBased::CreateZlibDecoder() {
return new DecoderRowBased(new DecompressorZlib(),
VideoPacketFormat::ENCODING_ZLIB);
@@ -26,7 +31,6 @@ DecoderRowBased::DecoderRowBased(Decompressor* decompressor,
: state_(kUninitialized),
decompressor_(decompressor),
encoding_(encoding),
- bytes_per_src_pixel_(0),
row_pos_(0),
row_y_(0),
// TODO(hclam): We should use the information from the update stream
@@ -45,38 +49,35 @@ void DecoderRowBased::Reset() {
}
bool DecoderRowBased::IsReadyForData() {
- return state_ == kReady;
+ return state_ == kReady || state_ == kProcessing || state_ == kDone;
}
-void DecoderRowBased::Initialize(scoped_refptr<media::VideoFrame> frame,
- const gfx::Rect& clip,
- int bytes_per_src_pixel) {
+void DecoderRowBased::Initialize(scoped_refptr<media::VideoFrame> frame) {
// Make sure we are not currently initialized.
CHECK_EQ(kUninitialized, state_);
- if (static_cast<PixelFormat>(frame->format()) != PIXEL_FORMAT_RGB32) {
+ if (frame->format() != media::VideoFrame::RGB32) {
LOG(WARNING) << "DecoderRowBased only supports RGB32.";
state_ = kError;
return;
}
frame_ = frame;
-
- // Reset the buffer location status variables.
- clip_ = clip;
- row_pos_ = 0;
- row_y_ = 0;
- bytes_per_src_pixel_ = bytes_per_src_pixel;
-
state_ = kReady;
}
-void DecoderRowBased::DecodeBytes(const std::string& encoded_bytes) {
- DCHECK_EQ(kReady, state_);
+Decoder::DecodeResult DecoderRowBased::DecodePacket(
+ const VideoPacket* packet) {
+ UpdateStateForPacket(packet);
- const uint8* in = reinterpret_cast<const uint8*>(encoded_bytes.data());
- const int in_size = encoded_bytes.size();
- const int row_size = clip_.width() * bytes_per_src_pixel_;
+ if (state_ == kError) {
+ return DECODE_ERROR;
+ }
+
+ const uint8* in = reinterpret_cast<const uint8*>(packet->data().data());
+ const int in_size = packet->data().size();
+
+ const int row_size = clip_.width() * kBytesPerPixel;
int stride = frame_->stride(media::VideoFrame::kRGBPlane);
uint8* rect_begin = frame_->data(media::VideoFrame::kRGBPlane);
@@ -88,15 +89,19 @@ void DecoderRowBased::DecodeBytes(const std::string& encoded_bytes) {
stride = -stride;
}
- // TODO(ajwong): This should be bytes_per_dst_pixel shouldn't this.?
- uint8* out = rect_begin +
- stride * (clip_.y() + row_y_) +
- bytes_per_src_pixel_ * clip_.x();
+ uint8* out = rect_begin + stride * (clip_.y() + row_y_) +
+ kBytesPerPixel * clip_.x();
// Consume all the data in the message.
bool decompress_again = true;
int used = 0;
while (decompress_again && used < in_size) {
+ if (row_y_ >= clip_.height()) {
+ state_ = kError;
+ LOG(WARNING) << "Too much data is received for the given rectangle.";
+ return DECODE_ERROR;
+ }
+
int written = 0;
int consumed = 0;
// TODO(ajwong): This assume source and dest stride are the same, which is
@@ -114,6 +119,60 @@ void DecoderRowBased::DecodeBytes(const std::string& encoded_bytes) {
out += stride;
}
}
+
+ if (state_ == kDone && row_y_ < clip_.height()) {
+ state_ = kError;
+ LOG(WARNING) << "Received LAST_PACKET, but didn't get enough data.";
+ return DECODE_ERROR;
+ }
+
+ return state_ == kDone ? DECODE_DONE : DECODE_IN_PROGRESS;
+}
+
+void DecoderRowBased::UpdateStateForPacket(const VideoPacket* packet) {
+ if (state_ == kError) {
+ return;
+ }
+
+ if (packet->flags() & VideoPacket::FIRST_PACKET) {
+ if (state_ != kReady && state_ != kDone) {
+ state_ = kError;
+ LOG(WARNING) << "Received unexpected FIRST_PACKET.";
+ return;
+ }
+ state_ = kProcessing;
+
+ // Reset the buffer location status variables on the first packet.
+ clip_.SetRect(packet->format().x(), packet->format().y(),
+ packet->format().width(), packet->format().height());
+ row_pos_ = 0;
+ row_y_ = 0;
+ }
+
+ if (state_ != kProcessing) {
+ state_ = kError;
+ LOG(WARNING) << "Received unexpected packet.";
+ return;
+ }
+
+ if (packet->flags() & VideoPacket::LAST_PACKET) {
+ if (state_ != kProcessing) {
+ state_ = kError;
+ LOG(WARNING) << "Received unexpected LAST_PACKET.";
+ return;
+ }
+ state_ = kDone;
+ }
+
+ return;
+}
+
+void DecoderRowBased::GetUpdatedRects(UpdatedRects* rects) {
+ rects->push_back(clip_);
+}
+
+VideoPacketFormat::Encoding DecoderRowBased::Encoding() {
+ return encoding_;
}
} // namespace remoting