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
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,7 @@ import android.widget.TextView
import androidx.annotation.RequiresApi
import androidx.fragment.app.Fragment
import com.pedro.common.ConnectChecker
import com.pedro.common.VideoCodec
import com.pedro.common.onMainThreadHandler
import com.pedro.encoder.input.sources.video.Camera1Source
import com.pedro.encoder.input.sources.video.Camera2Source
Expand Down Expand Up @@ -78,6 +79,7 @@ class CameraFragment: Fragment(), ConnectChecker {
val genericStream: GenericStream by lazy {
GenericStream(requireContext(), this).apply {
getGlInterface().autoHandleOrientation = true
setVideoCodec(VideoCodec.H265)
}
}
private lateinit var surfaceView: SurfaceView
Expand Down
81 changes: 41 additions & 40 deletions rtsp/src/main/java/com/pedro/rtsp/rtp/packets/H264Packet.kt
Original file line number Diff line number Diff line change
Expand Up @@ -68,10 +68,9 @@ class H264Packet: BasePacket(RtpConstants.clockVideoFrequency,
if (nals.isEmpty()) return

val ts = mediaFrame.info.timestamp * 1000L
val nalType = nals[0].get()
val naluLength = nals.sumOf { it.remaining() }
val type: Int = (nalType and 0x1F).toInt()
val frames = mutableListOf<RtpFrame>()
val nalType = nals[0].get(0)
val type: Int = (nalType and 0x1F).toInt()
if (type == RtpConstants.IDR || mediaFrame.info.isKeyFrame) {
stapA?.let {
val buffer = getBuffer(it.size + RtpConstants.RTP_HEADER_LENGTH)
Expand All @@ -87,50 +86,52 @@ class H264Packet: BasePacket(RtpConstants.clockVideoFrequency,
}
}
if (sendKeyFrame) {
// Small NAL unit => Single NAL unit
if (nals.size == 1 && naluLength <= maxPacketSize - RtpConstants.RTP_HEADER_LENGTH - 1) {
val buffer = getBuffer(naluLength + RtpConstants.RTP_HEADER_LENGTH + 1)
buffer[RtpConstants.RTP_HEADER_LENGTH] = nalType
nals[0].get(buffer, RtpConstants.RTP_HEADER_LENGTH + 1, naluLength)
val rtpTs = updateTimeStamp(buffer, ts)
markPacket(buffer) //mark end frame
updateSeq(buffer)
val rtpFrame = RtpFrame(buffer, rtpTs, buffer.size, channelIdentifier)
frames.add(rtpFrame)
} else {
// Set FU-A header
header[1] = nalType and 0x1F // FU header type
header[1] = header[1].plus(0x80).toByte() // set start bit to 1
// Set FU-A indicator
header[0] = nalType and 0x60 and 0xFF.toByte() // FU indicator NRI
header[0] = header[0].plus(28).toByte()
nals.forEachIndexed { index, data ->
var sum = 0
val nalType = data.get()
val nalSize = data.remaining()
while (sum < nalSize) {
val length = if (nalSize - sum > maxPacketSize - RtpConstants.RTP_HEADER_LENGTH - 2) {
maxPacketSize - RtpConstants.RTP_HEADER_LENGTH - 2
} else {
data.remaining()
}
val buffer = getBuffer(length + RtpConstants.RTP_HEADER_LENGTH + 2)
buffer[RtpConstants.RTP_HEADER_LENGTH] = header[0]
// Switch start bit
buffer[RtpConstants.RTP_HEADER_LENGTH + 1] = if (sum > 0) header[1] and 0x7F else header[1]
// Small NAL unit => Single NAL unit
if (nalSize <= maxPacketSize - RtpConstants.RTP_HEADER_LENGTH - 1) {
val buffer = getBuffer(nalSize + RtpConstants.RTP_HEADER_LENGTH + 1)
buffer[RtpConstants.RTP_HEADER_LENGTH] = nalType
data.get(buffer, RtpConstants.RTP_HEADER_LENGTH + 1, nalSize)
val rtpTs = updateTimeStamp(buffer, ts)
data.get(buffer, RtpConstants.RTP_HEADER_LENGTH + 2, length)
sum += length
// Last packet before next NAL
if (sum >= nalSize) {
// End bit on
buffer[RtpConstants.RTP_HEADER_LENGTH + 1] = buffer[RtpConstants.RTP_HEADER_LENGTH + 1].plus(0x40).toByte()
if (index == nals.size - 1) markPacket(buffer) //mark end frame
}
if (index == nals.size - 1) markPacket(buffer) //mark end frame
updateSeq(buffer)
val rtpFrame = RtpFrame(buffer, rtpTs, buffer.size, channelIdentifier)
frames.add(rtpFrame)
} else {
// Set FU-A header
header[1] = nalType and 0x1F // FU header type
header[1] = header[1].plus(0x80).toByte() // set start bit to 1
// Set FU-A indicator
header[0] = nalType and 0x60 and 0xFF.toByte() // FU indicator NRI
header[0] = header[0].plus(28).toByte()

var sum = 0
while (sum < nalSize) {
val length = if (nalSize - sum > maxPacketSize - RtpConstants.RTP_HEADER_LENGTH - 2) {
maxPacketSize - RtpConstants.RTP_HEADER_LENGTH - 2
} else {
data.remaining()
}
val buffer = getBuffer(length + RtpConstants.RTP_HEADER_LENGTH + 2)
buffer[RtpConstants.RTP_HEADER_LENGTH] = header[0]
// Switch start bit
buffer[RtpConstants.RTP_HEADER_LENGTH + 1] = if (sum > 0) header[1] and 0x7F else header[1]
val rtpTs = updateTimeStamp(buffer, ts)
data.get(buffer, RtpConstants.RTP_HEADER_LENGTH + 2, length)
sum += length
// Last packet before next NAL
if (sum >= nalSize) {
// End bit on
buffer[RtpConstants.RTP_HEADER_LENGTH + 1] = buffer[RtpConstants.RTP_HEADER_LENGTH + 1].plus(0x40).toByte()
if (index == nals.size - 1) markPacket(buffer) //mark end frame
}
updateSeq(buffer)
val rtpFrame = RtpFrame(buffer, rtpTs, buffer.size, channelIdentifier)
frames.add(rtpFrame)
}
}
}
}
} else {
Log.i(TAG, "waiting for keyframe")
Expand Down
64 changes: 32 additions & 32 deletions rtsp/src/main/java/com/pedro/rtsp/rtp/packets/H265Packet.kt
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,6 @@ 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.getVideoStartCodeSize
import java.nio.ByteBuffer
import kotlin.experimental.and

Expand All @@ -32,7 +31,7 @@ import kotlin.experimental.and
*
* RFC 7798.
*/
class H265Packet: BasePacket(
class H265Packet : BasePacket(
RtpConstants.clockVideoFrequency,
RtpConstants.payloadType + RtpConstants.trackVideo
) {
Expand Down Expand Up @@ -64,38 +63,39 @@ class H265Packet: BasePacket(
if (nals.isEmpty()) return

val ts = mediaFrame.info.timestamp * 1000L
val nalType = nals[0].get()
val nalType2 = nals[0].get()
val naluLength = nals.sumOf { it.remaining() }
val type: Int = nalType.toInt().shr(1 and 0x3f)
val frames = mutableListOf<RtpFrame>()
// Small NAL unit => Single NAL unit
if (nals.size == 1 && naluLength <= maxPacketSize - RtpConstants.RTP_HEADER_LENGTH - 2) {
val buffer = getBuffer(naluLength + RtpConstants.RTP_HEADER_LENGTH + 2)
//Set PayloadHdr (exact copy of nal unit header)
buffer[RtpConstants.RTP_HEADER_LENGTH] = nalType
buffer[RtpConstants.RTP_HEADER_LENGTH + 1] = nalType2
nals[0].get(buffer, RtpConstants.RTP_HEADER_LENGTH + 2, naluLength)
val rtpTs = updateTimeStamp(buffer, ts)
markPacket(buffer) //mark end frame
updateSeq(buffer)
val rtpFrame = RtpFrame(buffer, rtpTs, buffer.size, channelIdentifier)
frames.add(rtpFrame)
} else {
//Set PayloadHdr (16bit type=49)
header[0] = (49 shl 1).toByte()
header[1] = 1
// Set FU header
// +---------------+
// |0|1|2|3|4|5|6|7|
// +-+-+-+-+-+-+-+-+
// |S|E| FuType |
// +---------------+
header[2] = type.toByte() // FU header type
header[2] = header[2].plus(0x80).toByte() // Start bit
nals.forEachIndexed { index, data ->

nals.forEachIndexed { index, data ->
val nalType = data.get()
val nalType2 = data.get()
val nalSize = data.remaining()
// Small NAL unit => Single NAL unit
if (nalSize <= maxPacketSize - RtpConstants.RTP_HEADER_LENGTH - 2) {
val buffer = getBuffer(nalSize + RtpConstants.RTP_HEADER_LENGTH + 2)
//Set PayloadHdr (exact copy of nal unit header)
buffer[RtpConstants.RTP_HEADER_LENGTH] = nalType
buffer[RtpConstants.RTP_HEADER_LENGTH + 1] = nalType2
data.get(buffer, RtpConstants.RTP_HEADER_LENGTH + 2, nalSize)
val rtpTs = updateTimeStamp(buffer, ts)
if (index == nals.size - 1) markPacket(buffer) //mark end frame
updateSeq(buffer)
val rtpFrame = RtpFrame(buffer, rtpTs, buffer.size, channelIdentifier)
frames.add(rtpFrame)
} else {
val type: Int = nalType.toInt().shr(1 and 0x3f)
//Set PayloadHdr (16bit type=49)
header[0] = (49 shl 1).toByte()
header[1] = 1
// Set FU header
// +---------------+
// |0|1|2|3|4|5|6|7|
// +-+-+-+-+-+-+-+-+
// |S|E| FuType |
// +---------------+
header[2] = type.toByte() // FU header type
header[2] = header[2].plus(0x80).toByte() // Start bit

var sum = 0
val nalSize = data.remaining()
while (sum < nalSize) {
val length = if (nalSize - sum > maxPacketSize - RtpConstants.RTP_HEADER_LENGTH - 3) {
maxPacketSize - RtpConstants.RTP_HEADER_LENGTH - 3
Expand Down
Loading