Log in

View Full Version : Does fix_win_stdin patch really work?


roozhou
6th June 2008, 15:24
I have tried several builds with or without fix_win_stdin patch. Unfortunately none works well when i redirect stdin to pipes. The only fully working builds are from MediaCoder (http://mediacoder.sourceforge.net/dlupdate.htm) packages.

x264 stops after a few frames and the output file is 0 byte. Stdout looks like


x264 [info]: using cpu capabilities: MMX MMX2 SSE SSE2 SSE3 3DNow
encoded frames: 1/1 (100.0%), 0.00 fps, eta 0:00:00
encoded 1 frames, 1.#J fps, 0.00 kb/s


or


x264 [info]: using cpu capabilities: MMX MMX2 SSE SSE2 SSE3 3DNow
encoded frames: 5/5 (100.0%), 0.00 fps, eta 0:00:00
encoded 5 frames, 312.50 fps, 0.00 kb/s


The result is not deterministic. "encoded frames" varies between 1 to 10 even with the same frame sequence and sometimes x264 begins to work normally.

I noticed that avc2avi has the same problem but in avc2avi mod (http://forum.doom9.org/showthread.php?t=118267&highlight=avc2avi) the bug is fixed.

buzzqw
6th June 2008, 15:58
i pipe from ffmpeg to x264 .. and for me is ok

ffmpeg.exe -i aaa.vob -vcodec rawvideo -pix_fmt yuv420p -r 25.000 -cropleft 0 -croptop 72 -cropright 0 -cropbottom 72 -sws_flags 2 -s 640x264 -aspect 2.431 -f rawvideo - | x264 - --bitrate 1217 --progress --ref 3 --deblock 0,0 --direct auto --subme 5 --trellis 1 --me dia --keyint 250 --merange 16 --bframes 2 --level 4.1 --fps 25.000 640x264 -o aaa.mp4

BHH

roozhou
6th June 2008, 20:47
I am redirecting stdin to named pipes (aka FIFO). Look at these funny stats


x264 [info]: using cpu capabilities: MMX MMX2 SSE SSE2 SSE3 3DNow
encoded frames: 1/5 (20.0%), 0.00 fps, eta 0:00:00
encoded frames: 2/5 (40.0%), 0.00 fps, eta 0:00:00
encoded frames: 3/5 (60.0%), 0.00 fps, eta 0:00:00
encoded frames: 4/5 (80.0%), 0.00 fps, eta 0:00:00
encoded frames: 5/5 (100.0%), 312.50 fps, eta 0:00:00

encoded 5 frames, 312.50 fps, 0.00 kb/s

and

x264 [info]: using cpu capabilities: MMX MMX2 SSE SSE2 SSE3 3DNow
encoded frames: 1/1 (100.0%), 0.00 fps, eta 0:00:00

encoded 1 frames, 1.#J fps, 0.00 kb/s


What is "1.#J fps"? And where the hell did x264 get the frame count? It should not be there and x264 should read to EOF when using stdin.

foxyshadis
8th June 2008, 02:49
1.#J is what you get if you try to print Not A Number (NaN), which often comes from dividing 0 by 0 - likely x264 is receiving 0 for both the numerator and denominator of the framerate, obviously framecount is also garbage. Looks like it's not working after all.

roozhou
8th June 2008, 23:46
I think following code in muxer.c leads to this bug

if( !fseek( h->fh, 0, SEEK_END ) )
{
uint64_t i_size = ftell( h->fh );
fseek( h->fh, 0, SEEK_SET );
i_frame_total = (int)(i_size / ( h->width * h->height * 3 / 2 ));
}


It works fine if the stream buffer is empty. When the stream buffer is not empty, fseek seeks to the end of buffered data and ftell returns non zero. The problem can be fixed by addingif (stdin == h->fh) return 0; before this block.

For existing CLI builds, I found that hacking msvcr.fsetpos would fix this problem. I opened x264.exe with debugging tool and search for "JMP msvcr.fsetpos", replacing it with XOR EAX, EAX + RET. This method works on all MinGW builds.

akupenguin
9th June 2008, 00:04
Testing for stdin fails to detect named pipes. But I guess that's ok, because there is no such thing as named pipes on windows, and linux doesn't have this problem.

Dust Signs
9th June 2008, 00:22
Tthere is no such thing as named pipes on windows
Of course there is: http://msdn.microsoft.com/en-us/library/aa365590.aspx

Dust Signs

roozhou
9th June 2008, 00:30
Who tells you there is no named pipes on windows? Actually there are functions called CreateNamedPipe and ConnectNamedPipe in Win32 API.
This is how I redirect stdin of a process to a named pipe:

HANDLE hPipe;
STARTUPINFOA stinfo={0};
PROCESS_INFORMATION pinfo={0};
SECURITY_ATTRIBUTES sa={sizeof(SECURITY_ATTRIBUTES),NULL,TRUE};
...
if (INVALID_HANDLE_VALUE == (hPipe = CreateNamedPipeA(lpPipeName,PIPE_ACCESS_DUPLEX,PIPE_TYPE_BYTE | PIPE_READMODE_BYTE | PIPE_WAIT,PIPE_UNLIMITED_INSTANCES,BUFSIZE,BUFSIZE,0,&sa)))
return;
ConnectNamedPipe(hPipe,NULL);
stinfo.cb = sizeof(STARTUPINFO);
stinfo.dwFlags = STARTF_USESTDHANDLES;
stinfo.hStdInput = hPipe;
stinfo.hStdOutput = GetStdHandle(STD_OUTPUT_HANDLE);
stinfo.hStdError = GetStdHandle(STD_ERROR_HANDLE);
if (CreateProcessA(lpProcessName,lpArgs,0,0,TRUE,0,NULL,NULL,&stinfo,&pinfo))
{
WaitForSingleObject(pinfo.hProcess,INFINITE);
}


When the x264 process is created, the process connected to the named pipe may have alreadly written data to the pipe and x264 will get a nonzero file size by calling fseek+ftell.

akupenguin
9th June 2008, 00:51
Are those 17 lines of C required, or is there an equivalent to what I would do in linux, which is
mkfifo pipename
x264 pipename

roozhou
9th June 2008, 01:19
Are those 17 lines of C required, or is there an equivalent to what I would do in linux, which is
mkfifo pipename
x264 pipename

cmd in windows does not provide an equivalent command to mkfifo in linix, so you need to write a "mkfifo" for windows.

CruNcher
12th July 2008, 14:59
Useing this

mencoder.exe Vegas_1280x528.wmv -really-quiet -nosound -ovc raw -vf format=i420 -of rawvideo -o - | x264 -o output.264 --quiet --subme 3 --crf 22 --fps 23.976 - 1280x528
[swscaler @ 00CC1854]using unscaled yuv420p -> yuv420p special converter


i get this :(

http://s1.directupload.net/file/d/1488/73grqlto_png.htm

Win XP SP3

(it seems only Stanley the Author of MediaCoder does it currently right, i find it sad that he doesn't seem to contribute it back to x264)

Hey FFMPEG works :) thx buzzqw

ffmpeg.exe -i Vegas_1280x528.wmv -vcodec rawvideo -pix_fmt yuv420p -r 23.976 -f rawvideo - | x264 -o output.264 --quiet --subme 3 --crf 22 --fps 23.976 - 1280x528


tough i have another Problem now doing some tests ehh this is strange but it seems like FFMPEG (creates ghost frames via the Pipe) hard to say what's going on but the Piped Version has a longer runtime then the Original (alot more Frames)

Input = 3634 Frames (2:31)
FFMPEG Pipe = 3705 Frames (2:34) <- were are these additional frames coming from ???

look @ this (bitrate is higher with less frames)

FFMPEG Pipe = encoded 3705 frames, 30.69 fps, 1809.75 kb/s
Avisynth (ffdshow) = encoded 3634 frames, 32.08 fps, 1859.78 kb/s

any idea what's going on (MediaCoder does the same with ffmpegs pipe tough Mencoders Pipe is correct) ?

ahhh RTFM yeah i found -copyts' Copy timestamps from input to output.
now it's much better but 2 frames are missing now

FFMPEG Pipe = 3632 Frames (2:31) encoded 3632 frames, 30.29 fps, 1854.75 kb/s (any idea how to get these 2 frames back, were are they ?)
hmm even if a programm starts counting frames @ 1 instead of 0 then there should be at least 3633 frames right so it would be still 1 frame missing ?