Log in

View Full Version : fake avi (mjpg) from .avs?


marcorocco
31st August 2017, 00:05
Hi to all,
I wonder if is there a way to do a "fork" or a program that expose the output of avisynth in a fake .avi MJPEG interlaced file.

For example myfile.avs point to the orginal.mxf video source. The fork have to build a fake .avi with MJPG fourcc. This because my old NLE software cannot read the new formats.

If necessary I can pay for it, thanks

kolak
31st August 2017, 00:22
Any compressed formant will be difficult.
You can 100x easier present file as uncompressed YUV or RGB which is already supported and should work even in very old NLE.

StainlessS
31st August 2017, 00:25
Sounds to me a little bit more complicated, an AVI with MJPEG fourCC would need also to produce MJPEG compressed AVI,
so Avisynth itself is probably of no use.
However, could perhaps persuade ffmpeg to convert to AVI with MJPEG compression.

Bat to convert some formats (just add *.AVS or whatever other inputs required) using ffmpeg.
Below uses output PCM audio, and ut_video video codec, but might be able to convince it to recompress as MJPeg. (see ffmpeg docs)
Also, would need ffmpeg that is enabled for avs input (as in above *.avs).

setlocal

REM Where to Find ffmpeg
set FFMPEG="C:\BIN\ffmpeg.exe"

REM Where to get input file, No terminating Backslash, "." = current directory
set INDIR="."

REM Where to place output file, No terminating Backslash.
set OUTDIR=".\OUTPUT"

FOR %%A IN (*.wmv *.mpg *.avi *.flv *.mov *.mp4 *.m4v *.RAM *.RM *y4m *.yuv) DO (
%FFMPEG% -i "%INDIR%\%%A" -vcodec utvideo -acodec pcm_s16le "%OUTDIR%\%%~nxA.AVI"

)

Pause


Avisynth plugin to write AVI file, TWriteAVI v2.0:- https://forum.doom9.org/showthread.php?t=172837&highlight=TWriteAVI

Also might be of interest but I dont know what it can do:- https://forum.doom9.org/showthread.php?t=133313

EDIT: Kolak probably 100% correct in that any NLE should read uncompressed AVI. (Might need convertToRGB24 or something at end of script).

EDIT: Perhaps its just a matter of changing file type extender in file selector dialog to eg "*.*" so
that you can see and perhaps load an AVS instead of AVI. (it may say eg "All supported types" by default).
Failing that, you could try entering the filename and extender manually into the filename box in Fileselector dialog,
not convenient but perhaps will work.

hello_hello
31st August 2017, 06:56
Isn't the real issue the video is interlaced and your NLE doesn't automatically de-interlace the AVS output?
https://forum.videohelp.com/threads/382836-can-avisynth-directly-encode-a-AVI-MJPEG-video-file#post2480181

I don't know anything about the NLE you're using, and I recall you mentioning something about it not being able to operate in DirectShow mode..... or something..... I didn't really understand what the issue was at the time so I didn't give it any more thought.

