簡體   English   中英

用Java填充字節數組

[英]Filling a byte array in Java

對於我正在研究的項目的一部分,我正在實現一個RTP包,我必須用RTP頭字段填充字節的頭部數組。

  //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 ];

這是我的方法:

/*      
 * 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();

任何其他,也許'更好'的方法來做到這一點?

我想我會使用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);

您可以直接將int轉換為Java中的byte ,而無需創建Integer對象。 需要顯式強制轉換,因為一個byte的可能值范圍比int要窄。 例如:

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

這些數據存在一個問題。 通常協議在那里使用無符號字節,Java有簽名字節。 因此,對於正確的字節數組填充,我通常使用這樣的構造:

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

簡單的轉換為字節類型將無法正常工作。

更新。 這里不需要“&0xff”。 簡單的演員會工作。

除了提出的答案,試試Preon

使用Preon ,RtpHeader可以表示如下:

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; 

}

將其編碼為字節可能就像這樣簡單:

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

但是,請記住,Preon中的編碼仍處於早期階段。 對於這個特殊情況,它似乎有效,但我不會做出任何保證。

使用Preon的好處顯然是您不必費心自己編寫所有編碼和解碼邏輯。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM