Main Page | Class Hierarchy | Class List | File List | Class Members | Related Pages

AxisSource.java

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

Generated on Tue Mar 23 11:54:24 2004 for Data turbine for NEESGrid by doxygen 1.3.6