Log in

View Full Version : replace frame with picture file


t1dUs
26th March 2006, 22:01
Since I cannot access avisynt.org then I'll ask it here: what is the function to replace a frame of a clip for a picture file? The thing is that I took one of the frames in my clip and repaired it with paintshop pro. Also, are all the picture formats equally good?

If possible do it with this example in order to see the syntax of the function:
the picture -> c:\picture.bmp
frame to replace -> 300

TIA

Tripx
26th March 2006, 22:04
ReplaceFrame (http://zeratul.cellosoft.com/replaceframe/)

t1dUs
26th March 2006, 22:28
thnx Tripx, but isn't there a built in function inside avysinth already? I'd prefer to know that one instead of having to install new dlls in windows' system folder.

PS: I'm gettin external exception E06D7363, so I need somethin else :(

Mug Funky
27th March 2006, 01:34
try this: i haven't used it for a while, but i use this for replacing splats with photoshopped fixes (tedious work...)

function imagesplice (clip c, string "filename", int "frameno")
{
frame=imagesource(filename)
frame=frame.selectevery(frame.framecount,0).assumefps(c.framerate).converttoyv12()
c.trim(0,frameno-1)++frame++c.trim(frameno+1,0)
}

usage:

imagesplice("blurt.png",1200)

would replace frame 1200 with the picture "blurt.png". works for yv12 for now, but it's a trivial matter to modify it for yuy2 or rgb.

just stick that code block in your script, or whack it in a new text file called imagesplice.avsi in your plugins directory.

foxyshadis
27th March 2006, 01:35
System folder? You should be putting them in avisynth's plugin folder. You can also add jdl-util.avsi and jdl-range.avsi (http://www.avisynth.org/stickboy/) to the folder instead, and use jdl_replacerange with the same start & end. Something like:


avisource("stuff.avi")
JDL_ReplaceRange(imagesource("picture.bmp").converttoyv12,300,300)


[edit] *shakes fist at Mug Funky* :p

t1dUs
27th March 2006, 03:13
thnx a lot to Mug Funky and foxyshadis, both ways work like a charm :D , but I think I'll stick to Mug Funky's since it requires less typing :P

Dogway
9th February 2010, 00:40
ya, I know the thread is old, but the problem is related to the function posted by Mug Funky.

Im using it in my script together a call function when required loading an avs with all the imagesplice frames list.

Everything works correctly until I put a trim function in the script, which corrupts the framenumber. I would like to know how to make the frame order based on the untrimed video so it keeps consistency.

DirectShowsource("mysource.mp4",audio = false)

trim(1688,1787)

Import("LoadRef.avs")

function imagesplice (clip c, string "filename", int "frameno")
{
frame=imagesource(filename)
frame=frame.selectevery(frame.framecount,0).assumefps(c.framerate).converttoyv12()
c.trim(0,frameno-1)++frame++c.trim(frameno+1,0)
}

LoadRef.avs

imagesplice("1162.jpg",1162)
imagesplice("1347.jpg",1347)
imagesplice("1485.jpg",1485)
imagesplice("1508.jpg",1508)
(...)

Guest
9th February 2010, 00:50
Do the trim AFTER the imagesplice's.

Dogway
9th February 2010, 01:08
I wished it was that simple. I have tried to put it in every place I could imagine. I dont understand the declaration in the function, but maybe indicating there to read from the original source, and not trimmed version.

Gavino
9th February 2010, 10:33
Putting the Trim at the end of the script does make the splices work on the original untrimmed source.

But of course the splices to frames 1162, 1347, 1485 and 1508 will be trimmed out of the final result. Is that what you want?

Dogway
9th February 2010, 18:50
ups, sorry. It seemed to be my fault. I took the framenumbers based on ffmpegsource, and after when I changed the call function to DirectShowSource, the framenumbers changed and I didnt realize.

I dont understand why it happens, which of them do you suggest me to use? Sorry for the mistake.

Hola Gavino, me alegro de ver mas espaņoles por aqui.

Gavino
9th February 2010, 19:49
Hola, Dogway.
I took the framenumbers based on ffmpegsource, and after when I changed the call function to DirectShowSource, the framenumbers changed and I didnt realize.
I dont understand why it happens, which of them do you suggest me to use?
DirectShowSource does not always provide frame-accurate seeking, so ffmpegsource is probably better for this source.

GMJCZP
8th November 2014, 04:59
Sorry to revive this topic.
A while ago I met the helpful script Mug Funky's ImageSplice, and unfortunately noticed two problems:

- You can't replace the first frame (frame 0)
- Incompatibilities with the audio.

This led me, based on ImageSplice, create gradually a single script to that meets the same idea but in a more functional way...

GMJCZP
8th November 2014, 05:06
RescueFrame

The plan in RescueFrame is the following:

- Add to the original video as a first frame the modified frame, that is, as a sort of header record.
- Then, know the frame or frames to replace to use internally the Freezeframe function, by taking the modified frame or "header record".
- Finally, the first frame is removed, all while preserving the original audio, if be present.

Here the script:

###
#
# RescueFrame is a function dedicated for replace undesirable frames
# with frames captured and/or edited previously. For AVS+ only.
#
# Written by GMJCZP
#
# - Initial release (07/11/2014)
#
# - Version 2.0 (24/05/2021)
# Now it works in HBD! (AVS+ only!).
#
# - Version 2.1 (26/05/2021)
# Better handling of Overlay.
#
# - Version 3.0 (06/06/2021)
# Optimization of the entire function, including the elimination of
# Overlay, resulting in a increase in speed; fix in audio handling.
#
###

###
# USAGE / SUGGESTIONS
###
#
# In case of restoration, to capture the frame to edit, making sure that it is
# identical to the original.
# A sure method can be to place this sentence before to call RescueFrame:
# ConverttoRGB24().ImageWriter("", frame, frame, "bmp").ConverttoYV12()
# and then to go to frame. It will be generated a bmp file in the same folder where
# is the Avisynth script. In that instant one already can it erases the sentence of up.
#
# Another sure method is using VirtulDub for Copy frames.
#
# NEVER to use VirtualDubMod for copy/snapshot frames!
#
# Once made the capture can use your favorite program of edition of images
# for its edition and then call this function.
#
###

###
# PARAMETERS
###
#
# "FileName"
# Name of the file of the edited frame. Example: "MyRestoredFrame000.bmp"
#
# "FrameNumber"
# Number of frame to replace.
#
# "NumRep"
# Number of times that the frame will repeat, replacing the successive frames.
#
####

function RescueFrame (clip video, string FileName, int FrameNumber, int "NumRep")
{
NumRep = Default(NumRep, 0)

edit_frame = ImageSource(FileName,use_DevIL=true,end=0,fps=framerate(video)).converttoYV12().convertbits(video.BitsPerComponent())
clp = edit_frame + video.KillAudio()
clp = clp.Freezeframe(FrameNumber+1,FrameNumber+1+NumRep,0).Deleteframe(0)
clp = (HasAudio(video) == false) ? clp : AudioDubEx(clp,video)
return clp
}

EDIT: For some reason I do not know, if StackHorizontal (or StackVertical) is used BEFORE the RescueFrame, the frame to the right (or below) is black, so the call order must be reversed.

Mounir
18th May 2015, 00:30
I like this RescueFrame script above but i'd need to work with avisource instead of imagesource (that i've figured it out you only replace source = avisource(FileName) but then come my desire to use a Trim for this avisource to select the wanted frame, here i'm hiting a rock; if you can guide me...

StainlessS
18th May 2015, 00:52
Just as in above script, to trim a single frame use

vFrame = Trim(vClip,FrameNo,-1)

-2 trims 2 frames etc.

Also note, In RescueFrame, FileName and FrameNumber are given as Optional (in quotes) but they do not have defaults and so will
error if called without them.
Either provide defaults or remove quotes.

Also note, FrameSel/Rep can extract any number of frames and then replace them again later.

EDIT: Here:- http://forum.doom9.org/showthread.php?t=167971&highlight=framesel

GMJCZP
24th May 2021, 04:22
See post # 14

Currently RescueFrame only operates in 8 bits, the culprit is in the Overlay call, is there any way to bring the script to HBD?

Fortunately it is not a serious matter but academically speaking it would be interesting to resolve it.

StainlessS
24th May 2021, 13:56
It would be a better function if supplied as arg, frames clip instead of a filename.
And the clip being required to be in a colorspace compatible with the source clip (and Overlay or Layer).
In AVS+ Overlay/Layer, (I think) colorspace has to be same type, ie Interleaved/Planar, and same bit depth.

This is some code from Work In Progress script to match colorspace exactly. [also some required support functions not posted]


Function ExL_MatchCS(clip c,clip matchto,String "matrix",Bool "fulls",bool "fulld") { # Match c clip to matchto clip colorspace
RT_DebugF("ExL_MatchCS: IN c=%s MatchTo=%s",c.X_PixelType,matchto.X_PixelType)
if(c.X_PixelType != matchto.X_PixelType) {
# currently (avs+ 3.5) fulld must equal fulls
mat=Default(matrix,"PC.601") # Matrix default no change ie full range matrix : fulls=auto ie undefined, true for RGB else false.
matchto.IsYV12?c.ConvertToYV12(matrix=Mat):matchto.IsYUY2?c.ConvertToYUY2(matrix=Mat):matchto.IsRGB24?c.ConvertToRGB24(matrix=Mat)
\ : matchto.IsRGB32?c.ConvertToRGB32(matrix=Mat):matchto.IsYV16?c.ConvertToYV16(matrix=Mat):matchto.IsYV24?c.ConvertToYV24(matrix=Mat)
\ : matchto.IsY8?c.ConvertToY8(matrix=Mat):matchto.IsRGB48?c.ConvertToRGB48(matrix=Mat):matchto.IsRGB64?c.ConvertToRGB64(matrix=Mat):Undefined
if(!Defined) { # Is Avs+ AND MatchTo == Planar, Can use AVS+ functions directly here.
c
if(matchto.IsRGB) {
matchto.HasAlpha == HasAlpha ? NOP : matchto.HasAlpha ? ConvertToPlanarRGBA(matrix=Mat) : ConvertToPlanarRGB(matrix=Mat)
} else if(matchto.IsY) {
RT_DebugF("Match to IsY")
ConvertToY(matrix=Mat)
} else {
RT_DebugF("Match to IsYUVA=%s or ISYUV=%s",matchto.IsYUVA,matchto.IsYUV)
if(matchto.Is444) { ConvertToYUV444(matrix=Mat) }
else if(matchto.Is422) { ConvertToYUV422(matrix=Mat) }
else if(matchto.Is420) { ConvertToYUV420(matrix=Mat) }
}
mbpc=matchto.BitsPerComponent bpc=BitsPerComponent
if(mbpc!=bpc) {
RT_debugF("Converting Bits from %d to %d",X_Bpc,matchto.X_Bpc)
ConvertBits(mbpc) #,fulls=fulls,fulld=fulld)
}
(matchto.HasAlpha==HasAlpha) ? NOP : HasAlpha ? RemoveAlphaPlane : AddAlphaPlane
}
} else { c }
RT_DebugF("ExL_MatchCS: OUT c=%s matchto=%s",X_PixelType,matchto.X_PixelType)
return last
}


It can be a real pain.

Alternative to the orginal mug_funky style function


# NOT HBD aware for FrameSel/FrameRep SHOW=TRUE.
# When Not Showing Text(ie not changing frame content), does not require knowledge of HBD, ie works OK.
Colorbars.ShowFrameNumber.ConvertToYV24.ConvertBits(10).KillAudio
ORG=Last # Original, with/without audio
F=FlipVertical # Flipped, or maybe from ImageSource
R=F.FrameSel(10,20,30) # 3 flipped frames, 10, 20, 30, into R clip frames 0,1,2
# Equivalent to 3 frames read from file and converted to same colorspace as source.

Framerep(Last,R, 10,20,30) # Replace 3 frames, 10, 20, 30 (From R clip frames 0,1,2)

#Framerep(Last,R,SCmd="10;20;30") # Replace 3 frames 10,20,30, SCMD using command in string. CMD using command File.
AudioDubEx(Last,ORG) # Restore Audio from source, if present
Info

#convertToRGB32 # To view. Not needed for some players eg PotPlayer

return Last

EDIT: Above added AudioDubEx

EDIT: FrameSel/FrameRep, does not support Audio, AudioDubEx with original audio from source clip.

https://i.postimg.cc/sB7VbcCf/Ov-Test-00.jpg (https://postimg.cc/sB7VbcCf)

EDIT: FrameSel/Framerep supports thousands of frame replacements [commands in text file], timed when plugin first written
to be about 40,000 frames indexes read from text file in about 2 seconds, before frameserving starts.
During frameserving, overhead not much different to a trim and splce of a single frame.

GMJCZP
24th May 2021, 16:03
It would be a better function if supplied as arg, frames clip instead of a filename.
And the clip being required to be in a colorspace compatible with the source clip (and Overlay or Layer).
In AVS+ Overlay/Layer, (I think) colorspace has to be same type, ie Interleaved/Planar, and same bit depth.

This is some code from Work In Progress script to match colorspace exactly. [also some required support functions not posted]


Function ExL_MatchCS(clip c,clip matchto,String "matrix",Bool "fulls",bool "fulld") { # Match c clip to matchto clip colorspace
RT_DebugF("ExL_MatchCS: IN c=%s MatchTo=%s",c.X_PixelType,matchto.X_PixelType)
if(c.X_PixelType != matchto.X_PixelType) {
# currently (avs+ 3.5) fulld must equal fulls
mat=Default(matrix,"PC.601") # Matrix default no change ie full range matrix : fulls=auto ie undefined, true for RGB else false.
matchto.IsYV12?c.ConvertToYV12(matrix=Mat):matchto.IsYUY2?c.ConvertToYUY2(matrix=Mat):matchto.IsRGB24?c.ConvertToRGB24(matrix=Mat)
\ : matchto.IsRGB32?c.ConvertToRGB32(matrix=Mat):matchto.IsYV16?c.ConvertToYV16(matrix=Mat):matchto.IsYV24?c.ConvertToYV24(matrix=Mat)
\ : matchto.IsY8?c.ConvertToY8(matrix=Mat):matchto.IsRGB48?c.ConvertToRGB48(matrix=Mat):matchto.IsRGB64?c.ConvertToRGB64(matrix=Mat):Undefined
if(!Defined) { # Is Avs+ AND MatchTo == Planar, Can use AVS+ functions directly here.
c
if(matchto.IsRGB) {
matchto.HasAlpha == HasAlpha ? NOP : matchto.HasAlpha ? ConvertToPlanarRGBA(matrix=Mat) : ConvertToPlanarRGB(matrix=Mat)
} else if(matchto.IsY) {
RT_DebugF("Match to IsY")
ConvertToY(matrix=Mat)
} else {
RT_DebugF("Match to IsYUVA=%s or ISYUV=%s",matchto.IsYUVA,matchto.IsYUV)
if(matchto.Is444) { ConvertToYUV444(matrix=Mat) }
else if(matchto.Is422) { ConvertToYUV422(matrix=Mat) }
else if(matchto.Is420) { ConvertToYUV420(matrix=Mat) }
}
mbpc=matchto.BitsPerComponent bpc=BitsPerComponent
if(mbpc!=bpc) {
RT_debugF("Converting Bits from %d to %d",X_Bpc,matchto.X_Bpc)
ConvertBits(mbpc) #,fulls=fulls,fulld=fulld)
}
(matchto.HasAlpha==HasAlpha) ? NOP : HasAlpha ? RemoveAlphaPlane : AddAlphaPlane
}
} else { c }
RT_DebugF("ExL_MatchCS: OUT c=%s matchto=%s",X_PixelType,matchto.X_PixelType)
return last
}


It can be a real pain.

Alternative to the orginal mug_funky style function


# NOT HBD aware for FrameSel/FrameRep SHOW=TRUE.
# When Not Showing Text(ie not changing frame content), does not require knowledge of HBD, ie works OK.
Colorbars.ShowFrameNumber.ConvertToYV24.ConvertBits(10).KillAudio
ORG=Last # Original, with/without audio
F=FlipVertical # Flipped, or maybe from ImageSource
R=F.FrameSel(10,20,30) # 3 flipped frames, 10, 20, 30, into R clip frames 0,1,2
# Equivalent to 3 frames read from file and converted to same colorspace as source.

Framerep(Last,R, 10,20,30) # Replace 3 frames, 10, 20, 30 (From R clip frames 0,1,2)

#Framerep(Last,R,SCmd="10;20;30") # Replace 3 frames 10,20,30, SCMD using command in string. CMD using command File.
AudioDubEx(Last,ORG) # Restore Audio from source, if present
Info

#convertToRGB32 # To view. Not needed for some players eg PotPlayer

return Last

EDIT: Above added AudioDubEx

EDIT: FrameSel/FrameRep, does not support Audio, AudioDubEx with original audio from source clip.

https://i.postimg.cc/sB7VbcCf/Ov-Test-00.jpg (https://postimg.cc/sB7VbcCf)

I have already mentioned this to you before, it is difficult for me to follow up on certain issues. Thanks.

The filename thing is because ImageSource needs the image file, which is the one that will replace the frame or group of frames.

The error message says:

"Overlay: input and overlay clip must have the same bit depths!"

StainlessS
24th May 2021, 16:19
Well as I said, the function is not very well defined/implemented.
Scrap it and re-write taking clip arg instead of filename. Unless you want to implement
additional code which auto converts to same colorspace as source.
It is a lot easier for the user to just do a convert than to auto convert.
I'm not really quite sure what the requirements are, both have to be interleaved, or both planar,
and same bit depth, may be the minimum requirements for Overlay and Layer.

EDIT: Also may need to use eg Conversion Matrix.

EDIT: I think Overlay did originally work with any colorspace [pre AVS+],
but currently needs same bit depth and same interleaved/planar format,
so not going be an easy drop-in fix for your function.

GMJCZP
24th May 2021, 16:24
Ok, how would I implement the change to clip arg, if I am inputting an image file?

I wanted a function that was simple, I did not expect this pain, as you well say

StainlessS
24th May 2021, 16:29
OK, I'll take a look at your function, [I only briefly looked at it for a few seconds], was immediately apparent
that filename was not a good idea.

GMJCZP
24th May 2021, 16:35
OK, I'll take a look at your function, [I only briefly looked at it for a few seconds], was immediately apparent
that filename was not a good idea.

As I have the paradigm of the function having an image file as input, it is hard for me to see an alternative.

My only ambition is that it maintains its spirit and functionality but in any bit depth.

But as we say in my land, you have the solution on the tip of your tongue ;)

