video_decoder_verbatim.cc revision d0247b1b59f9c528cb6df88b4f2b9afaf80d181e
15821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Copyright (c) 2012 The Chromium Authors. All rights reserved. 25821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Use of this source code is governed by a BSD-style license that can be 35821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// found in the LICENSE file. 45821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 55821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "remoting/codec/video_decoder_verbatim.h" 65821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 7a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)#include "base/logging.h" 8c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)#include "remoting/base/util.h" 95821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 105c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liunamespace remoting { 112a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 125c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liunamespace { 130529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch// Both input and output data are assumed to be RGBA32. 14c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)const int kBytesPerPixel = 4; 152a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} // namespace 16c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 17c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)VideoDecoderVerbatim::VideoDecoderVerbatim() {} 18a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) 19a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)VideoDecoderVerbatim::~VideoDecoderVerbatim() {} 20a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) 215c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liubool VideoDecoderVerbatim::IsReadyForData() { 225c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu return true; 230529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch} 24a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) 252a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void VideoDecoderVerbatim::Initialize(const webrtc::DesktopSize& screen_size) { 265c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu updated_region_.Clear(); 275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) screen_buffer_.reset(); 285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) screen_size_ = screen_size; 305c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu // Allocate the screen buffer, if necessary. 3190dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) if (!screen_size_.is_empty()) { 325c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu screen_buffer_.reset( 335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) new uint8 345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) [screen_size_.width() * screen_size_.height() * kBytesPerPixel]); 355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 365c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu} 3790dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) 385c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo LiuVideoDecoder::DecodeResult VideoDecoderVerbatim::DecodePacket( 395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const VideoPacket* packet) { 405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) webrtc::DesktopRegion region; 415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const char* in = packet->data().data(); 435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int stride = kBytesPerPixel * screen_size_.width(); 445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) for (int i = 0; i < packet->dirty_rects_size(); ++i) { 455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) Rect proto_rect = packet->dirty_rects(i); 465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) webrtc::DesktopRect rect = 4790dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) webrtc::DesktopRect::MakeXYWH(proto_rect.x(), proto_rect.y(), 4890dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) proto_rect.width(), proto_rect.height()); 4990dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) region.AddRect(rect); 505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!DoesRectContain(webrtc::DesktopRect::MakeSize(screen_size_), rect)) { 525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) LOG(ERROR) << "Invalid packet received"; 535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return DECODE_ERROR; 54a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) } 55c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 56c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) int rect_row_size = kBytesPerPixel * rect.width(); 575c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu uint8_t* out = screen_buffer_.get() + rect.top() * stride + 585c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu rect.left() * kBytesPerPixel; 595c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu for (int y = rect.top(); y < rect.top() + rect.height(); ++y) { 605c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu if (in + rect_row_size > packet->data().data() + packet->data().size()) { 615c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu LOG(ERROR) << "Invalid packet received"; 625c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu return DECODE_ERROR; 635c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu } 645c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu memcpy(out, in, rect_row_size); 655c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu in += rect_row_size; 665c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu out += stride; 67a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) } 68a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) } 69a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) 705c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu if (in != packet->data().data() + packet->data().size()) { 71a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) LOG(ERROR) << "Invalid packet received"; 72a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) return DECODE_ERROR; 73a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) } 745c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu 755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) updated_region_.AddRegion(region); 765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 777dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch return DECODE_DONE; 78c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)} 795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)VideoPacketFormat::Encoding VideoDecoderVerbatim::Encoding() { 815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return VideoPacketFormat::ENCODING_VERBATIM; 825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 832a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 842a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void VideoDecoderVerbatim::Invalidate(const webrtc::DesktopSize& view_size, 85c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) const webrtc::DesktopRegion& region) { 865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) updated_region_.AddRegion(region); 875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 88c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 89c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)void VideoDecoderVerbatim::RenderFrame(const webrtc::DesktopSize& view_size, 90c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) const webrtc::DesktopRect& clip_area, 915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) uint8* image_buffer, 925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int image_stride, 935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) webrtc::DesktopRegion* output_region) { 945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) output_region->Clear(); 955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 96 // TODO(alexeypa): scaling is not implemented. 97 webrtc::DesktopRect clip_rect = webrtc::DesktopRect::MakeSize(screen_size_); 98 clip_rect.IntersectWith(clip_area); 99 if (clip_rect.is_empty()) 100 return; 101 102 int screen_stride = screen_size_.width() * kBytesPerPixel; 103 104 for (webrtc::DesktopRegion::Iterator i(updated_region_); 105 !i.IsAtEnd(); i.Advance()) { 106 webrtc::DesktopRect rect(i.rect()); 107 rect.IntersectWith(clip_rect); 108 if (rect.is_empty()) 109 continue; 110 111 CopyRGB32Rect(screen_buffer_.get(), screen_stride, 112 clip_rect, 113 image_buffer, image_stride, 114 clip_area, 115 rect); 116 output_region->AddRect(rect); 117 } 118 119 updated_region_.Clear(); 120} 121 122const webrtc::DesktopRegion* VideoDecoderVerbatim::GetImageShape() { 123 return NULL; 124} 125 126} // namespace remoting 127