HEVC NAL types are encoded as (byte >> 1) & 0x3f, not byte & 0x7f. The old code checked (byte & 0x7f) == 35, which never matched because HEVC AUD (type 35) appears as byte 0x46 (35 << 1 = 70 = 0x46). This is why H.265 produced zero frames — the delimiter finder never found a frame boundary, so no frames were ever emitted to the client. H.264 was unaffected because its NAL type mask (byte & 0x1f) happened to work for type 9 values.
- commit
- cc543a92226ac53ed945950552c2661a50e28e5b
- parent
- a69055418c4455959a6abd253d15dea95bdd60ce
- author
- dami etoile <dami.etoile@gmail.com>
| M | src-tauri/ | 31 | +++++++++++++++++++----------- |
@@ -870,26 +870,29 @@ fn codec_format(codec: &str) -> (&'static str, &'static str) {
870870 }871871 872872 /// Find the next frame delimiter in the NAL stream.873-/// H.264/H.265: AUD start code (00 00 00 01 + NAL type 9 for H.264, type 35 for H.265)873+/// H.264/H.265: AUD start code (NAL type 9 for H.264, type 35 for H.265)874874 /// AV1: temporal delimiter OBU875875 fn find_next_frame_delim(data: &[u8], from: usize, codec: &str) -> Option<usize> {876- let aud_nal_type = match codec {877- "h265" => 35, // HEVC AUD878- _ => 9, // H.264 AUD879- };880-881876 let mut i = from;882877 while i + 4 < data.len() {883878 if data[i] == 0 && data[i + 1] == 0 {884879 if data[i + 2] == 0 && i + 3 < data.len() && data[i + 3] == 1 {885880 // 4-byte start code886881 if codec == "av1" {887- // AV1 temporal delimiter: OBU type 2 (0x12 or 0x22 with extension flag)882+ // AV1 temporal delimiter: OBU type 2 (0x10 in type field)888883 if i + 4 < data.len() && (data[i + 4] & 0x38) == 0x10 {889884 return Some(i);890885 }891- } else if i + 4 < data.len() && (data[i + 4] & 0x7f) == aud_nal_type {892- return Some(i);886+ } else if codec == "h265" {887+ // HEVC NAL type is (byte >> 1) & 0x3f, AUD = 35888+ if i + 4 < data.len() && ((data[i + 4] >> 1) & 0x3f) == 35 {889+ return Some(i);890+ }891+ } else {892+ // H.264 NAL type is byte & 0x1f, AUD = 9893+ if i + 4 < data.len() && (data[i + 4] & 0x1f) == 9 {894+ return Some(i);895+ }893896 }894897 i += 4;895898 continue;@@ -900,8 +903,14 @@ fn find_next_frame_delim(data: &[u8], from: usize, codec: &str) -> Option<usize>
900903 if i + 3 < data.len() && (data[i + 3] & 0x38) == 0x10 {901904 return Some(i);902905 }903- } else if i + 3 < data.len() && (data[i + 3] & 0x7f) == aud_nal_type {904- return Some(i);906+ } else if codec == "h265" {907+ if i + 3 < data.len() && ((data[i + 3] >> 1) & 0x3f) == 35 {908+ return Some(i);909+ }910+ } else {911+ if i + 3 < data.len() && (data[i + 3] & 0x1f) == 9 {912+ return Some(i);913+ }905914 }906915 i += 3;907916 continue;