Log in

View Full Version : direct stream copy (again)


Pages : [1] 2

esby
23rd February 2004, 23:55
http://esby.free.fr/prog/dsynth
Modified version of avs 2.55 supporting directStreaming.
check the readme for explanations, or read this thread.


Old post:
I've done some tests for implementating direct stream copy
(mainly with video stream)under avs.

first try:
removing all filters except avisource, trim and a few ones
from avs 0.3 ...
by using a different guid and a different extension (avd)
we can allow some direct stream copy using avisynth syntax.
but it is limited to video only, and it only works in direct stream.
(that's why it is called Dsynth)

http://esby.free.fr/prog/dsynth
Edit- the url might not work
backup url: http://www.chez.com/esbyphp/DSynth
-copy it in a blank explorer...-
/Edit-

Second try:
I tried with avs 2.54:
Three main problems:
* FindSample needs to emulated in order to tell the application
where are KF and DF in a stream...
* the size of the frame is variable and needs to be feeded
for the various CAVIStreamSynth functions.
* we need to pass back the compressed frames to the application
( --> CAVIStreamSynth::read(..) )from avi_source.cpp level.

It is possible to solve the two first problems by using env->SetVar() and env->GetVar() and calling 'dummy' filterGraph.getFrame(pos,parent->env)
and getting the needed data in the returned env...
We must disable the cache strategy in order to get this method working,
since when the frames are cached, the filterchain does not end to avi_source level...

For the third point,
since the frame is compressed, it's just a plain array of byte of variable size...
meaning the framebuffer cannot be used in the current state...

I thought of passing the frame via an avsValue (like framesize & FindSample info), but i was not able to cast it correctly...
Maybe i'm missing something here...

The only work around solution is modifying VideoFrame
adding an pointer to a dynamic array of byte in it...
which would broke the plugin load if i'm not wrong.
but we could use a wrapper to solved the problem.
Another idea is to create a CompressedVideoFrame class
which would inherit from VideoFrame,
and would be defined in another place than avisynth.h,
thus avoiding plugin havoc if it is done properly (am i right?)

If anyone has ideas or suggestions...

PS:(edit)
Supposed i can derivate VideoFrame and keeping the plugin working,
i'll be able to store the framesize, the compressed frame and the FindSample infos alltogether...

timecop
1st March 2004, 04:20
hi esby, what's your purpose with this?
(See my DirectStreamSource() post in this forum).
Is this something like that you are trying to achieve?

sh0dan
1st March 2004, 09:11
@timecop: Your suggestion for "DirectStreamSource()" isn't possible. What esby is doing (starting from scratch) is more a realistic project.

timecop
1st March 2004, 09:22
thats what I noticed.
which is good.
obviously that means people want this functionality.
I wonder why he's going for video, isntead of audio though.
Oh well, I wait until he wakes up and answers.

esby
1st March 2004, 23:23
Well i'm going for video,
since that is my actual need.
(a tool to fast splice avifiles...)

I don't think audio would be more complicated,
and it could be easier if i'm not wrong,
since most audio 'formats' (should i say codec?) have a fixed samplesize...
and no delta/keyframe strategy too afik.
--> for example, altering a bit the actual structure could make it work for audio encoded in cbr at 128kbit ...

I don't know if i'll be able to derivate the VideoFrame structure in order to get the wanted compatibility and result...
I think i'll go for 'recoding' dsynth using the 2.0X code as a base...

esby

On another note,
@shodan,
what can be changed in the 2.5 avisynth .h without destabilizing the code (mostly plugin loading i suppose)?
(eg no new enum? no new function? changing implementation of methods allowed? etc.)
I'm a bit 'new' to c++ (at least for doing this kind of things with it) and i'm finding no docs about the limit i can reach and not exceed while playing with .h and structure compatibility...

sh0dan
2nd March 2004, 00:11
You can add functions or change to structs and classes. There have been several updates and additions to avisynth.h since the first release. The functions of the .h file are compiled into plugins. You can also add enums.

You cannot change the data(sizes) of the structs or classes.

esby
3rd March 2004, 02:32
You cannot change the data(sizes) of the structs or classes.


Does it go against this comment i saw in avisynth.h ?

int num_frames;
// This is more extensible than previous versions. More properties can be added seeminglesly.

or wait, properties refers to methods here and not data right?

esby

Richard Berg
3rd March 2004, 04:49
You can add to the enums since they're basically just scoped typedefs, but not anything that would change sizeof(VideoInfo) or the other classes.

esby
4th March 2004, 04:05
[edit warning]
some of the considerations here might be out of date...
And the changes involved not necessary.
I edited (and deleted the) the monolog i did in 3 or 4 posts...
speaking alone... (mostly for myself,
In fact, formulating the problem allows to help solving it...

Edit:monoLog Part 1 of 4:

@shodan
There seems to be an exception to what you previously said...
(not that i'm blaming you,
but i encounter crash when modifying that... :angry: )


class IScriptEnvironment {
(...)
virtual PVideoFrame __stdcall NewVideoFrame(const VideoInfo& vi, int align=FRAME_ALIGN) = 0;



if i add a dummy
virtual PVideoFrame __stdcall NewCompressedVideoFrame(const VideoInfo& vi, int align, int size) = 0; //* added
just after the NewVideoFrame declaration, the plugins won't load...

but if i add it at the end of the virtual class, they will load...

Any idea to explain this behaviour?
Thanks in advance.

esby

Edit:monoLog Part 2 of 4:


Actually i have a modified version of avs 2.54 that works
with directStreamCopy for video...
And that is able to work in 'normal mode' without spotted problem too... ( with some plugins loaded, and used)

The only problem left (apparently) is that i am not able to find a way to detect if a filterchain can support DirectStreamCopy or not...

i ve thought about adding methods to IClip & descendants
bool _stdcall CanDirectStream() { return false };
bool _stdcall CanDirectStreamChain() {(return CanDirectStream() & child->CanDirectStream() )};

Something like that more or less,
but apparently the way i'm doing it is wrong,
CanDirectStream() is never called in avi_source where i redefined it right (or at least i'm thinking it...)


any idea?
Or any other way to do the job,
the goal being to detect if the filterchain can support DSc
allowing to set on/off a boolean stored in the colorspace property...

esby

Edit:monoLog Part 3 of 4:

@Shodan,

Would it be possible technically
to have all audio filters inherit from an GenericAudioFilter?
-which could be inheriting directly from GenericVideoFilter...

Because i'm searching a way to get a same behaviour for the audio filters
without adding manually the needed function in each -.-

And it sounds more logical for me to have an 'AudioFilterType'

The goal being to implement that in GenericVideoFilter

bool __stdcall GetDirectStreamVideo() { return false;}
bool __stdcall GetDirectStreamVideoChain() {
// yeah that s ugly ... but it should be taking care of any filter loaded by loadpluginEx ...
int b = 2;
b = child->GetDirectStreamVideoChain();
if (b==2) b=0; // those filters are not altering the initial value and probably not supporting DSc
return GetDirectStreamVideo() && b;
}
bool __stdcall GetDirectStreamAudio() { return false;}
bool __stdcall GetDirectStreamAudioChain() {
// yeah that s ugly ... but it should be taking care of any filter loaded by loadpluginEx ...
int b = 2;
b = child->GetDirectStreamAudioChain();
if (b==2) b=0; // those filters are not altering the initial value and probably not supporting DSc
return GetDirectStreamAudio() && b;
}


and redefining for the video filters that allow DSC like that

bool __stdcall GetDirectStreamVideo() { return true;}

etc.

Having the audio filter derivating from a common class
could allow to redefine GetDirectStreamAudio() reply to false for those only,
and to specifically enable the ones working, including possible external filter...

esby

Edit:monoLog Part 4 of 4:

Ouups sound like i deleted the post before making a copy... :rolleyes:
Or maybe it never existed, i need sleep...
Anyway, if someone can provide a copy of the missing message i'll put it here,
but i don't think there is much importance...

esby

esby
22nd March 2004, 03:38
Ok,
some news:

http://esby.free.fr/prog/dsynth/

I have somewhat succeeded in modifying avisynth 2.55,
in order to allow directStreaming if the filterchain makes it possible.

The filterchain is analysed.... If it supports directStreaming,
it enables it... For audio and/or video...
Eg:
avisource()
-> DirectStreaming in Audio & video
avisource().trim(0,100)
-> DirectStreaming in Audio & video
avisource().trim(0,100).crop(0,0,-2,0)
-> DirectStreaming in Audio
avisource().ForceVideoDecoding().forceAudioDecoding()
--> no direct streaming used, the old methods of avs 2.55 are used...

Limitations:
First, you must trim on a keyframe if you don't want to get Garbage
in output...
For that you can use avisplicer (when it does not fails loading the avi, (i need to fix a bug in it))

External filters disable DirectStreaming... (video and audio)
because i could not find a way to avoid a pure virtual function error
at runtime...


Filters supporting direct video Streaming are:
Avisource()
Trim()
spice() aka + and ++)

Filters supporting direct Audio Streaming are:

All*, BUT for audio filters, please use ForceAudioDecoding().
(not needed for external filters since it is forced anyway)

ForceVideoDecoding() exists for the rare cases
when you want to disable Video directStreaming...
Such as filter not supporting it and bugging... (could happend)
Uncompressed video format being the source,
thus probably no gain in using Video directStreaming...


Modifications planned:

* Modify audioDub() (for supporting DS)
* Find a way to enable the external filters...
(Maybe with some loadPluginEx magic...)
* Add a DropFrame filter, acting like a freezeFrame in normal mode.
syntax: dropframe(clip,framePos) (setting size of the frame to 0, making it dropped)
* Fix audio filters... (disabling direct streaming)

esby

Mug Funky
22nd March 2004, 07:13
you rock

this will make DV editing SOOO much cooler. now i barely even need premiere.

[edit]

would it be possible to add the option that if a trim isn't made on an i-frame, it could decompress the requested frame, recompress as an i-frame, and then continue? it wouldn't be lossless, but it'd be so close as to make no odds. of course, it might not be fun implementing...

[edit edit]

another useful feature would be something like "assumeFourCC("string")"... this would be good when one has several DV codecs on their system and has different uses for each of them (like slow but no coring, rather than fast + chroma bug + good for preview)

this obviously wont affect the output as no recompression is taking place, but would be useful for other things.

stickboy
22nd March 2004, 08:28
Originally posted by Mug Funky
another useful feature would be something like "assumeFourCC("string")"... this would be good when one has several DV codecs on their system and has different uses for each of themI've been thinking about something similar for a little while. What I had in mind was that AVISource/DirectShowSource/et al. could take an optional parameter to override the file's fourCC setting; e.g. AVISource("foo.avi" fourCC="cdvc") (or maybe "forceFourCC"--har har).

(But I'm straying off-topic, since none of that would be specific to esby's work.)

esby
22nd March 2004, 09:03
mmm, from what I've read...

would it be possible to add the option that if a trim isn't made on an i-frame, it could decompress the requested frame, recompress as an i-frame, and then continue? it wouldn't be lossless, but it'd be so close as to make no odds. of course, it might not be fun implementing...

That would mean 'introducing' the concept of encoder as a filter type...
which is not for today...
And if you plan on reencoding any type of stream in the corresponding codec,
that's just 'hard'...
(hints: there are several way to encode within a codec, hints hints...)

All I can think actually would be to clone the trim function to another one,
adding a parameter for indicating to avs which encoder and 'profile' should be used...
But if you consider tcpframeserver and the multiple output plugin possibilities,
you could serve localy an compressed clip to an application
while having tcpipfilter forks the directstream or the decompressed stream
to another avs instance, itself serving it to a transcoder and thus
allowing to encode a splice of it directly...
While you are still serving your main video to the main encoding application:

for example:
src = src.trim(45,70)
supposing there is an I-frame(KF) on frame 50.
trim should serve like this:
45: dropped KF (size=0)
46-49:dropped nonKF (size=0)
50-70:serving the compressed frame corresponding.
'tcpipfilter/fork' should serve:
0-5: decompressed frames corresponding to frames: 45-49

Of course it is just an idea, but it would allow easier editing...


another useful feature would be something like "assumeFourCC
("string")"...

I've thinked about it already,
this is possible without problem,
and actually, there is a need to code the other f4cc used in avi...
(dunno "which one is which one", one is preferred decoder, while the other is codec used)
And allowing to change them is not be a problem (both would be stored in env)...


On another note, I've though about the advantages of direct Streaming:
* Of course, trimming raw material while keeping the audio synchronized is good...
* More interessant, and more important for me, splicing the video easily is better...
But there are two (at least) 'hidden' advantages:
*First, as I said, serving (compressed) frames via tcpfilter... (in a near future?)
will have tcpipfilter act as a local aviSynth 'fork'...
The fact we could serve compressed or uncompressed frames or data in interesting too...

*Secondly, I said data, why?
some filters output data,
why not serving those data via a dummy compressed avifile datastream...
Meaning we do not serve the initial stream, but a new stream using a dummy f4cc,
and we can save it via virtualdub using directStreamCopy
Each frame would store the data of the filter,
maybe textbased data, maybe not, in each corresponding compressed frame.
And any application could get these via a simple avifile interface,
supposing its author codes the corresponding 'directstream decryptor'...
Or just implements its from an avisynth model plugin.
An usage could be met in filters like SSIM,vgmCalc
and maybe a crc frame calculator filter, able to work in directStreaming AND in normal mode...
This last filter could detect what was changed between two encodes of a same source,
and thus, allowing to only reencode the needed parts,
supposed we applied a filter on a particular range,
or we just change a sub (typo correction) in the ssa used for encoding...

And on a last note, quality related filters could help to do perform multiple pass encoding
or deep analysis of video material...


esby


PS:@stickboy:
forceFourcCC here is a double 'har har', because actually,
the decoder is initiallized in the constructor,
which is not really accessible by forcef4cc function which would modify env.
(problem with order of creation/analysis)

But adding an option to avisource might work fine :)
For directStreamSource I don't know.
Considering we need 190mb of 'useless crap' to compile it,
i'm not going to modify it personnaly.
(Edit: useless crap in the meaning we don't need it here,
not to insult the developper involved with this)

PS2: I've been wondering about 'my pure virtual function problem',
and having been tricking GetVersion() is making me wondering the following:

Virtual class are ought to be redefined...

But I see no redefinitions of GetVersion() in any classes...
which are concretes...
So all I can suppose, is that the function is redefined by default,
with the default implementation used in the base class,
as soon as the child_class is no longer abstract.
(no pure virtual function left)

When I change the GetVersion() answer of the base IClip (eg: adding 1):
All calls will resolve and gives 3 (instead of 2)...
And they will load, since the version check
is only for external filters apparently... :)
But When I load an external filter, the version reply is always 2,
no matter what I modified in GetVersion()

From that, I can conclude, that the external filters are still
based on the 'old' avisynth.h structure used at their creation...

Now coming to my pure virtual function problem:

It happends in getDirectStreamVideoChain() (or *AudioChain)
If I understand well, this function try to call child->getDirectStreamVideoChain()
which fails with an external filter... (pure virtual function call)
As I said before, the external filter probably does not have this function declared,
and thus the call fails.

Now I am wondering, Is my reasoning correct?
Is there any way to call the new methods on those 'old' objects?

Maybe by declaring a static method at IClip level,
which would do the job on a GenericVIdeoFIlter passed as parameter?

PS3: I ve found some minors inconsistancy in code about child usage,
especially in the ones derivating directly from pclip.
Some of them could derivates from GenericVideoFilter,
and have the first child normalized.
(as child, not childa, child1, Vchild etc.)

Edit: i edited the syntax and corrected most of my typos :)