StainlessS
24th May 2021, 17:37
GMJCZP,
Rather than fix your function, might I suggest that you take a look at FrameSel/FrameRep,
the intent right from before starting the plugin [even before its predecessor FrameSelect/FrameReplace],
was to be able to extract damaged frames from a video clip, and save to disk, after editing frames,
load back into Avisynth and using the exact same extraction command file (or string), replace the
repaired frames back into the source clip again.
Also, when extracting frames, allows you to extract 1 or more frames either side of the damaged frame,
so you could use undamaged adjacent frames to fix a damaged frame [in paint program].

There is one thing I should have mentioned about this filter, ie

Original intent for this filter, was to extract frames for manual repair in eg paint program, and then replace back into source clip.

EDIT: Last paragraph of this post:
http://forum.doom9.org/showthread.php?p=1520157#post1520157


Also, Got a plugin on the drawing board, (working but
incomplete) that selects single frames from a clip and could eg
be used to 'pull out' frames used in the eg CP plugin above.
This could be used instead of the CP plugin but using the same command
file to view the edited/un-edited frames without lots of scanning.
Also intend to give it the ability to pull out not just single frames but
also optionally to pull out a frame either side of the single
frames, and also the ability to put back a single frame in the
same place that it got them from, all using the same command
file. This would be potentially usefull for creating a RotoScoping
software tool, that could be given both frames either side of a
bad one to aid in hand repair of the frame in a RotorScoping
paint type program. Afterwards, a SelectEvery(3,1) would pick
out the edited frames and then put them back where they
belong. Of course the frames could be saved as Bitmaps for the
editing program if required and reloaded back into Avisynth
converted to the correct colorSpace before replacement.:rolleyes:

