Filling an array of bytes in Java

For the part of the project I'm working on, I am implementing RTPpacket, where I need to populate an array of byte headers with RTP header fields.

//size of the RTP header: static int HEADER_SIZE = 12; // bytes //Fields that compose the RTP header public int Version; // 2 bits public int Padding; // 1 bit public int Extension; // 1 bit public int CC; // 4 bits public int Marker; // 1 bit public int PayloadType; // 7 bits public int SequenceNumber; // 16 bits public int TimeStamp; // 32 bits public int Ssrc; // 32 bits //Bitstream of the RTP header public byte[] header = new byte[ HEADER_SIZE ]; 

That was my approach:

 /* * bits 0-1: Version * bit 2: Padding * bit 3: Extension * bits 4-7: CC */ header[0] = new Integer( (Version << 6)|(Padding << 5)|(Extension << 6)|CC ).byteValue(); /* * bit 0: Marker * bits 1-7: PayloadType */ header[1] = new Integer( (Marker << 7)|PayloadType ).byteValue(); /* SequenceNumber takes 2 bytes = 16 bits */ header[2] = new Integer( SequenceNumber >> 8 ).byteValue(); header[3] = new Integer( SequenceNumber ).byteValue(); /* TimeStamp takes 4 bytes = 32 bits */ for ( int i = 0; i < 4; i++ ) header[7-i] = new Integer( TimeStamp >> (8*i) ).byteValue(); /* Ssrc takes 4 bytes = 32 bits */ for ( int i = 0; i < 4; i++ ) header[11-i] = new Integer( Ssrc >> (8*i) ).byteValue(); 

Any other maybe the β€œbest” ways to do this?

+4
source share
5 answers

I think I would use ByteBuffer

 ByteBuffer buf = ByteBuffer.wrap(header); buf.setOrder(ByteOrder.BIG_ENDIAN); buf.put((byte)((Version << 6)|(Padding << 5)|(Extension << 6)|CC)); buf.put((byte)((Marker << 7)|PayloadType)); buf.put((short)SequenceNumber); buf.put(TimeStamp); buf.put(Ssrc); 
+6
source

You can convert int directly to byte in Java without creating an Integer object. Explicit casting is required because byte has a narrower range of possible values ​​than int . For instance:

 header[1] = (byte) (Marker << 7 | PayloadType); 
+2
source

There is one problem with such data. Typically, protocols use unsigned bytes, and Java has bytes. So, for the correct filling of the byte array, I usually use this construction:

 bytearray[index] = (byte) ((some integer-result calculation) & 0xff); 

A simple byte type selection will not work correctly.

Update "& 0xff" is not required here. Simple execution will work.

0
source

in addition to the answers provided try Preon

0
source

With Preon , RtpHeader can be represented as follows:

 public class RtpHeader { @BoundNumber(size = "2") public int version; @Bound public boolean padding; @Bound public boolean extension; @BoundNumber(size="4") public int csrcCount; @Bound public boolean marker; @BoundNumber(size="7") public int payloadType; @BoundNumber(size="16", byteOrder = ByteOrder.BigEndian) public int sequenceNumber; @BoundNumber(size="32", byteOrder = ByteOrder.BigEndian) public int timestamp; @BoundNumber(size="32", byteOrder = ByteOrder.BigEndian) public int synchronizationSource; @BoundList(size="csrcCount") public int[] csrcs; } 

Encoding this byte can be as simple as this:

  Codec<RtpHeader> codec = Codecs.create(RtpHeader.class); RtpHeader header = new RtpHeader(); ... // Setting header values OutputStream out = ...; Codecs.encode(header, codec, out); 

However, remember that coding in Preon is still in its early stages. This seems to work in this particular case, but I'm not going to make any guarantees.

The advantage of using Preon is obviously the fact that you don't have to worry about writing all the coding and decoding logic.

0
source

Source: https://habr.com/ru/post/1306572/


All Articles