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
12 changes: 12 additions & 0 deletions common/src/main/java/com/pedro/common/Extensions.kt
Original file line number Diff line number Diff line change
Expand Up @@ -341,4 +341,16 @@ fun ByteBuffer.put(buffer: ByteBuffer, offset: Int, length: Int) {
*/
fun InetAddress.addressToString(): String {
return (hostAddress ?: hostName).substringBefore("%")
}

fun ByteBuffer.getData(): ByteArray = removeHeader().toByteArray()

fun ByteBuffer.removeHeader(): ByteBuffer {
val startCodeSize = this.getStartCodeSize()
this.position(startCodeSize)
return this.slice()
}

fun ByteArray.writeUInt32(offset: Int, value: Int) {
value.toUInt32().copyInto(this, offset)
}
52 changes: 52 additions & 0 deletions common/src/test/java/com/pedro/common/ExtensionTest.kt
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@
package com.pedro.common

import com.pedro.common.frame.MediaFrame
import org.junit.Assert.assertArrayEquals
import org.junit.Assert.assertEquals
import org.junit.Test
import java.nio.ByteBuffer
Expand Down Expand Up @@ -55,4 +56,55 @@ class ExtensionTest {
val md5Hash = fakeBuffer.getMd5Hash()
assertEquals(expectedResult, md5Hash)
}

@Test
fun `GIVEN ByteBuffer WHEN start code has 3 bytes THEN return 3`() {
val fakeBuffer = ByteBuffer.wrap(byteArrayOf(0x0, 0x0, 0x1, 0x0))
val index = fakeBuffer.getStartCodeSize()
assertEquals(3, index)
}

@Test
fun `GIVEN ByteBuffer WHEN start code has 4 bytes THEN return 4`() {
val fakeBuffer = ByteBuffer.wrap(byteArrayOf(0x0, 0x0, 0x0, 0x1, 0x0))
val index = fakeBuffer.getStartCodeSize()
assertEquals(4, index)
}

@Test
fun `GIVEN ByteBuffer WHEN start code not found THEN return 0`() {
val fakeBuffer = ByteBuffer.wrap(byteArrayOf(0x0, 0x0, 0x0, 0x0, 0x0))
val index = fakeBuffer.getStartCodeSize()
assertEquals(0, index)
}

@Test
fun `GIVEN a ByteBuffer WHEN get data THEN get bytearray without start code`() {
val fakeByteBuffer = ByteBuffer.wrap(byteArrayOf(0x00, 0x00, 0x00, 0x01, 0x01))
val expectedResult = byteArrayOf(0x01)
val result = fakeByteBuffer.getData()
assertArrayEquals(expectedResult, result)
}

@Test
fun `GIVEN a ByteBuffer with start code WHEN remove header THEN get a buffer without start code`() {
val fakeBuffer = ByteBuffer.wrap(byteArrayOf(0x00, 0x00, 0x00, 0x01, 0x65, 0x02))
val result = fakeBuffer.removeHeader()
assertEquals(ByteBuffer.wrap(byteArrayOf(0x65, 0x02)), result)
}

@Test
fun `GIVEN a ByteBuffer without start code WHEN remove header THEN get a buffer with the same data`() {
val fakeBuffer = ByteBuffer.wrap(byteArrayOf(0x65, 0x02, 0x03, 0x04))
val result = fakeBuffer.removeHeader()
assertEquals(ByteBuffer.wrap(byteArrayOf(0x65, 0x02, 0x03, 0x04)), result)
}

@Test
fun `GIVEN a ByteArray WHEN write uint32 in an offset THEN get array with value written in big endian`() {
val fakeBuffer = ByteArray(8)
fakeBuffer.writeUInt32(2, 0x01020304)
val expectedResult = byteArrayOf(0x00, 0x00, 0x01, 0x02, 0x03, 0x04, 0x00, 0x00)
assertArrayEquals(expectedResult, fakeBuffer)
}
}
20 changes: 4 additions & 16 deletions rtmp/src/main/java/com/pedro/rtmp/flv/video/packet/H264Packet.kt
Original file line number Diff line number Diff line change
Expand Up @@ -21,8 +21,10 @@ import com.pedro.common.VideoCodec
import com.pedro.common.frame.MediaFrame
import com.pedro.common.getStartCodeSize
import com.pedro.common.nal.NalReader
import com.pedro.common.removeHeader
import com.pedro.common.removeInfo
import com.pedro.common.toByteArray
import com.pedro.common.writeUInt32
import com.pedro.rtmp.flv.BasePacket
import com.pedro.rtmp.flv.FlvPacket
import com.pedro.rtmp.flv.FlvType
Expand Down Expand Up @@ -54,7 +56,7 @@ class H264Packet: BasePacket() {
}

