| Index: remoting/codec/video_decoder_verbatim.cc
|
| diff --git a/remoting/codec/video_decoder_verbatim.cc b/remoting/codec/video_decoder_verbatim.cc
|
| index fa3669046bd16fb4f88d17224712ccc001576d4d..b6b21793cc99e224198c88643e9a459e2f3bdd5d 100644
|
| --- a/remoting/codec/video_decoder_verbatim.cc
|
| +++ b/remoting/codec/video_decoder_verbatim.cc
|
| @@ -14,31 +14,13 @@ namespace {
|
| const int kBytesPerPixel = 4;
|
| } // namespace
|
|
|
| -
|
| VideoDecoderVerbatim::VideoDecoderVerbatim()
|
| - : state_(kUninitialized),
|
| - clip_(SkIRect::MakeEmpty()),
|
| - row_pos_(0),
|
| - row_y_(0),
|
| - screen_size_(SkISize::Make(0, 0)) {
|
| -}
|
| + : screen_size_(SkISize::Make(0, 0)) {}
|
|
|
| -VideoDecoderVerbatim::~VideoDecoderVerbatim() {
|
| -}
|
| +VideoDecoderVerbatim::~VideoDecoderVerbatim() {}
|
|
|
| bool VideoDecoderVerbatim::IsReadyForData() {
|
| - switch (state_) {
|
| - case kUninitialized:
|
| - case kError:
|
| - return false;
|
| - case kReady:
|
| - case kProcessing:
|
| - case kPartitionDone:
|
| - case kDone:
|
| - return true;
|
| - }
|
| - NOTREACHED();
|
| - return false;
|
| + return true;
|
| }
|
|
|
| void VideoDecoderVerbatim::Initialize(const SkISize& screen_size) {
|
| @@ -48,120 +30,53 @@ void VideoDecoderVerbatim::Initialize(const SkISize& screen_size) {
|
| screen_size_ = screen_size;
|
| // Allocate the screen buffer, if necessary.
|
| if (!screen_size_.isEmpty()) {
|
| - screen_buffer_.reset(new uint8[
|
| - screen_size_.width() * screen_size_.height() * kBytesPerPixel]);
|
| + screen_buffer_.reset(
|
| + new uint8
|
| + [screen_size_.width() * screen_size_.height() * kBytesPerPixel]);
|
| }
|
| -
|
| - state_ = kReady;
|
| }
|
|
|
| VideoDecoder::DecodeResult VideoDecoderVerbatim::DecodePacket(
|
| const VideoPacket* packet) {
|
| - UpdateStateForPacket(packet);
|
| -
|
| - 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 out_stride = screen_size_.width() * kBytesPerPixel;
|
| - uint8* out = screen_buffer_.get() + out_stride * (clip_.top() + row_y_) +
|
| - kBytesPerPixel * clip_.left();
|
| -
|
| - // Consume all the data in the message.
|
| - int used = 0;
|
| - while (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 bytes_to_copy = std::min(in_size - used, row_size - row_pos_);
|
| - memcpy(out + row_pos_, in + used, bytes_to_copy);
|
| -
|
| - used += bytes_to_copy;
|
| - row_pos_ += bytes_to_copy;
|
| -
|
| - // If this row is completely filled then move onto the next row.
|
| - if (row_pos_ == row_size) {
|
| - ++row_y_;
|
| - row_pos_ = 0;
|
| - out += out_stride;
|
| - }
|
| - }
|
| -
|
| - if (state_ == kPartitionDone || state_ == kDone) {
|
| - if (row_y_ < clip_.height()) {
|
| - state_ = kError;
|
| - LOG(WARNING) << "Received LAST_PACKET, but didn't get enough data.";
|
| + SkRegion region;
|
| +
|
| + const char* in = packet->data().data();
|
| + int stride = kBytesPerPixel * screen_size_.width();
|
| + for (int i = 0; i < packet->dirty_rects_size(); ++i) {
|
| + Rect proto_rect = packet->dirty_rects(i);
|
| + SkIRect rect = SkIRect::MakeXYWH(proto_rect.x(),
|
| + proto_rect.y(),
|
| + proto_rect.width(),
|
| + proto_rect.height());
|
| + region.op(rect, SkRegion::kUnion_Op);
|
| +
|
| + if (!SkIRect::MakeSize(screen_size_).contains(rect)) {
|
| + LOG(ERROR) << "Invalid packet received";
|
| return DECODE_ERROR;
|
| }
|
|
|
| - updated_region_.op(clip_, SkRegion::kUnion_Op);
|
| - }
|
| -
|
| - if (state_ == kDone) {
|
| - return DECODE_DONE;
|
| - } else {
|
| - return DECODE_IN_PROGRESS;
|
| - }
|
| -}
|
| -
|
| -void VideoDecoderVerbatim::UpdateStateForPacket(const VideoPacket* packet) {
|
| - if (state_ == kError) {
|
| - return;
|
| - }
|
| -
|
| - if (packet->flags() & VideoPacket::FIRST_PACKET) {
|
| - if (state_ != kReady && state_ != kDone && state_ != kPartitionDone) {
|
| - state_ = kError;
|
| - LOG(WARNING) << "Received unexpected FIRST_PACKET.";
|
| - return;
|
| - }
|
| -
|
| - // Reset the buffer location status variables on the first packet.
|
| - clip_.setXYWH(packet->format().x(), packet->format().y(),
|
| - packet->format().width(), packet->format().height());
|
| - if (!SkIRect::MakeSize(screen_size_).contains(clip_)) {
|
| - state_ = kError;
|
| - LOG(WARNING) << "Invalid clipping area received.";
|
| - return;
|
| + int rect_row_size = kBytesPerPixel * rect.width();
|
| + uint8_t* out = screen_buffer_.get() + rect.y() * stride +
|
| + rect.x() * kBytesPerPixel;
|
| + for (int y = rect.y(); y < rect.y() + rect.height(); ++y) {
|
| + if (in + rect_row_size > packet->data().data() + packet->data().size()) {
|
| + LOG(ERROR) << "Invalid packet received";
|
| + return DECODE_ERROR;
|
| + }
|
| + memcpy(out, in, rect_row_size);
|
| + in += rect_row_size;
|
| + out += stride;
|
| }
|
| -
|
| - state_ = kProcessing;
|
| - 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_ = kPartitionDone;
|
| + if (in != packet->data().data() + packet->data().size()) {
|
| + LOG(ERROR) << "Invalid packet received";
|
| + return DECODE_ERROR;
|
| }
|
|
|
| - if (packet->flags() & VideoPacket::LAST_PARTITION) {
|
| - if (state_ != kPartitionDone) {
|
| - state_ = kError;
|
| - LOG(WARNING) << "Received unexpected LAST_PARTITION.";
|
| - return;
|
| - }
|
| - state_ = kDone;
|
| - }
|
| + updated_region_.op(region, SkRegion::kUnion_Op);
|
|
|
| - return;
|
| + return DECODE_DONE;
|
| }
|
|
|
| VideoPacketFormat::Encoding VideoDecoderVerbatim::Encoding() {
|
|
|