And example from FrameSel/Framerep thread:- https://forum.doom9.org/showthread.php?p=1670789#post1670789

# Example scripts to show use with a paint program for manual frame repair.

# Extract Script
C=Colorbars().Trim(0,-50).ShowFrameNumber.ConvertToRGB24 # 50 frames (0 -> 49), RGB24
BADFRAMES = "10;20;30;40" # 4 bad frames in source clip
EDITCLIP=FrameSel(C,scmd=BADFRAMES,ordered=True) # Extract BAD frames
EDITCLIP.ImageWriter(file="Pic%06d.bmp",type="bmp",info=true) # Write bitmaps to edit
return Last
# Need to play all way through for ImageWriter to work properly.


# Here, EDIT bad frames in paint program

Some editing in paint prog



# Replace Script, after editing

C=Colorbars().Trim(0,-50).ShowFrameNumber.ConvertToRGB24 # 50 frames (0 -> 49), RGB24
BADFRAMES = "10;20;30;40" # 4 bad frames in source clip
END = 3 # unique_bad_frames - 1 (number of frames in BADFRAMES-1)
REPAIRED=ImageReader(file="Pic%06d.bmp",end=END)
#REPAIRED=REPAIRED.Invert() # Hilite repaired frames, easier to see
Return FrameRep(C,REPAIRED,scmd=BADFRAMES,show=true) # Fix bad frames with REPAIRED clip using exact same BADFRAMES spec.
# NOTE, you need to tell ImageReader the last frame number to read,
# the default for End is 1000, so imagereader will read in 4 frames (0 to 3) and 997 duplicates,
# FrameRep would throw an error as it does not know what to do with the unwanted 997 duplicate frames that were 'helpfully' appended.
# The 1st script, ImageWriter(Info=True) arg, shows the FrameNumber and name for each frame, and the number shown on the last frame
# can be assigned to END in 2nd script, shows eg "Frame 3 written to: D:\Pic000003.bmp".
# The Last frame number shown by Info=True, will be correct even if BADFRAMES list (in eg string or command file) has duplicates
# as they will be sorted and only unique frames delivered by FrameSel when Ordered=True is used, eg
# BADFRAMES="40;30;20;10;20;30;40", if used in 1st script FrameSel will select exactly the same frames as BADFRAMES="10;20;30;40",
# ie 4 frames and in sequential order (Ordered=True).