I wonder though, if it's possible to add the interlaced flag to the AVisynth output. If you wrap a script into an AVI with MakeAVIS or avs2avi (it's attached to the post above the one I linked to) and process the video output with ffdshow (in the case of MakeAVIS you probably have to enable "Avisynth" in ffdshow's codec list for it to work) could you then force an interlaced flag with ffdshow?
MakeAVIS should come along for the ride when you install ffdshow, although I don't think the installer creates a shortcut to it, but makeAVIS.exe should be found in the same location.... wherever ffdshow is installed.

Edit: I just realised the ffdshow VFW decoder configuration doesn't have an option to force an interlaced flag as the DirectShow decoder does. Doesn't VFW support interlaced video as such?

Maybe the above idea can't work (unless you decode with DirectShowSource??). If not, ignore my post. :(

marcorocco
31st August 2017, 11:04
My old NLE cannot manage correctly VFW and Directshow source. It only have a uncompressed reader and a MJPEG reader: both with internal decompressor that works well but in uncompressed mode (.avi/YUY2) I can feed it using AVFS and it works.. quality is the best but AVFS don't expose a interlaced flag in his AVI virtual file, so that my NLE interpret as alwais progressive input and don't apply his internal deinterlacer.

I try to understand if is possible have, as alternative, a virtual mjpeg .avi file instead of the YUY2 ucompressed .avi file.

At the moment I'm forced to trascode all clip as .avi mjpeg clips... the quality is 98% similar but it very time-expensive. OR it would be nice if AVFS exposes a real flagged interlaced output, but not.. it don't expose any flag in the .avi header and my NLE interpret as progressive alwais

marcorocco
31st August 2017, 11:11
Sounds to me a little bit more complicated, an AVI with MJPEG fourCC would need also to produce MJPEG compressed AVI,
so Avisynth itself is probably of no use.
However, could perhaps persuade ffmpeg to convert to AVI with MJPEG compression.

Bat to convert some formats (just add *.AVS or whatever other inputs required) using ffmpeg.
Below uses output PCM audio, and ut_video video codec, but might be able to convince it to recompress as MJPeg. (see ffmpeg docs)
Also, would need ffmpeg that is enabled for avs input (as in above *.avs).

setlocal

REM Where to Find ffmpeg
set FFMPEG="C:\BIN\ffmpeg.exe"

REM Where to get input file, No terminating Backslash, "." = current directory
set INDIR="."

REM Where to place output file, No terminating Backslash.
set OUTDIR=".\OUTPUT"

FOR %%A IN (*.wmv *.mpg *.avi *.flv *.mov *.mp4 *.m4v *.RAM *.RM *y4m *.yuv) DO (
%FFMPEG% -i "%INDIR%\%%A" -vcodec utvideo -acodec pcm_s16le "%OUTDIR%\%%~nxA.AVI"

)

Pause


Avisynth plugin to write AVI file, TWriteAVI v2.0:- https://forum.doom9.org/showthread.php?t=172837&highlight=TWriteAVI

Also might be of interest but I dont know what it can do:- https://forum.doom9.org/showthread.php?t=133313

EDIT: Kolak probably 100% correct in that any NLE should read uncompressed AVI. (Might need convertToRGB24 or something at end of script).

EDIT: Perhaps its just a matter of changing file type extender in file selector dialog to eg "*.*" so
that you can see and perhaps load an AVS instead of AVI. (it may say eg "All supported types" by default).
Failing that, you could try entering the filename and extender manually into the filename box in Fileselector dialog,
not convenient but perhaps will work.


thank you but my dinosaur NLE can read only .AVI YUY2 uncompressed or .AVI MJPEG video files (unfortunaly not utVideo codec). AVFS don't expose any interlaced flag in .AVI files so my NLE become trick. I wonder if it's possible to have a virtual .AVI mjpeg file from .avs source

ps: TWriteAVI very interesting to transcode into .AVI mjpeg video files but - IF I don't mistake - I cannot find any 64bit version of twriteavi plugin. And, if possibile, I like to generate a virtual .avi MJPEG from .avs source

hello_hello
31st August 2017, 12:03
According to the changelog:

2008.06.09 - 0.0.0.2
- Added AVFS_AVI_VidFcc script variable, to allow overriding video
format fourcc code. Useful to improve compatibility with specific
encoders or readers that do not recognize the YUY2 or YV12 fourcc
codes used by default.

And in the sample.avs file it says:

# Override fourcc code for video data. This has no effect
# on the format of the video data in the emitted file, but
# may be useful for applications that recognize the format
# when it has a different fourcc code.
# AVFS_AVI_VidFcc="yuvs"

It appears there's no reason why you couldn't change the fourcc to whatever you want. Of course that's just telling your NLE to expect the wrong type of video and probably won't help with your interlaced problem (unless mjpeg is an interlaced-only format). What's wrong with the workaround you mentioned in your old thread of adding de-interlacing to the script?

marcorocco
31st August 2017, 12:30
According to the changelog:

2008.06.09 - 0.0.0.2
- Added AVFS_AVI_VidFcc script variable, to allow overriding video
format fourcc code. Useful to improve compatibility with specific
encoders or readers that do not recognize the YUY2 or YV12 fourcc
codes used by default.

And in the sample.avs file it says:

# Override fourcc code for video data. This has no effect
# on the format of the video data in the emitted file, but
# may be useful for applications that recognize the format
# when it has a different fourcc code.
# AVFS_AVI_VidFcc="yuvs"

It appears there's no reason why you couldn't change the fourcc to whatever you want. Of course that's just telling your NLE to expect the wrong type of video and probably won't help with your interlaced problem (unless mjpeg is an interlaced-only format). What's wrong with the workaround you mentioned in your old thread of adding de-interlacing to the script?

my NLE recognize correctly only YUY2 by AVFS fourcc, however the output of AVFS is only uncompressed and can not be, for example, MJPEG or MPEG2. Using AVFS, teorically, I can mount all the clip adding the bob() in the .avs original script but it's only "visual deinterlacer" during the editing: all the rendered area assumpted by the NLE are build based on the source already deinterlaced. When I export the project, I need to convert all the .avs file in a "real" interlaced removing the deinterlacer bob() and rebuild all the rendered areas... it become a little complicated. In addition: for each clip loaded using the AVFS, a portion of RAM memory is allocated, if I need to load for example 250 clip .. I finish to have the pc clogged and almost useless. To avoid this pandemonium I prefer trascode all clip in .AVI MJPEG and they are loaded in few seconds and the usage of ram memory by the NLE is minimum and editing is rock stable. Exactly I don't know why the AVFS uses memory ram but when I have a lot of clip .. the editing become difficult.

StainlessS
31st August 2017, 18:37
thank you but my dinosaur NLE can read only .AVI YUY2 uncompressed or .AVI MJPEG video files (unfortunaly not utVideo codec). AVFS don't expose any interlaced flag in .AVI files so my NLE become trick. I wonder if it's possible to have a virtual .AVI mjpeg file from .avs source

ps: TWriteAVI very interesting to transcode into .AVI mjpeg video files but - IF I don't mistake - I cannot find any 64bit version of twriteavi plugin. And, if possibile, I like to generate a virtual .avi MJPEG from .avs source

The Ut_video codec thing was an example, you would need look up ffmpeg docs to find the name of MJPEG codec (thats your job).

I wonder if it's possible to have a virtual .AVI mjpeg file from .avs source

As I said, it would need to provide Compressed MJPEG AVI, not uncomressed avs.

I would not be too eager to do 64 bit TWriteAVI, I dont know the VirtualDub code that well (I aint a CPP progger) and have no idea how it would perform if complied x64. (EDIT: I'm on XP32 and so could not test it)

Did you try with eg ConvertToRGB24/ConvertToRGB3/ConvertToYUY2/ at end of script and try load with manual enter of full path and filename in dialog box ?

marcorocco
31st August 2017, 20:52
AVFS works well: I can "directly" open the output of avisynth/AVFS in my NLE in YUY2 uncompressed mode but my NLE interpret all the footage as "progressive" because there in no interlaced flags inside the AVFS exposed output.
This mean that, for example, the NLE don't apply his internal deinterlacer and other problems. I don't need to convert ConvertToRGB24/ConvertToRGB3, or in general I use the ConvertToYUY2() because the NLE treat all in 4:2:2.
My alternative is to encode all the clip in .AVI MJPEG with an appropriate batch, it works but.. the quality is not the 100% meanwhile using AVFS is 100% identical as the source.

Think a virtual .avi mjpeg file is not tecnically possible

TwriteAvi is nice even if a 64 bit version would probably be more enjoyable :)

kolak
2nd September 2017, 12:42
My old NLE cannot manage correctly VFW and Directshow source. It only have a uncompressed reader and a MJPEG reader: both with internal decompressor that works well but in uncompressed mode (.avi/YUY2) I can feed it using AVFS and it works.. quality is the best but AVFS don't expose a interlaced flag in his AVI virtual file, so that my NLE interpret as alwais progressive input and don't apply his internal deinterlacer.

I try to understand if is possible have, as alternative, a virtual mjpeg .avi file instead of the YUY2 ucompressed .avi file.

At the moment I'm forced to trascode all clip as .avi mjpeg clips... the quality is 98% similar but it very time-expensive. OR it would be nice if AVFS exposes a real flagged interlaced output, but not.. it don't expose any flag in the .avi header and my NLE interpret as progressive alwais

AVI doesn't have standard way of marking files as interlaced.
It's rather simple and old container.
If your NLE can recognised interlacing flag in its own files it will be done in its own specific way. Some NLEs do it (like Edius), but each does it in own way and files are still not recognised properly between NLEs. You need something more robust like MOV which has a standard way of storing interlacing, timecode, aspect flags etc.

LoRd_MuldeR
3rd September 2017, 13:34
AVI doesn't have standard way of marking files as interlaced.
[...] You need something more robust like MOV which has a standard way of storing interlacing, timecode, aspect flags etc.

This is something that, in the AVI format, an "interlaced aware" Codec would probably store in the 'strd' (additional header data) chunk, contained in the 'strl' chunk of the particular stream.

Not really a "standard way", as this is Codec-specific information.

But, to the best of my knowledge, the situation really is not different with MP4/MOV, where such information would be part of the 'stsd' (sample description table) atom - which again contains Codec-specific information.

For example, an AVC/H.264 stream has an 'avcC' (AVC Decoder Configuration) atom inside its 'stsd' atom. There you'll find the SPS (Sequence Parameter Set) and PPS (Picture Parameter Set).

StainlessS
4th September 2017, 03:43
I would not be too eager to do 64 bit TWriteAVI, I dont know the VirtualDub code that well (I aint a CPP progger) and have no idea how it would perform if complied x64. (EDIT: I'm on XP32 and so could not test it)


Just set up VS 2008, and attempted to compile 64 bit version, no go I'm afraid.
There are (I think) 3 files containing intel assembler (which I dont speak),
1) cpuaccel.cpp. CPU capability detector.
2) misc.cpp. Two MulDiv type functions, signed and unsigned.
3) FastWriteStream.cpp. Fast file writing functions, with some kind of thread switching/locking (which I also dont have much of a clue about).

