@@ -623,26 +623,30 @@ static void r10k_to_yuv444p16le(AVFrame * __restrict out_frame, const unsigned c
623623}
624624
625625#if defined __GNUC__
626- static inline void r12l_to_yuv444pXXle (int depth , AVFrame * __restrict out_frame , const unsigned char * __restrict in_data , int width , int height )
626+ static inline void r12l_to_yuv4XXpYYle (int depth , bool out_422 , AVFrame * __restrict out_frame , const unsigned char * __restrict in_data , int width , int height )
627627 __attribute__((always_inline ));
628628#endif
629- static inline void r12l_to_yuv444pXXle (int depth , AVFrame * __restrict out_frame , const unsigned char * __restrict in_data , int width , int height )
629+ static inline void r12l_to_yuv4XXpYYle (int depth , bool out_422 , AVFrame * __restrict out_frame , const unsigned char * __restrict in_data , int width , int height )
630630{
631631 assert ((uintptr_t ) out_frame -> linesize [0 ] % 2 == 0 );
632632 assert ((uintptr_t ) out_frame -> linesize [1 ] % 2 == 0 );
633633 assert ((uintptr_t ) out_frame -> linesize [2 ] % 2 == 0 );
634634
635635 const struct color_coeffs cfs = * get_color_coeffs (CS_DFL , depth );
636- #define WRITE_RES \
636+ #define WRITE_RES ( idx ) \
637637 res_y = (RGB_TO_Y(cfs, r, g, b) >> (COMP_BASE + 12 - depth)) + \
638638 (1 << (depth - 4)); \
639- res_cb = (RGB_TO_CB(cfs, r, g, b) >> (COMP_BASE + 12 - depth)) + \
640- (1 << (depth - 1)); \
641- res_cr = (RGB_TO_CR(cfs, r, g, b) >> (COMP_BASE + 12 - depth)) + \
642- (1 << (depth - 1)); \
643- *dst_y++ = CLAMP_LIMITED_Y(res_y, depth); \
644- *dst_cb++ = CLAMP_LIMITED_CBCR(res_cb, depth); \
645- *dst_cr++ = CLAMP_LIMITED_CBCR(res_cr, depth);
639+ *dst_y++ = CLAMP_LIMITED_Y(res_y, depth); \
640+ if (!out_422 || idx % 2 == 0) { \
641+ res_cb = \
642+ (RGB_TO_CB(cfs, r, g, b) >> (COMP_BASE + 12 - depth)) + \
643+ (1 << (depth - 1)); \
644+ res_cr = \
645+ (RGB_TO_CR(cfs, r, g, b) >> (COMP_BASE + 12 - depth)) + \
646+ (1 << (depth - 1)); \
647+ *dst_cb++ = CLAMP_LIMITED_CBCR(res_cb, depth); \
648+ *dst_cr++ = CLAMP_LIMITED_CBCR(res_cr, depth); \
649+ }
646650
647651 const int src_linesize = vc_get_linesize (width , R12L );
648652 for (int y = 0 ; y < height ; ++ y ) {
@@ -666,30 +670,30 @@ static inline void r12l_to_yuv444pXXle(int depth, AVFrame * __restrict out_frame
666670 src += 4 ;
667671
668672 b |= (src [BYTE_SWAP (0 )] & 0xF ) << 8 ;
669- WRITE_RES // 0
673+ WRITE_RES ( 0 )
670674 r = src [BYTE_SWAP (1 )] << 4 | src [BYTE_SWAP (0 )] >> 4 ; // r1
671675 g = src [BYTE_SWAP (2 )];
672676 g |= (src [BYTE_SWAP (3 )] & 0xF ) << 8 ;
673677 b = src [BYTE_SWAP (3 )] >> 4 ;
674678 src += 4 ;
675679
676680 b |= src [BYTE_SWAP (0 )] << 4 ; // b1
677- WRITE_RES // 1
681+ WRITE_RES ( 1 )
678682 r = src [BYTE_SWAP (1 )];
679683 r |= (src [BYTE_SWAP (2 )] & 0xF ) << 8 ;
680684 g = src [BYTE_SWAP (3 )] << 4 | src [BYTE_SWAP (2 )] >> 4 ; // g2
681685 src += 4 ;
682686
683687 b = src [BYTE_SWAP (0 )];
684688 b |= (src [BYTE_SWAP (1 )] & 0xF ) << 8 ;
685- WRITE_RES // 2
689+ WRITE_RES ( 2 )
686690 r = src [BYTE_SWAP (2 )] << 4 | src [BYTE_SWAP (1 )] >> 4 ; // r3
687691 g = src [BYTE_SWAP (3 )];
688692 src += 4 ;
689693
690694 g |= (src [BYTE_SWAP (0 )] & 0xF ) << 8 ;
691695 b = src [BYTE_SWAP (1 )] << 4 | src [BYTE_SWAP (0 )] >> 4 ; // b3
692- WRITE_RES // 3
696+ WRITE_RES ( 3 )
693697 r = src [BYTE_SWAP (2 )];
694698 r |= (src [BYTE_SWAP (3 )] & 0xF ) << 8 ;
695699 g = src [BYTE_SWAP (3 )] >> 4 ;
@@ -698,48 +702,63 @@ static inline void r12l_to_yuv444pXXle(int depth, AVFrame * __restrict out_frame
698702 g |= src [BYTE_SWAP (0 )] << 4 ; // g4
699703 b = src [BYTE_SWAP (1 )];
700704 b |= (src [BYTE_SWAP (2 )] & 0xF ) << 8 ;
701- WRITE_RES // 4
705+ WRITE_RES ( 4 )
702706 r = src [BYTE_SWAP (3 )] << 4 | src [BYTE_SWAP (2 )] >> 4 ; // r5
703707 src += 4 ;
704708
705709 g = src [BYTE_SWAP (0 )];
706710 g |= (src [BYTE_SWAP (1 )] & 0xF ) << 8 ;
707711 b = src [BYTE_SWAP (2 )] << 4 | src [BYTE_SWAP (1 )] >> 4 ; // b5
708- WRITE_RES // 5
712+ WRITE_RES ( 5 )
709713 r = src [BYTE_SWAP (3 )];
710714 src += 4 ;
711715
712716 r |= (src [BYTE_SWAP (0 )] & 0xF ) << 8 ;
713717 g = src [BYTE_SWAP (1 )] << 4 | src [BYTE_SWAP (0 )] >> 4 ; // g6
714718 b = src [BYTE_SWAP (2 )];
715719 b |= (src [BYTE_SWAP (3 )] & 0xF ) << 8 ;
716- WRITE_RES // 6
720+ WRITE_RES ( 6 )
717721 r = src [BYTE_SWAP (3 )] >> 4 ;
718722 src += 4 ;
719723
720724 r |= src [BYTE_SWAP (0 )] << 4 ; // r7
721725 g = src [BYTE_SWAP (1 )];
722726 g |= (src [BYTE_SWAP (2 )] & 0xF ) << 8 ;
723727 b = src [BYTE_SWAP (3 )] << 4 | src [BYTE_SWAP (2 )] >> 4 ; // b7
724- WRITE_RES // 7
728+ WRITE_RES ( 7 )
725729 src += 4 ;
726730 }
727731 }
728732}
729733
730734static void r12l_to_yuv444p10le (AVFrame * __restrict out_frame , const unsigned char * __restrict in_data , int width , int height )
731735{
732- r12l_to_yuv444pXXle (10 , out_frame , in_data , width , height );
736+ r12l_to_yuv4XXpYYle (10 , false , out_frame , in_data , width , height );
733737}
734738
735739static void r12l_to_yuv444p12le (AVFrame * __restrict out_frame , const unsigned char * __restrict in_data , int width , int height )
736740{
737- r12l_to_yuv444pXXle (12 , out_frame , in_data , width , height );
741+ r12l_to_yuv4XXpYYle (12 , false , out_frame , in_data , width , height );
738742}
739743
740744static void r12l_to_yuv444p16le (AVFrame * __restrict out_frame , const unsigned char * __restrict in_data , int width , int height )
741745{
742- r12l_to_yuv444pXXle (16 , out_frame , in_data , width , height );
746+ r12l_to_yuv4XXpYYle (16 , false, out_frame , in_data , width , height );
747+ }
748+
749+ static void r12l_to_yuv422p10le (AVFrame * __restrict out_frame , const unsigned char * __restrict in_data , int width , int height )
750+ {
751+ r12l_to_yuv4XXpYYle (10 , true, out_frame , in_data , width , height );
752+ }
753+
754+ static void r12l_to_yuv422p12le (AVFrame * __restrict out_frame , const unsigned char * __restrict in_data , int width , int height )
755+ {
756+ r12l_to_yuv4XXpYYle (12 , true, out_frame , in_data , width , height );
757+ }
758+
759+ static void r12l_to_yuv422p16le (AVFrame * __restrict out_frame , const unsigned char * __restrict in_data , int width , int height )
760+ {
761+ r12l_to_yuv4XXpYYle (16 , true, out_frame , in_data , width , height );
743762}
744763
745764/// @brief Converts RG48 to yuv444p 10/12/14 le
@@ -1174,6 +1193,9 @@ static const struct uv_to_av_conversion *get_uv_to_av_conversions() {
11741193 { R12L , AV_PIX_FMT_YUV444P10LE , r12l_to_yuv444p10le },
11751194 { R12L , AV_PIX_FMT_YUV444P12LE , r12l_to_yuv444p12le },
11761195 { R12L , AV_PIX_FMT_YUV444P16LE , r12l_to_yuv444p16le },
1196+ { R12L , AV_PIX_FMT_YUV422P10LE , r12l_to_yuv422p10le },
1197+ { R12L , AV_PIX_FMT_YUV422P12LE , r12l_to_yuv422p12le },
1198+ { R12L , AV_PIX_FMT_YUV422P16LE , r12l_to_yuv422p16le },
11771199 { RG48 , AV_PIX_FMT_YUV444P10LE , rg48_to_yuv444p10le },
11781200 { RG48 , AV_PIX_FMT_YUV444P12LE , rg48_to_yuv444p12le },
11791201 { RG48 , AV_PIX_FMT_YUV444P16LE , rg48_to_yuv444p16le },
0 commit comments