5

私が取り組んでいるプロジェクトの一部では、バイトのヘッダー配列に RTP ヘッダー フィールドを入力する必要がある RTPpacket を実装しています。

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

これを行うための他の、おそらく「より良い」方法はありますか?

4

5 に答える 5

6

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);
于 2010-04-10T19:22:18.837 に答える
2

オブジェクトを作成しなくても、 Java で を にint直接変換できます。aは可能な値の範囲が an よりも狭いため、明示的なキャストが必要です。例えば:byteIntegerbyteint

header[1] = (byte) (Marker << 7 | PayloadType);
于 2010-04-10T18:33:53.337 に答える
0

提示された回答に加えて、プレオンを試してみてください

于 2010-04-10T23:36:18.003 に答える
0

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 を使用する利点は、エンコードとデコードのロジックをすべて自分で作成する必要がないことです。

于 2010-08-28T14:11:33.780 に答える
0

このようなデータには 1 つの問題があります。通常、プロトコルはそこで符号なしバイトを使用し、Java には符号付きバイトがあります。したがって、正しいバイト配列の塗りつぶしのために、私は通常、次のような構成を使用します。

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

バイト型への単純なキャストは正しく機能しません。

アップデート。「& 0xff」はここでは必要ありません。単純なキャストが機能します。

于 2010-04-10T18:52:31.580 に答える