# ----------------

# Example scripts to show use with a paint/rotoscope program that can read in bad frames together with previous and next frames,
# and manually fix frames using image data from previous or next frames to repair damage.

# Extract Script
C=Colorbars().Trim(0,-50).ShowFrameNumber.ConvertToRGB24 # 50 frames (0 -> 49), RGB24
BADFRAMES = "10;20;30;40" # 4 bad frames in source clip
EDITCLIP=FrameSel(C,scmd=BADFRAMES,ordered=True,extract=3) # Extract Previous, Target and Next frames for each BAD frame
EDITCLIP.ImageWriter(file="Pic%06d.bmp",type="bmp",info=true) # Write bitmaps to edit
return Last



# Here, EDIT in Triple frame paint/rotoscope editing program

Some editing in paint prog



# Replace Script, after editing triplets

C=Colorbars().Trim(0,-50).ShowFrameNumber.ConvertToRGB24 # 50 frames (0 -> 49), RGB24
END = 11 # unique_bad_frames * Extract - 1
BADFRAMES = "10;20;30;40" # 4 bad frames in source clip
EDITCLIP=ImageReader(file="Pic%06d.bmp",end=END)
REPAIRED=EDITCLIP.SelectEvery(3,1) # Select repaired BAD frames, 2nd of each triplet
#REPAIRED=REPAIRED.Invert() # Hilite repaired frames, easier to see
Return FrameRep(C,REPAIRED,scmd=BADFRAMES,show=true) # Fix bad frames with REPAIRED clip using exact same BADFRAMES spec.