Si
22nd March 2004, 18:32
@esby
I know this will sound silly to you but what do you mean by "directstreaming" :confused: :o

Is it equivalent to directstream mode copy in VirtualDub?

Or is it something else.

regards
Simon

esby
22nd March 2004, 23:29
It is the same as virtualDub.
Frames are not decompressed in avisynth
and directly served to the application.

Meaning you can save the clip in direct stream copy using virtualdub

Of course, the drawback is that you cannot 'filter' the video in directstreaming.

But you can still edit it, if you stay compliant to the avi structure.
(eg: you can trim, supposing you start on an IFrame(KF)...)

Now to the handling in avs.

If a filterchain support directStreaming, it is enabled.
if not, it is disabled.

There is still one 'restriction' left to it, you can't use external filters when directStreaming.
But i hope to fix the problem...

esby


Edit:

Let's forgot the concept of fork with tcpserver...
since tcpserver is acting on itself,
and not linked to the vdub client that could ask for frames to encode.
There will be no benefit at all, since the frames would be rerequested in the filter chain...
And there might be problem of synchronization if we fork with differents tcpclients on the other side...

Mug Funky
25th March 2004, 10:32
one thing that would be totally killer would be to allow this to work with sh0dan's (very experimental) TCPserver plugin.

if you could serve compressed frames (and perhaps some kind of seek-last-I-frame behaviour would be useful) there'd be a massive saving of bandwidth... i just tested TCPserver on my cable modem... needless to say it was a little slow :), but needn't be as i was serving 384x288 Xvid.

