Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 4 additions & 0 deletions io/src/main/java/org/red5/codec/AV1Video.java
Original file line number Diff line number Diff line change
Expand Up @@ -95,6 +95,10 @@ public boolean addData(IoBuffer data, int timestamp) {
// get the fourcc
int fourcc = data.getInt();
// reset back to the beginning after we got the fourcc
if (fourcc != codec.getFourcc()) {
data.reset();
return false;
}
data.reset();
if (isDebug) {
log.debug("{} - frame type: {} packet type: {}", VideoCodec.valueOfByFourCc(fourcc), frameType, packetType);
Expand Down
23 changes: 20 additions & 3 deletions io/src/main/java/org/red5/codec/AbstractVideo.java
Original file line number Diff line number Diff line change
Expand Up @@ -215,9 +215,17 @@ public boolean addData(IoBuffer data, int timestamp) {
if (multitrackType != AvMultitrackType.ManyTracksManyCodecs) {
// The tracks are encoded with the same codec identified by the FOURCC
trackCodec = getTrackCodec(data);
if (trackCodec == null) {
data.rewind();
return false;
}
}
} else {
trackCodec = getTrackCodec(data);
if (trackCodec == null) {
data.rewind();
return false;
}
}
if (isTrace)
log.trace("Multitrack: {} multitrackType: {} packetType: {}", multitrack, multitrackType, packetType);
Expand All @@ -229,6 +237,10 @@ public boolean addData(IoBuffer data, int timestamp) {
if (multitrackType == AvMultitrackType.ManyTracksManyCodecs) {
// The tracks are encoded with their own codec identified by the FOURCC
trackCodec = getTrackCodec(data);
if (trackCodec == null) {
data.rewind();
return false;
}
}
// track ordering
// For identifying the highest priority (a.k.a., default track) or highest quality track, it is RECOMMENDED
Expand All @@ -246,7 +258,7 @@ public boolean addData(IoBuffer data, int timestamp) {
trackSize = (data.get() & 0xff) << 16 | (data.get() & 0xff) << 8 | data.get() & 0xff;
}
// we're multitrack and multicodec so update track id
if (multitrackType == AvMultitrackType.ManyTracksManyCodecs) {
if (multitrackType == AvMultitrackType.ManyTracksManyCodecs && trackCodec != null) {
trackCodec.setTrackId(trackId);
}
} else if (packetType == VideoPacketType.Metadata) {
Expand All @@ -271,7 +283,7 @@ public boolean addData(IoBuffer data, int timestamp) {
if (command != null && trackCodec == null) {
result = true;
} else {
result = multitrack ? true : codec == trackCodec.getCodec();
result = multitrack ? true : (trackCodec != null && codec == trackCodec.getCodec());
}
if (result && this instanceof IEnhancedRTMPVideoCodec) {
IEnhancedRTMPVideoCodec enhancedCodec = IEnhancedRTMPVideoCodec.class.cast(this);
Expand Down Expand Up @@ -326,8 +338,13 @@ protected IVideoStreamCodec getTrackCodec(IoBuffer data) {
log.trace("Fourcc: {} pos: {}", fourcc, data.position());
}
if (!tracks.containsKey(fourcc)) {
VideoCodec trakCodec = VideoCodec.valueOfByFourCc(fourcc);
if (trakCodec == null) {
log.warn("Unknown video fourcc: {}", fourcc);
return null;
}
// create a new codec instance
trackCodec = VideoCodec.valueOfByFourCc(fourcc).newInstance();
trackCodec = trakCodec.newInstance();
tracks.put(fourcc, trackCodec);
} else {
trackCodec = tracks.get(fourcc);
Expand Down
25 changes: 24 additions & 1 deletion io/src/main/java/org/red5/codec/ExtendedAudio.java
Original file line number Diff line number Diff line change
Expand Up @@ -49,7 +49,9 @@ public IAudioStreamCodec getTrackCodec(int trackId) {
public boolean canHandleData(IoBuffer data) {
boolean result = false;
if (data != null && data.limit() > 0) {
data.mark();
result = ((data.get() & IoConstants.MASK_SOUND_FORMAT) >> 4) == codec.getId();
data.reset();
}
return result;
}
Expand Down Expand Up @@ -100,10 +102,18 @@ Standard RTMP bits (for SoundFormat != 9):
if (multitrackType != AvMultitrackType.ManyTracksManyCodecs) {
// The tracks are encoded with the same codec identified by the FOURCC
trackCodec = getTrackCodec(data);
if (trackCodec == null) {
data.reset();
return false;
}
}
} else {
// The tracks are encoded with the same codec identified by the FOURCC
trackCodec = getTrackCodec(data);
if (trackCodec == null) {
data.reset();
return false;
}
}
}
// read all the data
Expand All @@ -114,6 +124,10 @@ Standard RTMP bits (for SoundFormat != 9):
if (multitrackType == AvMultitrackType.ManyTracksManyCodecs) {
// The tracks are encoded with their own codec identified by the FOURCC
trackCodec = getTrackCodec(data);
if (trackCodec == null) {
data.reset();
return false;
}
}
// track ordering
// For identifying the highest priority (a.k.a., default track) or highest quality track, it is RECOMMENDED
Expand All @@ -136,6 +150,10 @@ Standard RTMP bits (for SoundFormat != 9):
}
} else {
trackCodec = getTrackCodec(data);
if (trackCodec == null) {
data.reset();
return false;
}
}
switch (packetType) {
case CodedFrames: // pass coded data
Expand Down Expand Up @@ -194,9 +212,14 @@ Standard RTMP bits (for SoundFormat != 9):
protected IAudioStreamCodec getTrackCodec(IoBuffer data) {
Integer fourcc = data.getInt();
log.debug("Fourcc: {} pos: {}", fourcc, data.position());
AudioCodec audioCodec = AudioCodec.valueOfByFourCc(fourcc);
if (audioCodec == null) {
log.warn("Unknown audio fourcc: {}", fourcc);
return null;
}
if (!tracks.containsKey(fourcc)) {
// create a new codec instance
trackCodec = AudioCodec.valueOfByFourCc(fourcc).newInstance();
trackCodec = audioCodec.newInstance();
tracks.put(fourcc, trackCodec);
} else {
trackCodec = tracks.get(fourcc);
Expand Down
4 changes: 2 additions & 2 deletions io/src/main/java/org/red5/codec/MPEG1Video.java
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@ public class MPEG1Video extends AbstractVideo {
private static boolean isDebug = log.isDebugEnabled();

/** Video decoder configuration data */
private FrameData decoderConfiguration;
private FrameData decoderConfiguration = new FrameData();

{
codec = VideoCodec.MPEG1;
Expand Down Expand Up @@ -60,7 +60,7 @@ public boolean addData(IoBuffer data, int timestamp) {
// get frame type
byte frameType = data.get();
byte avcType = data.get();
if ((frameType & 0x0f) == VideoCodec.AVC.getId()) {
if ((frameType & 0x0f) == codec.getId()) {
// check for keyframe
if ((frameType & 0xf0) == FLV_FRAME_KEY) {
if (isDebug) {
Expand Down
10 changes: 9 additions & 1 deletion io/src/main/java/org/red5/codec/ScreenVideo.java
Original file line number Diff line number Diff line change
Expand Up @@ -153,7 +153,7 @@ private void updateSize(IoBuffer data) {
this.blockDataSize = blockSize;
this.totalBlockDataSize = totalBlockSize;
this.blockData = new byte[blockSize * this.blockCount];
this.blockSize = new int[blockSize * this.blockCount];
this.blockSize = new int[this.blockCount];
// Reset the sizes to zero
for (int idx = 0; idx < this.blockCount; idx++) {
this.blockSize[idx] = 0;
Expand All @@ -176,6 +176,10 @@ public boolean addData(IoBuffer data) {

int countBlocks = this.blockCount;
while (data.remaining() > 0 && countBlocks > 0) {
if (data.remaining() < 2) {
data.rewind();
return false;
}
short size = data.getShort();
countBlocks--;
if (size == 0) {
Expand All @@ -184,6 +188,10 @@ public boolean addData(IoBuffer data) {
pos += this.blockDataSize;
continue;
}
if (size < 0 || size > this.blockDataSize || data.remaining() < size) {
data.rewind();
return false;
}

// Store new block data
this.blockSize[idx] = size;
Expand Down
32 changes: 22 additions & 10 deletions io/src/main/java/org/red5/codec/ScreenVideo2.java
Original file line number Diff line number Diff line change
Expand Up @@ -134,9 +134,9 @@ private void updateSize(IoBuffer data) {
width = widthInfo & 0xfff;
height = heightInfo & 0xfff;
// calculate size of blocks
blockWidth = (widthInfo & 0xf000 >> 12) + 1;
blockWidth = ((widthInfo & 0xf000) >> 12) + 1;
blockWidth <<= 4;
blockHeight = (heightInfo & 0xf000 >> 12) + 1;
blockHeight = ((heightInfo & 0xf000) >> 12) + 1;
blockHeight <<= 4;
int xblocks = width / blockWidth;
if ((width % blockWidth) != 0) {
Expand All @@ -156,7 +156,7 @@ private void updateSize(IoBuffer data) {
blockDataSize = compressedSize;
totalBlockDataSize = totalBlockSize;
blockData = new byte[compressedSize * blockCount];
blockSize = new int[compressedSize * blockCount];
blockSize = new int[blockCount];
// Reset the sizes to zero
for (int idx = 0; idx < blockCount; idx++) {
blockSize[idx] = 0;
Expand All @@ -176,25 +176,37 @@ public boolean addData(IoBuffer data) {
int pos = 0;
byte[] tmpData = new byte[blockDataSize];
// reserved (6) has iframeimage (1) has palleteinfo (1)
if (!data.hasRemaining()) {
data.rewind();
return false;
}
specInfo1 = data.get();
int countBlocks = blockCount;
while (data.remaining() > 0 && countBlocks > 0) {
if (data.remaining() < 2) {
data.rewind();
return false;
}
short size = data.getShort();
countBlocks--;
if (size == 0) {
// Block has not been modified
idx += 1;
pos += blockDataSize;
continue;
} else {
// imageformat
specInfo2 = data.get();
size--;
}
int sizeVal = size & 0xffff;
if (sizeVal < 1 || sizeVal > blockDataSize || data.remaining() < sizeVal) {
data.rewind();
return false;
}
// imageformat
specInfo2 = data.get();
sizeVal--;
// Store new block data
blockSize[idx] = size;
data.get(tmpData, 0, size);
System.arraycopy(tmpData, 0, blockData, pos, size);
blockSize[idx] = sizeVal;
data.get(tmpData, 0, sizeVal);
System.arraycopy(tmpData, 0, blockData, pos, sizeVal);
idx += 1;
pos += blockDataSize;
}
Expand Down