@@ -349,14 +349,35 @@ impl<T: Pixel> ContextInner<T> {
349349 }
350350 self . frame_q . insert ( input_frameno, frame) ;
351351
352+ #[ cfg( feature = "unstable" ) ]
353+ // Update T.35 metadata from encoder config
354+ let maybe_updated_t35_metadata = self . get_maybe_updated_t35_metadata (
355+ input_frameno,
356+ params. as_ref ( ) . map ( |params| params. t35_metadata . as_ref ( ) ) ,
357+ ) ;
358+
352359 if let Some ( params) = params {
353360 if params. frame_type_override == FrameTypeOverride :: Key {
354361 self . keyframes_forced . insert ( input_frameno) ;
355362 }
356363 if let Some ( op) = params. opaque {
357364 self . opaque_q . insert ( input_frameno, op) ;
358365 }
366+
367+ #[ cfg( not( feature = "unstable" ) ) ]
359368 self . t35_q . insert ( input_frameno, params. t35_metadata ) ;
369+
370+ #[ cfg( feature = "unstable" ) ]
371+ if let Some ( new_t35_metadata) = maybe_updated_t35_metadata {
372+ self . t35_q . insert ( input_frameno, new_t35_metadata. into_boxed_slice ( ) ) ;
373+ } else {
374+ self . t35_q . insert ( input_frameno, params. t35_metadata ) ;
375+ }
376+ } else {
377+ #[ cfg( feature = "unstable" ) ]
378+ if let Some ( new_t35_metadata) = maybe_updated_t35_metadata {
379+ self . t35_q . insert ( input_frameno, new_t35_metadata. into_boxed_slice ( ) ) ;
380+ }
360381 }
361382
362383 if !self . needs_more_frame_q_lookahead ( self . next_lookahead_frame ) {
@@ -1688,4 +1709,59 @@ impl<T: Pixel> ContextInner<T> {
16881709 ( prev_keyframe_nframes, prev_keyframe_ntus)
16891710 }
16901711 }
1712+
1713+ #[ cfg( feature = "unstable" ) ]
1714+ /// Updates the T.35 metadata to be added to the frame.
1715+ /// The existing T.35 array may come from `FrameParameters`.
1716+ /// New metadata is added from the encoder config:
1717+ /// - HDR10+, ST2094-40 in `EncoderConfig.hdr10plus_payloads`
1718+ ///
1719+ /// Returns an `Option`, where `None` means the T.35 metadata is unchanged.
1720+ /// Otherwise, the updated T.35 metadata array is returned.
1721+ fn get_maybe_updated_t35_metadata (
1722+ & self , input_frameno : u64 , maybe_existing_t35_metadata : Option < & [ T35 ] > ,
1723+ ) -> Option < Vec < T35 > > {
1724+ let hdr10plus_payload = self
1725+ . config
1726+ . hdr10plus_payloads
1727+ . as_ref ( )
1728+ . and_then ( |list| list. get ( & input_frameno) ) ;
1729+
1730+ let update_t35_metadata = hdr10plus_payload. is_some ( ) ;
1731+
1732+ let mut new_t35_metadata = if update_t35_metadata {
1733+ Some (
1734+ maybe_existing_t35_metadata. map_or_else ( Vec :: new, |t35| t35. to_vec ( ) ) ,
1735+ )
1736+ } else {
1737+ None
1738+ } ;
1739+
1740+ if let Some ( list) = new_t35_metadata. as_mut ( ) {
1741+ // HDR10+, ST2094-40
1742+ if let Some ( payload) = hdr10plus_payload {
1743+ // FIXME: Make const
1744+ let st2094_40_needle = & [
1745+ 0x00 , 0x03C , // Samsung Electronics America
1746+ 0x00 , 0x01 , // ST-2094-40
1747+ 0x04 , // application_identifier = 4
1748+ 0x01 , // application_mode =1
1749+ ] ;
1750+
1751+ let has_existing_hdr10plus_meta = list. iter ( ) . any ( |t35| {
1752+ t35. country_code == 0xB5 && t35. data . starts_with ( st2094_40_needle)
1753+ } ) ;
1754+
1755+ if !has_existing_hdr10plus_meta {
1756+ list. push ( T35 {
1757+ country_code : 0xB5 ,
1758+ country_code_extension_byte : 0x00 ,
1759+ data : payload. clone ( ) . into_boxed_slice ( ) ,
1760+ } ) ;
1761+ }
1762+ }
1763+ }
1764+
1765+ new_t35_metadata
1766+ }
16911767}
0 commit comments