the simplest way to do this might be a matter of detecting TCPserver in a script and treating it as a special case, but obviously i have no real idea what this involves...

esby
26th March 2004, 00:06
I uploaded a new version,

I did some cleaning in the source,
chaning function members name (the one used for dstreaming)
making them a bit more logical (at least i hope that)
Audiodub now support directStreaming.

Check toDo.txt for more informations...

esby

PS: [edit] with audiodub,
it is possible to do external video filtering while keeping audio compressed now.

eg:
avisource()
filters() # supposed we defined a function filters() that does some video processing, including external ones

to keep audio compressed:
video = avisource()
audio = video
video = video.filters()
return audiodub(last,audio) # will output uncompressed video frames & compressed audio frames

Of course this is a workaround, and if you want to do trimming,
you'll be forced to trim either before or after video & audio are separated, or you'll be forced to apply it to both.

Mug Funky
26th March 2004, 16:18
excellent :)

esby
29th March 2004, 01:01
Uploaded new version (v3)

mostly:

I found a way to allow directstreaming audio with external filters,
the trick being to skip one or more filters in a filterchain,
supposing we detect it/them is external (GetVersion==1 or GetVersion==2), while internal use GetVersion==3 (or external supporting dstream)
There is a 'disturbing' trick to detect the external filters
not based on GenericVideoFilter...
When casting those (derived from IClip) on a GenericVideoFilter type
the videoinfo properties seem shifted (and totally uncorrect).
My ugly trick is detecting the shift of value,
and thus preventing a runtime error casting a non existent child...
If anyone has a better solution (which should not use RTTI like actually), i'll be glad to hear it.

