diff --git a/libraries/exoplayer_rtsp/src/main/java/androidx/media3/exoplayer/rtsp/reader/RtpH263Reader.java b/libraries/exoplayer_rtsp/src/main/java/androidx/media3/exoplayer/rtsp/reader/RtpH263Reader.java index 147887e665..341d64256c 100644 --- a/libraries/exoplayer_rtsp/src/main/java/androidx/media3/exoplayer/rtsp/reader/RtpH263Reader.java +++ b/libraries/exoplayer_rtsp/src/main/java/androidx/media3/exoplayer/rtsp/reader/RtpH263Reader.java @@ -104,7 +104,8 @@ import org.checkerframework.checker.nullness.qual.MonotonicNonNull; // | RR |P|V| PLEN |PEBIT| // +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ int currentPosition = data.getPosition(); - int header = data.readUnsignedShort(); + ParsableByteArray bitstreamData = new ParsableByteArray(data.getData().clone()); + int header = bitstreamData.readUnsignedShort(); boolean pBitIsSet = (header & 0x400) > 0; // Check if optional V (Video Redundancy Coding), PLEN or PEBIT is present, RFC4629 Section 5.1. @@ -123,16 +124,16 @@ import org.checkerframework.checker.nullness.qual.MonotonicNonNull; } gotFirstPacketOfH263Frame = true; - int payloadStartCode = data.peekUnsignedByte() & 0xFC; + int payloadStartCode = bitstreamData.peekUnsignedByte() & 0xFC; // Packets that begin with a Picture Start Code(100000). Refer RFC4629 Section 6.1. if (payloadStartCode < PICTURE_START_CODE) { Log.w(TAG, "Picture start Code (PSC) missing, dropping packet."); return; } // Setting first two bytes of the start code. Refer RFC4629 Section 6.1.1. - data.getData()[currentPosition] = 0; - data.getData()[currentPosition + 1] = 0; - data.setPosition(currentPosition); + bitstreamData.getData()[currentPosition] = 0; + bitstreamData.getData()[currentPosition + 1] = 0; + bitstreamData.setPosition(currentPosition); } else if (gotFirstPacketOfH263Frame) { // Check that this packet is in the sequence of the previous packet. int expectedSequenceNumber = RtpPacket.getNextSequenceNumber(previousSequenceNumber); @@ -154,7 +155,7 @@ import org.checkerframework.checker.nullness.qual.MonotonicNonNull; } if (fragmentedSampleSizeBytes == 0) { - parseVopHeader(data, isOutputFormatSet); + parseVopHeader(bitstreamData, isOutputFormatSet); if (!isOutputFormatSet && isKeyFrame) { if (width != payloadFormat.format.width || height != payloadFormat.format.height) { trackOutput.format( @@ -163,9 +164,9 @@ import org.checkerframework.checker.nullness.qual.MonotonicNonNull; isOutputFormatSet = true; } } - int fragmentSize = data.bytesLeft(); + int fragmentSize = bitstreamData.bytesLeft(); // Write the video sample. - trackOutput.sampleData(data, fragmentSize); + trackOutput.sampleData(bitstreamData, fragmentSize); fragmentedSampleSizeBytes += fragmentSize; sampleTimeUsOfFragmentedSample = toSampleUs(startTimeOffsetUs, timestamp, firstReceivedTimestamp);