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
Register FAQ Calendar Today's Posts Search

 
 
Thread Tools Search this Thread Display Modes
Prev Previous Post   Next Post Next
Old 5th August 2012, 08:42   #1  |  Link
turbine
Registered User
 
Join Date: Jul 2012
Posts: 7
ImageSource(), ImageWriter(), x264-compressed still photos, avisynth improvements

YES... FINALLY I can post! The five-day waiting period is NOT a very kind policy, and definitely one that turns away contributors. I'd suggest a better solution would be requiring moderation during that period. Having said that, I appreciate this forum and its contributors. With a bit of trial and error the posts have been helpful and making sense of avisynth's impressive capabilities but cumbersome scripting format and design flaws.

I've been experimenting with using x264 to encode libraries of still images with impressive results. I'd like to share my results so far so that they may help others and assist further avisynth development.

FIRST... we need a script to construct the clip from images:

---begin "image seq reader.avs"------------------------------------------------------------
LoadPlugin("C:\Program Files\megui\tools\ffms\ffms2.dll")

fc = 23808
base_filename = "D:\img\album1\img"
img_type = "png"
digits = 6
h = 2048
w = 2048
fpsrate = 1.00
w_filename = "width.txt"
h_filename = "height.txt"
newline = Chr(13) + Chr(10)
w_header = "Type int" + newline + "Default -1" + newline
h_header = "Type int" + newline + "Default -1" + newline
matte = BlankClip(length=fc,w,h,"RGB32",fpsrate,audio_rate=0,channels=0) #init globally
frame = BlankClip(length=0,w,h,"RGB32",fpsrate,audio_rate=0,channels=0) #init globally

#Build returnclip
rclip = ScriptClip(matte,"""
cf = current_frame
img_filename=base_filename+RightStr("000000000"+String(cf),digits)+"."+img_type
frame=ImageSource(file=img_filename, start=0, end=0, fps=fpsrate, use_DevIL=false, info=false, pixel_type="RGB32")
return Layer(matte, frame, "add", level=257)
""")

rclip = WriteFileStart(rclip, w_filename, "w_header", append=true)
rclip = WriteFileStart(rclip, h_filename, "h_header", append=true)
rclip = WriteFile(rclip, w_filename, "String(current_frame) + Chr(32) + String(frame.Width())")
rclip = WriteFile(rclip, h_filename, "String(current_frame) + Chr(32) + String(frame.Height())")

return rclip.ConvertToYV12()

---end "image seq reader.avs"------------------------------------------------------------


...And to extract the images:


---begin "image seq writer.avs"------------------------------------------------------------

#LoadPlugin("C:\Program Files\AviSynth 2.5\plugins\GScript.dll")
LoadPlugin("C:\Program Files\megui\tools\ffms\ffms2.dll")

srce_filename = "D:\img\album1.mp4"
dest_filename = "D:\img\extract\img" #includes image filename prefix
dest_delimiter = "_"
image_type = "png"
w_filename = "width.txt"
h_filename = "height.txt"

FFVideoSource(srce_filename)

w = FFVideoSource(srce_filename).Width()
h = FFVideoSource(srce_filename).Height()
fc = FrameCount()
i = 0 #iteration

ScriptClip("""
cf = current_frame
ImageWriter(Trim(cf, -1).ConvertToRGB().Crop(0,0,img_w,img_h), dest_filename+RightStr("000000"+String(cf),6)+dest_delimiter, 0, 0, image_type, info=false)
AddBorders(0,0, w-img_w, h-img_h, $111111)
ConvertToYV12()
""")

ConditionalReader(h_filename, "img_h", show=false)
ConditionalReader(w_filename, "img_w", show=false)

---end "image seq writer.avs"------------------------------------------------------------

MANY avisynth shortcomings quickly became apparent when I got into this project. Although it's not common for video to have varying frame dimensions, here it is a necessity. I found I couldn't even TEMPORARILY have a frame a different size, it had to be another clip entirely. There also appears to be no way to attach metadata to a clip or a specific frame, hence the parallel data files "width.txt" and "height.txt"

Constructing those files was no picnic either, due to the basic flaw of having separate per-script commands and per-frame commands, and variable scope issues. To make matters worse, basic control structure and conditional operators (for-next and if-then-else) loops are not possible in the normal fashion without an add-on such as Gscript. Gscript actually worked great, but didn't return a single frame until the entire clip was constructed. Basic file handing is also missing.

If that wasn't enough, I learned that avisynth has a bad habit of ignoring commands which do not contribute to the final output, requiring hacks.

DEVELOPMENT SUGGESTIONS:
Avisynth could *greatly* benefit from an additional mode that allows more straightforward scripting, the use of current_frame referencing globally, if-then statements, for-next loops, and an option to elminate the ignoring of commands which don't affect the final output, some sort of "force" option.

New object types: More than anything else, what's missing are frame and metadata classes. ( http://avisynth.org/mediawiki/Script_variables ). A clip object would consist of a set of frames, and both frame and clip classes would contain metadata classes, which users could extend, depending on the desired destination container.

A "force" option which guarantees all commands would execute (unless restricted by conditional control structure, of course, i.e. "IF(i>2)AND(i<1)THEN" would never happen)

Output: Some sort of console and video output would be great. MessageClip() and similar functions are useful, but a poor substitute.

The existing WriteFile() and ConditionalReader() functions are dependent on clip objects. Basic "normal" file I/O functionality would be highly useful, and scriptwriters could customize and extend their configuration files to their heart's content. I'd suggest FileOpen(), FileClose(), FileWrite(), FileRead(), each returning a bool for error condition, which could be read by GetFileError(). The important thing is these commands would be completely independent of clip or frame objects.

Finally, extending ImageSource() and ImageWriter() to be methods of a frame class would be a lifesaver. I see this has been somewhat solved by others' excellent work with the Immaavs and Corona plugins, although it appears Immaavs does not handle subfolders with wildcards, and I don't believe the Corona plugin can't return the filename into a string, it can only write it to the image.

This takes me to my next battle and where I could use some help: What's a good way to pick up where the Corona reader leaves off? Specifically, I'd like these scripts to handle an entire folder, including subfolders, and get the filenames into a string, so that they can be written to a file along with the dimensions, keep track of how many images are written, etc. The writing script would then recreate the path.

Lastly, I greatly appreciate the contributions of those that have taken avisynth as far as it has and who have posted about their problems and solutions, they've been a big help when found via Google searches. I understand avisynth's limitations are the result of the thinking at the time it was initially designed a decade or more ago, along with limitations of the AVI container itself (which led to problematic hacks such as the "packed" bitstream, a hack which caused far more problems than it solved).

Best regards,
turbine

Last edited by Guest; 5th August 2012 at 12:46. Reason: 12
turbine is offline   Reply With Quote
 

Tags
file i/o, frame, imagesource, imagewriter, metadata


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 01:43.


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