I found a minor 'bug' or maybe harrassment...
+ and ++ are linked directly to the splice function,
and shortcuts the the evaluation...
...Since i put all exotic directstream filters in separate c++/h
+ and ++ will call the old version of splice,
thus disabling directstreaming...
So if you need to use dstreaming, just use alignedsplice() or unalignedsplice()


esby


PS: I think i'll stop working on that for a while,
maybe checking one or two possible bugs
(mainly checking that the modified filters use FindCompatibleChild()
to avoid pure virtual function call),
but my time is gonna schedule between some others c++ delphi programation...

Mug Funky
29th March 2004, 08:19
minor "harassment" to use your term :)

looks like the files carrying the source or the dll are swapped on the download page...

esby
29th March 2004, 11:33
indeed,
i'll fix it when i'll be at home
[edit]
fixed i recompiled it here and reuploaded the rared file
[since i accidentaly deleted it while swapping files on the ftp]

esby

esby
7th May 2004, 16:31
updated dsynth a bit:

mostly some minor fixes,
including blackness() correct declaration for non support of direct streaming.

there is a new calcCRC() internal filter
This is experimental, and since it can work in direct stream copy,
i added it to the dsynth internal filters directly
syntax is: calcCRC( clip, string filename,boolean debug)

filename being where the crc are written
(one crc calculated per frame parsed)
debug outputting the calculated crc to the log

