WIP fix: Skip NAL header byte when reading SPS profile data in HlsMuxer #20

Open
dean wants to merge 2 commits from fix/hlsmuxer-codec-string into main

View File

@@ -753,17 +753,32 @@ class HlsMuxer(
dos.writeShort(-1) // pre-defined dos.writeShort(-1) // pre-defined
output.write(buildAvcCBox(sps, pps)) output.write(buildAvcCBox(sps, pps))
output.write(buildPaspBox())
return wrapBox("avc1", output.toByteArray()) return wrapBox("avc1", output.toByteArray())
} }
/**
* Builds pixel aspect ratio box to explicitly declare square pixels (1:1).
* This helps players correctly interpret video dimensions without SAR scaling.
*/
private fun buildPaspBox(): ByteArray {
val output = ByteArrayOutputStream()
val dos = DataOutputStream(output)
dos.writeInt(1) // hSpacing (horizontal)
dos.writeInt(1) // vSpacing (vertical)
return wrapBox("pasp", output.toByteArray())
}
private fun buildAvcCBox(sps: ByteArray, pps: ByteArray): ByteArray { private fun buildAvcCBox(sps: ByteArray, pps: ByteArray): ByteArray {
val output = ByteArrayOutputStream() val output = ByteArrayOutputStream()
val dos = DataOutputStream(output) val dos = DataOutputStream(output)
val profileIdc = if (sps.isNotEmpty()) sps[0].toInt() and 0xFF else 0x42 // SPS NAL unit format: [NAL header, profile_idc, constraint_flags, level_idc, ...]
val profileCompat = if (sps.size > 1) sps[1].toInt() and 0xFF else 0x00 // Skip byte 0 (NAL header, typically 0x67) to get the actual profile data
val levelIdc = if (sps.size > 2) sps[2].toInt() and 0xFF else 0x1F val profileIdc = if (sps.size > 1) sps[1].toInt() and 0xFF else 0x42
val profileCompat = if (sps.size > 2) sps[2].toInt() and 0xFF else 0x00
val levelIdc = if (sps.size > 3) sps[3].toInt() and 0xFF else 0x1F
dos.writeByte(1) // configuration version dos.writeByte(1) // configuration version
dos.writeByte(profileIdc) // AVC profile dos.writeByte(profileIdc) // AVC profile