Fix review comment in RTP H263 Reader

Change-Id: I987baf379ecf3ba3f387cb38f22646023739addb
This commit is contained in:
Rakesh Kumar 2022-05-05 14:01:06 +05:30
parent ffa04ea949
commit ff80a41f90
2 changed files with 38 additions and 10 deletions

View File

@ -101,8 +101,23 @@ import com.google.common.collect.ImmutableMap;
*/ */
private static final int DEFAULT_VP8_HEIGHT = 240; private static final int DEFAULT_VP8_HEIGHT = 240;
/** Default width and height for H263. */ /**
* Default height for H263.
*
* <p>RFC4629 does not mandate codec specific data (like width and height) in the fmtp attribute.
* These values are taken from <a
* href=https://cs.android.com/android/platform/superproject/+/master:frameworks/av/media/codec2/components/mpeg4_h263/C2SoftMpeg4Dec.cpp;l=130
* >Android's software H263 decoder</a>.
*/
private static final int DEFAULT_H263_WIDTH = 352; private static final int DEFAULT_H263_WIDTH = 352;
/**
* Default height for H263.
*
* <p>RFC4629 does not mandate codec specific data (like width and height) in the fmtp attribute.
* These values are taken from <a
* href=https://cs.android.com/android/platform/superproject/+/master:frameworks/av/media/codec2/components/mpeg4_h263/C2SoftMpeg4Dec.cpp;l=130
* >Android's software H263 decoder</a>.
*/
private static final int DEFAULT_H263_HEIGHT = 288; private static final int DEFAULT_H263_HEIGHT = 288;
/** The track's associated {@link RtpPayloadFormat}. */ /** The track's associated {@link RtpPayloadFormat}. */
@ -189,7 +204,8 @@ import com.google.common.collect.ImmutableMap;
processMPEG4FmtpAttribute(formatBuilder, fmtpParameters); processMPEG4FmtpAttribute(formatBuilder, fmtpParameters);
break; break;
case MimeTypes.VIDEO_H263: case MimeTypes.VIDEO_H263:
// H263 does not require a FMTP attribute. So Setting default width and height. // H263 never uses fmtp width and height attributes (RFC4629 Section 8.2), setting default
// width and height.
formatBuilder.setWidth(DEFAULT_H263_WIDTH).setHeight(DEFAULT_H263_HEIGHT); formatBuilder.setWidth(DEFAULT_H263_WIDTH).setHeight(DEFAULT_H263_HEIGHT);
break; break;
case MimeTypes.VIDEO_H264: case MimeTypes.VIDEO_H264:

View File

@ -30,28 +30,31 @@ import androidx.media3.extractor.TrackOutput;
import org.checkerframework.checker.nullness.qual.MonotonicNonNull; import org.checkerframework.checker.nullness.qual.MonotonicNonNull;
/** /**
* Parses a H263 byte stream carried on RTP packets, and extracts H263 individual video frames as * Parses a H263 byte stream carried on RTP packets, and extracts H263 frames as defined in RFC4629.
* defined in RFC4629.
*/ */
/* package */ final class RtpH263Reader implements RtpPayloadReader { /* package */ final class RtpH263Reader implements RtpPayloadReader {
private static final String TAG = "RtpH263Reader"; private static final String TAG = "RtpH263Reader";
private static final long MEDIA_CLOCK_FREQUENCY = 90_000; private static final long MEDIA_CLOCK_FREQUENCY = 90_000;
/** VOP unit type. */ /** I-frame VOP unit type. */
private static final int I_VOP = 0; private static final int I_VOP = 0;
private final RtpPayloadFormat payloadFormat; private final RtpPayloadFormat payloadFormat;
private @MonotonicNonNull TrackOutput trackOutput; private @MonotonicNonNull TrackOutput trackOutput;
/**
* First received RTP timestamp. All RTP timestamps are dimension-less, the time base is defined
* by {@link #MEDIA_CLOCK_FREQUENCY}.
*/
private long firstReceivedTimestamp; private long firstReceivedTimestamp;
private int previousSequenceNumber; private int previousSequenceNumber;
/** The combined size of a sample that is fragmented into multiple RTP packets. */ /** The combined size of a sample that is fragmented into multiple RTP packets. */
private int fragmentedSampleSizeBytes; private int fragmentedSampleSizeBytes;
private static int width; private int width;
private static int height; private int height;
private static boolean isKeyFrame; private boolean isKeyFrame;
private boolean isOutputFormatSet; private boolean isOutputFormatSet;
private long startTimeOffsetUs; private long startTimeOffsetUs;
@ -144,7 +147,7 @@ import org.checkerframework.checker.nullness.qual.MonotonicNonNull;
isKeyFrame ? C.BUFFER_FLAG_KEY_FRAME : 0, isKeyFrame ? C.BUFFER_FLAG_KEY_FRAME : 0,
fragmentedSampleSizeBytes, fragmentedSampleSizeBytes,
/* offset= */ 0, /* offset= */ 0,
/* encryptionData= */ null); /* cryptoData= */ null);
fragmentedSampleSizeBytes = 0; fragmentedSampleSizeBytes = 0;
isKeyFrame = false; isKeyFrame = false;
} }
@ -163,12 +166,21 @@ import org.checkerframework.checker.nullness.qual.MonotonicNonNull;
* Parses VOP Coding type and resolution. * Parses VOP Coding type and resolution.
*/ */
private void getBufferFlagsAndResolutionFromVop(ParsableByteArray data, boolean gotResolution) { private void getBufferFlagsAndResolutionFromVop(ParsableByteArray data, boolean gotResolution) {
// Picture Segment Packets (RFC4629 Section 6.1).
// Search for SHORT_VIDEO_START_MARKER (0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0). // Search for SHORT_VIDEO_START_MARKER (0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0).
int currPosition = data.getPosition(); int currPosition = data.getPosition();
if (data.readUnsignedInt() >> 10 == 0x20) { long shortHeader = data.readUnsignedInt();
if ((shortHeader & 0xffff) >> 10 == 0x20) {
int header = data.peekUnsignedByte(); int header = data.peekUnsignedByte();
int vopType = ((header >> 1) & 0x01); int vopType = ((header >> 1) & 0x01);
if (!gotResolution && vopType == I_VOP) { if (!gotResolution && vopType == I_VOP) {
/**
* Parsing resolution from source format.
*
* <p> These values are taken from <a
* href=https://cs.android.com/android/platform/superproject/+/master:frameworks/av/media/codecs/m4v_h263/dec/src/vop.cpp;l=1126
* >Android's software H263 decoder</a>.
*/
int sourceFormat = ((header >> 2) & 0x07); int sourceFormat = ((header >> 2) & 0x07);
if (sourceFormat == 1) { if (sourceFormat == 1) {
width = 128; width = 128;