@@ -92,6 +92,32 @@ static int mpeg_ts_write_section_header(const mpeg_ts_enc_context_t *ts, int pid
9292 return r ;
9393}
9494
95+
96+ // Generate Opus control header according to ETSI TS 103 491 section 6.2.1
97+ static uint8_t * mpeg_ts_write_opus_control_header (uint8_t * p , size_t payload_size )
98+ {
99+ // opus_control_header according to ETSI TS 103 491 v0.1.3 section 6.2.1
100+ // control_header_prefix: 11 bits = 0x3FF (all 1s)
101+ // start_trim_flag: 1 bit = 0 (no start trimming)
102+ // end_trim_flag: 1 bit = 0 (no end trimming)
103+ // control_extension_flag: 1 bit = 0 (no extensions)
104+ // Reserved: 2 bits = 0
105+ uint16_t header_prefix = 0x7FE0 ; // 11111 1111 1110 0000 = 0x3FF shifted left 5 bits
106+ p [0 ] = (header_prefix >> 8 ) & 0xFF ; // 0x7F
107+ p [1 ] = header_prefix & 0xFF ; // 0xE0
108+
109+ // Write payload size using variable-length encoding
110+ // For sizes >= 255, use 0xFF bytes followed by the remainder
111+ p += 2 ;
112+ while (payload_size >= 255 ) {
113+ * p ++ = 0xFF ;
114+ payload_size -= 255 ;
115+ }
116+ * p ++ = (uint8_t )payload_size ;
117+
118+ return p ;
119+ }
120+
95121static uint8_t * mpeg_ts_write_aud (const mpeg_ts_enc_context_t * tsctx , const struct pes_t * stream , const uint8_t * payload , size_t bytes , uint8_t * p )
96122{
97123 if (PSI_STREAM_H264 == stream -> codecid && !tsctx -> h26x_with_aud && !mpeg_h264_start_with_access_unit_delimiter (payload , bytes ))
@@ -123,6 +149,14 @@ static uint8_t* mpeg_ts_write_aud(const mpeg_ts_enc_context_t* tsctx, const stru
123149 p [6 ] = 0x28 ; // B&P&I (0x2) + rbsp stop one bit
124150 p += 7 ;
125151 }
152+ else if (PSI_STREAM_AUDIO_OPUS == stream -> codecid
153+ && (bytes < 3 || 0x7F != payload [0 ] || 0xE0 != (payload [1 ] & 0xE0 )))
154+ {
155+ // ETSI TS 103 491 v0.1.3 section 6.2.1
156+ // Each Opus access unit in MPEG-TS shall contain an opus_control_header
157+ // when the next 11 bits are 0x3FF. Only add if not already present.
158+ p = mpeg_ts_write_opus_control_header (p , bytes );
159+ }
126160
127161 return p ;
128162}
@@ -552,3 +586,5 @@ int mpeg_ts_add_program_stream(void* ts, uint16_t pn, int codecid, const void* e
552586
553587 return -1 ; // ENOTFOUND: program not found
554588}
589+
590+
0 commit comments