@@ -120,12 +120,102 @@ void AVSC_CC assrender_destroy(void* ud, AVS_ScriptEnvironment* env)
120120 free (ud );
121121}
122122
123+ static matrix_type matrix_from_frame_props (
124+ AVS_ScriptEnvironment * env ,
125+ AVS_Clip * clip ,
126+ const AVS_VideoInfo * vi ,
127+ int * ok_out )
128+ {
129+ * ok_out = 0 ;
130+
131+ if (!avs_has_video (vi ) || !avs_is_yuv (vi ))
132+ return MATRIX_NONE ;
133+
134+ AVS_VideoFrame * frame = avs_get_frame (clip , 0 );
135+ if (!frame )
136+ return MATRIX_NONE ;
137+
138+ int err ;
139+ const AVS_Map * props = avs_get_frame_props_ro (env , frame );
140+ if (!props ) {
141+ avs_release_video_frame (frame );
142+ return MATRIX_NONE ;
143+ }
144+
145+ // _Matrix: ITU-T H.265 Table E.5 / AviSynth+ AVS_MATRIX_* index
146+ int matrix = avs_prop_get_int (env , props , "_Matrix" , 0 , & err );
147+ if (err ) {
148+ avs_release_video_frame (frame );
149+ return MATRIX_NONE ;
150+ }
151+
152+ // _ColorRange: 0 = full (PC), 1 = limited (TV) :contentReference[oaicite:1]{index=1}
153+ int range = avs_prop_get_int (env , props , "_ColorRange" , 0 , & err );
154+ if (err )
155+ range = 1 ; // default to TV/limited for YUV if not present
156+
157+ avs_release_video_frame (frame );
158+
159+ const int full = (range == 0 );
160+
161+ /*
162+ * _Matrix values (H.265 / AviSynth+):
163+ * 0: RGB
164+ * 1: BT.709
165+ * 2: unspecified
166+ * 4: FCC (BT.470M)
167+ * 5: BT.470BG / Rec.601
168+ * 6: ST.170M (also 601)
169+ * 7: ST.240M
170+ * 9: BT.2020 (non-constant luminance)
171+ * 10: BT.2020 (constant luminance)
172+ * (others ignored here)
173+ */
174+
175+ matrix_type mt = MATRIX_NONE ;
176+
177+ switch (matrix ) {
178+ case 1 : // BT.709
179+ mt = full ? MATRIX_PC709 : MATRIX_BT709 ;
180+ break ;
181+
182+ case 5 : // BT.470BG / Rec.601
183+ case 6 : // ST.170M (treated as 601)
184+ mt = full ? MATRIX_PC601 : MATRIX_BT601 ;
185+ break ;
186+
187+ case 4 : // FCC
188+ mt = full ? MATRIX_PCFCC : MATRIX_TVFCC ;
189+ break ;
190+
191+ case 7 : // 240M
192+ mt = full ? MATRIX_PC240M : MATRIX_TV240M ;
193+ break ;
194+
195+ case 9 : // BT.2020 (ncl)
196+ case 10 :// BT.2020 (cl)
197+ mt = full ? MATRIX_PC2020 : MATRIX_BT2020 ;
198+ break ;
199+
200+ default :
201+ // 0 (RGB), 2 (unspec), 8 (YCgCo), 12/13/14… → we don’t trust it
202+ mt = MATRIX_NONE ;
203+ break ;
204+ }
205+
206+ if (mt != MATRIX_NONE )
207+ * ok_out = 1 ;
208+
209+ return mt ;
210+ }
211+
123212AVS_Value AVSC_CC assrender_create (AVS_ScriptEnvironment * env , AVS_Value args ,
124213 void * ud )
125214{
126215 AVS_Value v ;
127216 AVS_FilterInfo * fi ;
128217 AVS_Clip * c = avs_new_c_filter (env , & fi , avs_array_elt (args , 0 ), 1 );
218+ const AVS_VideoInfo * vi = & fi -> vi ;
129219 char e [250 ];
130220
131221 const char * f = avs_as_string (avs_array_elt (args , 1 ));
@@ -366,10 +456,23 @@ AVS_Value AVSC_CC assrender_create(AVS_ScriptEnvironment* env, AVS_Value args,
366456 color_mt = MATRIX_BT2020;
367457 else
368458 */
369- if (fi -> vi .width > 1280 || fi -> vi .height > 576 )
370- color_mt = MATRIX_PC709 ;
371- else
372- color_mt = MATRIX_PC601 ;
459+
460+ int mt_from_props_ok = 0 ;
461+ matrix_type mt_from_props = MATRIX_NONE ;
462+
463+ if (avs_get_version (c ) >= 9 ) {
464+ mt_from_props = matrix_from_frame_props (env , c , vi , & mt_from_props_ok );
465+ }
466+
467+ if (mt_from_props_ok && mt_from_props != MATRIX_NONE ) {
468+ color_mt = mt_from_props ;
469+ } else {
470+ if (vi -> width >= 1280 || vi -> height >= 576 ) {
471+ color_mt = MATRIX_PC709 ;
472+ } else {
473+ color_mt = MATRIX_PC601 ;
474+ }
475+ }
373476 }
374477 else {
375478 color_mt = MATRIX_BT601 ;
0 commit comments