Given that I also cannot test anything, cannot procede any further, sorry again.

EDIT:
cpuaccel.cpp

extern "C" {
bool FPU_enabled, MMX_enabled, ISSE_enabled;
};

// This is ridiculous.

static long CPUCheckForSSESupport() {
__try {
// __asm andps xmm0,xmm0

__asm _emit 0x0f
__asm _emit 0x54
__asm _emit 0xc0

} __except(EXCEPTION_EXECUTE_HANDLER) {
if (_exception_code() == STATUS_ILLEGAL_INSTRUCTION)
g_lCPUExtensionsAvailable &= ~(CPUF_SUPPORTS_SSE|CPUF_SUPPORTS_SSE2);
}

return g_lCPUExtensionsAvailable;
}

long __declspec(naked) CPUCheckForExtensions() {
__asm {
push ebp
push edi
push esi
push ebx

xor ebp,ebp ;cpu flags - if we don't have CPUID, we probably
;won't want to try FPU optimizations.

;check for CPUID.

pushfd ;flags -> EAX
pop eax
or eax,00200000h ;set the ID bit
push eax ;EAX -> flags
popfd
pushfd ;flags -> EAX
pop eax
and eax,00200000h ;ID bit set?
jz done ;nope...

;CPUID exists, check for features register.

mov ebp,00000003h
xor eax,eax
cpuid
or eax,eax
jz done ;no features register?!?

;features register exists, look for MMX, SSE, SSE2.

mov eax,1
cpuid
mov ebx,edx
and ebx,00800000h ;MMX is bit 23
shr ebx,21
or ebp,ebx ;set bit 2 if MMX exists

mov ebx,edx
and edx,02000000h ;SSE is bit 25
shr edx,25
neg edx
and edx,00000018h ;set bits 3 and 4 if SSE exists
or ebp,edx

and ebx,04000000h ;SSE2 is bit 26
shr ebx,21
and ebx,00000020h ;set bit 5
or ebp,ebx

;check for vendor feature register (K6/Athlon).

mov eax,80000000h
cpuid
mov ecx,80000001h
cmp eax,ecx
jb done

;vendor feature register exists, look for 3DNow! and Athlon extensions

mov eax,ecx
cpuid

mov eax,edx
and edx,80000000h ;3DNow! is bit 31
shr edx,25
or ebp,edx ;set bit 6

mov edx,eax
and eax,40000000h ;3DNow!2 is bit 30
shr eax,23
or ebp,eax ;set bit 7

and edx,00400000h ;AMD MMX extensions (integer SSE) is bit 22
shr edx,19
or ebp,edx

done:
mov eax,ebp
mov g_lCPUExtensionsAvailable, ebp

;Full SSE and SSE-2 require OS support for the xmm* registers.

test eax,00000030h
jz nocheck
call CPUCheckForSSESupport
nocheck:
pop ebx
pop esi
pop edi
pop ebp
ret
}
}


