Welcome to Doom9's Forum, THE in-place to be for everyone interested in DVD conversion.

Before you start posting please read the forum rules. By posting to this forum you agree to abide by the rules.

 

Go Back   Doom9's Forum > Capturing and Editing Video > Avisynth Development

Reply
 
Thread Tools Search this Thread Display Modes
Old 29th May 2010, 10:28   #1  |  Link
PitifulInsect
Registered User
 
Join Date: Nov 2008
Location: Sydney, Australia
Posts: 26
New Plugin - Sashimi (raw file access)

Hey there Doom9erinos!

History:
Many an age ago, I wrote my own raw reading and writing plugins for AVISynth because RawReader didn't do quite what I wanted.
Later, I needed to use raw reading of some files in a corporate environment, and software without clear licensing was banned from even being downloaded so I couldn't use RawReader! I dusted off my old plugins, made the first version of Sashimi, and made it GPLv2 (please note before commenting, that many business applications still have a big issue with GPLv3 because of the NAP clause, so I deliberately used v2 and for the next while at least I think that you should too if you'd like your software to be widely used and you don't plan to sue anyone).
Finally and more recently, I cleaned it up a lot and added some features, so now I'm putting it out there.

Actual Relevant Stuff:
In combination with the included .avsi scripts, it can read and write a whole host of raw formats, and I've used it myself a lot so it's relatively well tested but I'm sure that some major issues will be found as soon as others start using it too.
Let me know what you think! I'm keen to get feedback, and I plan to fix bugs if any are found, but I'm one of those people who sometimes takes ages to respond, so advance apologies if I'm slow answering any direct questions.

See here for the latest version on my site:
https://sites.google.com/site/ourenthusiasmsasham/soft

But for simplicity, the plugin and source are also attached to this post.

UPDATE: I've fixed bugs and extended the abilities since the original post. Even though discussion and development continues, these attached files are up to date, get sashimi here.
Previous versions are available at my site and linked from within the documentation. See below for comments, and here for the files:
Attached Files
File Type: zip sashimi_086.zip (152.4 KB, 360 views)
File Type: zip sashimi_086_src.zip (189.2 KB, 154 views)

Last edited by PitifulInsect; 11th June 2015 at 06:33. Reason: Updated URL to host site
PitifulInsect is offline   Reply With Quote
Old 29th May 2010, 17:13   #2  |  Link
b66pak
Registered User
 
b66pak's Avatar
 
Join Date: Aug 2008
Location: The Land Of Dracula (Romania - EU)
Posts: 934
thanks a lot...
_
__________________
if you ask a question and somebody give you the correct answer don't forget to leave a "thank you" note...
Visit The Land Of Dracula (Romania - EU)!
b66pak is offline   Reply With Quote
Old 29th May 2010, 22:39   #3  |  Link
IanB
Avisynth Developer
 
Join Date: Jan 2003
Location: Melbourne, Australia
Posts: 3,167
Quote:
Originally Posted by PitifulInsect View Post
...
But for simplicity, the plugin and source are also attached to this post:
Attached Files
File Type: zip sashimi_073.zip (146.9 KB, 20 views)
File Type: zip sashimi_073_src.zip (122.9 KB, 6 views)
Seems the attachments are barseackwards

The 147KB file is the source, the 123KB file is the release.
IanB is offline   Reply With Quote
Old 4th June 2010, 05:54   #4  |  Link
foxyshadis
ангел смерти
 
foxyshadis's Avatar
 
Join Date: Nov 2004
Location: Lost
Posts: 9,556
I like it, I could have used it last week! But it will be quick to switch to it from ImmaWrite/RawReader.
foxyshadis is offline   Reply With Quote
Old 5th June 2010, 19:24   #5  |  Link
PitifulInsect
Registered User
 
Join Date: Nov 2008
Location: Sydney, Australia
Posts: 26
Cheers IanB, they were backwards, but I've changed them around to be the right way around while updating the version to 0.74.