There is a problem with this filter call apparently
when an avisynth dll is dynamicly loaded with an application.
(eg you invoke virtualdub on a script, and have avisynth.dll in the vdub directory. I'll try to understand why, but if anyone can explain what's happening i'm interested...)

esby

Bidoche
7th May 2004, 17:00
There is a problem with this filter call apparently
when an avisynth dll is dynamicly loaded with an application.
(eg you invoke virtualdub on a script, and have avisynth.dll in the vdub directory. I'll try to understand why, but if anyone can explain what's happening i'm interested...)Please be more specific with your problem.
How could we explain anything when you don't even tell us what happens.

esby
7th May 2004, 22:04
bidoche:

avisource("myavi.avi")
calcCRC("mystatfile.crc",false)

on some computers, including mine it works fine.
on some others, it gives
"Avisynth open failure:
script error: Invalid arguments to function CalcCRC
<insert location of the script - line>

Now if you put the avisynth.dll in the vdub directory
and try opening with vdub it will generate the error,
no matter if you had it working before.

esby

esby
7th May 2004, 22:29
sounds like i fixed the problem.

the static method (constructor?) used to create the filter instance was not properly defined.
I fixed it and it seems working now.

esby

Mug Funky
8th May 2004, 11:59
hmm... while bidoche is here, i wonder if it would be possible to include direct streaming into avisynth 3.0 (i realise it's not at that stage in development yet). there's been mutterings about some kind of NLE in linux, and it looks like avisynth 3 will be ported to linux. direct streaming is a must for any serious NLE program, and for avisynth, well let's say i'd abandon premiere almost completely if avisynth did direct streaming (premiere's direct streaming is so temparamental as to be almost completely useless, ditto final cut pro).

well, anyhoo, cudos to esby for this mod of avisynth - it's proven useful to me even in this early stage, and i watch it's development closely.

Bidoche
8th May 2004, 13:27
Hum... maybe possible.

But I don't think it belongs into the avisynth.dll, but rather into a plugin.

Let me explain how :

The plugin provides a Source function
This function doesn't create standard VideoFrames but custom ones, this is possible because VideoFrame is just an polymorphic interface in 3.0.
These CustomVideoFrame, are index into the source file on disk.

To maintain all standard functions happy, they can decode on request to a normal VideoFrame when needed.
But a filter with awareness of them could do more.

esby
8th May 2004, 15:57
well as long it is taken in account at the creation,
and allowed by a plugin it's fine with me.

Actually in 2.5, what stopped me from using the actual structure
is the fixed framesize of the PVideoFrame buffer, and of the video info associated.
Since you expect a different size for each frame, and since vi
is static, and can only give one, you'll need a trick to store
the size and use only a part of a maximal given size per frame buffer.
Which is possible of course, but can makes problems if a normal filter try to treat compressed data, as if they were not,
what is not possible in dsynth actually.

Of course it belongs to the plugins area, but only if if the plugins can support differents types of frame by default. And don't forget that you'll still need to pass the frame structure information to the encoding application, meaning taking it in account from a 2.5 to 3.0 perspective. (I'm mostly referering to the transmission of findSample() information here.)

And if i had a better way to detect external filter that don' have a child (directly derived from PClip), i would be happy actually.
Because i only check there is an house on a fixed position on the moutain, and not if the mountain is really present... (Of couse if the house is here, the mountain must be present too, but who knows...)


esby

PS: on another note, the fact that an application will link to an avisynth dll directly over the one present in %system directory, if it is found in the same directory gives interesting perspectives:
you can use avs 2.53 or any version you need normally, and if you need to do direct streaming with a given application, you can put the avisynth.dll in the directory application, and dsynth will be loaded then.

Bidoche
8th May 2004, 16:57
Which is possible of course, but can makes problems if a normal filter try to treat compressed data, as if they were notThat's where the VideoFrame frontend fallbacks to decoding and forward to a inner normal VideoFrame

Of course it belongs to the plugins area, but only if if the plugins can support differents types of frame by default. And don't forget that you'll still need to pass the frame structure information to the encoding application, meaning taking it in account from a 2.5 to 3.0 perspective. (I'm mostly referering to the transmission of findSample() information here.)I don't follow you there...

And if i had a better way to detect external filter that don' have a child (directly derived from PClip), i would be happy actually.I provide clip::NoChild, clip::OneChild, clip::TwoChilds as Clip subinterfaces that filters MUST subclass according to their child arity.
I intended them (among others things) as helpers for filter graph explorers, but if it can help you too.

esby
8th May 2004, 17:11
I don't follow you there...

Having a compressed frame or not is not the whole part of the problem:

you need to parse structure information to the application, since it is asking what type of frames it is requesting.

Basically in all normal avs version, the frametype is Keyframe (or Intra).

the consequence is that you need to :

- declare that the stream can contain other frames than KF.
- implementate FindSample() in order to transmit what exactly the application is getting. (a non keyframe or a keyframe basically)

for that last matter, using getFrame() is not the solution,
since cache strategy will biase it, unless you want to force the disabling of cache.

Another approach would be to consider compressed state as a colorspace,
after all it is just something that needs to be decoded if needed.
Or the filtre is able to operate in the given colorspace, or it musts throws an error (or automatically decompresses...?).

esby

Bidoche
9th May 2004, 11:28
You mean the IAVIStream::FindSample method...
I did not get that you were doing something on that side too.

That means that a plugin is not enough to reproduce your behavior in 3.0, you need to rewrap the IAVIFile exported by avs into your own on the other side.

esby
20th August 2004, 22:52
Updated dsynth with the last cvs source.
(it should be avs 2.55 alpha rc2)

for changes, check here.... http://esby.free.fr/prog/dsynth/todo%20Dsynth.txt

uploading version 7b - fixed a small bug with + and ++ decoding the video in all cases...
esby

Mug Funky
21st August 2004, 18:32
hmm... seems to only crash VDM for me. MSVCRTD.dll apparently (couldn't read it properly - the end of the filename was cut off after the dot...)

do i need to update my runtimes?

esby
21st August 2004, 19:01
mmmm xp sp2 or not ?


esby

Mug Funky
23rd August 2004, 07:37
nah, i'm kickin' it oldskoo and keepin' it real with win2k (umm.. sp2 i think)

more possibly relevant details are:

pentium 3, 733 (hopelessly outdated, i know, but a tweaked system means it runs as fast as most of my friend's 1.5ghz machines)

384 SDRAM, NTFS filesystem (i'm clutching at straws here :)), geforce2 MX400

Kurosu
23rd August 2004, 09:37
Originally posted by Bidoche
Hum... maybe possible.
But I don't think it belongs into the avisynth.dll, but rather into a plugin.
I have mixed feelings about this. If an application wants to process video through avisynth and keep audio unprocessed (tough luck if any trim-like operation occurs) or vice versa, shouldn't that be made possible without requiring external stuff ? As far as I see this is the main use for directstream copy.

The plugin provides a Source function
This function doesn't create standard VideoFrames but custom ones, this is possible because VideoFrame is just an polymorphic interface in 3.0.
These CustomVideoFrame, are index into the source file on disk.

Or could be indexes, as you may need quite a lot more info than the raw bitstream: previous frame data, keyframe information, presentation /decoding time, ... Therefore, having a custom object to hold more than the chunk/packet data is the way to go. I thought a new ColorSpace would be sufficient, but it appears it isn't.


To maintain all standard functions happy, they can decode on request to a normal VideoFrame when needed.
But a filter with awareness of them could do more.
Even with the kind of data I've described, it's going to be very complex, and bother very container- and codec/format-dependant.

I'm not sure how much you can do with directstream copy, except splices and trims with a lot of requirements at the bitstream level. So there may be no reason to allow more, and simply make the packet/frame undecodable. The way I see it, you should never try to splice a directlystreamed stream with a decoded stream. Even when encoding the decoded part with the same codec, you can't be sure the headers will be identical: you'll have to split and encode separately then splice them at a muxer/container level. Again, it all depends on what level of reliability you aim at. I hope users will keep that in mind before reporting problems that can't be solved.

esby
23rd August 2004, 09:44
I'm not sure how much you can do with directstream copy,

look on directstream.h,
you'll get a list of the function I ported to dsynth,
that might be a good list of the usage.

I must add assumeFPS() to this list too, since it is only modifying framerate.

esby

rling
17th September 2004, 10:48
I'm very interested in the progress of Dsynth, because it would be useful for lossless editing of the MJPEG AVIs created by digital cameras.

Although, I tried using the current version (v7c) to edit a MJPEG AVI and got problems, probably just cause I dont really know what I'm doing. The fourCC code is MJPG, and I can drop one of these into VirtualDub and choose "File Information" and it says the decompressor is "VirtualDub internal MJPEG". I added the avisynth.dll from Dsynth v7c to the VirtualDub directory, and wrote a script with one line:

AviSource("MVI_0412.AVI")

When I try to open this script, I get:

Avisynth open failure:
AVISource: couldn't locate a decompressor for fourcc mjpg

Why is AVISource trying to locate a decompressor, shouldn't it be passing the compressed data to VirtualDub without caring what it is? I would have expected VirtualDub to get the compressed data as if it had opened the AVI directly, and to use "VirtualDub internal MJPEG" to display it.

Incidentally I tried installing the PicVideo2 MJPEG codec, and this caused VirtualDub to open the script OK. I guess Avisynth was decompressing it. But when I saved it using "direct stream copy" the result was blank.

Thanks for any help! And well done esby, I'm sure this is a great piece of software (or at least, destined for greatness ;-)) that I just don't know how to use properly.

R

esby
17th September 2004, 13:05
This error is here, because I made the choice that you have a vfw decoder for the content you are trying to direct stream, mainly to keep the original avisynth comportment.

Avisynth try to decode a stream by checking the first frame decoding, no matter what, I did not change this aspect with dsynth, so you still need to be able to decode the first frame to direct stream it.

Usually, if you want to take out this restriction, use ffvfw to decode the stream via the vfw interface, dsynth will try to decode the first frame, and if he succeed, you'll be able to direct stream.

Now, for your blank saved video, I have no idea of what happened exactly, if you can send me a few frames of your sample source, maybe I'll be able to do something.


esby

esby
18th September 2004, 02:01
New version up - based on 2.55 release. named v8 for my conveniance
(I know, that is not a brilliant tracking scheme, but at least it works for me ^^)

http://esby.free.fr/prog/dsynth/

Fixed a bug with colorBars, since this one produces sound (I discovered that),
and thus does not support audio direct streaming.

Discovered a bug with huffyuv crashing with avisource("huff.avi")
workaround is to force the video decoding (forceVideoDecoding().)
And I strongly suggests to do that for now,
since you won't get much speed from directstreaming huffy files...


esby

PS: @R: try changing the fourCC of the avi file you saved.
Actually dsynth transmit an "yv12/MJPG" f4cc,
which you may try to change by "mjpg/MJPG".
This can be applied to all video direct streamed.

rling
20th September 2004, 03:49
Thanks esby.

I have found out more about what happened. The PicVideo MJPEG codec allowed Dsynth to open the MJPEG file, but the frames were actually served compressed. I found this out because the PicVideo codec puts a watermark on frames it decompresses, and the watermark did not appear in VirtualDub. So, the output clip was created using direct stream copy.

So why was it blank? This took a little bit of time. VirtualDub could still play the clip, but Windows Media Player and ZoomPlayer couldn't. Changing the codec from YUY2 to mjpg did not work. But, there were many differences in the file headers of the source clips and the output clip, and I spent some time comparing them with the VirtualDub binary editor. Finally... in the video stream header there is a BITMAPINFOHEADER with a BitsPerPixel member. In the output clip this was 16! Changing it to 24 fixed the problem and all players can now play it.

Hope this helps you. I'm looking forward to trying the new Dsynth.

R

esby
22nd September 2004, 01:09
@R: I think I need to thank you for that bug report.

Indeed the number of bits per pixels are uncorrect.
This is coming from the fact I am using (or should I say was, but the bug is not yet fixed right now) vi->BitsPerPixel() , using normal avisynth info & method for being initiated...
While it should not be a problem when decoding, it is one here, since the value avisynth is giving to this parameter is set according to the colorspace it can decode to (probably yuy2, 16 bits), while the real value is of course 24 bits.

This problem is probably causing the crash i encoutered while doing huffuyv tests.


I think I'll [edit] hope to be able to fix the bug during the week...

esby

esby
10th October 2004, 17:27
v9 available.
Still based on 2.55 release.

Changes:

* Fixed the 'huff loading bug'.
(other codec related problems should be fixed too including R one...)

* changed ForceF4ccDecoder() to ForceFccDecoder()...
Added ForceFccHandler() to modify the fccHandler...
Now dsynth should transmit this one correctly instead of DIB / NULL.

* Fixed a bug related with seeking while using multikillframes()

esby

jkwarras
28th October 2004, 11:33
Hi,

I've read this thread with a lot of interest, but I don't really understand what's the purpose and how to use dsynth. Could someone explain me in some clear way, please? or point me in the right direction... (I really feel dumb)...

What I've understood its that it's intended to do direct stream copy within avisynth.

- Does than means that this could be use for editing stuff and this would save it without recompressing? It would be then usefull to NLE stuff...

- Can I apply filters? And in this case what's the behaviour of dsynth? Does it then swith to normal avisource() and then recompress the video?

Thanks in advance
:rolleyes: :D

Mug Funky
28th October 2004, 12:05
yes, it does direct stream copying.

this will be very useful for NLE purposes so long as you have I-frame only codecs (DV, MJPEG, maybe MPEG-4 I-frame only).

as soon as a filter is applied that involves actually modifying a frame, dsynth turns off direct streaming and behaves like regular avisynth, serving uncompressed frames to your encoding app.

so you were right on both counts :)

jkwarras
28th October 2004, 17:57
Originally posted by Mug Funky
so you were right on both counts :)
Cool :D (I fee less dumb)

Thanks for the info Mugfunky :) I'll test it ASAP.

Hmmm..One more question that comes to my mind: If a filter is applied to just one part of the video, does dsynth re-compress everything anyway or it only compress the filtered parts?

Mug Funky
28th October 2004, 18:19
well, to do that your encoding app (and the archaic video for windows) would need to be aware of the decisions being made inside the avisynth script.

so no... but if a NLE app were built around dsynth then this would be possible.

esby
28th October 2004, 22:53
Hmmm..One more question that comes to my mind: If a filter is applied to just one part of the video, does dsynth re-compress everything anyway or it only compress the filtered parts?

The answer is no: the filter chain is analyzed, if at least one filter does not support direct stream copy, the whole chain is treated via the normal methods. So Dsynth will act as avisynth, and decompress everything.

Now for what Mug Funky is saying... it is half false half true...
vfw does not allow to have compressed and uncompressed video inside of a same avi stream.
So whether your video is decompressed, whether it is compressed.
So if you create one avs... the answer will be or black or white, but not both.

Now if you have an nle able to see that you do processing on only part on the video while you want to keep intact the rest, maybe it'll try to reencode only the corresponding part. Now saying it will use dsynth is very *hazardous*.

As far I know, only alfa encoder was supposed to take a few advantage of Dsynth, but it is currently broken and not usable at all. Now if someone do something using Dsynth, I won't mind at all.

esby

esby
4th November 2004, 02:58
I have been trying to find why dsynth is not able to properly direct stream audio using vbr mp3...

The only explanation I have found, or hypothesis, should I say, is that dsynth is not able to serve a vbr mp3 file because it goes somewhat 'fixed' by the vdub inherited procedures, since it needs it to properly decode the stream...
Apparently one of the fixed properties is nBlockAlign that is set back to 1...

Am I wondering if I should try to continue fixing that stuff,
since it would only lead to modify or recreate the structure used for serving the audio, in a dummier way, since it would just serves the audio properties and frames, without even trying to check them, and of course correct them... which is is the current problem here.

If anyone has ideas or comments on this issue, I'd appreciate.
Personnaly I think that vbr mp3 should be avoided at any cost in avi container... Since avisynth, and thus dsynth are based on avi (for now), no vbr mp3 supported should be the proper answer...
Now since dsynth is just asked to serve what he get as input, I think that it should be able to output 'garbage' if it is inputed such data as long the garbage remains identical.

esby

rling
9th November 2004, 07:19
Hi esby,

how hard would it be for dsynth to always serve compressed frames, no matter what filters are used? the idea is, like this:

- if an output frame is exactly the same as the input frame, the original compressed frame is served. (hopefully this happens most of the time)

- in other case (for example, part way through a Dissolve) the source frame(s) are decompressed, the filters are applied to get the output frame, and the output frame is recompressed using the appropriate codec.

I would find this very useful for DV editing, because sometimes I use a Dissolve or other effect - but maybe only 5% of frames are affected. It is not efficient to decompress and recompress the other 95% of frames which are unchanged, which is what Avisynth/VirtualDub does now!

Cheers!

R.