StainlessS
24th May 2021, 20:45
GMJCZP,
Here is a pair of scripts, with mod to self calculate number of frames to read into reader script.
You still need to do manual conversion of input images to same colorspace as src.

Also note, ImageWriter not updated since v2.61, ie 8 bit.

Create folder IMGEDIT\ in current directory.
Then try the script

1_Select.avs

# 1_Select.avs # Script to extract bad frames, and save to images as RGB24

PATH = "IMGEDIT\" # If Folder, then MUST Exist and include End SLASH. CAn Be "" or eg ".\"
BASENAME = "EDIT_PIC_"
EXT = ".BMP"
TYPE = "bmp" # File Type
EXTRACT = 3 # Number of frames to extract for each target frame [usually 1, 3 = prev + Target + Next)
BADFRAMES = "10;20;30;40" # 4 bad frames in source clip
MAT = "Rec601" # Matrix for Conversion

SRC=Colorbars().Trim(0,-50).ShowFrameNumber # 50 frames (0 -> 49)
SRC=SRC.ConvertToYV24(matrix=MAT).ConvertBits(10) # YUV444P10 : Simulated input source clip.

FN = PATH + BASENAME + "%06d"+EXT # FileName
FN = FN.RT_GetFullPathName

### ABOVE SAME AS IN REPLACE Script, 2_REPLACE.avs ######################

EDITCLIP=FrameSel(SRC,scmd=BADFRAMES,ordered=True,extract=EXTRACT) # Select Number of Frames in BADFRAMES * EXTRACT