Minor bugfix aside, what I did was add a massive pile of documentation and a heap of runnable examples. I'm going to brag here about what the plugin does in those examples, so that this thread can be found by anyone doing a text search for how to do those things:
  • Read and write raw files as GREY, Y8, and (interleaved) BGR, RGB, BGRA, ARBG, ABGR, and RGBA
  • Read and write raw planar files as RGB24, RGB32, YUV444, YUV422, YUV420-as-YV12, and YUV420-as-IMC2
  • Read and write interleaved YUV files as YUV, YUY2, UYVY, and AYUV
  • Read uncompressed YUV (YCbCr) format files created in ImageMagick without the need for a colourspace conversion
  • Has documentation on how to pass YUV (YCbCr) images into ImageMagick out of AVISynth without the need for a colourspace conversion
  • Read and write other raw exotic formats
  • Read and write all of the above as either single video files or as collections of raw images per-frame
  • and lots more! (well, I already mentioned the "exotic" thing, so this might be a small lie).

Cheers for the comments so far!

Last edited by PitifulInsect; 5th June 2010 at 19:46. Reason: I hate typos! Fixed.
PitifulInsect is offline   Reply With Quote
Old 6th June 2010, 10:18   #6  |  Link
Chikuzen
typo lover
 
Chikuzen's Avatar
 
Join Date: May 2009
Posts: 595
@PitifulInsect
Thanks!

btw,i have a question.
are you scheduled corresponding to reading yuv4mpeg2?
Chikuzen is offline   Reply With Quote
Old 7th June 2010, 09:26   #7  |  Link
18fps
Registered User
 
Join Date: Oct 2008
Posts: 55
A question: could it be used to read an "exotic" RGB48 file?
18fps is offline   Reply With Quote
Old 8th June 2010, 03:49   #8  |  Link
foxyshadis
ангел смерти
 
foxyshadis's Avatar
 
Join Date: Nov 2004
Location: Lost
Posts: 9,556
Just note that if you need to process YUV files in imagemagick, the 16-bit precision (Q16) version often crashes reading and writing them.

One minor bug I found: RawWriter(...,overwrite=true) will only open the file, write into it, and close, but it will not truncate it first. So you get a bunch of garbage at the end if the original file was longer than the new one.
foxyshadis is offline   Reply With Quote
Old 18th June 2010, 07:43   #9  |  Link
PitifulInsect
Registered User
 
Join Date: Nov 2008
Location: Sydney, Australia
Posts: 26
Quote:
Originally Posted by Chikuzen View Post
are you scheduled corresponding to reading yuv4mpeg2?
I had to look it up - I hadn't come across it before.

Sorry Chikuzen, I wasn't planning to, but it should work just fine if you read the human-readable (as I understand it) headers and set the right offset, which would probably be good enough for a once-off solution. I would think that a half hour of hacking would make a Python script to parse the YUV4MPEG2 headers and write an appropriate AVISynth script (that sets the offset and dimensions, then calls the appropriate Sashimi function).

If you (or anyone) should write such a Python script, post it here and I'll include it in the next Sashimi release. If there are any YUV4MPEG2 pixel formats that Sashimi doesn't support (but AVISynth could), then please let me know. I won't immediately offer to do it myself, since I'm unfamiliar with the format or its usage, but I might wander back to this sometime - I'm intrigued!

I'm wondering if the headers could somehow be parsed directly from within a tricky AVISynth script without invoking anything else...
PitifulInsect is offline   Reply With Quote
Old 18th June 2010, 08:45   #10  |  Link
PitifulInsect
Registered User
 
Join Date: Nov 2008
Location: Sydney, Australia
Posts: 26
Quote:
Originally Posted by 18fps View Post
A question: could it be used to read an "exotic" RGB48 file?
16 bits per channel? Yes, but then what to do in AVISynth which only supports 8-bit formats?

