vncinput.cc revision 9356:b279bad40aa3
16019SN/A/* 26019SN/A * Copyright (c) 2010 ARM Limited 37102SN/A * All rights reserved 47102SN/A * 57102SN/A * The license below extends only to copyright in the software and shall 67102SN/A * not be construed as granting a license to any other intellectual 77102SN/A * property including but not limited to intellectual property relating 87102SN/A * to a hardware implementation of the functionality of the software 97102SN/A * licensed hereunder. You may use the software subject to the license 107102SN/A * terms below provided that you ensure that this notice is replicated 117102SN/A * unmodified and in its entirety in all distributions of the software, 127102SN/A * modified or unmodified, in source code or in binary form. 137102SN/A * 147102SN/A * Redistribution and use in source and binary forms, with or without 156019SN/A * modification, are permitted provided that the following conditions are 166019SN/A * met: redistributions of source code must retain the above copyright 176019SN/A * notice, this list of conditions and the following disclaimer; 186019SN/A * redistributions in binary form must reproduce the above copyright 196019SN/A * notice, this list of conditions and the following disclaimer in the 206019SN/A * documentation and/or other materials provided with the distribution; 216019SN/A * neither the name of the copyright holders nor the names of its 226019SN/A * contributors may be used to endorse or promote products derived from 236019SN/A * this software without specific prior written permission. 246019SN/A * 256019SN/A * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 266019SN/A * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 276019SN/A * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 286019SN/A * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 296019SN/A * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 306019SN/A * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 316019SN/A * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 326019SN/A * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 336019SN/A * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 346019SN/A * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 356019SN/A * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 366019SN/A * 376019SN/A * Authors: Ali Saidi 386019SN/A * William Wang 396019SN/A */ 406019SN/A 416019SN/A/** @file 426019SN/A * Implementiation of a VNC input 436019SN/A */ 446019SN/A 456019SN/A#include <sys/types.h> 466019SN/A 476019SN/A#include "base/vnc/vncinput.hh" 486019SN/A#include "base/output.hh" //simout 496019SN/A#include "base/trace.hh" 506019SN/A#include "debug/VNC.hh" 516019SN/A 526310SN/Ausing namespace std; 537102SN/A 546268SN/AVncInput::VncInput(const Params *p) 556268SN/A : SimObject(p), keyboard(NULL), mouse(NULL), 566268SN/A vc(NULL), fbPtr(NULL), videoMode(VideoConvert::UnknownMode), 576268SN/A _videoWidth(1), _videoHeight(1), captureEnabled(p->frame_capture), 586268SN/A captureCurrentFrame(0), captureLastHash(0), captureBitmap(0) 596276SN/A{ 606280SN/A if (captureEnabled) { 616268SN/A // remove existing frame output directory if it exists, then create a 626268SN/A // clean empty directory 636268SN/A const string FRAME_OUTPUT_SUBDIR = "frames_" + name(); 646268SN/A simout.remove(FRAME_OUTPUT_SUBDIR, true); 656268SN/A captureOutputDirectory = simout.createSubdirectory( 666741SN/A FRAME_OUTPUT_SUBDIR); 677102SN/A } 687102SN/A} 697102SN/A 706741SN/Avoid 716741SN/AVncInput::setFrameBufferParams(VideoConvert::Mode mode, uint16_t width, 726741SN/A uint16_t height) 736268SN/A{ 746272SN/A DPRINTF(VNC, "Updating video params: mode: %d width: %d height: %d\n", mode, 756272SN/A width, height); 766268SN/A 776268SN/A if (mode != videoMode || width != videoWidth() || height != videoHeight()) { 786741SN/A videoMode = mode; 796268SN/A _videoWidth = width; 806268SN/A _videoHeight = height; 816268SN/A 826268SN/A if (vc) 836268SN/A delete vc; 846741SN/A 856019SN/A vc = new VideoConvert(mode, VideoConvert::rgb8888, videoWidth(), 866268SN/A videoHeight()); 876268SN/A 886268SN/A if (captureEnabled) { 896268SN/A // create bitmap of the frame with new attributes 906268SN/A if (captureBitmap) 916019SN/A delete captureBitmap; 926019SN/A 937129Sgblack@eecs.umich.edu assert(fbPtr); 946019SN/A captureBitmap = new Bitmap(videoMode, width, height, fbPtr); 956268SN/A assert(captureBitmap); 967139Sgblack@eecs.umich.edu } 976268SN/A } 986268SN/A} 996747SN/A 1006747SN/Avoid 1016747SN/AVncInput::captureFrameBuffer() 1026751SN/A{ 1036751SN/A assert(captureBitmap); 1046753SN/A 1056753SN/A // skip identical frames 1066753SN/A uint64_t new_hash = captureBitmap->getHash(); 1076753SN/A if (captureLastHash == new_hash) 1086753SN/A return; 1096753SN/A captureLastHash = new_hash; 1106753SN/A 1116753SN/A // get the filename for the current frame 1126751SN/A char frameFilenameBuffer[64]; 1136751SN/A snprintf(frameFilenameBuffer, 64, "fb.%06d.%lld.bmp.gz", 1146751SN/A captureCurrentFrame, static_cast<long long int>(curTick())); 1156751SN/A const string frameFilename(frameFilenameBuffer); 1166751SN/A 1176751SN/A // create the compressed framebuffer file 1186751SN/A ostream *fb_out = simout.create(captureOutputDirectory + frameFilename, 1196747SN/A true); 1206751SN/A captureBitmap->write(fb_out); 1216751SN/A simout.close(fb_out); 1226753SN/A 1236753SN/A ++captureCurrentFrame; 1246753SN/A} 1256753SN/A 1266751SN/A// create the VNC Replayer object 1276751SN/AVncInput * 1286751SN/AVncInputParams::create() 1296751SN/A{ 1306268SN/A return new VncInput(this); 1316268SN/A} 1327152Sgblack@eecs.umich.edu