misc.cpp

long __declspec(naked) MulDivTrunc(long a, long b, long c) {
__asm {
mov eax,[esp+4]
imul dword ptr [esp+8]
idiv dword ptr [esp+12]
ret
}
}

unsigned __declspec(naked) __stdcall MulDivUnsigned(unsigned a, unsigned b, unsigned c) {
__asm {
mov eax,[esp+4]
mov ecx,[esp+12]
mul dword ptr [esp+8]
shr ecx,1
add eax,ecx
adc edx,0
div dword ptr [esp+12]
ret 12
}
}


FastWriteStream.cpp, two chunks of code something like this

if (lWritePointer >= lBufferSize)
lWritePointer -= lBufferSize;

// atomic add

__asm mov eax,this
__asm mov ebx,buffree
__asm lock add [eax]FastWriteStream.lDataPoint,ebx

// Signal the background thread if there might be enough to write.
//
// There's a chance that the background thread flips in here and
// takes out the data before we get to this point. But if that
// happens, well, it just did what we wanted it to anyway, so why
// bother signalling it?

if (lDataPoint >= lChunkSize)
SetEvent(hEventOkRead);
}

...

// Atomically update data point and signal write thread

__asm mov eax,this
__asm mov ebx,len
__asm lock sub [eax]FastWriteStream.lDataPoint,ebx