Off the top of my head without testing (someone please test, debug, and re-post if you've used it - At the minimum I'll include it in the next release):
Code:
#
# Pass your double-frame-width frames through this sucker
# If you only want the low or high bits, then just use the appropriate
# first lines from this function, otherwise set bitshift between 1 and 7
#
function 16bit_to_8bit(clip c, int bitshift)
{
    hibits = TurnLeft().SeparateFields().SelectEven().TurnRight()
    lobits = TurnLeft().SeparateFields().SelectOdd().TurnRight()

    hibits = hibits.Levels(0,1,255, 32*bitshift,255, false)
    lobits = lobits.Levels(0,1,255, 0,32*bitshift-1, false)
    return hibits.Overlay(lobits, mode="Add")
}
You lose precision by going via AVISynth, but at least you're able to process the images at all.

Thoughts or suggestions from someone with 16-bit experience? Is a bit-offset between 0 and 8 a sensible approach? Should it be a scaling factor between 1 and 255? Should it be a range (between 1 and 65535) to scale to 255? Is there some other common way to deal with this?

16-bit data is probably a common enough use-case scenario to warrant direct support. I'm tempted to throw in the towel on 12-bit data though - what a nuisance!
PitifulInsect is offline   Reply With Quote
Old 18th June 2010, 08:58   #11  |  Link
PitifulInsect
Registered User
 
Join Date: Nov 2008
Location: Sydney, Australia
Posts: 26
Quote:
Originally Posted by foxyshadis View Post
Just note that if you need to process YUV files in imagemagick, the 16-bit precision (Q16) version often crashes reading and writing them.
You mean ImageMagick's problem, right? Sadly, though I love what ImageMagick is and does, I fully agree that it's a temperamental creature and the documentation can be a bit of a maze.

If you spot a Sashimi problem though, let me know and I'll jump all over it.

Quote:
Originally Posted by foxyshadis View Post
One minor bug I found: RawWriter(...,overwrite=true) will only open the file, write into it, and close, but it will not truncate it first. So you get a bunch of garbage at the end if the original file was longer than the new one.
Hmmm - that's kinda deliberate, but I guess that it's non-obvious behaviour - my bad. The exotic file-writing example uses the fact that you can write a file in multiple passes, and I also imagined that someone might want to write headers to files then add content later. It wasn't adequately documented though, and I suppose that I should also add a "truncate" parameter and set it to true by default, but be able to set it to false for the examples that I just mentioned. Sound good? It makes the default behaviour as expected but retains the ability to be fancy.

Cheers for the comments!

Last edited by PitifulInsect; 18th June 2010 at 09:03. Reason: just fixing a tired brainfart typo which made no sense into something that makes more sense, (I hope).
PitifulInsect is offline   Reply With Quote
Old 18th June 2010, 10:48   #12  |  Link
cretindesalpes
͡҉҉ ̵̡̢̛̗̘̙̜̝̞̟̠͇̊̋̌̍̎̏̿̿
 
cretindesalpes's Avatar
 
