Last modified on Thu Jan 26 23:27:35 PST 1995 by msm modified on Thu Aug 19 10:29:32 PDT 1993 by sfreeman
INTERFACEThe ports were once upon a time htons'ed. INET ports are in local endian (yes I know its wrong) unlike addreses which are never messed with. So to make sure the new code which doesn't mess with the ports interoperates with the old stuff we have to use some bizzare numbers here.jvprotocol ; FROM Ctypes IMPORT int, unsigned_int, unsigned_short_int;
CONST PORT_AUDIO_SOURCE = 53001; PORT_AUDIO_HEAR = 53000; PORT_VIDEO = 53001;J-Video Protocol definitions
|
Client -> server messages use a single character (0 - 255):
1 - 15: Number of credits - add to stream's current balance 16 - 31: Max credits - 1 (upper limit of balance) 48 - 63: '0' - '?' Quality 71: 'H' Heartbeat (source does nothing) : 'M' Client can handle multicast 81: 'Q' Qualities (reply with a set of strings) 83: 'S' Status (reply with a set of strings) : 'U' UDP request OK. : 'u' UDP request failed. : 'V' Suspend stream : 'v' Resume stream 128 - 254: Sync, where code is to be returned in sync reply. 255: Extended (more than one byte) command
TYPE ClientRequest = BITS 8 FOR [16_0 .. 16_ff]; ClientNumCredits = [16_01 .. 16_0f]; ClientMaxCredits = [16_10 .. 16_1f]; ClientQualityVal = [16_30 .. 16_3f]; ClientSyncVal = [16_80 .. 16_ff]; CONST ClientHeartbeat = 16_48; (* 'H' *) ClientMulticastAble = 16_4D; (* 'M' *) ClientQualities = 16_51; (* 'Q' *) ClientStatus = 16_53; (* 'S' *) ClientUDPRequestOK = 16_55; (* 'U' *) ClientUDPRequestFailed = 16_75; (* 'u' *) ClientSuspendStream = 16_56; (* 'V' *) ClientResumeStream = 16_76; (* 'v' *) ExtendedCommand = 16_FF;Extended commands
FrameRateHint = 1; TYPE FrameRateHintRec = RECORD type: int; period: int; END;server -> client messages
CONST JVP_FirstEvent = JVP_VIDEO; JVP_VIDEO = 1; (* used *) JVP_RESOLUTION = 2; (* not used *) JVP_TYPE = 3; (* used *) JVP_AUDIO = 4; (* used *) JVP_SYNC = 5; (* used *) JVP_STATUS = 6; (* used *) JVP_QUALITIES = 7; (* used *) JVP_ENDMARK = 8; (* not used *) JVP_ERROR = 9; (* not used *) JVP_INFO = 10; (* not used *) JVP_AUDIO_SILENCE = 11; (* not used *) JVP_AUDIO_MULTICAST = 12; JVP_VIDEO_UDP_REQUEST = 13; JVP_VIDEO_UDP_RESPONSE = 14; JVP_VIDEO_UDP_DATA = 15; JVP_LastEvent = JVP_VIDEO_UDP_DATA; TYPE TypeCode = BITS BITSIZE(int) FOR [JVP_FirstEvent .. JVP_LastEvent]; CONST MaxControlMsgBytes = 128; (* storage for non-video data *) MaxControlMsgSize = 128 DIV BYTESIZE(CHAR); TYPE ControlBuffer = ARRAY [0 .. MaxControlMsgSize - 1] OF CHAR;This does not appear to really be used for anything. * Formerly from Utime.
TYPE struct_timeval = RECORD tv_sec: unsigned_int; (* Really should be LONGINT for year 2038. *) tv_usec: unsigned_int; (* Really should be LONGINT for alignment. *) END; TYPE VideoFrame = RECORD type : int := JVP_VIDEO; length : int; timestamp: struct_timeval; (* data goes here for 'length' bytes *) END; VideoFramePtr = UNTRACED REF VideoFrame; TYPE Resolution = RECORD type : int := JVP_RESOLUTION; swidth, sheight: int; (* Source width, height *) cwidth, cheight: int; (* Width & height when compressed *) END; ResolutionPtr = UNTRACED REF Resolution; CONST JVP_KIND_JPEG = 0; TYPE VideoType = RECORD type : int := JVP_TYPE; kind : int := JVP_KIND_JPEG; qfactor: int; (* kludge; should send table *) width : int; height : int; END; VideoTypePtr = UNTRACED REF VideoType; TYPE AudioFrame = RECORD type: int := JVP_AUDIO; seqNum: unsigned_int; (* not consecutive; cumulative count of samples *) length : int; timestamp: struct_timeval; (* data goes here for 'length' bytes *) END; AudioFramePtr = UNTRACED REF AudioFrame; TYPE SyncFrame = RECORD type: int := JVP_SYNC; code: int; time: int; END; SyncFramePtr = UNTRACED REF SyncFrame; TYPE StatusFrame = RECORD type : int := JVP_STATUS; length: int; END; StatusFramePtr = UNTRACED REF StatusFrame; TYPE QualitiesFrame = RECORD type : int := JVP_QUALITIES; length: int; (* Strings of the form "%d %d %d %d" quality, width, height, qfactor *) (* Terminated by a zero-length string *) END; QualitiesFramePtr = UNTRACED REF QualitiesFrame; TYPE EndMark = RECORD type : int := JVP_ENDMARK; timestamp: struct_timeval; END; EndMarkPtr = UNTRACED REF EndMark; TYPE ErrorFrame = RECORD type : int := JVP_ERROR; length: int; (* Null terminated error string *) END; ErrorFramePtr = UNTRACED REF ErrorFrame; TYPE InfoFrame = RECORD type : int := JVP_INFO; length: int; (* of data following *) code : int; (* whatever *) timestamp: struct_timeval; (* Additional data here *) END; InfoFramePtr = UNTRACED REF InfoFrame; TYPE AudioSilenceFrame = RECORD type: int := JVP_AUDIO_SILENCE; seqNum: unsigned_int; (* not consecutive; cumulative count of samples *) length: int; (* number of silent samples *) timestamp: struct_timeval; END; AudioSilenceFramePtr = UNTRACED REF AudioSilenceFrame; TYPE AudioMulticastInfo = RECORD type: int := JVP_AUDIO_MULTICAST; addr: unsigned_int; END; AudioMulticastInfoPtr = UNTRACED REF AudioMulticastInfo; TYPE VideoUdpControl = RECORD (* both req/response *) type : int; jvpu_daddr: unsigned_int; jvpu_saddr: unsigned_int; jvpu_dport: unsigned_short_int; jvpu_sport: unsigned_short_int; END; VideoUdpControlPtr = UNTRACED REF VideoUdpControl; TYPE VideoUdpData = RECORD type : int := JVP_VIDEO_UDP_DATA; jvpu_length: int; (* total data *) jvpu_timestamp: ARRAY [0 .. 1] OF struct_timeval; (* lance wanted two *) jvpu_sequence: int; (* for reassembly *) END; VideoUdpDataPtr = UNTRACED REF VideoUdpData; CONST HdrSizes = ARRAY TypeCode OF CARDINAL{ BYTESIZE(VideoFrame), BYTESIZE(Resolution), BYTESIZE(VideoType), BYTESIZE(AudioFrame), BYTESIZE(SyncFrame), BYTESIZE(StatusFrame), BYTESIZE(QualitiesFrame), BYTESIZE(EndMark), BYTESIZE(ErrorFrame), BYTESIZE(InfoFrame), BYTESIZE(AudioSilenceFrame), BYTESIZE(AudioMulticastInfo), BYTESIZE(VideoUdpControl), BYTESIZE(VideoUdpControl), BYTESIZE(VideoUdpData)};no message is shorter than an AnyHeader, so we can always read in the number of bytes in an AnyHeader
TYPE AnyHeader = RECORD type : int; dummy: int; END; AnyHeaderPtr = UNTRACED REF AnyHeader; CONST MaxHdrSize = MaxHdrBytes DIV BYTESIZE(CHAR); MaxHdrBytes = MAX( BYTESIZE(ARRAY [0 .. 63] OF CHAR), MAX( BYTESIZE(AnyHeader), MAX( HdrSizes[JVP_VIDEO], MAX( HdrSizes[JVP_RESOLUTION], MAX( HdrSizes[JVP_TYPE], MAX( HdrSizes[JVP_AUDIO], MAX( HdrSizes[JVP_SYNC], MAX( HdrSizes[JVP_STATUS], MAX( HdrSizes[JVP_QUALITIES], MAX( HdrSizes[JVP_ENDMARK], MAX( HdrSizes[JVP_ERROR], MAX( HdrSizes[JVP_INFO], MAX( HdrSizes[JVP_AUDIO_SILENCE], MAX( HdrSizes[JVP_AUDIO_MULTICAST], MAX( HdrSizes[JVP_VIDEO_UDP_REQUEST], MAX( HdrSizes[JVP_VIDEO_UDP_RESPONSE], HdrSizes[JVP_VIDEO_UDP_DATA])))))))))))))))); TYPE Header = ARRAY [0 .. MaxHdrSize - 1] OF CHAR; HeaderPtr = UNTRACED REF Header; END jvprotocol.