SetEvent(hEventOkWrite);




EDIT: Solved the misc.cpp prob as so (exact same code in Vapoursynth, from original VirtualDub source)

#if defined(WIN32) && defined(_M_IX86)

long __declspec(naked) MulDivTrunc(long a, long b, long c) {
__asm {
mov eax,[esp+4]
imul dword ptr [esp+8]
idiv dword ptr [esp+12]
ret
}
}

unsigned __declspec(naked) __stdcall MulDivUnsigned(unsigned a, unsigned b, unsigned c) {
__asm {
mov eax,[esp+4]
mov ecx,[esp+12]
mul dword ptr [esp+8]
shr ecx,1
add eax,ecx
adc edx,0
div dword ptr [esp+12]
ret 12
}
}
# elseif
long MulDivTrunc(long a, long b, long c) {
return (long)(((sint64)a * b) / c);
}

unsigned __stdcall MulDivUnsigned(unsigned a, unsigned b, unsigned c) {
return (unsigned)(((uint64)a * b + 0x80000000) / c);
}
# endif

kolak
15th September 2017, 23:34
This is something that, in the AVI format, an "interlaced aware" Codec would probably store in the 'strd' (additional header data) chunk, contained in the 'strl' chunk of the particular stream.

Not really a "standard way", as this is Codec-specific information.

But, to the best of my knowledge, the situation really is not different with MP4/MOV, where such information would be part of the 'stsd' (sample description table) atom - which again contains Codec-specific information.

For example, an AVC/H.264 stream has an 'avcC' (AVC Decoder Configuration) atom inside its 'stsd' atom. There you'll find the SPS (Sequence Parameter Set) and PPS (Picture Parameter Set).

Not really. MOV has a standardised way of storing aspect, interlacing type, color matrix etc. on container level, regardless what codec is in the stream.
https://developer.apple.com/library/content/documentation/QuickTime/QTFF/QTFFChap3/qtff3.html

Table 4-2. This is used a lot and it does help to properly "describe" files.