Join Date: Feb 2009
Location: No support in PM
Posts: 712
Quote:
Originally Posted by PitifulInsect View Post
16 bits per channel? Yes, but then what to do in AVISynth which only supports 8-bit formats?
I recently wrote a dithering script (I'm currently converting it to a plug-in for faster processing) and modified several denoising plug-ins in order to extract the extra bits from already dithered data. You could use a compatible method : either stack vertically the MSB part and the LSB part, or interleave them.
cretindesalpes is offline   Reply With Quote
Old 18th June 2010, 13:45   #13  |  Link
kemuri-_9
Compiling Encoder
 
kemuri-_9's Avatar
 
Join Date: Jan 2007
Posts: 1,348
Quote:
Originally Posted by PitifulInsect View Post
I had to look it up - I hadn't come across it before.

Sorry Chikuzen, I wasn't planning to, but it should work just fine if you read the human-readable (as I understand it) headers and set the right offset, which would probably be good enough for a once-off solution. I would think that a half hour of hacking would make a Python script to parse the YUV4MPEG2 headers and write an appropriate AVISynth script (that sets the offset and dimensions, then calls the appropriate Sashimi function).

If you (or anyone) should write such a Python script, post it here and I'll include it in the next Sashimi release. If there are any YUV4MPEG2 pixel formats that Sashimi doesn't support (but AVISynth could), then please let me know. I won't immediately offer to do it myself, since I'm unfamiliar with the format or its usage, but I might wander back to this sometime - I'm intrigued!

I'm wondering if the headers could somehow be parsed directly from within a tricky AVISynth script without invoking anything else...
http://linux.die.net/man/5/yuv4mpeg is a fairly good description of the format.
the format has a file header in addition to frame headers.
so in addition to the initial offset for the file header, you'll need to offset more at the start of each of frame for the frame header.

for avisynth 2.5.x you'd only need need to worry about 4:2:0.
for 2.6.x you'd need to also support 4:1:1, 4:2:2, and 4:4:4.

you could also refer to x264 and/or ffmpeg as they have some specific demuxer/muxer related code for yuv4mpeg.
__________________
custom x264 builds & patches | F@H | My Specs
kemuri-_9 is offline   Reply With Quote
Old 18th June 2010, 19:00   #14  |  Link
Wilbert
Moderator
 
Join Date: Nov 2001
Location: Netherlands
Posts: 6,364
yuv4mpeg writing is supported in ImmaWrite too. Its format:
Code:
line terminator \n = 0x0A (in C/C++)

yuv4mpeg.h in mjpegtools_1.9.0rc3.zip

/************************************************************************
 ************************************************************************

  Description of the (new!, forever?) YUV4MPEG2 stream format:

  STREAM consists of
    o one '\n' terminated STREAM-HEADER
    o unlimited number of FRAMEs

  FRAME consists of
    o one '\n' terminated FRAME-HEADER
    o "length" octets of planar YCrCb 4:2:0 image data
        (if frame is interlaced, then the two fields are interleaved)


  STREAM-HEADER consists of
     o string "YUV4MPEG2"
     o unlimited number TAGGED-FIELDs, each preceded by ' ' separator
     o '\n' line terminator

  FRAME-HEADER consists of
     o string "FRAME"
     o unlimited number of TAGGED-FIELDs, each preceded by ' ' separator
     o '\n' line terminator


  TAGGED-FIELD consists of
     o single ascii character tag
     o VALUE (which does not contain whitespace)

  VALUE consists of
     o integer (base 10 ascii representation)
  or o RATIO
  or o single ascii character
  or o non-whitespace ascii string

  RATIO consists of
     o numerator (integer)
     o ':' (a colon)
     o denominator (integer)


  The currently supported tags for the STREAM-HEADER:
     W - [integer] frame width, pixels, should be > 0
     H - [integer] frame height, pixels, should be > 0
     C - [string]  chroma-subsampling/data format
           420jpeg   (default)
           420mpeg2
           420paldv
           411
           422
           444       - non-subsampled Y'CbCr
	   444alpha  - Y'CbCr with alpha channel (with Y' black/white point)
           mono      - Y' plane only
     I - [char] interlacing:  p - progressive (none)
                              t - top-field-first
                              b - bottom-field-first
                              m - mixed -- see 'I' tag in frame header
                              ? - unknown
     F - [ratio] frame-rate, 0:0 == unknown
     A - [ratio] sample (pixel) aspect ratio, 0:0 == unknown
     X - [character string] 'metadata' (unparsed, but passed around)

  The currently supported tags for the FRAME-HEADER:
     Ixyz - framing/sampling (required if-and-only-if stream is "Im")
          x:  t - top-field-first
              T - top-field-first and repeat
	      b - bottom-field-first
              B - bottom-field-first and repeat
              1 - single progressive frame
              2 - double progressive frame (repeat)
              3 - triple progressive frame (repeat twice)

          y:  p - progressive:  fields sampled at same time
              i - interlaced:   fields sampled at different times

          z:  p - progressive:  subsampling over whole frame
              i - interlaced:   each field subsampled independently
              ? - unknown (allowed only for non-4:2:0 subsampling)           
       
     X - character string 'metadata' (unparsed, but passed around)

 ************************************************************************
 ************************************************************************/
Wilbert is offline   Reply With Quote
Old 19th June 2010, 00:04   #15  |  Link
foxyshadis
ангел смерти
 
foxyshadis's Avatar
 
Join Date: Nov 2004
Location: Lost
Posts: 9,556
Quote:
Originally Posted by PitifulInsect View Post
Hmmm - that's kinda deliberate, but I guess that it's non-obvious behaviour - my bad. The exotic file-writing example uses the fact that you can write a file in multiple passes, and I also imagined that someone might want to write headers to files then add content later. It wasn't adequately documented though, and I suppose that I should also add a "truncate" parameter and set it to true by default, but be able to set it to false for the examples that I just mentioned. Sound good? It makes the default behaviour as expected but retains the ability to be fancy.

Cheers for the comments!
Sounds good to me. I had no idea you could even do that, didn't look deep enough into the docs. Cool!

Quote:
Originally Posted by cretindesalpes View Post
I recently wrote a dithering script (I'm currently converting it to a plug-in for faster processing) and modified several denoising plug-ins in order to extract the extra bits from already dithered data. You could use a compatible method : either stack vertically the MSB part and the LSB part, or interleave them.
Does dithering alone actually work? Most of the time 12+ bit formats require gamma correction before truncation/dither to 8/10 bit. (I've seen 10 bit go either way.) I guess as long as you aren't too heavy on denoising and don't try to convert to/from rgb, it'll work. On the other hand, resizing should be more accurate.

PitifulInsect: Avisynth 2.6 is supposed to get full support for a 16-bit format, but right now it's rudimentary and unusable. I wish I was good enough at optimization to help with that.
foxyshadis is offline   Reply With Quote
Old 3rd July 2010, 03:23   #16  |  Link
Chikuzen
typo lover
 
Chikuzen's Avatar
 
Join Date: May 2009
Posts: 595
Quote:
Originally Posted by PitifulInsect View Post
If you (or anyone) should write such a Python script, post it here and I'll include it in the next Sashimi release.
Code:
#!/bin/env python
import sys
colorspace = None
plugin = r'c:\avisynth 2.5\plugins_32bit\'
print 'input y4m file path'
y4mpath = raw_input()

f=open(y4mpath,'r')
line1 = f.readline()
line2 = f.readline()
f.close()

header=line1.strip('\n').split(' ')
if header[0] != 'YUV4MPEG2':
 print 'This file is not yuv4mpeg2. Please confirm and try again.'
 sys.exit()

for param in header:
 if param[0] == 'C':
  colorspace = 'yuv' + param[1:4]
 if param[0] == 'W':
  width = param[1:]
 if param[0] == 'H':
  height = param[1:]
 if param[0] == 'F':
  fps = param.strip("F").split(":")
  fps_num = fps[0]
  fps_den = fps[1]

if colorspace == None:
 colorspace = 'yuv420'

filepath = y4mpath.replace('/','\\')
filehead = str(len(line1))
framehead = str(len(line2))

loadPlugin = 'LoadPlugin(%(plugin)s+"Sashimi.dll")\n' % vars()
importavs = 'Import(%(plugin)s+"PlanarConversions.avsi")\n' % vars()
y4mreader = 'RawReadPlanar("%(filepath)s", "%(colorspace)s", %(width)s, %(height)s, %(filehead)s, %(framehead)s)\n' % vars()
assumefps = 'AssumeFPS(%(fps_num)s, %(fps_den)s)\n' % vars()

avs = open('./y4msource.avs','w')
for makeavs in [loadPlugin, importavs, y4mreader, assumefps]:
 avs.write(makeavs)
avs.close()
This is python script that I wrote for the first time.
Please teach me when a mistake is found.

Last edited by Chikuzen; 10th January 2011 at 23:33.
Chikuzen is offline   Reply With Quote
Old 9th January 2011, 14:58   #17  |  Link
jmac698
Registered User
 
Join Date: Jan 2006
Posts: 1,867
Pitiful,
Could you update to include v210 format? I've started here:
UPDATED TO V0.5
Code:
#v210 Reader Ver 0.5 Feb/11 by jmac698
#Read v210 quicktime files with rawreader, by jmac698
#Requires Sashimi 0.75 http://sites.google.com/site/ourenthusiasmsasham/contributions/open-source-software#TOC-Sashimi
#also http://forum.doom9.org/showthread.php?p=1403600
#Masktools 2a48 http://manao4.free.fr/masktools-v2.0a48.zip
#In this experiment version, the QTSource is not used...
#QTSource http://www.tateu.net/software/ tested wtih Version 0.1.1 2011-02-19
#Quicktime 7:  http://www.free-codecs.com/download/QT_Lite.htm qtlite 4.1 with quicktime 7.69.80.9
#FFMpegSource: http://code.google.com/p/ffmpegsource/downloads/list  2.15
#Ver 0.5 - reads all test videos in .mov given the right headersize, fixed pixel order
#Ver 0.4 - reads full image in 8bit greyscale, with 10bit easily accessible
#Ver 0.3 - reads fully to 8bit greyscale, now requires masktools 2a48
#Ver 0.2 - fixed wrapping bug.  83 pixels *8=664, that would be the trailing bytes
#Ver 0.1 - reads only greyscale, can only read 1/3 of the size, only reads upper 6 bits, wrapped by 83 pixels
#Errors and what to do
#Message: Unable to Initialize Quicktime Environment
# to fix: install quicktime components

Global deeplasthi=blankclip(pixel_type="YV12").tweak(bright=-255,coring=false).tweak(bright=16,coring=false)
Global deeplastlo=blankclip(pixel_type="YV12").tweak(bright=-255,coring=false).tweak(bright=0,coring=false)
Global format=0#0=YV12, 1=YUY2, 2=RGB

fn="E:\project001a\deepcolor\v210 samples\"
f1="radialramp_480p29.97_16bitRGB_v210.mov"#hdr=48, 1 frame
f2="radialramp_576p25_16bitRGB_v210.mov"#hdr=48, 1 frame
f3="radialramp_720p23.976_16bitRGB_v210.mov"#hdr=48, 1 frame
f4="radialramp_1080p29.97_16bitRGB_v210.mov"#hdr=48, 1 frame
f5="testchart720p29.97_v210.mov"#hdr=48, 2 frame
f6="ArriAlexa.PR422.BT709.v210.mov"#hdr=1896, 121 frames
f7="bm444-480p29.97_r210.avi"#can't be loaded by ffvideosource, but should be able to be read raw
f8="v210.mov"#parkjoy standard test video, hdr=20528, 3 frames
fn=fn+f5
#deepread(fn)#f3, f5, f7 don't work i.e. QTSource has compatibility problems
#qtinput(fn,color=2,audio=2,mode=4)#mode 0,3 opens all but no video, mode4 couldn't find vfw codec but when enabled access violation
readv210(fn)
#ffvideosource(fn)#f7 don't work


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 readv210(string fn) {#reads v210 file of a given dimensions, but need to provide a header size
    #How to find the right header size: try starting at 48, and then count how many lines of garbage are at the top.
    #  then multiple rows of garbage by rowsize as calculated below (1920 for 480p/576p files, 5120 for 1080p files), and add this to headersize
    #  finally count the number of garbage pixels or shift at the left, divide by 3 and times 4, add this to headersize
    #  i.e. headersize=0.  There were 36 pixels of garbage at the top left, so headersize=36/3*4=48
    #  you can also increment by byte until you see picture, after that you can increment by 4 at a time to shift left by 3 pixels
    video=ffvideosource(fn)#opens the video however only as 8 bit, so we'll use the proper video properties from this to read raw
    w=video.width
    h=video.height
    f=video.framecount
    multiple48=w%48==0#is width a multiple of 48?  If false, there's some padding at the end of each row
    rowsize=ceil(w*8/3/128.0)*128#rows are padded to the nearest 48 pixels which is 128 bytes in v210 format
    hdr=w==1920?48:w==1280?48:w==720?48:48#These only work for some test files and can be considered the minimum header
    base=RawReader(fn, format="y8", width=rowsize, height=h, numframes=f, filehead=hdr, framehead=0)
    #a 1080p v210 (f8) file needed 5120*1080=5529600 bytes per frame, 3 frames, and header size=20528, trailer=664.   Filesize was 16609992
    #a 1080p v210 (f4) file needed 5120*1080=5529600 bytes per frame, 1 frame, and header size=48, trailer=15880.   Filesize was 5545528
    #a 720p v210 (f3) file needed 3456*720=2488320 bytes per frame, 1 frame, and header size=48, trailer=16762  Filesize was 2505130
    #a 480p v210 (f1) file needed 1920*480=921600 bytes per frame, 1 frame, and header size=48, trailer=15880  Filesize was 937528
    #byte3        byte2      byte1        byte0
    #xx987654 32109876 54321098 76543210
    #   Cr0              Y0              Cb0
    #byte3        byte2      byte1        byte0
    #xx987654 32109876 54321098 76543210
    #   Y2               Cb1             Y1   
    high4=base.every(4,2).every(2,0)#byte2, first row in diagram above or 3rd byte every 8 (so every(8,2) would work too), Y0 high 4 bits (in low 4 bits)
    low6=base.every(4,1).every(2,0)
    mt_lutxy(low6,high4,yexpr="y 15 &u 4 << x 4 >> +")#x 4 >> y 4 << +
    y0=last
    high2=base.every(4,1).every(2,1)
    low8=base.every(4,0).every(2,1)
    mt_lutxy(low8,high2,yexpr="y 3 &u 6 << x 2 >> +")#x 4 >> y 4 << +
    y1=last
    high6=base.every(4,3).every(2,1)#The 3rd byte in every 32bit word, and the 2nd word every 2 words, which is Y2 and Y5 pixels
    low4=base.every(4,2).every(2,1)
    mt_lutxy(low4,high6,yexpr="x 6 >> y 2 << +")
    y2=last
    weave3h(y0,y1,y2)
    crop(0,0,-(last.width-w),0)#dimensions that are padded need to get cropped at the right, e.g. width=1280 is read at 1296 then cropped
}

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 getlowbyte(clip vround, clip vtrunc) {#vround may have some pixels +1 compared to vtrunc; put the difference in the high bit
  Overlay(vround,vtrunc, mode="Subtract", pc_range=true)#e.g. y:129-128=1, 128-128=0. u,v are 128 or 129
  coloryuv(gain_y=127*256,off_u=-128,off_v=-128)
  coloryuv(gain_u=127*256,gain_v=127*256)
}

function deepread(string fn) {
  global deeplasthi=qtinput(fn,color=2,audio=2,mode=1,raw="v210")
  global format=IsYUY2(deeplasthi)?1:0
  qtinput(fn,color=2,audio=2,mode=1,raw="v210",dither=1)#9th bit
  #low bit to high bit
  getlowbyte(last,deeplasthi)
  global deeplastlo=last
  deeplasthi
}
I would like it if you store 10bit values as two bytes in two clips, then scripts can use 16bit video in a semi-compatible way.

Last edited by jmac698; 25th February 2011 at 08:36. Reason: Updated to v0.5
jmac698 is offline   Reply With Quote
Old 24th February 2011, 14:39   #18  |  Link
PitifulInsect
Registered User
 
Join Date: Nov 2008
Location: Sydney, Australia
Posts: 26
Hey all! Apologies for the extended absence.

A friend suggested directly reading gzipped files, since gzip is also GPLv2, and it sounded like a good idea - for some synthetic sequences, you can save a lot of diskspace working directly with compressed files. Unfortunately I found that the interface to gzip is more than a little hairy, I fought a tonne of compatibility problems, and when I got a debug-only version working I discovered that the caching performance was appalling since reading and seeking within the file requires decompressing big big chunks or even the whole thing to RAM! If that sounds like and exhasperatedly long sentence, there's a reason!

So yeah, development stalled, and all of your wonderful comments went unanswered. Sorry! I'm putting the idea of live compression aside for now - just use XVid or AVC (.h264) lossless if you need something in your workflow :-)

On to the updates!
  • foxyshadis - I've added that truncate option (default true) as discussed. Thank you for that feedback!
  • Chikuzen, kemuri-_9, Wilbert - I'm having a think about how to best deal with yuv4mpeg. Thank you especially Chikuzen for the script!
  • 18fps, foxyshadis, cretindesalpes - It looks like higher bit depths are a major use case alright!
    • For 16-bit, I have not yet, but will add some scripts for handling it in greyscale, and a native function for interleaved-16-bit RGB since no combination of TurnLeft(), Interleave() and SeparateFields() can interleave 3 things together.
    • This should also cover 24 and 48 bit values, handling them all as multiple planes of 8-bit internal values.
    • 12-bit breaks a lot of assumptions though, I'll put my thinking hat on for that one.
  • jmac698 - Thank you! A piece of the puzzle for free! Could you post a link to a sample file in v210 format or an official description of the format? For now anyone looking for it has your original solution right here :-) I'll learn about it and extend Sashimi next update.

Meantime: Version 0.75 posted! See top of page.
Thanks all! More updates soon I hope.
PitifulInsect is offline   Reply With Quote
Old 24th February 2011, 17:08   #19  |  Link
Gavino
Avisynth language lover
 
Join Date: Dec 2007
Location: Spain
Posts: 3,431
Quote:
Originally Posted by PitifulInsect View Post
... no combination of TurnLeft(), Interleave() and SeparateFields() can interleave 3 things together.
Not sure if it's the same as what you want, but have you seen this thread?
__________________
GScript and GRunT - complex Avisynth scripting made easier
Gavino is offline   Reply With Quote
Old 24th February 2011, 23:22   #20  |  Link
jmac698
Registered User
 
Join Date: Jan 2006
Posts: 1,867
Yes, I've extracted the weave3, I've had to do this myself a few months ago, which also lead me to discover bug... err, issue with pointresize; the implementation is different for each colorspace, the point which is thrown away in downsizing is different.
Code:
w = width(Clip1)
h = height(Clip1)

Pair1 = Interleave(Clip1, Clip3).Weave
Pair2 = Interleave(Clip2, Clip3).Weave
QuadHeight = Interleave(Pair1, Pair2).Weave # Line sequence is Clip1, Clip2, Clip3, Clip3, repeating.
TripleHeight = PointResize(QuadHeight, w, h*3)
Pt: I wrote a working full 10bit file reader with 16bit color controls in deepcolor utilties. The official docs are http://developer.apple.com/quicktime...h019.html#v210
The full quicktime spec is huge; but getting a visible image is easy, just skip some bytes and interpret the packed pixel format. Some people posted samples in my other thread. http://forum.doom9.org/showthread.ph...07#post1467907
jmac698 is offline   Reply With Quote
Reply

Thread Tools Search this Thread
Search this Thread:

Advanced Search
Display Modes

Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is On
HTML code is Off

Forum Jump


All times are GMT +1. The time now is 12:07.


Powered by vBulletin® Version 3.8.11
Copyright ©2000 - 2024, vBulletin Solutions Inc.