fun sendVideoInfo(sps: ByteBuffer, pps: ByteBuffer) {
videoInfo = listOf(removeHeader(sps), removeHeader(pps))
videoInfo = listOf(sps.removeHeader(), pps.removeHeader())
}

override suspend fun createFlvPacket(
Expand Down Expand Up @@ -111,28 +113,14 @@ class H264Packet: BasePacket() {
var offset = header.size
nals.forEach {
val nalSize = it.capacity()
writeNaluSize(buffer, offset, nalSize)
buffer.writeUInt32(offset, nalSize)
it.get(buffer, offset + naluSize, nalSize)
offset += naluSize + nalSize
}
System.arraycopy(header, 0, buffer, 0, header.size)
callback(FlvPacket(buffer, ts, buffer.size, FlvType.VIDEO))
}

//naluSize = UInt32
private fun writeNaluSize(buffer: ByteArray, offset: Int, size: Int) {
buffer[offset] = (size ushr 24).toByte()
buffer[offset + 1] = (size ushr 16).toByte()
buffer[offset + 2] = (size ushr 8).toByte()
buffer[offset + 3] = size.toByte()
}

private fun removeHeader(byteBuffer: ByteBuffer, size: Int = -1): ByteBuffer {
val position = if (size == -1) byteBuffer.getStartCodeSize() else size
byteBuffer.position(position)
return byteBuffer.slice()
}

override fun reset(resetInfo: Boolean) {
if (resetInfo) videoInfo = null
configSend = false
Expand Down
20 changes: 4 additions & 16 deletions rtmp/src/main/java/com/pedro/rtmp/flv/video/packet/H265Packet.kt
Original file line number Diff line number Diff line change
Expand Up @@ -21,8 +21,10 @@ import com.pedro.common.VideoCodec
import com.pedro.common.frame.MediaFrame
import com.pedro.common.getStartCodeSize
import com.pedro.common.nal.NalReader
import com.pedro.common.removeHeader
import com.pedro.common.removeInfo
import com.pedro.common.toByteArray
import com.pedro.common.writeUInt32
import com.pedro.rtmp.flv.BasePacket
import com.pedro.rtmp.flv.FlvPacket
import com.pedro.rtmp.flv.FlvType
Expand All @@ -49,7 +51,7 @@ class H265Packet: BasePacket() {
private var videoInfo: List<ByteBuffer>? = null

fun sendVideoInfo(sps: ByteBuffer, pps: ByteBuffer, vps: ByteBuffer) {
this.videoInfo = listOf(removeHeader(sps), removeHeader(pps), removeHeader(vps))
this.videoInfo = listOf(sps.removeHeader(), pps.removeHeader(), vps.removeHeader())
}

override suspend fun createFlvPacket(
Expand Down Expand Up @@ -111,28 +113,14 @@ class H265Packet: BasePacket() {
var offset = header.size
nals.forEach {
val nalSize = it.capacity()
writeNaluSize(buffer, offset, nalSize)
buffer.writeUInt32(offset, nalSize)
it.get(buffer, offset + naluSize, nalSize)
offset += naluSize + nalSize
}
System.arraycopy(header, 0, buffer, 0, header.size)
callback(FlvPacket(buffer, ts, buffer.size, FlvType.VIDEO))
}

//naluSize = UInt32
private fun writeNaluSize(buffer: ByteArray, offset: Int, size: Int) {
buffer[offset] = (size ushr 24).toByte()
buffer[offset + 1] = (size ushr 16).toByte()
buffer[offset + 2] = (size ushr 8).toByte()
buffer[offset + 3] = size.toByte()
}

private fun removeHeader(byteBuffer: ByteBuffer, size: Int = -1): ByteBuffer {
val position = if (size == -1) byteBuffer.getStartCodeSize() else size
byteBuffer.position(position)
return byteBuffer.slice()
}

override fun reset(resetInfo: Boolean) {
if (resetInfo) videoInfo = null
configSend = false
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -18,11 +18,11 @@ package com.pedro.rtsp.rtp.packets

import com.pedro.common.VideoCodec
import com.pedro.common.frame.MediaFrame
import com.pedro.common.getData
import com.pedro.common.nal.NalReader
import com.pedro.common.removeInfo
import com.pedro.rtsp.rtsp.RtpFrame
import com.pedro.rtsp.utils.RtpConstants
import com.pedro.rtsp.utils.getData
import java.nio.ByteBuffer
import kotlin.experimental.and
import kotlin.experimental.or
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -18,11 +18,11 @@ package com.pedro.rtsp.rtp.packets

import com.pedro.common.VideoCodec
import com.pedro.common.frame.MediaFrame
import com.pedro.common.getData
import com.pedro.common.nal.NalReader
import com.pedro.common.removeInfo
import com.pedro.rtsp.rtsp.RtpFrame
import com.pedro.rtsp.utils.RtpConstants
import com.pedro.rtsp.utils.getData
import java.nio.ByteBuffer
import kotlin.experimental.or

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@ import android.util.Log
import com.pedro.common.AudioCodec
import com.pedro.common.TimeUtils
import com.pedro.common.VideoCodec
import com.pedro.common.getData
import com.pedro.common.getMd5Hash
import com.pedro.common.socket.base.TcpStreamSocket
import com.pedro.rtsp.rtsp.Protocol
Expand All @@ -31,7 +32,6 @@ import com.pedro.rtsp.rtsp.commands.SdpBody.createH265Body
import com.pedro.rtsp.rtsp.commands.SdpBody.createOpusBody
import com.pedro.rtsp.utils.RtpTracks
import com.pedro.rtsp.utils.encodeToString
import com.pedro.rtsp.utils.getData
import java.io.IOException
import java.net.DatagramSocket
import java.nio.ByteBuffer
Expand Down
22 changes: 0 additions & 22 deletions rtsp/src/main/java/com/pedro/rtsp/utils/Extensions.kt
Original file line number Diff line number Diff line change
Expand Up @@ -25,32 +25,10 @@ fun ByteArray.encodeToString(): String {
return Base64.encode(this)
}

fun ByteBuffer.getData(): ByteArray {
val startCodeSize = this.getVideoStartCodeSize()
val bytes = ByteArray(this.capacity() - startCodeSize)
this.position(startCodeSize)
this.get(bytes, 0, bytes.size)
return bytes
}

fun ByteArray.setLong(n: Long, begin: Int, end: Int) {
var value = n
for (i in end - 1 downTo begin step 1) {
this[i] = (value % 256).toByte()
value = value shr 8
}
}

fun ByteBuffer.getVideoStartCodeSize(): Int {
var startCodeSize = 0
if (this.get(0).toInt() == 0x00 && this.get(1).toInt() == 0x00
&& this.get(2).toInt() == 0x00 && this.get(3).toInt() == 0x01) {
//match 00 00 00 01
startCodeSize = 4
} else if (this.get(0).toInt() == 0x00 && this.get(1).toInt() == 0x00
&& this.get(2).toInt() == 0x01) {
//match 00 00 01
startCodeSize = 3
}
return startCodeSize
}
29 changes: 0 additions & 29 deletions rtsp/src/test/java/com/pedro/rtsp/utils/ExtensionsTest.kt
Original file line number Diff line number Diff line change
Expand Up @@ -34,14 +34,6 @@ class ExtensionsTest {
assertEquals(expectedString, result)
}

@Test
fun `GIVEN a ByteBuffer WHEN get data THEN get bytearray without startVideoCode`() {
val fakeByteBuffer = ByteBuffer.wrap(byteArrayOf(0x00, 0x00, 0x00, 0x01, 0x01))
val expectedResult = byteArrayOf(0x01)
val result = fakeByteBuffer.getData()
assertArrayEquals(expectedResult, result)
}

@Test
fun `GIVEN ByteArray WHEN set long value in a position with a limit THEN get array with long put`() {
val fakeBuffer = byteArrayOf(0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0)
Expand All @@ -50,25 +42,4 @@ class ExtensionsTest {
fakeBuffer.setLong(value, 0, 4)
assertArrayEquals(expectedResult, fakeBuffer)
}

@Test
fun `GIVEN ByteBuffer WHEN video start code has 3 bytes THEN return 3`() {
val fakeBuffer = ByteBuffer.wrap(byteArrayOf(0x0, 0x0, 0x1, 0x0))
val index = fakeBuffer.getVideoStartCodeSize()
assertEquals(3, index)
}

@Test
fun `GIVEN ByteBuffer WHEN video start code has 4 bytes THEN return 4`() {
val fakeBuffer = ByteBuffer.wrap(byteArrayOf(0x0, 0x0, 0x0, 0x1, 0x0))
val index = fakeBuffer.getVideoStartCodeSize()
assertEquals(4, index)
}

@Test
fun `GIVEN ByteBuffer WHEN video start code not found THEN return 0`() {
val fakeBuffer = ByteBuffer.wrap(byteArrayOf(0x0, 0x0, 0x0, 0x0, 0x0))
val index = fakeBuffer.getVideoStartCodeSize()
assertEquals(0, index)
}
}
Loading
Loading