@@ -225,51 +225,110 @@ def rgb2yuv(r, g, b):
225225 'RGB565' ,
226226 'YUV10' ,
227227 'YUV-linear' ,
228+ 'YUV444-planar' ,
229+ 'YUV422-planar' ,
230+ 'YUV420-planar' ,
228231 ]
229232 pixfmt = args .encode_pixelfmt
230233
234+ # Driver doesn't support this either
231235 if pixfmt == 'YUV-linear' and args .encode_subsampling == '444' :
232- # Driver doesn't support this either
236+ print ("WARNING: This combination does not appear to work!!!" )
237+ if pixfmt == 'YUV422-planar' and args .encode_subsampling == '444' :
238+ print ("WARNING: This combination does not appear to work!!!" )
239+ if pixfmt == 'YUV420-planar' and args .encode_subsampling == '444' :
233240 print ("WARNING: This combination does not appear to work!!!" )
234241
235242 image_data = b''
243+ image_data_P1 = b''
236244 with Image .open (args .input ) as im :
237245 im_W , im_H = im .size
238246
239- for y in range (im_H ):
240- for x in range (im_W ):
241- r , g , b = im .getpixel ((x , y ))
242- if pixfmt == 'RGB888' :
243- image_data += struct .pack ("BBBB" , r , g , b , 255 )
244- elif pixfmt == 'RGB101010' :
245- image_data += struct .pack ("<I" , (r << 2 ) | (g << 12 ) | (b << 22 ))
246- elif pixfmt == 'RGB565' :
247- image_data += struct .pack ("<H" , (r >> 3 ) | ((g >> 2 ) << 5 ) | ((b >> 3 ) << 11 ))
248- elif pixfmt == 'YUV10' :
249- # absolute garbage color space conversion
250- # for demonstration purposes only
251- y_ , u_ , v_ = rgb2yuv (r , g , b )
252- image_data += struct .pack ("<I" , (y_ << 2 ) | (u_ << 12 ) | (v_ << 22 ))
253- elif pixfmt == 'YUV-linear' :
247+ if pixfmt != 'YUV420-planar' :
248+ for y in range (im_H ):
249+ for x in range (im_W ):
250+ r , g , b = im .getpixel ((x , y ))
251+ if pixfmt == 'RGB888' :
252+ image_data += struct .pack ("BBBB" , r , g , b , 255 )
253+ elif pixfmt == 'RGB101010' :
254+ image_data += struct .pack ("<I" , (r << 2 ) | (g << 12 ) | (b << 22 ))
255+ elif pixfmt == 'RGB565' :
256+ image_data += struct .pack ("<H" , (r >> 3 ) | ((g >> 2 ) << 5 ) | ((b >> 3 ) << 11 ))
257+ elif pixfmt == 'YUV10' :
258+ # absolute garbage color space conversion
259+ # for demonstration purposes only
260+ y_ , u_ , v_ = rgb2yuv (r , g , b )
261+ image_data += struct .pack ("<I" , (y_ << 2 ) | (u_ << 12 ) | (v_ << 22 ))
262+ elif pixfmt == 'YUV-linear' :
263+ # garbage color space conversion, garbage subsampling
264+ # for demonstration purposes only
265+ y_ , u_ , v_ = rgb2yuv (r , g , b )
266+ if x & 1 == 0 :
267+ color = u_
268+ else :
269+ color = v_
270+ image_data += struct .pack ("BB" , y_ , color )
271+ elif pixfmt == 'YUV444-planar' :
272+ # garbage color space conversion
273+ # for demonstration purposes only
274+ y_ , u_ , v_ = rgb2yuv (r , g , b )
275+ image_data += struct .pack ("B" , y_ )
276+ image_data_P1 += struct .pack ("BB" , u_ , v_ )
277+ elif pixfmt == 'YUV422-planar' :
278+ # garbage color space conversion, garbage subsampling
279+ # for demonstration purposes only
280+ y_ , u_ , v_ = rgb2yuv (r , g , b )
281+ if x & 1 == 0 :
282+ color = u_
283+ else :
284+ color = v_
285+ image_data += struct .pack ("B" , y_ )
286+ image_data_P1 += struct .pack ("B" , color )
287+ else :
288+ assert False
289+ else :
290+ for y in range (im_H ):
291+ for x in range (im_W ):
292+ r , g , b = im .getpixel ((x , y ))
254293 # garbage color space conversion, garbage subsampling
255294 # for demonstration purposes only
256295 y_ , u_ , v_ = rgb2yuv (r , g , b )
257296 if x & 1 == 0 :
258297 color = u_
259298 else :
260299 color = v_
261- image_data += struct .pack ("BB " , y_ , color )
262- else :
263- assert False
300+ image_data += struct .pack ("B " , y_ )
301+ if y & 1 == 0 :
302+ image_data_P1 += struct . pack ( "B" , color )
264303
265304 if pixfmt in ['RGB888' , 'RGB101010' , 'YUV10' ]:
266305 BYTESPP = 4
306+ BYTESPP_P1 = 0
307+ P1_DIVH = 1
267308 elif pixfmt in ['RGB565' , 'YUV-linear' ]:
268309 BYTESPP = 2
310+ BYTESPP_P1 = 0
311+ P1_DIVH = 1
312+ elif pixfmt == 'YUV444-planar' :
313+ BYTESPP = 1
314+ BYTESPP_P1 = 2
315+ P1_DIVH = 1
316+ elif pixfmt == 'YUV422-planar' :
317+ BYTESPP = 1
318+ BYTESPP_P1 = 1
319+ P1_DIVH = 1
320+ elif pixfmt == 'YUV420-planar' :
321+ BYTESPP = 1
322+ BYTESPP_P1 = 1
323+ P1_DIVH = 2
269324 else :
270325 assert False
271326 surface_stride = im_W * BYTESPP
272327 surface_sz = surface_stride * im_H
328+ surface_P1_off = surface_sz
329+ print (f"Plane 1 offset at { surface_P1_off :08X} " )
330+ surface_P1_stride = im_W * BYTESPP_P1
331+ surface_sz += surface_P1_stride * im_H // P1_DIVH
273332 input_mem_sz = align_up (surface_sz )
274333
275334 output_mem_sz = input_mem_sz
@@ -824,6 +883,7 @@ def set_default_regs(param1=0):
824883
825884if args .encode :
826885 iface .writemem (input_buf_phys , image_data )
886+ iface .writemem (input_buf_phys + surface_P1_off , image_data_P1 )
827887 print ("Pixel data uploaded" )
828888
829889 jpeg .MODE = 0x17f
@@ -842,11 +902,16 @@ def set_default_regs(param1=0):
842902 else :
843903 assert False
844904
845- jpeg .PX_USE_PLANE1 = 0x0
905+ if BYTESPP_P1 != 0 :
906+ jpeg .PX_USE_PLANE1 = 1
907+ jpeg .PX_PLANE1_WIDTH = im_W * BYTESPP_P1 - 1
908+ jpeg .PX_PLANE1_HEIGHT = im_H // P1_DIVH - 1
909+ else :
910+ jpeg .PX_USE_PLANE1 = 0
911+ jpeg .PX_PLANE1_WIDTH = 0xffffffff
912+ jpeg .PX_PLANE1_HEIGHT = 0xffffffff
846913 jpeg .PX_PLANE0_WIDTH = im_W * BYTESPP - 1
847914 jpeg .PX_PLANE0_HEIGHT = im_H - 1
848- jpeg .PX_PLANE1_WIDTH = 0xffffffff
849- jpeg .PX_PLANE1_HEIGHT = 0xffffffff
850915 jpeg .TIMEOUT = 266000000
851916
852917 jpeg .PX_TILES_W = divroundup (im_W , macroblock_W )
@@ -905,19 +970,81 @@ def set_default_regs(param1=0):
905970 jpeg .PX_PLANE1_TILING_V = 0
906971 else :
907972 assert False
973+ elif pixfmt == 'YUV444-planar' :
974+ if args .encode_subsampling == '444' or args .encode_subsampling == '400' :
975+ jpeg .PX_PLANE0_TILING_H = 1
976+ jpeg .PX_PLANE0_TILING_V = 8
977+ jpeg .PX_PLANE1_TILING_H = 2
978+ jpeg .PX_PLANE1_TILING_V = 8
979+ elif args .encode_subsampling == '422' :
980+ jpeg .PX_PLANE0_TILING_H = 2
981+ jpeg .PX_PLANE0_TILING_V = 8
982+ jpeg .PX_PLANE1_TILING_H = 4
983+ jpeg .PX_PLANE1_TILING_V = 8
984+ elif args .encode_subsampling == '420' :
985+ jpeg .PX_PLANE0_TILING_H = 2
986+ jpeg .PX_PLANE0_TILING_V = 16
987+ jpeg .PX_PLANE1_TILING_H = 4
988+ jpeg .PX_PLANE1_TILING_V = 16
989+ else :
990+ assert False
991+ elif pixfmt == 'YUV422-planar' :
992+ if args .encode_subsampling == '444' or args .encode_subsampling == '400' :
993+ jpeg .PX_PLANE0_TILING_H = 1
994+ jpeg .PX_PLANE0_TILING_V = 8
995+ jpeg .PX_PLANE1_TILING_H = 1
996+ jpeg .PX_PLANE1_TILING_V = 8
997+ elif args .encode_subsampling == '422' :
998+ jpeg .PX_PLANE0_TILING_H = 2
999+ jpeg .PX_PLANE0_TILING_V = 8
1000+ jpeg .PX_PLANE1_TILING_H = 2
1001+ jpeg .PX_PLANE1_TILING_V = 8
1002+ elif args .encode_subsampling == '420' :
1003+ jpeg .PX_PLANE0_TILING_H = 2
1004+ jpeg .PX_PLANE0_TILING_V = 16
1005+ jpeg .PX_PLANE1_TILING_H = 2
1006+ jpeg .PX_PLANE1_TILING_V = 16
1007+ else :
1008+ assert False
1009+ elif pixfmt == 'YUV420-planar' :
1010+ if args .encode_subsampling == '444' or args .encode_subsampling == '400' :
1011+ jpeg .PX_PLANE0_TILING_H = 1
1012+ jpeg .PX_PLANE0_TILING_V = 8
1013+ jpeg .PX_PLANE1_TILING_H = 1
1014+ jpeg .PX_PLANE1_TILING_V = 4
1015+ elif args .encode_subsampling == '422' :
1016+ jpeg .PX_PLANE0_TILING_H = 2
1017+ jpeg .PX_PLANE0_TILING_V = 8
1018+ jpeg .PX_PLANE1_TILING_H = 2
1019+ jpeg .PX_PLANE1_TILING_V = 4
1020+ elif args .encode_subsampling == '420' :
1021+ jpeg .PX_PLANE0_TILING_H = 2
1022+ jpeg .PX_PLANE0_TILING_V = 16
1023+ jpeg .PX_PLANE1_TILING_H = 2
1024+ jpeg .PX_PLANE1_TILING_V = 8
1025+ elif args .encode_subsampling == '411' :
1026+ jpeg .PX_PLANE0_TILING_H = 4
1027+ jpeg .PX_PLANE0_TILING_V = 8
1028+ jpeg .PX_PLANE1_TILING_H = 4
1029+ jpeg .PX_PLANE1_TILING_V = 4
1030+ else :
1031+ assert False
9081032 else :
9091033 assert False
9101034 jpeg .PX_PLANE0_STRIDE = surface_stride
911- jpeg .PX_PLANE1_STRIDE = 0
1035+ jpeg .PX_PLANE1_STRIDE = surface_P1_stride
9121036
913- if pixfmt in ['RGB888' , 'RGB101010' , 'RGB565' , 'YUV10' ]:
1037+ if pixfmt in ['RGB888' , 'RGB101010' , 'RGB565' , 'YUV10' , 'YUV444-planar' ]:
9141038 if args .encode_subsampling in ['422' , '420' ]:
9151039 jpeg .CHROMA_HALVE_H_TYPE1 = 1
9161040 if args .encode_subsampling == '420' :
9171041 jpeg .CHROMA_HALVE_V_TYPE1 = 1
918- elif pixfmt in ['YUV-linear' ]:
1042+ elif pixfmt in ['YUV-linear' , 'YUV422-planar' ]:
9191043 if args .encode_subsampling == '420' :
9201044 jpeg .CHROMA_HALVE_V_TYPE1 = 1
1045+ elif pixfmt == 'YUV420-planar' :
1046+ if args .encode_subsampling in ['422' , '444' ]:
1047+ jpeg .CHROMA_DOUBLE_V = 1
9211048 else :
9221049 assert False
9231050
@@ -951,6 +1078,8 @@ def set_default_regs(param1=0):
9511078 jpeg .ENCODE_PIXEL_FORMAT .set (FORMAT = E_ENCODE_PIXEL_FORMAT .YUV10_linear )
9521079 elif pixfmt == 'YUV-linear' :
9531080 jpeg .ENCODE_PIXEL_FORMAT .set (FORMAT = E_ENCODE_PIXEL_FORMAT .YUV_linear )
1081+ elif pixfmt in ['YUV444-planar' , 'YUV422-planar' , 'YUV420-planar' ]:
1082+ jpeg .ENCODE_PIXEL_FORMAT .set (FORMAT = E_ENCODE_PIXEL_FORMAT .YUV_planar )
9541083 else :
9551084 assert False
9561085 if pixfmt == 'YUV-linear' :
@@ -960,12 +1089,12 @@ def set_default_regs(param1=0):
9601089 jpeg .ENCODE_COMPONENT3_POS = 2
9611090 else :
9621091 jpeg .ENCODE_COMPONENT0_POS = 0
963- jpeg .ENCODE_COMPONENT1_POS = 1
964- jpeg .ENCODE_COMPONENT2_POS = 2
1092+ jpeg .ENCODE_COMPONENT1_POS = 0
1093+ jpeg .ENCODE_COMPONENT2_POS = 1
9651094 jpeg .ENCODE_COMPONENT3_POS = 3
9661095
9671096 jpeg .INPUT_START1 = input_buf_iova
968- jpeg .INPUT_START2 = 0xdeadbeef
1097+ jpeg .INPUT_START2 = input_buf_iova + surface_P1_off
9691098 jpeg .INPUT_END = input_buf_iova + input_mem_sz + 7 # NOTE +7
9701099 jpeg .OUTPUT_START1 = output_buf_iova
9711100 jpeg .OUTPUT_START2 = 0xdeadbeef
0 commit comments