From 3bacb1646c9ecd01e403465c7643888e83a9e79d Mon Sep 17 00:00:00 2001 From: Manisha Jajoo Date: Mon, 18 Jul 2022 10:43:41 +0530 Subject: [PATCH] Keep the input data constant in consume method Earlier, the consume method of RtpH263Reader was changing the bytes of the input bitstream during header parse. This commit copies the input into local context and changes the local variable as per the specifications thus keeping the input constant. --- .../exoplayer/rtsp/reader/RtpH263Reader.java | 17 +++++++++-------- 1 file changed, 9 insertions(+), 8 deletions(-) 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);