@@ -729,6 +729,7 @@ static inline void r12l_to_yuv4XXpYYle(int depth, bool out_422, AVFrame * __rest
729729 src += 4 ;
730730 }
731731 }
732+ #undef WRITE_RES
732733}
733734
734735static void r12l_to_yuv444p10le (AVFrame * __restrict out_frame , const unsigned char * __restrict in_data , int width , int height )
@@ -761,6 +762,115 @@ static void r12l_to_yuv422p16le(AVFrame * __restrict out_frame, const unsigned c
761762 r12l_to_yuv4XXpYYle (16 , true, out_frame , in_data , width , height );
762763}
763764
765+ #if P210_PRESENT
766+ // copied from r12l_to_yuv4XXpYYle
767+ static void
768+ r12l_to_p210le (AVFrame * __restrict out_frame ,
769+ const unsigned char * __restrict in_data , int width , int height )
770+ {
771+ assert ((uintptr_t ) out_frame -> linesize [0 ] % 2 == 0 );
772+ assert ((uintptr_t ) out_frame -> linesize [1 ] % 2 == 0 );
773+
774+ const struct color_coeffs cfs = * get_color_coeffs (CS_DFL , DEPTH10 );
775+ #define WRITE_RES (idx ) \
776+ res_y = (RGB_TO_Y(cfs, r, g, b) >> (COMP_BASE + 12 - DEPTH16)) + \
777+ (1 << (DEPTH16 - 4)); \
778+ *dst_y++ = CLAMP_LIMITED_Y(res_y, DEPTH16); \
779+ if ((idx) % 2 == 0) { \
780+ res_cb = \
781+ (RGB_TO_CB(cfs, r, g, b) >> (COMP_BASE + 12 - DEPTH16)) + \
782+ (1 << (DEPTH16 - 1)); \
783+ res_cr = \
784+ (RGB_TO_CR(cfs, r, g, b) >> (COMP_BASE + 12 - DEPTH16)) + \
785+ (1 << (DEPTH16 - 1)); \
786+ *dst_cbcr++ = CLAMP_LIMITED_CBCR(res_cb, depth); \
787+ *dst_cbcr++ = CLAMP_LIMITED_CBCR(res_cr, depth); \
788+ }
789+
790+ const int src_linesize = vc_get_linesize (width , R12L );
791+ for (int y = 0 ; y < height ; ++ y ) {
792+ const unsigned char * src = in_data + y * src_linesize ;
793+ uint16_t * dst_y = (uint16_t * )(void * ) (out_frame -> data [0 ] + out_frame -> linesize [0 ] * y );
794+ uint16_t * dst_cbcr = (uint16_t * )(void * ) (out_frame -> data [1 ] + out_frame -> linesize [1 ] * y );
795+
796+ OPTIMIZED_FOR (int x = 0 ; x < width ; x += 8 ) {
797+ comp_type_t r = 0 ;
798+ comp_type_t g = 0 ;
799+ comp_type_t b = 0 ;
800+ comp_type_t res_y = 0 ;
801+ comp_type_t res_cb = 0 ;
802+ comp_type_t res_cr = 0 ;
803+
804+ r = src [BYTE_SWAP (0 )];
805+ r |= (src [BYTE_SWAP (1 )] & 0xF ) << 8 ;
806+ g = src [BYTE_SWAP (2 )] << 4 | src [BYTE_SWAP (1 )] >> 4 ; // g0
807+ b = src [BYTE_SWAP (3 )];
808+ src += 4 ;
809+
810+ b |= (src [BYTE_SWAP (0 )] & 0xF ) << 8 ;
811+ WRITE_RES (0 )
812+ r = src [BYTE_SWAP (1 )] << 4 | src [BYTE_SWAP (0 )] >> 4 ; // r1
813+ g = src [BYTE_SWAP (2 )];
814+ g |= (src [BYTE_SWAP (3 )] & 0xF ) << 8 ;
815+ b = src [BYTE_SWAP (3 )] >> 4 ;
816+ src += 4 ;
817+
818+ b |= src [BYTE_SWAP (0 )] << 4 ; // b1
819+ WRITE_RES (1 )
820+ r = src [BYTE_SWAP (1 )];
821+ r |= (src [BYTE_SWAP (2 )] & 0xF ) << 8 ;
822+ g = src [BYTE_SWAP (3 )] << 4 | src [BYTE_SWAP (2 )] >> 4 ; // g2
823+ src += 4 ;
824+
825+ b = src [BYTE_SWAP (0 )];
826+ b |= (src [BYTE_SWAP (1 )] & 0xF ) << 8 ;
827+ WRITE_RES (2 )
828+ r = src [BYTE_SWAP (2 )] << 4 | src [BYTE_SWAP (1 )] >> 4 ; // r3
829+ g = src [BYTE_SWAP (3 )];
830+ src += 4 ;
831+
832+ g |= (src [BYTE_SWAP (0 )] & 0xF ) << 8 ;
833+ b = src [BYTE_SWAP (1 )] << 4 | src [BYTE_SWAP (0 )] >> 4 ; // b3
834+ WRITE_RES (3 )
835+ r = src [BYTE_SWAP (2 )];
836+ r |= (src [BYTE_SWAP (3 )] & 0xF ) << 8 ;
837+ g = src [BYTE_SWAP (3 )] >> 4 ;
838+ src += 4 ;
839+
840+ g |= src [BYTE_SWAP (0 )] << 4 ; // g4
841+ b = src [BYTE_SWAP (1 )];
842+ b |= (src [BYTE_SWAP (2 )] & 0xF ) << 8 ;
843+ WRITE_RES (4 )
844+ r = src [BYTE_SWAP (3 )] << 4 | src [BYTE_SWAP (2 )] >> 4 ; // r5
845+ src += 4 ;
846+
847+ g = src [BYTE_SWAP (0 )];
848+ g |= (src [BYTE_SWAP (1 )] & 0xF ) << 8 ;
849+ b = src [BYTE_SWAP (2 )] << 4 | src [BYTE_SWAP (1 )] >> 4 ; // b5
850+ WRITE_RES (5 )
851+ r = src [BYTE_SWAP (3 )];
852+ src += 4 ;
853+
854+ r |= (src [BYTE_SWAP (0 )] & 0xF ) << 8 ;
855+ g = src [BYTE_SWAP (1 )] << 4 | src [BYTE_SWAP (0 )] >> 4 ; // g6
856+ b = src [BYTE_SWAP (2 )];
857+ b |= (src [BYTE_SWAP (3 )] & 0xF ) << 8 ;
858+ WRITE_RES (6 )
859+ r = src [BYTE_SWAP (3 )] >> 4 ;
860+ src += 4 ;
861+
862+ r |= src [BYTE_SWAP (0 )] << 4 ; // r7
863+ g = src [BYTE_SWAP (1 )];
864+ g |= (src [BYTE_SWAP (2 )] & 0xF ) << 8 ;
865+ b = src [BYTE_SWAP (3 )] << 4 | src [BYTE_SWAP (2 )] >> 4 ; // b7
866+ WRITE_RES (7 )
867+ src += 4 ;
868+ }
869+ }
870+ #undef WRITE_RES
871+ }
872+ #endif // P210_PRESENT
873+
764874/// @brief Converts RG48 to yuv444p 10/12/14 le
765875#if defined __GNUC__
766876static inline void rg48_to_yuv444pXXle (int depth , AVFrame * __restrict out_frame , const unsigned char * __restrict in_data , int width , int height )
@@ -1195,6 +1305,9 @@ static const struct uv_to_av_conversion *get_uv_to_av_conversions() {
11951305 { R12L , AV_PIX_FMT_YUV422P10LE , r12l_to_yuv422p10le },
11961306 { R12L , AV_PIX_FMT_YUV422P12LE , r12l_to_yuv422p12le },
11971307 { R12L , AV_PIX_FMT_YUV422P16LE , r12l_to_yuv422p16le },
1308+ #if P210_PRESENT
1309+ { R12L , AV_PIX_FMT_P210LE , r12l_to_p210le },
1310+ #endif // defined P210_PRESENT
11981311 { RG48 , AV_PIX_FMT_YUV444P10LE , rg48_to_yuv444p10le },
11991312 { RG48 , AV_PIX_FMT_YUV444P12LE , rg48_to_yuv444p12le },
12001313 { RG48 , AV_PIX_FMT_YUV444P16LE , rg48_to_yuv444p16le },
0 commit comments