jmac698
28th September 2011, 07:14
@Pit
I finally got around to writing my own readv210 with your new version, and I found another way to do it in just 2 passes. Not sure if it's any faster or not though; the code certainly seems simpler to me.
#v210 Reader Ver 0.5 by jmac698
#Read v210 Quicktime files with Sashimi, by jmac698
#Ver 0.5 - reads grey image in a new way with sashimi 0.85
#Requirements - only Sashimi 0.85
fn="D:\project001a\deepcolor\v210 samples\v210.mov"
readv210new(fn, 48, 1920, 1080)
function readv210new(string fn, int file_head, int frame_width, int frame_height) {#greyscale v210 file
line_size = (frame_width * 16 / 6 + 127) / 128 * 128 # all lines are padded to 128 bytes boundary
LeftWords = RawReader(fn, "RGB", line_size/4, frame_height, filehead=file_head, packing="8:0:8; 6:0:6; 18:0:2")#3 bitfields in 32bits
RightWords = RawReader(fn, "RGB", line_size/4, frame_height, filehead=file_head, packing="20:16:4; 4:0:4; 8:2:6")
p2 = LeftWords.every(2,1)
p3 = RightWords.every(2,1)
p0 = LeftWords.every(2,0)
p1 = RightWords.every(2,0)
Cb0_7_0=p0.showred
Y0_5_0=p0.showgreen
Cb0_9_8=p0.showblue
Cr0_3_0=p1.ShowRed
Y0_9_6=p1.ShowGreen
Cr0_9_4=p1.showblue
Y1_7_0=p2.showred
Cb1_5_0=p2.showgreen
Y1_9_8=p2.showblue
Y2_3_0=p3.showred
Cb1_9_6=p3.showgreen
Y2_9_4=p3.showblue
Y0_9_2=CombineBits(Y0_9_6,Y0_5_0,4)
Y1_9_2=CombineBits(Y1_9_8,Y1_7_0,2)
Y2_9_2=CombineBits(Y2_9_4,Y2_3_0,6)
Weave3h(Y0_9_2,Y1_9_2,Y2_9_2)
}
function weave3h(clip a, clip b, clip c) {#horizontally weave 3 clips
a=a.turnright
b=b.turnright
c=c.turnright
interleave(a,b,a,c)#0 1 2 3->01 23->0213->213 or abc
assumefieldbased
assumetff
weave
assumefieldbased
assumetff
weave
pointresize(width,height*3/4)#deletes every 4th line offset 0
turnleft
}
function every(clip v, int n, int offset) {#select every n bytes horizontally with offset, works on yv12 only
v
w=width
h=height
pointresize(v,w*2,h)
crop(offset*2,0,0,0).addborders(0,0,offset*2,0)#shift left offset pixels
pointresize(w/n,h)
}
function CombineBits(clip left, clip right, int bits) {
#Combine first bitsl of left with first bitsr of right
#e.g. 9876xxxx and 5432xxxx with bitsl=4, bitsr=4 gives 98765432
bitsright=8-bits
pwr=pow(2,bitsright)
Overlay(left, right.Levels(0,1,256, 0,int(pwr), false), mode="Add")
}
Aegwyn11
6th June 2013, 20:19
Resurrecting an old very helpful thread :)
I modified the ReadV210 script included in Sashimi 0.85 to support Stack16 output, enabling use of tools like Dither. I also made it so you can define the fh in the function call, as this works better for me. I realize its a bit dirtier than jmac698's version, but that's the one I started with, it works, and I don't want to spend any more time on it :)
I double checked using Dither and my input file matched my output file bit for bit.
Checking that input file matches output file bit for bit:
Readv210(input.yuv, 1920, 1080)
Dither_quantize(10,reducerange=true)
Dither_out()
#Command to generate output.yuv
#avs2yuv -raw -csp I422 "input.avs" - | ffmpeg -y -f rawvideo -pix_fmt yuv422p10le -s 1920x1080 -r 60000/1001 -i - -c:v v210 "output.yuv"
Modified ReadV210:
#
# Example of reading a really difficult file format.
# See http://developer.apple.com/quicktime/icefloe/dispatch019.html#v210
#
# Peter Pakulski, 2011
#
# Stack16 output added by Aegwyn11, 2013 (requires AVIsynth 2.6)
#
function ReadV210(string filename, int width, int height, int "fh")
{
fh = Default (fh, 0)
#OldReadV210(filename, width, height, fh)
#OptimisedReadV210(filename, width, height, fh)
Readv210Stack16(filename, width, height, fh)
}
#
# A straightforwards interpretation of a curly file format.
#
function OldReadV210(string filename, int width, int height, int "fh")
{
#
# There seems to be a standard file-header length, and it's only 48 bytes.
# The rest of the specification (there's more) is after the file body.
#fh = 48
fh = Default (fh, 0)
# The Read-width of the image is the width padded up to the nearest 48-byte
# boundary as per the specification, and divided by 6 because of the
# effective interlacing you get from reading only one value per pass.
rwidth = (width/48 + (width%48==0 ? 0 : 1)) * 48 / 6
#
# What a NUISANCE! The v210 format is little-endian 32-bit words, 128 bits at
# a time. So from the specification, for example, starting with the first 32:
# _______ _______ _______ ______
# / Byte3 \/ Byte2 \/ Byte1 \/ Byte0\
# XX 9876543210 9876543210 9876543210
# \___Cr___/ \___Y0___/ \___Cb___/
#
# Is actually stored all mixed up, if reading it in, in byte order:
# ______ _______ _______ _______
# / Byte0\ / Byte1 \ / Byte2 \ / Byte3 \
# 76543210 543210 98 3210 9876 XX 987654
# \__Cb__/ \_Y0_/ Cb \Cr/ \Y0/ \_Cr_/
#
# This pattern repeats.
#
# So below: Extract the muddled pixel colour components, half at a time, in
# multiple reads. Assemble them, then assemble them into colour planes, and
# finally assemble the colour planes into a colour image.
#
# 4-byte word #0 - as above (Cr0, Y0, Cb0)
Cb0H = RawReader(filename, "Y8", rwidth, height, filehead=fh, packing="128:14:2")
Cb0L = RawReader(filename, "Y8", rwidth, height, filehead=fh, packing="128:0:6")
Cb0 = Cb0H.Overlay(Cb0L.Levels(0,1,256, 0,64, false), mode="Add")
Y0H = RawReader(filename, "Y8", rwidth, height, filehead=fh, packing="128:20:4")
Y0L = RawReader(filename, "Y8", rwidth, height, filehead=fh, packing="128:8:4")
Y0 = Y0H.Overlay(Y0L.Levels(0,1,256, 0,16, false), mode="Add")
Cr0H = RawReader(filename, "Y8", rwidth, height, filehead=fh, packing="128:26:6")
Cr0L = RawReader(filename, "Y8", rwidth, height, filehead=fh, packing="128:16:2")
Cr0 = Cr0H.Overlay(Cr0L.Levels(0,1,256, 0,4, false), mode="Add")
# 4-byte word #1 - Y2, CB1, Y1
Y1H = RawReader(filename, "Y8", rwidth, height, filehead=fh, packing="128:46:2")
Y1L = RawReader(filename, "Y8", rwidth, height, filehead=fh, packing="128:32:6")
Y1 = Y1H.Overlay(Y1L.Levels(0,1,256, 0,64, false), mode="Add")
Cb1H = RawReader(filename, "Y8", rwidth, height, filehead=fh, packing="128:52:4")
Cb1L = RawReader(filename, "Y8", rwidth, height, filehead=fh, packing="128:40:4")
Cb1 = Cb1H.Overlay(Cb1L.Levels(0,1,256, 0,16, false), mode="Add")
Y2H = RawReader(filename, "Y8", rwidth, height, filehead=fh, packing="128:58:6")
Y2L = RawReader(filename, "Y8", rwidth, height, filehead=fh, packing="128:48:2")
Y2 = Y2H.Overlay(Y2L.Levels(0,1,256, 0,4, false), mode="Add")
# 4-byte word #2 - Cb2, Y3, Cr1
Cr1H = RawReader(filename, "Y8", rwidth, height, filehead=fh, packing="128:78:2")
Cr1L = RawReader(filename, "Y8", rwidth, height, filehead=fh, packing="128:64:6")
Cr1 = Cr1H.Overlay(Cr1L.Levels(0,1,256, 0,64, false), mode="Add")
Y3H = RawReader(filename, "Y8", rwidth, height, filehead=fh, packing="128:84:4")
Y3L = RawReader(filename, "Y8", rwidth, height, filehead=fh, packing="128:72:4")
Y3 = Y3H.Overlay(Y3L.Levels(0,1,256, 0,16, false), mode="Add")
Cb2H = RawReader(filename, "Y8", rwidth, height, filehead=fh, packing="128:90:6")
Cb2L = RawReader(filename, "Y8", rwidth, height, filehead=fh, packing="128:80:2")
Cb2 = Cb2H.Overlay(Cb2L.Levels(0,1,256, 0,4, false), mode="Add")
# 4-byte word #3 - Y5, Cr2, Y4
Y4H = RawReader(filename, "Y8", rwidth, height, filehead=fh, packing="128:110:2")
Y4L = RawReader(filename, "Y8", rwidth, height, filehead=fh, packing="128:96:6")
Y4 = Y4H.Overlay(Y4L.Levels(0,1,256, 0,64, false), mode="Add")
Cr2H = RawReader(filename, "Y8", rwidth, height, filehead=fh, packing="128:116:4")
Cr2L = RawReader(filename, "Y8", rwidth, height, filehead=fh, packing="128:104:4")
Cr2 = Cr2H.Overlay(Cr2L.Levels(0,1,256, 0,16, false), mode="Add")
Y5H = RawReader(filename, "Y8", rwidth, height, filehead=fh, packing="128:122:6")
Y5L = RawReader(filename, "Y8", rwidth, height, filehead=fh, packing="128:112:2")
Y5 = Y5H.Overlay(Y5L.Levels(0,1,256, 0,4, false), mode="Add")
# Next, assemble the three planes of the image:
# Y (with components 0, 1, 2, 3, 4, and 5),
# and Cb and Cr (each with components 0, 1, and 2).
# Assemble padded to even numbers, then use PointResize to remove the padding.
Y0_3_2_5_1_4_p_p = Interleave(Y0, Y3, Y2, Y5, Y1, Y4, Y0, Y0).TurnRight()
Y03_25_14_pp = Y0_3_2_5_1_4_p_p.AssumeFieldBased().AssumeTFF().Weave()
Y0235_1p4p = Y03_25_14_pp.AssumeFieldBased().AssumeTFF().Weave()
Y012p345p = Y0235_1p4p.AssumeFieldBased().AssumeTFF().Weave()
Y012p345p = Y012p345p.TurnLeft()
Y012345 = Y012p345p.PointResize(Y012p345p.Width()*3/4, Y012p345p.Height())
Cb0_2_1_p = Interleave(Cb0, Cb2, Cb1, Cb0).TurnRight()
Cb02_1p = Cb0_2_1_p.AssumeFieldBased().AssumeTFF().Weave()
Cb012p = Cb02_1p.AssumeFieldBased().AssumeTFF().Weave()
Cb012p = Cb012p.TurnLeft()
Cb012 = Cb012p.PointResize(Cb012p.Width()*3/4, Cb012p.Height())
Cr0_2_1_p = Interleave(Cr0, Cr2, Cr1, Cr0).TurnRight()
Cr02_1p = Cr0_2_1_p.AssumeFieldBased().AssumeTFF().Weave()
Cr012p = Cr02_1p.AssumeFieldBased().AssumeTFF().Weave()
Cr012p = Cr012p.TurnLeft()
Cr012 = Cr012p.PointResize(Cr012p.Width()*3/4, Cr012p.Height())
Y012345 = Y012345.ConvertToYUY2()
Cb012 = Cb012.ConvertToYUY2()
Cr012 = Cr012.ConvertToYUY2()
YToUV(Cb012, Cr012, Y012345)
# Each row is padded out, so crop back to the actual size.
Crop(0, 0, width, height)
}
#
# This version as above, but optimised, taking some shortcuts.
# As is, it is very hard to read, which is why the above exists.
#
function OptimisedReadV210(string filename, int width, int height, int "fh")
{
#fh = 48
fh = Default (fh, 0)
rwidth = (width/48 + (width%48==0 ? 0 : 1)) * 48 * 2/3
Cb0Y1Cr1Y4_H = RawReader(filename, "Y8", rwidth, height, filehead=fh, packing="32:14:2")
Cb0Y1Cr1Y4_L = RawReader(filename, "Y8", rwidth, height, filehead=fh, packing="32:0:6")
Cb0Y1Cr1Y4 = Cb0Y1Cr1Y4_H.Overlay(Cb0Y1Cr1Y4_L.Levels(0,1,256, 0,64, false), mode="Add")
Y0Cb1Y3Cr2_H = RawReader(filename, "Y8", rwidth, height, filehead=fh, packing="32:20:4")
Y0Cb1Y3Cr2_L = RawReader(filename, "Y8", rwidth, height, filehead=fh, packing="32:8:4")
Y0Cb1Y3Cr2 = Y0Cb1Y3Cr2_H.Overlay(Y0Cb1Y3Cr2_L.Levels(0,1,256, 0,16, false), mode="Add")
Cr0Y2Cb2Y5_H = RawReader(filename, "Y8", rwidth, height, filehead=fh, packing="32:26:6")
Cr0Y2Cb2Y5_L = RawReader(filename, "Y8", rwidth, height, filehead=fh, packing="32:16:2")
Cr0Y2Cb2Y5 = Cr0Y2Cb2Y5_H.Overlay(Cr0Y2Cb2Y5_L.Levels(0,1,256, 0,4, false), mode="Add")
Cb0Y1Cr1Y4 = Cb0Y1Cr1Y4.TurnRight()
Cb0Cr1_Y1Y4 = Cb0Y1Cr1Y4.AssumeFrameBased().AssumeTFF().SeparateFields()
Y1Y4 = Cb0Cr1_Y1Y4.SelectOdd()
Cb0_Cr1 = Cb0Cr1_Y1Y4.SelectEven().AssumeFrameBased().AssumeTFF().SeparateFields()
Cb0 = Cb0_Cr1.SelectEven()
Cr1 = Cb0_Cr1.SelectOdd()
Y0Cb1Y3Cr2 = Y0Cb1Y3Cr2.TurnRight()
Y0Y3_Cb1Cr2 = Y0Cb1Y3Cr2.AssumeFrameBased().AssumeTFF().SeparateFields()
Y0Y3 = Y0Y3_Cb1Cr2.SelectEven()
Cb1_Cr2 = Y0Y3_Cb1Cr2.SelectOdd().AssumeFrameBased().AssumeTFF().SeparateFields()
Cb1 = Cb1_Cr2.SelectEven()
Cr2 = Cb1_Cr2.SelectOdd()
Cr0Y2Cb2Y5 = Cr0Y2Cb2Y5.TurnRight()
Cr0Cb2_Y2Y5 = Cr0Y2Cb2Y5.AssumeFrameBased().AssumeTFF().SeparateFields()
Y2Y5 = Cr0Cb2_Y2Y5.SelectOdd()
Cr0_Cb2 = Cr0Cb2_Y2Y5.SelectEven().AssumeFrameBased().AssumeTFF().SeparateFields()
Cr0 = Cr0_Cb2.SelectEven()
Cb2 = Cr0_Cb2.SelectOdd()
Y03_25_14_pp = Interleave(Y0Y3, Y2Y5, Y1Y4, Y0Y3)
Y0235_1p4p = Y03_25_14_pp.AssumeFieldBased().AssumeTFF().Weave()
Y012p345p = Y0235_1p4p.AssumeFieldBased().AssumeTFF().Weave()
Y012345 = Y012p345p.PointResize(Y012p345p.Width(), Y012p345p.Height()*3/4)
Y012345 = Y012345.TurnLeft()
Cb0_2_1_p = Interleave(Cb0, Cb2, Cb1, Cb0)
Cb02_1p = Cb0_2_1_p.AssumeFieldBased().AssumeTFF().Weave()
Cb012p = Cb02_1p.AssumeFieldBased().AssumeTFF().Weave()
Cb012 = Cb012p.PointResize(Cb012p.Width(), Cb012p.Height()*3/4)
Cb012 = Cb012.TurnLeft()
Cr0_2_1_p = Interleave(Cr0, Cr2, Cr1, Cr0)
Cr02_1p = Cr0_2_1_p.AssumeFieldBased().AssumeTFF().Weave()
Cr012p = Cr02_1p.AssumeFieldBased().AssumeTFF().Weave()
Cr012 = Cr012p.PointResize(Cr012p.Width(), Cr012p.Height()*3/4)
Cr012 = Cr012.TurnLeft()
Y012345 = Y012345.ConvertToYUY2()
Cb012 = Cb012.ConvertToYUY2()
Cr012 = Cr012.ConvertToYUY2()
YToUV(Cb012, Cr012, Y012345)
Crop(0, 0, width, height)
}
#
# This version as a modified version of OptimisedReadV210 to output Stack16.
# Using this, you can use Stack16 capable plugins (such as Dither) to process all 10 bits.
#
function Readv210Stack16(string filename, int width, int height, int "fh")
{
fh = Default (fh, 0)
rwidth = (width/48 + (width%48==0 ? 0 : 1)) * 48 * 2/3
Cb0Y1Cr1Y4_H = RawReader(filename, "Y8", rwidth, height, filehead=fh, packing="32:14:2")
Cb0Y1Cr1Y4_L = RawReader(filename, "Y8", rwidth, height, filehead=fh, packing="32:0:6")
Cb0Y1Cr1Y4_8 = Cb0Y1Cr1Y4_H.Overlay(Cb0Y1Cr1Y4_L.Levels(0,1,256, 0,64, false), mode="Add")
Cb0Y1Cr1Y4_10 = RawReader(filename, "Y8", rwidth, height, filehead=fh, packing="32:6:2")
Cb0Y1Cr1Y4 = StackVertical(Cb0Y1Cr1Y4_8,Cb0Y1Cr1Y4_10)
Y0Cb1Y3Cr2_H = RawReader(filename, "Y8", rwidth, height, filehead=fh, packing="32:20:4")
Y0Cb1Y3Cr2_L = RawReader(filename, "Y8", rwidth, height, filehead=fh, packing="32:8:4")
Y0Cb1Y3Cr2_8 = Y0Cb1Y3Cr2_H.Overlay(Y0Cb1Y3Cr2_L.Levels(0,1,256, 0,16, false), mode="Add")
Y0Cb1Y3Cr2_10 = RawReader(filename, "Y8", rwidth, height, filehead=fh, packing="32:12:2")
Y0Cb1Y3Cr2 = StackVertical(Y0Cb1Y3Cr2_8,Y0Cb1Y3Cr2_10)
Cr0Y2Cb2Y5_H = RawReader(filename, "Y8", rwidth, height, filehead=fh, packing="32:26:6")
Cr0Y2Cb2Y5_L = RawReader(filename, "Y8", rwidth, height, filehead=fh, packing="32:16:2")
Cr0Y2Cb2Y5_8 = Cr0Y2Cb2Y5_H.Overlay(Cr0Y2Cb2Y5_L.Levels(0,1,256, 0,4, false), mode="Add")
Cr0Y2Cb2Y5_10 = RawReader(filename, "Y8", rwidth, height, filehead=fh, packing="32:18:2")
Cr0Y2Cb2Y5 = StackVertical(Cr0Y2Cb2Y5_8,Cr0Y2Cb2Y5_10)
Cb0Y1Cr1Y4 = Cb0Y1Cr1Y4.TurnRight()
Cb0Cr1_Y1Y4 = Cb0Y1Cr1Y4.AssumeFrameBased().AssumeTFF().SeparateFields()
Y1Y4 = Cb0Cr1_Y1Y4.SelectOdd()
Cb0_Cr1 = Cb0Cr1_Y1Y4.SelectEven().AssumeFrameBased().AssumeTFF().SeparateFields()
Cb0 = Cb0_Cr1.SelectEven()
Cr1 = Cb0_Cr1.SelectOdd()
Y0Cb1Y3Cr2 = Y0Cb1Y3Cr2.TurnRight()
Y0Y3_Cb1Cr2 = Y0Cb1Y3Cr2.AssumeFrameBased().AssumeTFF().SeparateFields()
Y0Y3 = Y0Y3_Cb1Cr2.SelectEven()
Cb1_Cr2 = Y0Y3_Cb1Cr2.SelectOdd().AssumeFrameBased().AssumeTFF().SeparateFields()
Cb1 = Cb1_Cr2.SelectEven()
Cr2 = Cb1_Cr2.SelectOdd()
Cr0Y2Cb2Y5 = Cr0Y2Cb2Y5.TurnRight()
Cr0Cb2_Y2Y5 = Cr0Y2Cb2Y5.AssumeFrameBased().AssumeTFF().SeparateFields()
Y2Y5 = Cr0Cb2_Y2Y5.SelectOdd()
Cr0_Cb2 = Cr0Cb2_Y2Y5.SelectEven().AssumeFrameBased().AssumeTFF().SeparateFields()
Cr0 = Cr0_Cb2.SelectEven()
Cb2 = Cr0_Cb2.SelectOdd()
Y03_25_14_pp = Interleave(Y0Y3, Y2Y5, Y1Y4, Y0Y3)
Y0235_1p4p = Y03_25_14_pp.AssumeFieldBased().AssumeTFF().Weave()
Y012p345p = Y0235_1p4p.AssumeFieldBased().AssumeTFF().Weave()
Y012345 = Y012p345p.PointResize(Y012p345p.Width(), Y012p345p.Height()*3/4)
Y012345 = Y012345.TurnLeft()
Cb0_2_1_p = Interleave(Cb0, Cb2, Cb1, Cb0)
Cb02_1p = Cb0_2_1_p.AssumeFieldBased().AssumeTFF().Weave()
Cb012p = Cb02_1p.AssumeFieldBased().AssumeTFF().Weave()
Cb012 = Cb012p.PointResize(Cb012p.Width(), Cb012p.Height()*3/4)
Cb012 = Cb012.TurnLeft()
Cr0_2_1_p = Interleave(Cr0, Cr2, Cr1, Cr0)
Cr02_1p = Cr0_2_1_p.AssumeFieldBased().AssumeTFF().Weave()
Cr012p = Cr02_1p.AssumeFieldBased().AssumeTFF().Weave()
Cr012 = Cr012p.PointResize(Cr012p.Width(), Cr012p.Height()*3/4)
Cr012 = Cr012.TurnLeft()
Y012345 = Y012345.ConvertToYV16()
Cb012 = Cb012.ConvertToYV16()
Cr012 = Cr012.ConvertToYV16()
YToUV(Cb012, Cr012, Y012345)
#This is commented out because I don't think its necessary. ## This IS required for some resolutions, DUH.
Crop(0, 0, width, height*2)
}
vBulletin® v3.8.11, Copyright ©2000-2026, vBulletin Solutions Inc.