EDITCLIP=EDITCLIP.ConvertToRGB24(Matrix=MAT) # ImageWriter supports only 8 bit (I think, not updated since v2.61)

EDITCLIP.ImageWriter(file=FN,type=TYPE) # Write bitmaps to edit


Then try this one

2_Replace.avs # Script to replace EDITED/REPAIRED Bad Frames

# 2_Replace.avs # Script to replace Bad Frames

PATH = "IMGEDIT\" # If Folder, then MUST Exist and include End SLASH. CAn Be "" or eg ".\"
BASENAME = "EDIT_PIC_"
EXT = ".BMP"
TYPE = "bmp" # File Type
EXTRACT = 3 # Number of frames to extract for each target frame [usually 1, 3 = prev + Target + Next)
BADFRAMES = "10;20;30;40" # 4 bad frames in source clip
MAT = "Rec601" # Matrix for Conversion

SRC=Colorbars().Trim(0,-50).ShowFrameNumber # 50 frames (0 -> 49)
SRC=SRC.ConvertToYV24(matrix=MAT).ConvertBits(10) # YUV444P10 : Simulated input source clip.

FN = PATH + BASENAME + "%06d"+EXT # FileName
FN = FN.RT_GetFullPathName

### ABOVE SAME AS IN EXTRACT Script, 1_SELECT.avs ######################

HILITE = True # HILITE the Repaired frames, for perusal

FN_TPLT = PATH + BASENAME + "??????"+EXT # FileName with 6 digits
FN_TPLT = FN_TPLT.RT_GetFullPathName

TMPLIST = ("~" + RT_LocalTimeString + ".txt").RT_GetFullPathName # Temp file in current directory

COUNT = RT_WriteFileList(FN_TPLT,TMPLIST) # Write List of images matching template, and get count of Images
RT_FileDelete(TMPLIST) # Done with File List, delete it

END = COUNT - 1 # END = (unique_bad_frames * Extract) - 1

EDITCLIP = ImageReader(file=FN,end=END) # Read in REPAIRED Frames [Start at 0, ending at END]
EDITCLIP = EDITCLIP.ConvertToYV24(matrix=MAT).ConvertBits(10) # Manual convert to same format as SRC clip.

SELIX = EXTRACT / 2 # if Extract==1 then 0, ==3 then 1, ==7 then 3 [ie middle frame of SelectEvery]

REPAIRED = EDITCLIP.SelectEvery(EXTRACT,SELIX) # Select repaired Middle Frame from the edited clip.

REPAIRED = (HILITE) ? REPAIRED.LetterBox(8,8,8,8,$FF00FF) : REPAIRED # Hilite repaired ?

FrameRep(SRC,REPAIRED,scmd=BADFRAMES) # Fix bad frames with REPAIRED clip using exact same BADFRAMES spec.


If you want to only extract a single frame for each BADFRAME, then change EXTRACT to 1, in both scripts.
(I was making it the most complex, to check it works ok)

EDIT:
Files in IMGEDIT\, Previous, Target, and Next frames

edit_pic_000000.bmp # 9
edit_pic_000001.bmp # 10 <<<=== Target
edit_pic_000002.bmp # 11
edit_pic_000003.bmp # 19
edit_pic_000004.bmp # 20 <<<=== Target
edit_pic_000005.bmp # 21
edit_pic_000006.bmp # 29
edit_pic_000007.bmp # 30 <<<=== Target
edit_pic_000008.bmp # 31
edit_pic_000009.bmp # 39
edit_pic_000010.bmp # 40 <<<=== Target
edit_pic_000011.bmp # 41


EDIT:
I presumed that ImageReader had not been updated either, but,
http://avisynth.nl/index.php/ImageSource

ImageSource(string file, int start, int end, float fps, bool use_DevIL, bool info, string pixel_type)

string pixel_type = "RGB24"

Specifies the output pixel format:

If use_DevIL=true, Y8 (8-bit greyscale), RGB24 and RGB32 are supported.

AVS+ also supports their 16-bit counterparts: Y16, RGB48 and RGB64.
The alpha channel is loaded only for RGB32/64 and only if DevIL supports it for the loaded image format.

If use_DevIL=false, must be empty except when decoding a 12 bit, 3 plane EBMP;

in that case, pixel_type must be either YV12 (the default) or YV411.

So may work if your source clip is eg Y16 or RGB48 or RGB64.

MOD (untested)

Function RescueFrame (clip video, string FileName, int FrameNumber, int "NumRep") {
NumRep = Default(NumRep, 0)

source = ImageSource(FileName,use_DevIL=true,Pixel_Type=video.PixelType)
video_backup = video
edit_frame = Trim(video,0,-1).Overlay(source)
clp = edit_frame + video
clp = clp.Freezeframe(FrameNumber+1,FrameNumber+1+NumRep,0).Deleteframe(0)
clp = (HasAudio(video_backup) == false) ? clp : AudioDubEx(clp,video_backup)
return clp
}

GMJCZP
24th May 2021, 21:50
Thank you TinMan, I am living a nightmare when updating my pc with avs + and its plugins, right now I have problems with the 12-bit video that I posted in the neo_f3kdb thread and this script, also with Deblock_QED and with the Clang version of masktools2, it's crazy :(

Edit: I tested your suggestion and same error.

