00001
00002
00003
00004
00005
package org.nees.buffalo.video;
00006
00007
import java.io.DataInputStream;
00008
import java.io.IOException;
00009
00010
import java.net.URL;
00011
import java.net.URLConnection;
00012
import java.net.MalformedURLException;
00013
00014
import com.rbnb.sapi.ChannelMap;
00015
import com.rbnb.sapi.Source;
00016
import com.rbnb.sapi.SAPIException;
00017
00018
import com.rbnb.utility.ArgHandler;
00019
import com.rbnb.utility.RBNBProcess;
00020
00021
00022
00023
00024
00040 public class AxisSource {
00041
00042
private final static String DEFAULT_RBNB_SERVER =
"neestpm.mcs.anl.gov";
00043
private final static String DEFAULT_RBNB_PORT =
"3333";
00044
private final static String DEFAULT_RBNB_SOURCE =
"AxisVideo";
00045
private final static String DEFAULT_RBNB_CHANNEL =
"video.jpg";
00046
00047
private String cameraURLString = null;
00048
private String cameraHost = null;
00049
private String rbnbServerName = DEFAULT_RBNB_SERVER;
00050
private String rbnbServerPort = DEFAULT_RBNB_PORT;
00051
private String rbnbHostName = rbnbServerName +
":" + rbnbServerPort;
00052
private String rbnbSourceName = DEFAULT_RBNB_SOURCE;
00053
private String rbnbChannelName = DEFAULT_RBNB_CHANNEL;
00054
00055
private final int requestedFPS = 30;
00056
00057
private static final int DEFAULT_CACHE_SIZE=30;
00058
private int cacheSize = DEFAULT_CACHE_SIZE;
00059
00060
public AxisSource(String[] args)
00061 {
00062
00063
try {
00064 ArgHandler ah=
new ArgHandler(args);
00065
if (ah.checkFlag(
'h')) {
00066 printUsage();
00067 RBNBProcess.exit(0);
00068 }
00069
if (ah.checkFlag(
'v')) {
00070 String a=ah.getOption(
'v');
00071
if (a!=null) cameraHost=a;
00072 }
00073
if (ah.checkFlag(
'r')) {
00074 String a=ah.getOption(
'r');
00075
if (a!=null) rbnbServerName=a;
00076 }
00077
if (ah.checkFlag(
'p')) {
00078 String a=ah.getOption(
'p');
00079
if (a!=null) rbnbServerPort=a;
00080 }
00081
if (ah.checkFlag(
's')) {
00082 String a=ah.getOption(
's');
00083
if (a!=null) rbnbSourceName=a;
00084 }
00085
if (ah.checkFlag(
'c')) {
00086 String a=ah.getOption(
'c');
00087
if (a!=null) rbnbChannelName=a;
00088 }
00089
if (ah.checkFlag(
'z')) {
00090 String a=ah.getOption(
'z');
00091
if (a!=null)
00092
try
00093 {
00094 Integer i =
new Integer(a);
00095
int value = i.intValue();
00096 cacheSize = value;
00097 }
00098
catch (Exception ignore) {}
00099 }
00100 }
catch (Exception e) {
00101 System.err.println(
"AxisSource argument exception "+e.getMessage());
00102 e.printStackTrace();
00103 RBNBProcess.exit(0);
00104 }
00105
00106
if (cameraHost == null)
00107 {
00108 System.err.println(
"Axis Video Camera Host is required. Use AxisSource -h for help");
00109 printUsage();
00110 }
00111
00112 rbnbHostName = rbnbServerName +
":" + rbnbServerPort;
00113 cameraURLString =
"http://" + cameraHost +
"/axis-cgi/mjpg/video.cgi?camera=1&resolution=352x240&showlength=1&compression=25&clock=0&date=0&text=0&req_fps=30&deltatime=1";
00114
00115 }
00116
00117
public void start() {
00118
00119 System.out.println(
"Starting AxisSource with... \n"
00120 +
" camera URL = " + cameraURLString
00121 +
";\n RBNB Server = " + rbnbHostName
00122 +
"; RBNB Soruce name = " + rbnbSourceName
00123 +
"; RBNB Channel name = " + rbnbChannelName
00124 +
"/nUse AxisSource -h to see optional arguments.");
00125
00126
00127
boolean done =
false;
00128
while (!done) {
00129 done = !execute();
00130
try {
new java.lang.Thread().wait(1000); }
catch (Exception e) {}
00131 }
00132 }
00133
00134
private static void printUsage()
00135 {
00136 System.out.println(
"Usage for AxisSoruce...");
00137 System.out.println(
" -v Axis camera host (required)");
00138 System.out.println(
" [-r RBNB Server Name *"+ DEFAULT_RBNB_SERVER +
"]");
00139 System.out.println(
" [-p RBNB Server Port *" + DEFAULT_RBNB_PORT +
"]");
00140 System.out.println(
" [-s RBNB Source Name *" + DEFAULT_RBNB_SOURCE +
"]");
00141 System.out.println(
" [-c RBNB Source Channel Name *" + DEFAULT_RBNB_CHANNEL +
"]");
00142
00143 }
00144
00145
private boolean execute() {
00146 Source mySource =
new Source(cacheSize,
"none", 0);
00147
try {
00148 mySource.OpenRBNBConnection(rbnbHostName, rbnbSourceName);
00149 }
catch (SAPIException e) {
00150 System.err.println(
"Failed to connect to RBNB server with host = "
00151 + rbnbHostName +
" and Source = " + rbnbSourceName);
00152
return false;
00153 }
00154
00155 ChannelMap cmap =
new ChannelMap();
00156
int channelId = -1;
00157
try {
00158 channelId = cmap.Add(rbnbChannelName);
00159 }
catch (SAPIException e) {
00160 System.err.println(
"Failed to add video channel to channel map; name = "
00161 + rbnbChannelName);
00162 mySource.CloseRBNBConnection();
00163
return false;
00164 }
00165 cmap.PutTimeAuto(
"timeofday");
00166 cmap.PutMime(channelId,
"image/jpeg");
00167
00168 URL cameraURL = null;
00169
try {
00170 cameraURL =
new URL(cameraURLString);
00171 }
catch (MalformedURLException e) {
00172 System.err.println(
"URL is malformed; URL = " + cameraURLString);
00173 mySource.CloseRBNBConnection();
00174
return false;
00175 }
00176
00177 URLConnection cameraConnection = null;
00178
try {
00179 cameraConnection = cameraURL.openConnection();
00180 }
catch (IOException e) {
00181 System.err.println(
"Failed to connect to axis host with " + cameraURLString);
00182 mySource.CloseRBNBConnection();
00183
return false;
00184 }
00185
00186 DataInputStream dis = null;
00187
try {
00188 dis =
new DataInputStream(cameraConnection.getInputStream());
00189 }
catch (IOException e) {
00190 System.err.println(
"Failed to get data stream from axis host.");
00191 mySource.CloseRBNBConnection();
00192
return false;
00193 }
00194
00195 String delimiter =
"";
00196 String contentType =
"";
00197
int contentLength = 0;
00198
int deltaTime = 0;
00199 byte[] imageData;
00200
00201 StringBuffer inputLine =
new StringBuffer();
00202
int currImage = 0;
00203
boolean readingData =
false;
00204
boolean gotHeader =
false;
00205
00206
double lastTime = 0;
00207
double time = 0;
00208
double frameRate = 0;
00209
double averageFrameRate = requestedFPS;
00210
00211
boolean failed =
false;
00212
00213
while(currImage < 1000000) {
00214
00215
if (readingData) {
00216
00217
if (contentLength > 0) {
00218 imageData =
new byte[contentLength];
00219
try {
00220 dis.readFully(imageData);
00221 }
catch (IOException e) {
00222 System.err.println(
"Failed to read JPEG image data from data stream.");
00223 failed =
true;
00224
break;
00225 }
00226 }
else {
00227
int index = 0;
00228 imageData =
new byte[100000];
00229
00230
while (index < imageData.length) {
00231
if (index >= 4 && (
char)imageData[index-4] ==
'\r' && (
char)imageData[index-3] ==
'\n' && (
char)imageData[index-2] ==
'\r' && (
char)imageData[index-1] ==
'\n') {
00232 index = index - 4;
00233
break;
00234 }
00235
00236
try {
00237 imageData[index++] = dis.readByte();
00238 }
catch (IOException e) {
00239 System.err.println(
"Failed to read JPEG image data from data stream.");
00240 failed =
true;
00241
break;
00242 }
00243 }
00244
00245
if (failed)
break;
00246
00247
if (index == imageData.length) {
00248 System.err.println(
"Ran out of space in data buffer.");
00249
continue;
00250 }
00251
00252 }
00253
00254
if (currImage > 0) {
00255 frameRate = 1000/(
double)deltaTime;
00256 averageFrameRate = 0.995*averageFrameRate + 0.005*frameRate;
00257 }
00258
00259
try {
00260 cmap.PutDataAsByteArray(channelId, imageData);
00261 }
catch (SAPIException e) {
00262 System.err.println(
"Failed to put image data into channel map.");
00263 failed =
true;
00264
break;
00265 }
00266
00267
try {
00268 mySource.Flush(cmap,
true);
00269 }
catch (SAPIException e) {
00270 System.err.println(
"Failed to flush output data to server.");
00271 failed =
true;
00272
break;
00273 }
00274
00275
if (currImage % 30 == 0) System.out.print(((
long)(averageFrameRate*10))/((
double)10) +
" fps \r");
00276
00277 readingData =
false;
00278 gotHeader =
false;
00279
00280 delimiter =
"";
00281 contentType =
"";
00282 contentLength = 0;
00283 deltaTime = 0;
00284
00285 currImage++;
00286
00287 }
else {
00288
char c;
00289
try {
00290 c = (
char) dis.readByte();
00291 }
catch (IOException e) {
00292 System.err.println(
"Failed to read header data.");
00293 failed =
true;
00294
break;
00295 }
00296
00297
if (c ==
'\r') {
00298
try {
00299 dis.readByte();
00300 }
catch (IOException e) {
00301 System.err.println(
"Failed to read header data.");
00302 failed =
true;
00303
break;
00304 }
00305
00306
if (inputLine.toString().startsWith(
"--")) {
00307 delimiter = inputLine.substring(2);
00308 gotHeader =
true;
00309 }
else if (inputLine.toString().toLowerCase().startsWith(
"content-type")) {
00310 contentType = inputLine.substring(14);
00311 }
else if (inputLine.toString().toLowerCase().startsWith(
"content-length")) {
00312 contentLength = Integer.parseInt(inputLine.substring(16));
00313 }
else if (inputLine.toString().toLowerCase().startsWith(
"delta-time")) {
00314 deltaTime = Integer.parseInt(inputLine.substring(12));
00315 }
else if (gotHeader && inputLine.toString().trim().length() == 0) {
00316 readingData =
true;
00317 }
else if (inputLine.toString().trim().length() != 0){
00318 System.out.println(
"Received unexpected data.");
00319 }
00320
00321 inputLine =
new StringBuffer();
00322 }
else {
00323 inputLine.append(c);
00324 }
00325 }
00326 }
00327
00328
try {
00329 dis.close();
00330 }
catch (IOException e) {
00331 System.err.println(
"Failed to close connect to axis host.");
00332 }
00333
00334 mySource.CloseRBNBConnection();
00335
00336
return !failed;
00337
00338 }
00339
00340
public static void main(String[] args) {
00341
AxisSource s =
new AxisSource(args);
00342 s.
start();
00343 }
00344 }
00345