3838#include "libavutil/crc.h"
3939#include "libavutil/opt.h"
4040#include "libavutil/imgutils.h"
41+ #include "libavutil/timer.h"
4142
4243#ifdef __INTEL_COMPILER
4344#undef av_flatten
@@ -579,10 +580,13 @@ static void encode_plane(FFV1Context *s, uint8_t *src, int w, int h, int stride,
579580 }
580581}
581582
582- static void encode_rgb_frame (FFV1Context * s , uint32_t * src , int w , int h , int stride ){
583+ static void encode_rgb_frame (FFV1Context * s , uint8_t * src [ 3 ] , int w , int h , int stride [ 3 ] ){
583584 int x , y , p , i ;
584585 const int ring_size = s -> avctx -> context_model ? 3 : 2 ;
585586 int16_t * sample [4 ][3 ];
587+ int lbd = s -> avctx -> bits_per_raw_sample <= 8 ;
588+ int bits = s -> avctx -> bits_per_raw_sample > 0 ? s -> avctx -> bits_per_raw_sample : 8 ;
589+ int offset = 1 << bits ;
586590 s -> run_index = 0 ;
587591
588592 memset (s -> sample_buffer , 0 , ring_size * 4 * (w + 6 )* sizeof (* s -> sample_buffer ));
@@ -593,17 +597,24 @@ static void encode_rgb_frame(FFV1Context *s, uint32_t *src, int w, int h, int st
593597 sample [p ][i ]= s -> sample_buffer + p * ring_size * (w + 6 ) + ((h + i - y )%ring_size )* (w + 6 ) + 3 ;
594598
595599 for (x = 0 ; x < w ; x ++ ){
596- unsigned v = src [x + stride * y ];
597- int b = v & 0xFF ;
598- int g = (v >>8 )& 0xFF ;
599- int r = (v >>16 )& 0xFF ;
600- int a = v >>24 ;
600+ int b ,g ,r ,a ;
601+ if (lbd ){
602+ unsigned v = * ((uint32_t * )(src [0 ] + x * 4 + stride [0 ]* y ));
603+ b = v & 0xFF ;
604+ g = (v >>8 )& 0xFF ;
605+ r = (v >>16 )& 0xFF ;
606+ a = v >>24 ;
607+ }else {
608+ b = * ((uint16_t * )(src [0 ] + x * 2 + stride [0 ]* y ));
609+ g = * ((uint16_t * )(src [1 ] + x * 2 + stride [1 ]* y ));
610+ r = * ((uint16_t * )(src [2 ] + x * 2 + stride [2 ]* y ));
611+ }
601612
602613 b -= g ;
603614 r -= g ;
604615 g += (b + r )>>2 ;
605- b += 0x100 ;
606- r += 0x100 ;
616+ b += offset ;
617+ r += offset ;
607618
608619// assert(g>=0 && b>=0 && r>=0);
609620// assert(g<256 && b<512 && r<512);
@@ -615,7 +626,10 @@ static void encode_rgb_frame(FFV1Context *s, uint32_t *src, int w, int h, int st
615626 for (p = 0 ; p < 3 + s -> transparency ; p ++ ){
616627 sample [p ][0 ][-1 ]= sample [p ][1 ][0 ];
617628 sample [p ][1 ][ w ]= sample [p ][1 ][w - 1 ];
618- encode_line (s , w , sample [p ], (p + 1 )/2 , 9 );
629+ if (lbd )
630+ encode_line (s , w , sample [p ], (p + 1 )/2 , 9 );
631+ else
632+ encode_line (s , w , sample [p ], (p + 1 )/2 , bits + 1 );
619633 }
620634 }
621635}
@@ -980,6 +994,24 @@ static av_cold int encode_init(AVCodecContext *avctx)
980994 case PIX_FMT_0RGB32 :
981995 s -> colorspace = 1 ;
982996 break ;
997+ case PIX_FMT_GBRP9 :
998+ if (!avctx -> bits_per_raw_sample )
999+ s -> bits_per_raw_sample = 9 ;
1000+ case PIX_FMT_GBRP10 :
1001+ if (!avctx -> bits_per_raw_sample && !s -> bits_per_raw_sample )
1002+ s -> bits_per_raw_sample = 10 ;
1003+ case PIX_FMT_GBRP12 :
1004+ if (!avctx -> bits_per_raw_sample && !s -> bits_per_raw_sample )
1005+ s -> bits_per_raw_sample = 12 ;
1006+ case PIX_FMT_GBRP14 :
1007+ if (!avctx -> bits_per_raw_sample && !s -> bits_per_raw_sample )
1008+ s -> bits_per_raw_sample = 14 ;
1009+ else if (!s -> bits_per_raw_sample )
1010+ s -> bits_per_raw_sample = avctx -> bits_per_raw_sample ;
1011+ s -> colorspace = 1 ;
1012+ s -> chroma_planes = 1 ;
1013+ s -> version = FFMAX (s -> version , 1 );
1014+ break ;
9831015 default :
9841016 av_log (avctx , AV_LOG_ERROR , "format not supported\n" );
9851017 return AVERROR_INVALIDDATA ;
@@ -1225,7 +1257,10 @@ static int encode_slice(AVCodecContext *c, void *arg){
12251257 if (fs -> transparency )
12261258 encode_plane (fs , p -> data [3 ] + ps * x + y * p -> linesize [3 ], width , height , p -> linesize [3 ], 2 );
12271259 }else {
1228- encode_rgb_frame (fs , (uint32_t * )(p -> data [0 ]) + ps * x + y * (p -> linesize [0 ]/4 ), width , height , p -> linesize [0 ]/4 );
1260+ uint8_t * planes [3 ] = {p -> data [0 ] + ps * x + y * p -> linesize [0 ],
1261+ p -> data [1 ] + ps * x + y * p -> linesize [1 ],
1262+ p -> data [2 ] + ps * x + y * p -> linesize [2 ]};
1263+ encode_rgb_frame (fs , planes , width , height , p -> linesize );
12291264 }
12301265 emms_c ();
12311266
@@ -1500,9 +1535,12 @@ static void decode_plane(FFV1Context *s, uint8_t *src, int w, int h, int stride,
15001535 }
15011536}
15021537
1503- static void decode_rgb_frame (FFV1Context * s , uint32_t * src , int w , int h , int stride ){
1538+ static void decode_rgb_frame (FFV1Context * s , uint8_t * src [ 3 ] , int w , int h , int stride [ 3 ] ){
15041539 int x , y , p ;
15051540 int16_t * sample [4 ][2 ];
1541+ int lbd = s -> avctx -> bits_per_raw_sample <= 8 ;
1542+ int bits = s -> avctx -> bits_per_raw_sample > 0 ? s -> avctx -> bits_per_raw_sample : 8 ;
1543+ int offset = 1 << bits ;
15061544 for (x = 0 ; x < 4 ; x ++ ){
15071545 sample [x ][0 ] = s -> sample_buffer + x * 2 * (w + 6 ) + 3 ;
15081546 sample [x ][1 ] = s -> sample_buffer + (x * 2 + 1 )* (w + 6 ) + 3 ;
@@ -1521,7 +1559,10 @@ static void decode_rgb_frame(FFV1Context *s, uint32_t *src, int w, int h, int st
15211559
15221560 sample [p ][1 ][-1 ]= sample [p ][0 ][0 ];
15231561 sample [p ][0 ][ w ]= sample [p ][0 ][w - 1 ];
1524- decode_line (s , w , sample [p ], (p + 1 )/2 , 9 );
1562+ if (lbd )
1563+ decode_line (s , w , sample [p ], (p + 1 )/2 , 9 );
1564+ else
1565+ decode_line (s , w , sample [p ], (p + 1 )/2 , bits + 1 );
15251566 }
15261567 for (x = 0 ; x < w ; x ++ ){
15271568 int g = sample [0 ][1 ][x ];
@@ -1532,13 +1573,19 @@ static void decode_rgb_frame(FFV1Context *s, uint32_t *src, int w, int h, int st
15321573// assert(g>=0 && b>=0 && r>=0);
15331574// assert(g<256 && b<512 && r<512);
15341575
1535- b -= 0x100 ;
1536- r -= 0x100 ;
1576+ b -= offset ;
1577+ r -= offset ;
15371578 g -= (b + r )>>2 ;
15381579 b += g ;
15391580 r += g ;
15401581
1541- src [x + stride * y ]= b + (g <<8 ) + (r <<16 ) + (a <<24 );
1582+ if (lbd )
1583+ * ((uint32_t * )(src [0 ] + x * 4 + stride [0 ]* y ))= b + (g <<8 ) + (r <<16 ) + (a <<24 );
1584+ else {
1585+ * ((uint16_t * )(src [0 ] + x * 2 + stride [0 ]* y )) = b ;
1586+ * ((uint16_t * )(src [1 ] + x * 2 + stride [1 ]* y )) = g ;
1587+ * ((uint16_t * )(src [2 ] + x * 2 + stride [2 ]* y )) = r ;
1588+ }
15421589 }
15431590 }
15441591}
@@ -1646,7 +1693,10 @@ static int decode_slice(AVCodecContext *c, void *arg){
16461693 if (fs -> transparency )
16471694 decode_plane (fs , p -> data [3 ] + ps * x + y * p -> linesize [3 ], width , height , p -> linesize [3 ], 2 );
16481695 }else {
1649- decode_rgb_frame (fs , (uint32_t * )p -> data [0 ] + ps * x + y * (p -> linesize [0 ]/4 ), width , height , p -> linesize [0 ]/4 );
1696+ uint8_t * planes [3 ] = {p -> data [0 ] + ps * x + y * p -> linesize [0 ],
1697+ p -> data [1 ] + ps * x + y * p -> linesize [1 ],
1698+ p -> data [2 ] + ps * x + y * p -> linesize [2 ]};
1699+ decode_rgb_frame (fs , planes , width , height , p -> linesize );
16501700 }
16511701 if (fs -> ac && f -> version > 2 ) {
16521702 int v = fs -> c .bytestream_end - fs -> c .bytestream - 3 - 5 * f -> ec ;
@@ -1871,6 +1921,15 @@ static int read_header(FFV1Context *f){
18711921 av_log (f -> avctx , AV_LOG_ERROR , "chroma subsampling not supported in this colorspace\n" );
18721922 return -1 ;
18731923 }
1924+ if (f -> avctx -> bits_per_raw_sample == 9 )
1925+ f -> avctx -> pix_fmt = PIX_FMT_GBRP9 ;
1926+ else if (f -> avctx -> bits_per_raw_sample == 10 )
1927+ f -> avctx -> pix_fmt = PIX_FMT_GBRP10 ;
1928+ else if (f -> avctx -> bits_per_raw_sample == 12 )
1929+ f -> avctx -> pix_fmt = PIX_FMT_GBRP12 ;
1930+ else if (f -> avctx -> bits_per_raw_sample == 14 )
1931+ f -> avctx -> pix_fmt = PIX_FMT_GBRP14 ;
1932+ else
18741933 if (f -> transparency ) f -> avctx -> pix_fmt = PIX_FMT_RGB32 ;
18751934 else f -> avctx -> pix_fmt = PIX_FMT_0RGB32 ;
18761935 }else {
@@ -2130,7 +2189,8 @@ AVCodec ff_ffv1_encoder = {
21302189 PIX_FMT_YUV410P , PIX_FMT_0RGB32 , PIX_FMT_RGB32 , PIX_FMT_YUV420P16 ,
21312190 PIX_FMT_YUV422P16 , PIX_FMT_YUV444P16 , PIX_FMT_YUV444P9 , PIX_FMT_YUV422P9 ,
21322191 PIX_FMT_YUV420P9 , PIX_FMT_YUV420P10 , PIX_FMT_YUV422P10 , PIX_FMT_YUV444P10 ,
2133- PIX_FMT_GRAY16 , PIX_FMT_GRAY8 ,
2192+ PIX_FMT_GRAY16 , PIX_FMT_GRAY8 , PIX_FMT_GBRP9 , PIX_FMT_GBRP10 ,
2193+ PIX_FMT_GBRP12 , PIX_FMT_GBRP14 ,
21342194 PIX_FMT_NONE
21352195 },
21362196 .long_name = NULL_IF_CONFIG_SMALL ("FFmpeg video codec #1" ),
0 commit comments