00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026 #include "Aria.h"
00027 #include "ArExport.h"
00028 #include "ArHybridForwarderVideo.h"
00029
00036 AREXPORT ArHybridForwarderVideo::ArHybridForwarderVideo(ArServerBase *server,
00037 ArClientBase *client)
00038 {
00039 myServer = server;
00040 myClient = client;
00041 finishConstructor();
00042 }
00043
00053 AREXPORT ArHybridForwarderVideo::ArHybridForwarderVideo(ArServerBase *server,
00054 const char *hostname,
00055 int port)
00056 {
00057 myServer = server;
00058 myClient = new ArClientBase();
00059 myClient->setConnectTimeoutTime(1);
00060 myClient->blockingConnect(hostname, port, false);
00061 myClient->runAsync();
00062 finishConstructor();
00063 }
00064
00065 AREXPORT ArHybridForwarderVideo::~ArHybridForwarderVideo()
00066 {
00067
00068 }
00069
00070 AREXPORT void ArHybridForwarderVideo::finishConstructor(void)
00071 {
00072 myClient->lock();
00073 mySendVideoSizeCB = new ArFunctor2C<ArHybridForwarderVideo, ArServerClient*,
00074 ArNetPacket *>(this, &ArHybridForwarderVideo::sendVideoSize);
00075
00076 mySendVideoCB = new ArFunctor2C<ArHybridForwarderVideo, ArServerClient*,
00077 ArNetPacket *>(this, &ArHybridForwarderVideo::sendVideo);
00078
00079 myReceiveVideoSizeCB = new ArFunctor1C<ArHybridForwarderVideo,
00080 ArNetPacket *>(this, &ArHybridForwarderVideo::receiveVideoSize);
00081
00082 myReceiveVideoCB = new ArFunctor1C<ArHybridForwarderVideo,
00083 ArNetPacket *>(this, &ArHybridForwarderVideo::receiveVideo);
00084
00085 myClientCycleCB = new ArFunctorC<ArHybridForwarderVideo>(
00086 this, &ArHybridForwarderVideo::clientCycleCallback);
00087
00088 myReqSent = false;
00089 myLastReqSent.setToNow();
00090 myLastReceivedVideo.setToNow();
00091 myVideoRequestTime = 100;
00092 myForwardingVideo = false;
00093
00094 if (myClient != NULL && myServer != NULL && myClient->isConnected())
00095 {
00096 myClient->addCycleCallback(myClientCycleCB);
00097 if (myClient->dataExists("videoSize"))
00098 {
00099 myServer->addData("videoSize",
00100 "gets the width and height of the video data",
00101 mySendVideoSizeCB,
00102 "none", "uByte2: width, uByte2: height",
00103 "Video", "RETURN_SINGLE");
00104 myClient->addHandler("videoSize", myReceiveVideoSizeCB);
00105 myClient->requestOnce("videoSize");
00106 }
00107 if (myClient->dataExists("sendVideo"))
00108 {
00109 ArLog::log(ArLog::Normal, "Forwarding video.");
00110 myForwardingVideo = true;
00111 myClient->addHandler("sendVideo", myReceiveVideoCB);
00112 ArNetPacket packet;
00113 packet.uByteToBuf(90);
00114 myClient->requestOnce("sendVideo", &packet);
00115
00116 myIsSendVideoAvailable =
00117 myServer->addData("sendVideo", "gets video from the robot's camera (you should requestOnce this, you shouldn't request it, since you could easily fill the bandwidth that way)",
00118 mySendVideoCB, "uByte: quality (0 - 100)",
00119 "out: uByte2: width, uByte2: height, (len - readLen)*uByte: jpegData", "Video", "RETURN_VIDEO");
00120 }
00121 }
00122 myClient->unlock();
00123 }
00124
00125
00126 AREXPORT const char *ArHybridForwarderVideo::getCameraName()
00127 {
00128 return myCameraName.c_str();
00129 }
00130
00131 AREXPORT void ArHybridForwarderVideo::setCameraName(const char *cameraName)
00132 {
00133 if (cameraName != NULL) {
00134 myCameraName = cameraName;
00135 }
00136 else {
00137 myCameraName = "";
00138 }
00139
00140 }
00141
00142
00143 AREXPORT void ArHybridForwarderVideo::addToCameraCollection
00144 (ArCameraCollection &collection)
00145 {
00146 if (myCameraName.empty()) {
00147 return;
00148 }
00149
00150 const char *cameraName = myCameraName.c_str();
00151 if (!collection.exists(cameraName)) {
00152
00153 return;
00154 }
00155
00156 bool isSuccess = true;
00157
00158 if (myForwardingVideo) {
00159
00160 std::string packetName = "getPicture" + myCameraName;
00161
00162
00163
00164 isSuccess = myServer->addData(packetName.c_str(),
00165 "Gets video from the robot's camera",
00166 mySendVideoCB, "uByte: quality (0 - 100)",
00167 "out: uByte2: width, uByte2: height, (len - readLen)*uByte: jpegData", "Video");
00168
00169 if (isSuccess) {
00170 isSuccess = collection.addCameraCommand
00171 (cameraName,
00172 ArCameraCommands::GET_PICTURE,
00173 packetName.c_str(),
00174 myVideoRequestTime);
00175 }
00176
00177 if (!isSuccess) {
00178 ArLog::log(ArLog::Verbose,
00179 "Video forwarder could not add camera %s command %s",
00180 cameraName,
00181 packetName.c_str());
00182 }
00183
00184 }
00185
00186
00187
00188 if (myIsSendVideoAvailable) {
00189
00190 isSuccess = collection.addCameraCommand
00191 (cameraName,
00192 ArCameraCommands::GET_VIDEO,
00193 "sendVideo",
00194 myVideoRequestTime);
00195 }
00196
00197 }
00198
00199
00200
00201 AREXPORT void ArHybridForwarderVideo::sendVideoSize(ArServerClient *client,
00202 ArNetPacket *packet)
00203 {
00204 myMutex.lock();
00205 myReceivedVideoSize.setCommand(packet->getCommand());
00206 client->sendPacketTcp(&myReceivedVideoSize);
00207 myMutex.unlock();
00208 }
00209
00210 AREXPORT void ArHybridForwarderVideo::sendVideo(ArServerClient *client,
00211 ArNetPacket *packet)
00212 {
00213
00214 myMutex.lock();
00215 mySendVideoArgument.duplicatePacket(packet);
00216 mySendVideoArgument.resetRead();
00217
00218
00219
00220
00221 myReceivedVideo.setCommand(0);
00222 client->sendPacketUdp(&myReceivedVideo);
00223
00224 myMutex.unlock();
00225 }
00226
00227 AREXPORT void ArHybridForwarderVideo::receiveVideoSize(ArNetPacket *packet)
00228 {
00229
00230 myMutex.lock();
00231 myReceivedVideoSize.duplicatePacket(packet);
00232 mySendVideoArgument.resetRead();
00233 myMutex.unlock();
00234 }
00235
00236 AREXPORT void ArHybridForwarderVideo::receiveVideo(ArNetPacket *packet)
00237 {
00238
00239 myMutex.lock();
00240 myReceivedVideo.duplicatePacket(packet);
00241 myReceivedVideo.resetRead();
00242 myLastReceivedVideo.setToNow();
00243 myReqSent = false;
00244 myMutex.unlock();
00245 }
00246
00247 AREXPORT void ArHybridForwarderVideo::clientCycleCallback(void)
00248 {
00249 myMutex.lock();
00250 if ((myLastReceivedVideo.mSecSince() > myVideoRequestTime && !myReqSent) ||
00251 (myReqSent && myLastReqSent.mSecSince() > 3000))
00252 {
00253
00254 myClient->requestOnce("sendVideo", &mySendVideoArgument);
00255 myLastReqSent.setToNow();
00256 myReqSent = true;
00257 }
00258 myMutex.unlock();
00259 }
00260
00261 AREXPORT bool ArHybridForwarderVideo::isForwardingVideo(void) const
00262 {
00263 return myForwardingVideo;
00264 }