StainlessS
24th May 2021, 22:16
You musta been a villain in a previous life :)

Maybe try replace with FFImageSource, I've never used it. (if there is a format or pixel_type
option, then try with eg format=video.PixelType)

EDIT: All I'm finding is this:- http://avisynth.nl/index.php/FFmpegSource/FFImageSource

GMJCZP
24th May 2021, 23:22
I've been testing FFImageSource (StvG and 2.40) and it doesn't accept "Yuv420p12" as colorspace, the funny thing is that it talks about ffvideosource (??), when I put a colorspace that does support, I get the same Overlay error message.

GMJCZP
24th May 2021, 23:50
I have achieved something:

function RescueFrame (clip video, string FileName, int FrameNumber, int "NumRep")
{
NumRep = Default(NumRep, 0)

source = ImageSource(FileName,use_DevIL=true)
video_backup = video
edit_frame = Trim(video,0,-1).Overlay(source.converttoyv12().convertbits(video.BitsPerComponent()))
clp = edit_frame + video
clp = clp.Freezeframe(FrameNumber+1,FrameNumber+1+NumRep,0).Deleteframe(0)
clp = (HasAudio(video_backup) == false) ? clp : AudioDubEx(clp,video_backup)
return clp
}

Now, with which variable can I know the bit depth to use as an argument in convertbits?

EDIT: EUREKA!, see post #14

