Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Rtp mpeg4 #35

Merged
merged 6 commits into from Apr 11, 2022
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
Expand Up @@ -56,7 +56,7 @@
/** Prefix for the RFC6381 codecs string for AVC formats. */
private static final String H264_CODECS_PREFIX = "avc1.";
/** Prefix for the RFC6416 codecs string for MPEG4V-ES formats. */
private static final String MPEG4_CODECS_PREFIX = "mp4v";
private static final String MPEG4_CODECS_PREFIX = "mp4v.";

private static final String GENERIC_CONTROL_ATTR = "*";

Expand Down Expand Up @@ -181,12 +181,14 @@ private static void processMPEG4FmtpAttribute(
Format.Builder formatBuilder, ImmutableMap<String, String> fmtpAttributes) {
@Nullable String configInput = fmtpAttributes.get(PARAMETER_MP4V_CONFIG);
if (configInput != null) {
byte[] csd = Util.getBytesFromHexString(configInput);
formatBuilder.setInitializationData(ImmutableList.of(csd));
byte[] configBuffer = Util.getBytesFromHexString(configInput);
formatBuilder.setInitializationData(ImmutableList.of(configBuffer));
Pair<Integer, Integer> resolution =
CodecSpecificDataUtil.getVideoResolutionFromMpeg4VideoConfig(csd);
formatBuilder.setWidth(resolution.first);
formatBuilder.setHeight(resolution.second);
CodecSpecificDataUtil.getVideoResolutionFromMpeg4VideoConfig(configBuffer);
formatBuilder.setWidth(resolution.first).setHeight(resolution.second);
} else {
// set the default width and height
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why is the default width and height 352x288? Is it in an RFC? If so please add a link

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The default resolution is not mentioned in RFC.
For non-standard fmtp where configinput is missing, we use 352X288 as default since CIF is the default resolution used by Android Software decoder. Adding the link for your reference
https://cs.android.com/android/platform/superproject/+/master:frameworks/av/media/codec2/components/mpeg4_h263/C2SoftMpeg4Dec.cpp;l=130

formatBuilder.setWidth(352).setHeight(288);
}
@Nullable String profileLevel = fmtpAttributes.get(PARAMETER_PROFILE_LEVEL_ID);
formatBuilder.setCodecs(MPEG4_CODECS_PREFIX + (profileLevel == null ? "1" : profileLevel));
Expand Down
Expand Up @@ -88,7 +88,9 @@ public void consume(ParsableByteArray data, long timestamp, int sequenceNumber,
// Parse VOP Type and get the buffer flags
int limit = data.bytesLeft();
trackOutput.sampleData(data, limit);
if (sampleLength == 0) bufferFlags = getBufferFlagsFromVop(data);
if (sampleLength == 0) {
bufferFlags = getBufferFlagsFromVop(data);
}
sampleLength += limit;

// Marker (M) bit: The marker bit is set to 1 to indicate the last RTP
Expand Down Expand Up @@ -122,17 +124,16 @@ public void seek(long nextRtpTimestamp, long timeUs) {
*/
@C.BufferFlags
private static int getBufferFlagsFromVop(ParsableByteArray data) {
int flags = 0;
// search for VOP_START_CODE (00 00 01 B6)
byte[] inputData = data.getData();
byte[] startCode = new byte[] {0x0, 0x0, 0x1, (byte) 0xB6};
int vopStartCodePos = Bytes.indexOf(inputData, startCode);
if (vopStartCodePos != -1) {
data.setPosition(vopStartCodePos + 4);
int vopType = data.peekUnsignedByte() >> 6;
flags = vopType == I_VOP ? C.BUFFER_FLAG_KEY_FRAME : 0;
return (vopType == I_VOP ? C.BUFFER_FLAG_KEY_FRAME : 0);
}
return flags;
return 0;
}

private static long toSampleUs(
Expand Down