StainlessS
25th May 2021, 02:35
Can you post your image file please, for testing.
[I've got your crash helmet 12 bit sample].

I've been playing with it a bit, No idea at all if it will crash, or even pass syntax check,
I've got no test image, and am off to bed in a little while. [Totally Untested]

EDIT: SCRIPT REMOVED

EDIT: Some of above may not be necessary, I've forgot requirements,
but if the video and overlay are not same colorspace, then (I think) can return a different colorspace
compared with the video input colorspace, so best to make same if possible.

EDIT:
Although, Overlay arg
string output = (input)

Set output colorspace. Possible values are "YV24", "YUY2", "YV12", "Y8", "RGB32" and "RGB24".
AVS+ All 8-16 bits colorspaces e.g. "YUV420P14" and "RGB64"

GMJCZP
25th May 2021, 03:38
Image:

Here (http://www.filedropper.com/c03187)

You have to use my script that is already updated, it works perfect for me:

RescueFrame("C03_187.bmp",187)

The number of frame is 187 but you can use the one you prefer, as long as it does not exceed the maximum number, of course.

Edit: The sample has only 125 frames, well, choose a value between that limit.

StainlessS
25th May 2021, 03:46
Thanks,
see updated line in red.

I've just realized that your script replaces multiples sequential frames,
my earlier post was for many individual frames edited.
(I guess I just assumed that I knew what it did :( ) [I''m busy trying to do 27 different things at once]

EDIT:
see updated line in red.


clp = clp.Freezeframe(FrameNumber+1,FrameNumber+1+NumRep-1,0).Deleteframe(0)
Added in BLUE. ^


EDIT: Also, maybe for some things you need Pc Levels thing (matrix) if PC levels YUV video and RGB image.

EDIT: Your default Numrep is 0, that will replace 0+1 frames, is that intended ?
my above fix changes the end frame calculation, so numrep=1 would replace 1 frame.
(or course the +1 and -1 cancel each other out)

GMJCZP
25th May 2021, 04:34
If NumRep is equal to zero it means that the replaced frame is not repeated, only one frame is replaced, if for example you are going to watch a movie and if you liked it a lot you repeat it, then you saw it twice but you only repeated it once.

But you haven't told me if you've already tried my updated script.

StainlessS
25th May 2021, 05:44
Nope, not tried it yet, still on my way to bed.

kedautinh12
25th May 2021, 10:08
your script error StainlessS
Script error: expected `:'
(C:/Program Files (x86)/AviSynth+/plugins64+/RescueFrame.avsi, line 18, column 145)

StainlessS
25th May 2021, 15:04
your script error StainlessS
Yep, I see it, Tanks :)

StvG
25th May 2021, 19:30
I've been testing FFImageSource (StvG and 2.40) and it doesn't accept "Yuv420p12" as colorspace, the funny thing is that it talks about ffvideosource (??), when I put a colorspace that does support, I get the same Overlay error message.

Tested with the file from post #31 and colorspace="yuv420p16" works fine for me.

GMJCZP
25th May 2021, 21:21
Tested with the file from post #31 and colorspace="yuv420p16" works fine for me.


Originally Posted by GMJCZP View Post
I've been testing FFImageSource (StvG and 2.40) and it doesn't accept "Yuv420p12" as colorspace, the funny thing is that it talks about ffvideosource (??), when I put a colorspace that does support, I get the same Overlay error message.

StvG
25th May 2021, 22:10
I saw that but you also wrote you were getting some error if you put "colorspace that does support". I tried another colorspace and there is no error message.

Anyway that colorspace option should be avoided and instead a proper color conversion tool be used ( https://forum.doom9.org/showthread.php?p=1859622#post1859622 ).

GMJCZP
26th May 2021, 00:12
Sure enough, I used FFImageSource and the error message was telling me of FFVideoSource, which doesn't make sense. And the same message I got with both versions of FFMS2.

StainlessS
26th May 2021, 03:14
OK, I fixed a couple of obvious problems, only a bit of testing but seems to work.
Needs a lot more testing.

Debug stuff in-situ

Function RescueFrame(clip video, string FileName, int FrameNumber, int "NumRep") {
myName="RescueFrame: "
# Recent AVS+ and v2.60 only, video YUY2 YV411, NOT SUPPORTED
NumRep = Default(NumRep, 0)
Assert(VersionNumber >= 2.60,"RescueFrame: At least v2.60")
Assert(!(video.IsYUY2 || video.IsYV411) ,"RescueFrame: YUY2 and YV411 not supported")
IsPlus = (FindStr(VersionString,"AviSynth+")!=0)
video_backup = video
video # Last = video, video is a bit long winded, make for shorter script.
RT_DebugF("Input video PixelType='%s'",PixelType,name=myName)
vbpc = (IsPlus) ? BitsPerComponent : 8
vchans = (IsPlus) ? NumComponents : IsY8 ? 1 : IsRGB32 ? 4 : 3
vpixT = PixelType
getpT = (vbpc==8) ? ((vchans==1) ? "Y8" : "RGB24" ) : ((vchans==1) ? "Y16" : "RGB48" ) # if vbpc!=8 then is avs+
RT_DebugF("Calling ImageSource requesting PixelType='%s'",getpT,name=myName)
img = ImageSource(FileName,use_DevIL=true,pixel_type=getpT) # changed source to img, source a bit too long winded, make for shorter script.
RT_DebugF("ImageSource Returned PixelType='%s'",Img.PixelType,name=myName)
img = (img.IsRGB32) ? img.ConvertToRGB24 : (IsPlus && img.IsRGB64) ? img.ConvertToRGB48 : img # ensure not RGB32 nor RGB64
# img can be RGB24, Y8, AVS+ Also Y16, RGB48
img = (vbpc==8)
\ ? (IsY8?img.ConvertToY8:IsYV12?img.ConvertToYV12 :IsYV16?img.ConvertToYV16 :IsYV24?img.ConvertToYV24
\ : IsPlanar?img.ConvertToPlanarRGB:img.ConvertToRGB24)
\ : (IsY ?img.ConvertToY :Is420 ?img.ConvertToYUV420:Is422 ?img.ConvertToYUV422:Is444 ?img.ConvertToYUV444
\ : IsPlanar?img.ConvertToPlanarRGB:img.ConvertToRGB48)
RT_DebugF("CS Convert Image to %s",Img.PixelType,name=myName)
ibpc = (IsPlus) ? img.BitsPerComponent : 8
img = (ibpc!=vbpc) ? img.convertbits(vbpc) : img
RT_DebugF("Bit depth convert Image to %s",Img.PixelType,name=myName)
try {
edit_frame = Trim(video,0,-1).Overlay(img)
RT_DebugF("OVERLAY:- VID='%s' : IMG='%s' : RESULT='%s'",vpixT,img.PixelType,edit_frame.PixelType,name=myName)
} catch (msg) {
BugS=RT_String("*** ERROR OVERLAY VID='%s' : IMG='%s'\n%s",vpixT,img.PixelType,msg)
RT_DebugF("%s",BugS,name=myName)
Assert(False,myName+BugS)
}
clp = edit_frame + video
clp = clp.Freezeframe(FrameNumber+1,FrameNumber+1+NumRep,0).Deleteframe(0)
AudioDubEx(clp,video_backup)
return last
}

FN_V = ".\Sample.mp4".RT_GetFullPathName
FN_I = ".\C03_187.bmp".RT_GetFullPathName

LWLibavVideoSource(FN_V)
RescueFrame(FN_I, 87, 10-1) # 10 frames, 87 -> 96
Info
#ConvertToRGB32 # For view if your player has problems
Return Last

EDIT: Added a bit more Debug Info

Debug Output

00000193 03:34:43 [4320] RescueFrame: Input video PixelType='YUV420P12'
00000194 03:34:43 [4320] RescueFrame: Calling ImageSource requesting PixelType='RGB48'
00000195 03:34:43 [4320] RescueFrame: ImageSource Returned PixelType='RGB48'
00000196 03:34:43 [4320] RescueFrame: CS Convert Image to YUV420P16
00000197 03:34:43 [4320] RescueFrame: Bit depth convert Image to YUV420P12
00000198 03:34:43 [4320] RescueFrame: OVERLAY:- VID='YUV420P12' : IMG='YUV420P12' : RESULT='YUV420P12'


EDIT: Image file was actually 8 bit RGB24, we requested and got RGB48
Then converted to YUV420P16 and bit convert downwards to 12 bit YUV420P12, matching
the src video for overlay. Probably need to have Matrix stuff in there too.

kedautinh12
26th May 2021, 04:23
Thanks

GMJCZP
26th May 2021, 18:04
RescueFrame version 2.1: (https://forum.doom9.org/showthread.php?p=1699095#post1699095)

- Better handling of Overlay.

GMJCZP
7th June 2021, 05:09
RescueFrame 3.0: (https://forum.doom9.org/showthread.php?p=1699095#post1699095)

- Optimization of the entire script, elimination of Overlay, fix in audio handling.

kedautinh12
7th June 2021, 07:03
Thanks