Log in

View Full Version : MeGUI development


Pages : [1] 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92

Doom9
11th June 2005, 14:28
This thread is dedicated to the development of MeGUI. If you don't "speak" C# this is the wrong thread to post in. For generic MeGUI problems refer to the main MeGUI thread (http://forum.doom9.org/showthread.php?t=96032)

You can get the source code from Sourceforge (http://sourceforge.net/projects/megui)

And here is the current TODO list (http://forum.doom9.org/showthread.php?t=105162)

celtic_druid
12th June 2005, 04:51
C# didn't seem all that hard last time I had a go at it.

I think next mencoder compile I will just disable pthreads or at least now that I know it is autodetected under mingw I will pack the dll. I couldn't get it to encode with threads > 1 for libavc though. With ffmpeg it works fine.

berrinam
12th June 2005, 07:28
I don't know if anyone noticed, but MeGUI seems to only have 4 of the 5 macroblock motion estimation modes for x264 (the i4x4 checkbox is missing, and the p4x4 checkbox actually enables i4x4, so p4x4 can't be enabled). I don't know what is going on with this, but I wrote a patch based on the sources Doom9 posted recently. I know that Doom9 is planning to rewrite a lot of the code, so I noted all the changes I made so that I (or someone else) can make them again on the new version. It is included in the sourcecode. Anyone interested?

I've attached the compiled version and the sources.

Doom9
12th June 2005, 13:37
@berrinam: actually, I don't find an i4x4 option in the mencoder documentation. but it's there in x264 so I'll use it. I also noted that you tied the options together the way they should be so I'll definitely use it.

Just a guess without checkingNope, definitely not.. the Belgian locale uses the same decimal separator as the German one.. and you're not getting 25000 fps video, are you?

akupenguin
12th June 2005, 18:21
actually, I don't find an i4x4 option in the mencoder documentation. I added it to mencoder at the same time as I added i8x8.

Doom9
12th June 2005, 19:20
since I'm apparently struck by blindness.. what's the option and default value?

akupenguin
12th June 2005, 20:59
the option is 'i4x4' or 'noi4x4', and the default is 'i4x4'.

xtknight
13th June 2005, 02:38
alright here goes:
speed up d2v preview when cropping. Basically I overwrite a bunch of pixels with white when cropping. I do that looping over pixels over the frame. There's a much more efficient way working with images.. it's to freeze the bitmap into memory, then consider it a byte array with each pixel being followed by each other. Since we're dealing with 24 bit images, you have sets of 3 bytes that make up one color.. first comes B, then G, then R. So, instead of the 4 loops, there could be one, and pixels could be set to a color by changing bytes in the byte array. Then when done, unlock the image again.

This could also be used for auto-crop.

And all of that is staying in the managed domain, without even having to resort to pointers. I'll attach a sample (that uses unsafe code.. but it gets you the basics) here.

Once the GUI is done, it could be extended to support multiple zones (taken from the preview window.. with a start and end button).

Then there's AVI support in auto mode. mencoder can be used to mux (vbr)mp3 and ac3 into an AVI (this would obviously require besweet configuration for mp3 output).

Then of course there's lots of lavc and xvid options that are unsupported.. but I guess somebody should ask for a specific option first.

Then of course there's the matter of the progress bar for mp4 muxing (you'll find some starter points in the mp4muxer class.. I never quite finished it.. and with x264.exe support, mp4box might act a bit different if your video input is also an mp4).

And while we're with mp4box.. now that it supports language tags of course that's something (support starts with the d2v creator.. rather than to have a checked listbox I guess having two dropdowns listing all languages would be good.. and if there's no info file, a selection like track1/2/etc could be used).

D2V Creator: tracks selected for demux should be filled in as audio source in the main GUI.

One click mode: select .ifo/vob, pick audio track, audio and video profile and hit go.. a lot of code to enable this is already there but it needs to be tied together.

Last but not least, if bond can confirm that libavformat's mp4 muxing is okay for ASP, perhaps we could offer direct mp4 output for xvid/lavc using mencoder.

And yet another one: the x264cli encoder should get the video bitrate (encoder tells you at the end), and from that derive the mp4 overhead and save it to the mp4stats file (and since direct mp4 output is now possible, I guess the mp4stats in the mp4 muxer will have to be adapted to take mp4 video input into account).

Though I'm very unfamiliar with DVDs I could probably help you do that. The only thing I'm unfamiliar with/don't know a thing about is the d2v resizing thing...not sure what that is...if you explain it more I could catch on fairly easy...

You just want me to modify that posted source or is there a later version at this time? I have decent knowledge of .NET languages and a little C++. My understanding is you just want this in .NET though right? I'd be very excited to be able to help.

You mentioned you were doing a GUI redo...should I wait?

- xtknight

Doom9
13th June 2005, 08:23
about the d2v: have a look at the avisynth creator form.. check out what happens if you change the crop values. Basically it does this: start at the first line, iterate over every pixel and set its color to white, go to the next line, set color to white, etc. until you've reached the number of pixels to be cropped away from the top.

The same is done at the right, left, and bottom. Doing it that way, I'm effectively marking certain pixels twice (and since assigning a color to a pixel is slow, this is a major waste of time)

A better way would be to consider the image to be an array of bytes (pixel1x1-blue, pixel1x1-green, pixel1x1-red, pixel1x2-blue, pixel1x2-green, pixel1x2-red, pixel1x3-blue, etc). If you look up the class definition of Bitmap, you'll see that you can lock and unlock the image in memory, and from the IntPtr you get, you can treat it as an array of byte and do this whole operation much more effectively (white = [255, 255, 255]). If that's not enough info, check the source and the example I posted on page 40.

You can safely start with the AviSynth window.. that one's good for now. Progress bar for mp4 muxing is also something you could work on, it doesn't depend on the GUI changes that are currently in the works. The bitrate calculation for AVI muxing could also be done, as well as the AVI muxer itself (just don't integrate it into the main form yet.. that's the one that is being totally revamped). So basically, anything that doesn't touch the main form is okay to be started right now.

oh, and by the way, C# isn't a must.. if you write your own class and are more familiar with say C++, it's alright with me. I know C++, but C# seems like a more straightforward language to me.

Is it just me, or is the version you posted v0.1914?Nope, I forgot to update the exe. And I'm having a major mess in my head with the version numbers myself.. and the fact that the forum refused to let me attach the latest version didn't really help reducing my confusion.

berrinam
13th June 2005, 09:39
For anyone who didn't notice, v0.193 is now available at http://forum.doom9.org/MeGUI-0.193.zip

@Doom9, I'm also happy to help with MeGUI. Will you post sources for subsequent versions, or should I just use the old sources?

Doom9
13th June 2005, 09:58
@berrinam: I will post the sources. Above I have listed the work that can start right now using the latest published sources. Since I've taken it upon myself to rearrange the GUI, it would currently not make a lot of sense to release sources that contain half-finished features that I'm going to finish in the next few days (I hope to get quite far today after work). But as you can see from the latest version, a lot has already been done. Once I'm all done, it will become much easier to make changes as the code is more separated into specific modules. I've already reduced the size of the main class from more than 400KB to 180KB and there's more to come. I also want to move out a lot of the logic to other classes, thus enabling more people to work on the program concurrently without stepping on each other's toes.

xtknight
13th June 2005, 23:07
Doom9:

OK I'm not sure about the AVI muxer...I got real close but I still can't get the damned thing to work.

Does MP4Box show progress? Is there some verbose option? I didn't see any progress bar when I was muxing a video but maybe I'm just blind.

So this d2v crop is for the preview window?

For the grayscale code:
I'm not sure if this would qualify as safe or unsafe, but I got it off of MSDN:

...
// Get the address of the first line.
IntPtr ptr = bmpData.Scan0;
...
// Copy the RGB values into the array.
System.Runtime.InteropServices.Marshal.Copy(ptr, rgbValues, 0, bytes);
...
// Copy the RGB values back to the bitmap
System.Runtime.InteropServices.Marshal.Copy(rgbValues, 0, ptr, bytes);

That code is unsafe, correct, even though there are no * pointers, per se? Unfortunately, I think this is one weakness of safe code...it's just not fast enough. The ideal thing to do would be to use assembler, with optimizations up to SSE3, which I don't know but I imagine there's some grayscale code out there. (Though even without the optimizations it would still be a lot faster.) You'd do this by calling a COM DLL coded with inline assembly in C++. Just wondering...what's the advantage of using safe code over unsafe? The 'safe' code gets turned into assembly later, anyway...I mean as long as you have sufficient error-catching there's no need to rely on managed code IMO. You said you didn't mind if it was coded in C++, but essentially that's the same as the unsafe C# code you have there...so...unless there's a faster safe way of doing it you're stuck there...or if that code I posted above is infact "safened" by .NET...

Evidently I haven't dealt with this stuff too much...so that's why I was skeptical of whether I could do this or not. Guess I'll go do the other stuff. And just out of curiosity what is the grayscale function used for?

berrinam
14th June 2005, 02:56
I'm just as confused as xtknight. I don't see how you can optimize the code as much as you say without making it unsafe. Anyway, I have rewritten the crop function with pointers (I presume this makes it unsafe) to see if this is what you mean. I'm using argb because it makes it easier just to read in an integer. I've also written some similar code (but longer) for the autocrop function, but I'm not including that here.


private void cropImage(ref Bitmap b)
{
BitmapData image = b.LockBits(new Rectangle(0, 0, b.width, b.height), ImageLockMode.WriteOnly, PixelFormat.Format32bppArgb)
int* pointer = image.Scan0.ToPointer();
int* pixel;
int stride = image.Stride;
int white = Color.white.ToArgb()
int lineGap = stride - (4*b.width);
int centerJump = b.width - left - right;

pixel = pointer;
for (int j = 0; j < top; j++) {
for (int i = 0; i < b.Width; i++) {
*pixel = white;
pixel++;
}
pixel += lineGap;
}

for (int j = top; j < b.Height - bottom; j++)
{
for (int i = 0; i < left; i++) {
*pixel = white;
pixel++;
}
pixel += centerJump;
for (int i = 0; i < right; i++) {
*pixel = white;
pixel++;
}
pixel += lineGap;
}
for (int j = b.Height-bottom; j < b.Height; j++)
{
for (int i = 0; i < b.Width; i++)
{
*pixel = white;
pixel++;
}
pixel += lineGap;
}
b.UnlockBits(image);
}

stax76
14th June 2005, 07:00
you don't have to manipulate images unless you are having fun with it :D. My code is fast and can crop and scale. See it in the latest DVX version in action. For my crop dialog I want to borrow a idea of Recode but for now I'm working on Stax DVB but I'll try to give you some competion with my DVX successor later ;)


using System;
using System.Drawing;
using System.Runtime.InteropServices;
using System.IO;
using System.Drawing.Imaging;
using System.Windows.Forms;
using System.Reflection;
using System.Diagnostics;

namespace VFW
{
public class AVIFile
{
public int Left, Top, Right, Bottom;

IntPtr AviFile;
IntPtr FrameObject;
IntPtr AviStream;
AVISTREAMINFO StreamInfo;
Control Control;

int FrameCountValue;

public int FrameCount
{
get { return FrameCountValue; }
}

public float FrameRate
{
get { return StreamInfo.dwRate / (float)StreamInfo.dwScale; }
}

public Size FrameSize
{
get { return new Size((int)StreamInfo.rcFrame.right, (int)StreamInfo.rcFrame.bottom); }
}

public void Open(string fileName, Control c)
{
Open(fileName);

Control = c;
}

string GetFourCC(int value)
{
byte[] bytes = BitConverter.GetBytes(value);
char[] chars = new char[4];

for (int i = 0; i < bytes.Length; i++)
chars[i] = Convert.ToChar(bytes[i]);

return new String(chars);
}

public void Open(string fileName)
{
try
{
AVIFileInit();

int OF_SHARE_DENY_WRITE = 32;

int result = AVIFileOpen(ref AviFile, fileName,
OF_SHARE_DENY_WRITE, 0);

if (result != 0)
throw new Exception("AVIFileOpen failed");

result = AVIFileGetStream(AviFile, out AviStream,
1935960438 /*FourCC for vids*/, 0);

if (result != 0)
throw new Exception("AVIFileGetStream failed");

FrameCountValue = AVIStreamLength(AviStream.ToInt32());

StreamInfo = new AVISTREAMINFO();

result = AVIStreamInfo(AviStream.ToInt32(), ref StreamInfo,
Marshal.SizeOf(StreamInfo));

if (result != 0)
throw new Exception("AVIStreamInfo failed");

if (GetFourCC(Convert.ToInt32(StreamInfo.fccHandler)) == "YV12")
FrameObject = AVIStreamGetFrameOpen(AviStream, 1);
else
FrameObject = AVIStreamGetFrameOpen(AviStream, 0);

if (FrameObject == IntPtr.Zero)
throw new Exception("AVIStreamGetFrameOpen failed");
}
catch (Exception ex)
{
MessageBox.Show("An error occurred. Maybe no YV12 decoder available, installing XviD, DivX or ffdshow might help.\r\n\r\n" +
ex.ToString(), Application.ProductName,
MessageBoxButtons.OK, MessageBoxIcon.Error);
}
}

int PositionValue;

public int Position
{
get { return PositionValue; }
set
{
if (value < 0)
PositionValue = 0;
else if (value > FrameCount - 1)
PositionValue = FrameCount - 1;
else
PositionValue = value;
}
}

public void Close()
{
if (FrameObject != IntPtr.Zero)
{
AVIStreamGetFrameClose(FrameObject);
FrameObject = IntPtr.Zero;
}

if (AviStream != IntPtr.Zero)
{
AVIStreamRelease(AviStream);
AviStream = IntPtr.Zero;
}

if (AviFile != IntPtr.Zero)
{
AVIFileRelease(AviFile);
AviFile = IntPtr.Zero;
}

AVIFileExit();
}

public void Draw()
{
if (Control != null && Control.Visible)
{
Graphics g = Control.CreateGraphics();
Draw(g);
g.Dispose();
}
}

int DrawCount = 0;

public void Draw(Graphics g)
{
try
{
if (Control != null && Control.Visible && FrameObject != IntPtr.Zero)
{
Debug.WriteLine(++DrawCount);

Image img = GetBMPFromDib(new IntPtr(
AVIStreamGetFrame(FrameObject, Position)));

if (Left == 0 && Top == 0 && Right == 0 && Bottom == 0)
{
g.DrawImage(img, Control.ClientRectangle);
}
else
{
float factorX = (float)Control.Width / img.Width;
float factorY = (float)Control.Height / img.Height;

float left = Left * factorX;
float right = Right * factorX;
float top = Top * factorY;
float bottom = Bottom * factorY;

RectangleF rectDest = new RectangleF();

rectDest.X = left;
rectDest.Y = top;
rectDest.Width = Control.Width - left - right;
rectDest.Height = Control.Height - top - bottom;

Rectangle rectSrc = new Rectangle();

rectSrc.X = Left;
rectSrc.Y = Top;
rectSrc.Width = img.Width - Left - Right;
rectSrc.Height = img.Height - Top - Bottom;

g.DrawImage(img, rectDest, rectSrc, GraphicsUnit.Pixel);

SolidBrush sb = new SolidBrush(Color.White);

g.FillRectangle(sb, 0, 0, left, Control.Height);
g.FillRectangle(sb, 0, 0, Control.Width, top);
g.FillRectangle(sb, Control.Width - right, 0, right, Control.Height);
g.FillRectangle(sb, 0, Control.Height - bottom, Control.Width, bottom);

sb.Dispose();
}
}
}
catch (Exception ex)
{
MessageBox.Show("An error occurred. Maybe no YV12 decoder available, installing XviD, DivX or ffdshow might help.\r\n\r\n" +
ex.ToString(), Application.ProductName,
MessageBoxButtons.OK, MessageBoxIcon.Error);
}
}

public Bitmap GetBitmap()
{
return GetBMPFromDib(new IntPtr(
AVIStreamGetFrame(FrameObject, Position)));
}

public Bitmap GetBMPFromDib(IntPtr pDIB) {
IntPtr pPix = new IntPtr(pDIB.ToInt32() + Marshal.SizeOf(typeof(BITMAPINFOHEADER)));

MethodInfo mi = typeof(Bitmap).GetMethod("FromGDIplus",
BindingFlags.Static | BindingFlags.NonPublic);

IntPtr pBmp = IntPtr.Zero;
int status = GdipCreateBitmapFromGdiDib(pDIB, pPix, ref pBmp);

return (Bitmap)mi.Invoke(null, new object[] {pBmp});
}

[DllImport("gdi32.dll", ExactSpelling=true)]
static extern bool DeleteObject( IntPtr obj );

[DllImport("gdiplus.dll", ExactSpelling=true)]
static extern int GdipCreateBitmapFromGdiDib( IntPtr bminfo, IntPtr pixdat, ref IntPtr image );

[DllImport("gdiplus.dll", ExactSpelling=true)]
static extern int GdipCreateHBITMAPFromBitmap( IntPtr image, out IntPtr hbitmap, int bkg );

[DllImport("gdiplus.dll", ExactSpelling=true)]
static extern int GdipDisposeImage( IntPtr image );

[DllImport("avifil32.dll")]
static extern void AVIFileInit();

[DllImport("avifil32.dll", PreserveSig=true)]
static extern int AVIFileOpen(
ref IntPtr ppfile,
String szFile,
int uMode,
int pclsidHandler);

[DllImport("avifil32.dll")]
static extern int AVIFileGetStream(
IntPtr pfile,
out IntPtr ppavi,
int fccType,
int lParam);

[DllImport("avifil32.dll", PreserveSig=true)]
static extern int AVIStreamStart(int pavi);

[DllImport("avifil32.dll", PreserveSig=true)]
static extern int AVIStreamLength(int pavi);

[DllImport("avifil32.dll")]
static extern int AVIStreamInfo(
int pAVIStream,
ref AVISTREAMINFO psi,
int lSize);

[DllImport("avifil32.dll")]
static extern IntPtr AVIStreamGetFrameOpen(
IntPtr pAVIStream,
int lpbiWanted);

[DllImport("avifil32.dll")]
static extern int AVIStreamGetFrame(IntPtr pGetFrameObj, int lPos);

[DllImport("avifil32.dll")]
static extern int AVIFileCreateStream(
int pfile,
out IntPtr ppavi,
ref AVISTREAMINFO ptr_streaminfo);

[DllImport("avifil32.dll")]
static extern int AVIStreamGetFrameClose(
IntPtr pGetFrameObj);

[DllImport("avifil32.dll")]
static extern int AVIStreamRelease(IntPtr aviStream);

[DllImport("avifil32.dll")]
static extern int AVIFileRelease(IntPtr pfile);

[DllImport("avifil32.dll")]
static extern void AVIFileExit();

[StructLayout(LayoutKind.Sequential, Pack=1)]
struct RECT {
public UInt32 left;
public UInt32 top;
public UInt32 right;
public UInt32 bottom;
}

[StructLayout(LayoutKind.Sequential, CharSet=CharSet.Ansi, Pack=1)]
struct BITMAPFILEHEADER {
[MarshalAs( UnmanagedType.ByValArray, SizeConst=2)]
public Char[] Type;
public Int32 Size;
public Int16 reserved1;
public Int16 reserved2;
public Int32 OffBits;
}

[StructLayout(LayoutKind.Sequential, Pack=1)]
struct BITMAPINFOHEADER {
public UInt32 biSize;
public Int32 biWidth;
public Int32 biHeight;
public Int16 biPlanes;
public Int16 biBitCount;
public UInt32 biCompression;
public UInt32 biSizeImage;
public Int32 biXPelsPerMeter;
public Int32 biYPelsPerMeter;
public UInt32 biClrUsed;
public UInt32 biClrImportant;
}

[StructLayout(LayoutKind.Sequential, Pack=1)]
struct AVISTREAMINFO {
public UInt32 fccType;
public UInt32 fccHandler;
public UInt32 dwFlags;
public UInt32 dwCaps;
public UInt16 wPriority;
public UInt16 wLanguage;
public UInt32 dwScale;
public UInt32 dwRate;
public UInt32 dwStart;
public UInt32 dwLength;
public UInt32 dwInitialFrames;
public UInt32 dwSuggestedBufferSize;
public UInt32 dwQuality;
public UInt32 dwSampleSize;
public RECT rcFrame;
public UInt32 dwEditCount;
public UInt32 dwFormatChangeCount;
[MarshalAs(UnmanagedType.ByValArray, SizeConst=64)]
public UInt16[] szName;
}
}
}

berrinam
14th June 2005, 08:35
@stax: I understand what you mean. What about autocropping? Have you got any code that does that quickly?

Doom9
14th June 2005, 08:36
about safe/unsafe: I guess when you start using IntPtr it's essentually unsafe.. but basically I was concerned with having to use the unsafe flag for compilation and mark sections as unsafe. IntPtr, from my perspective, is basically a safe pointer and you don't have to worry about cleaning up the memory (that's my main gripe with unmanaged languages.. memory management.. ).

and I can do two passes with x264.exe just fine (that's one of the few things I actually tested in this build.. keep in mind it's alpha code)

berrinam
14th June 2005, 08:44
So where does that leave the whole situation with cropping, then? And how important is speeding up of cropping?

Doom9
14th June 2005, 10:19
So where does that leave the whole situation with cropping, then?I can't execute the code now, but it's pretty much what I was trying to describe. So if it works as it should we're good in that department. The autocrop you mentioned you had written in that style will also come in handy. As far as importance is concerned.. nobody has complained so far, and I think the performance bottleneck should be eliminated with your code and you can move to the next item on my list :)

Does MP4Box show progress? Yes it does. If you look at the mp4muxer class you see I'm already reading it.. I'm just not sending any statusupdates. My problem was that at some point during import. mp4box seems to run off, no longer waiting for me to read from stdout. So to reliably figure out when the next stream is being imported, you'll probably have to compare percentage values.

And as far as avi muxing is concerned, just use mencoder.. it can just mux a single stream, but supports cbr/vbr mp3 and AC3. I think that'll do just fine for now.

Does MeGUI really use the wrong parameter "i8x8mv" which really should be "i8x8"?Yes it does.. sorry about that. So before encoding, close MeGUI, open the xml files in question and edit the commandline, save them, restart MeGUI and start the jobs in the queue.

stax76
14th June 2005, 14:15
What about autocropping? Have you got any code that does that quickly?


I'm always tying to get with simple solutions therefore I'm parsing the output file of the auto crop AviSynth filter, I was always very satisfied with this method, needless to say it was a easy to implement it. If you like to you can write this in managed code but there is already managed code for this simply because C++ code can be compiled to IL. It's called managed extensions and the greatly improved successor is called C++/CLR. It's absolutely great for almost all interop tasks, more productive, more flexible and a lot easier as you only have to incude header files and it performs as well faster as normal interop, I use C++/CLR extensively in Stax DVB and for other projects. Besides that you have of course always a couple of other interop options like COM interop and P/Invoke.

Doom9
14th June 2005, 16:39
well.. I looked at DVX before doing my autocrop.. and ended up looking at GKnot for a "do it on your own solution". But if berrinam rewrote my autocrop based on the methods used in the preview cropping, it's going to be a lot faster than the current method (that still iterates over the image and does getPixel).

xtknight
14th June 2005, 19:20
sorry ignore this...my f**k up...

I can't get it to work in general...the log didn't show all the info so I replicated the same command in the command line.

Command line:

C:\Documents and Settings\unknown>"C:\tools\megui\mencoder.exe" "c:\mydocbackup\May 18-Channel 67 (7 19 pm) 001--mpeg2dec.avs" -ovc lavc -lavcopts vbitrate=80
-o "C:\Documents and Settings\unknown\Desktop\test.m4v" -of rawvideo
MEncoder dev-CVS-050524-19:49-3.4.2 (C) 2000-2005 MPlayer Team
CPU: Advanced Micro Devices (Family: 8, Stepping: 0)
Detected cache-line size is 64 bytes
CPUflags: Type: 8 MMX: 1 MMX2: 1 3DNow: 1 3DNow2: 1 SSE: 0 SSE2: 0
Compiled for x86 CPU with extensions: MMX MMX2 3DNow 3DNowEx SSE SSE2

85 audio & 199 video codecs
File not found: 'frameno.avi'
Failed to open frameno.avi
success: format: 0 data: 0x0 - 0x89
============ Sorry, this file format is not recognized/supported =============
=== If this file is an AVI, ASF or MPEG stream, please contact the author! ===
Cannot open demuxer.

Exiting...

AviSynth script:

MPEG2Source("C:\Documents and Settings\unknown\My Documents\May 18-Channel 67 (7 19 pm) 001.mpg")

This is understandable...it's an AviSynth script (it exists)...but why does your program import an AviSynth script when mencoder doesn't support it? Maybe it's just me? I've used mencoder with mpg files just fine. Never used vob/ifo files, etc...never recoded a DVD. I don't have any DVDs...I'm just trying to recode a TV show that was recorded in high bit-rate MPEG-2. Also any idea why mencoder doesn't recognize SSE/SSE2 in my Athlon64? Do I have to specify it manually some how? I'm asking all this now because I need to have a way to run MP4Box successfully from your program and fix the progress thing...

Doom9
14th June 2005, 19:35
If I can load the AviSynth script (e.g. you get a working preview window), then I have to assume it can be read. But, do you get that? You should see the video in the preview.. the thing is.. AviSynth displays a short video with the error if there's an internal error that isn't fatal. MPEG2Source expects a DGIndex project file though..

I'm afraid that's how it work.. if the AviSynth scrip can be opened with the AviFile API it is up to the user to decide if what he sees in the preview makes sense, and if it doesn't, fix it.

Create a dgindex project from your mpg file and load that via mpeg2source and everything should be okay.
Also any idea why mencoder doesn't recognize SSE/SSE2 in my Athlon64?That's normal.. it never has and never will. You'll find me asking the same thing in this very forum (not the same thread though I think).

xtknight
14th June 2005, 19:52
If I can load the AviSynth script (e.g. you get a working preview window), then I have to assume it can be read. But, do you get that? You should see the video in the preview.. the thing is.. AviSynth displays a short video with the error if there's an internal error that isn't fatal. MPEG2Source expects a DGIndex project file though..

I'm afraid that's how it work.. if the AviSynth scrip can be opened with the AviFile API it is up to the user to decide if what he sees in the preview makes sense, and if it doesn't, fix it.

Create a dgindex project from your mpg file and load that via mpeg2source and everything should be okay.
That's normal.. it never has and never will. You'll find me asking the same thing in this very forum (not the same thread though I think).

Well I fixed one careless mistake...turns out that MPEG2 file in the avs file didn't exist since I reinstalled Windows and moved the documents dir...so I changed that...

Yeah it wasn't showing in the preview. So now I use DirectShowSource and it works just fine.

Now the audio and video encode fine but I can't get MP4Box to run from the queue...nothing is logged in regard to MP4Box.

A command line like this worked for me:

C:\tools\megui>mp4box -add "C:\Documents and Settings\unknown\Desktop\may31rawaudio.mp4" -add "C:\Documents and Settings\unknown\Desktop\may31raw.m4v" -new "C:\Documents and Settings\unknown\Desktop\may31.mp4"

IsoMedia import - track ID 1 - Audio (SR 48000 - 2 channels) - SBR AAC
IsoMedia import - track ID 2 - media type odsm sub-type MPEG
IsoMedia import - track ID 3 - media type sdsm sub-type MPEG
MPEG-4 Video import - 720 x 480 @ 25.0000 FPS
Indicated Profile: Simple Profile @ Level 3
Import results: 500 VOPs (14 Is - 486 Ps)
Converting to ISMA Audio-Video MP4 file...
Saving may31.mp4: 0.500 secs Interleaving

Then after all that I can't play the file but I guess that's a separate issue. :confused: Also, should the FPS stay at 29.97 for NTSC video? Do I need to add fps=29.97 at the end of my DirectShowSource command?

Alright now the audio plays with mplayerc and video plays with Moonlight player...

Doom9
14th June 2005, 20:04
[quote]Do I need to add fps=29.97 at the end of my DirectShowSource command? I strongly suggest that.. it may work without but it's safer to specify it. And you also need to add -fps 29.97 before the -new in your mp4box commandline.. else you end up with 25fps video as you may have noticed.

As for playback, there are plenty of good tips in this and the container forum. Basically get the latest ffdshow and haali spliter (or ffdshow + install Nero).

As far as running mp4box goes.. you have the source ;) And if you're trying the alpha.. it might just be one of the million things that I broke since the latest stable release. I have the new version started for the first time now.. it's going to be a long while until everything works as it's supposed to.

xtknight
14th June 2005, 20:13
New windows installation so that's why I didn't have those codecs so thanks...I got it working now...plays fine and everything. It also muxes fine with the -fps 29.97.

IsoMedia import - track ID 1 - Audio (SR 48000 - 2 channels) - SBR AAC
IsoMedia import - track ID 2 - media type odsm sub-type MPEG
IsoMedia import - track ID 3 - media type sdsm sub-type MPEG
MPEG-4 Video import - 720 x 480 @ 29.9700 FPS

Last question-why is there 2 MPEG video tracks? I'm only giving it one raw input video file (just like your program would). Is one of them not video but extra information (like MPEG-21 or something)?

The thing is, I'm using your latest stable release (I believe), and MP4Box doesn't run with either that release (0.1914) or that latest dev release. I guess it's debugging time for me.

Doom9
14th June 2005, 20:20
well.. if you run mp4box -info (or something like that that works) on your audio .mp4 you'll see where those additional tracks come from. I don't particularly care why they are there.. but they are. If you care.. you'll find the answer somewhere in this forum.

xtknight
14th June 2005, 21:48
This has stumped me. Here is every line printed from stdout to the VS console (... as a placeholder):

MPEG-4 Video import - 720 x 480 @ 29.9700 FPS
Indicated Profile: Simple Profile @ Level 1
Importing: | | (01/100)
Importing: | | (02/100)
..........................................
Importing: |================== | (9The thread '<No Name>' (0xbbc) has exited with code 0 (0x0).
2/100)
Importing: |================== | (93/100)
Importing: |================== | (94/100)
..........................................
Importing: |=================== | (99/100)

Import results: 500 VOPs (24 Is - 476 Ps)
Converting to ISMA Audio-Video MP4 file...
Saving test6.mp4: 0.500 secs Interleaving
Writing: | | (01/100)
Writing: | | (02/100)
Writing: | | (03/100)
Writing: | | (04/100)
Writing: |= | (05/100)
Writing: |= | (06/100)
Writing: |= | (07/100)
Writing: |= | (08/100)
Writing: |= | (09/100)
Writing: |== | (10/100)
Writing: |== | (11/100)
Writing: |== | (12/100)
Writing: |== The thread '<No Name>' (0xbf8) has exited with code 0 (0x0).
| (13/100)

I noticed threads exiting between the progress indicators. And at the last one, a thread exited and the progress indicator stopped indefinitely. The interesting thing is the stderr reader thread is never aborted manually yet it ends abruptly for some reason. Maybe because of an exception...but why would there be an exception reading stderr when there's clearly output?

Doom9
14th June 2005, 22:14
@berrinam: could you post the autocrop code as well?

@xtknight: I think by now I've catched pretty much all the stdout/read error messages.. if you look at Encoder.cs you'll see I use a lot of try/catch.. so the only time such a thread would exit is if the process has ended.. you can easily verify that by placing breakpoints.

xtknight
15th June 2005, 00:23
@berrinam: could you post the autocrop code as well?

@xtknight: I think by now I've catched pretty much all the stdout/read error messages.. if you look at Encoder.cs you'll see I use a lot of try/catch.. so the only time such a thread would exit is if the process has ended.. you can easily verify that by placing breakpoints.

And that's exactly why I'm confused...there are no exceptions...

Unfortunately stuff like this happens in real time so breakpoints just don't work very well. The breakpoints won't stop the muxer so I can't see where its erroring...

So what I've decided to do is make a separate program to demonstrate the functionality, for two reasons:

1. MeGUI overwhelms me and it's hard to debug in such a big environment, especially having not wrote the program in the first place.

2. It's isolated and I can spend more time coding and less time browsing for my media files in the GUI itself to test it...

I hope you don't mind.

Update: Well what I think happening is the process exiting before the program has a chance to get the stdout...but I have no idea how to fix that. With the stdout redirect in DOS (>) I can get all of the messages from MP4Box, but in C# it just isn't getting the messages. If there's no other way to get the full stdout in C#, you could just open the file stdout-redirected to by DOS, and constantly read that in. Not that best way to do it though...well I hope I saved you some time anyway. If you want me to read progress using the DOS-outputed stdout, let me know. I wish there was a way to delay the process from exiting so it could get all the stdout. That would be ideal. Like I said there are no exceptions being thrown.

Doom9
15th June 2005, 07:25
Update: Well what I think happening is the process exiting before the program has a chance to get the stdout...uh, did you combine the output of multiple processes? there is a way to read everything from stdout.. process.ReadToEnd (or something similar.. I'm not in the IDE right now)

As I said previously, mp4box "running away" was what made me stop working on this.. but as it only runs away while writing the final output file.. it might not be terribly nice to have a progress bar that doesn't run linearly, but basically you could still use it for the importing.. I was thinking of having some indicator in the status update telling people "importing video", "importing audio1", "importing audio2", "importing subtitle1", .. "writing output", "splitting output", and each starts at 0%. The "running away" only seems to be happening in the last step.. so you can work around this by just not bothering with the progress in the last step, but rather use ideas from previous versiont that used mp4box, and simply have a thread that reads the output filesize and calculates the completion percentage from what you think the size should be and what it is.. it's not terribly accurate but it'll do just fine.

I never said it was straightforward.. why do you think I put it on hold? I even asked in the mp4box forum why mp4box acts the way it does : http://sourceforge.net/forum/forum.php?thread_id=1272493&forum_id=287547. No reply in almost 2 months.. clearly 3rd party programs using mp4box are no priority for the developers.

If you want me to read progress using the DOS-outputed stdout, let me know.Isn't that supposed to fail? If you have a file open in write mode, other processes cannot access it, can they?

P.S. You are now at the point where I was when I decided I wanted to do less boring things and hoping that the mp4box devs would do something about this behavior.. the challenge is going from this point to a working solution ;)

P.S.2 ) Perhaps I ought to file this behavior as a bug? After all except for the writing stage stdout is blocking.

berrinam
15th June 2005, 11:52
@berrinam: could you post the autocrop code as well?

Sorry about that, here are both pieces of code (now working :p )

Cropping function (changed):
private unsafe void cropImage(ref Bitmap b)
{
BitmapData image = b.LockBits(new Rectangle(0, 0, b.Width, b.Height), ImageLockMode.ReadWrite, PixelFormat.Format24bppRgb);
byte* pointer = (byte*)image.Scan0.ToPointer();
byte* pixel;
int stride = image.Stride;
byte white = (byte) Color.White.R;

pixel = pointer;
int width = b.Width;
int height = b.Height;
int width3 = 3 * width;
int left3 = 3 * left;
int right3 = 3 * right;

int lineGap = stride - width3;
int centerJump = width3 - left3 - right3;
for (int j = 0; j < top; j++)
{
for (int i = 0; i < width3; i++) {
*pixel = white;
pixel++;
}
pixel += lineGap;
}
int heightb = height - bottom;
for (int j = top; j < heightb; j++)
{
for (int i = 0; i < left3; i++) {
*pixel = white;
pixel++;
}
pixel += centerJump;
for (int i = 0; i < right3; i++) {
*pixel = white;
pixel++;
}
pixel += lineGap;
}
for (int j = b.Height-bottom; j < height; j++)
{
for (int i = 0; i < width3; i++)
{
*pixel = white;
pixel++;
}
pixel += lineGap;
}
b.UnlockBits(image);
}


Autocropping function (including a changed isBadPixel(int) function):
private bool isBadPixel(int pixel)
{
int comp = 12632256;
int res = pixel & comp;
return (res != 0);
}
/// <summary>
/// iterates through the lines and columns of the bitmap and checks whether the brightness of each pixel is under a certain threshold (isBadPixel)
/// if enough 'bad pixels' are found, this line is assumed to be an image line. Cropping is done up to the first such line.
/// </summary>
/// <param name="b">the bitmap to be analyzed</param>
/// <returns>struct containing the number of lines to be cropped away from the left, top, right and bottom</returns>
private unsafe CropValues getAutoCropValues(Bitmap b)
{
// When locking the pixels into memory, they are currently being converted from 24bpp to 32bpp. This incurs a small (5%) speed penalty,
// but means that pixel management is easier, because each pixel is a 4-byte int.
BitmapData image = b.LockBits(new Rectangle(0, 0, b.Width, b.Height), ImageLockMode.ReadOnly, PixelFormat.Format32bppArgb);
int* pointer = (int*) image.Scan0.ToPointer();
int* lineBegin, pixel;
int stride = image.Stride / 4;
CropValues retval = new CropValues();
bool lineFound = false;
int badPixelThreshold = 50;
int widthBadPixelThreshold = b.Width / badPixelThreshold;
int heightBadPixelThreshold = b.Height / badPixelThreshold;
int nbBadPixels = 0;

lineBegin = pointer;
for (int i = 0; i < b.Width; i++)
{
pixel = lineBegin;
for (int j = 0; j < b.Height; j++)
{
//if (b.GetPixel(i, j) != prevColor)
//if (isBadPixel(b.GetPixel(i, j)))
if (isBadPixel(*pixel))
nbBadPixels++;
if (nbBadPixels > heightBadPixelThreshold)
{
retval.left = i - 1;
if (retval.left < 0)
retval.left = 0;
if (retval.left % 2 != 0)
retval.left++;
lineFound = true;
break;
}
pixel += stride;
}
nbBadPixels = 0;
if (lineFound)
break;
lineBegin += 1; // 4-byte Argb
}
nbBadPixels = 0;
lineFound = false;
lineBegin = pointer;
for (int i = 0; i < b.Height; i++)
{
pixel = lineBegin;
for (int j = 0; j < b.Width; j++)
{
//if (b.GetPixel(j, i) != prevColor)
//if (isBadPixel(b.GetPixel(j, i)))
if (isBadPixel(*pixel))
nbBadPixels++;
if (nbBadPixels > widthBadPixelThreshold)
{
retval.top = i - 1;
if (retval.top < 0)
retval.top = 0;
if (retval.top % 2 != 0)
retval.top++;
lineFound = true;
break;
}
pixel += 1; // 4-byte Argb
}
nbBadPixels = 0;
if (lineFound)
break;
lineBegin += stride;
}
nbBadPixels = 0;
lineFound = false;
lineBegin = pointer + b.Width - 1;
for (int i = b.Width - 1; i >= 0 ; i--)
{
pixel = lineBegin;
for (int j = 0; j < b.Height; j++)
{
//if (b.GetPixel(i, j) != prevColor)
//if (isBadPixel(b.GetPixel(i, j)))
if (isBadPixel(*pixel))
nbBadPixels++;
if (nbBadPixels > heightBadPixelThreshold)
{
retval.right = b.Width - i;
if (retval.right < 0)
retval.right = 0;
if (retval.right % 2 != 0)
retval.right++;
lineFound = true;
break;
}
pixel += stride;
}
nbBadPixels = 0;
if (lineFound)
break;
lineBegin -= 1; // Backwards across 4-byte Argb
}
nbBadPixels = 0;
lineFound = false;
lineBegin = pointer + stride * (b.Height-1);
for (int i = b.Height - 1; i >= 0 ; i--)
{
pixel = lineBegin;
for (int j = 0; j < b.Width; j++)
{
//if (b.GetPixel(j, i) != prevColor)
//if (isBadPixel(b.GetPixel(j, i)))
if (isBadPixel(*pixel))
nbBadPixels++;
if (nbBadPixels > widthBadPixelThreshold)
{
retval.bottom = b.Height - i;
if (retval.bottom < 0)
retval.bottom = 0;
if (retval.bottom % 2 != 0)
retval.bottom++;
lineFound = true;
break;
}
pixel += 1;// 4-byte Argb
}
nbBadPixels = 0;
if (lineFound)
break;
lineBegin -= stride;
}
return retval;

}


The unsafe autocropping is about 4-8 times faster than before. Unsafe compiling must be allowed, though (Project->MeGUI properties->Build->Allow unsafe code blocks).

Doom9
15th June 2005, 18:26
here are both pieces of codeThanks. I'll integrate them shortly.

I had another idea about the mp4box "running away" problem. We know that this only happens in the last phase (correct me if I'm wrong), so you could rely on stdout for status updates until that last phase, then no longer send out status updates from the thread that reads stdout, but have another thread that reads the filesize and compares it to what you're supposed to get. And if the last step is splitting, since you know how mp4box names the split files, you can compare the size of the split file(s) with the size of the muxed mp4 and send statusupdates based on that).

xtknight
15th June 2005, 21:24
OK Doom9 I sent you a PM with the sample stdout interpreter/progress bar. It can update the status with either importing or writing (the only two I see when I mux video/audio). Enjoy. :D The path for muxing is hard-coded so when you integrate it you'll have to replace that obviously. For testing just specify the correct path for MP4Box and the MP4Box command line in the process.arguments. I don't know what was wrong with the StreamReader code you had but this class I got from CodeProject (http://www.codeproject.com/csharp/LaunchProcess.asp) seemed to do the trick, and it was easy as child's play from there.

On the left of my program's dialog it shows the actual stdout and on the right the interpreted form of it. Above both of those textboxes lies a label and a progress bar which also represent the status.

I also used the getLineType function among others from your program, and they include slight modifications.

Note: that CodeProject article says ReadToEnd() won't work because the status update in the GUI has to be synchronous and realtime with the external process's stdout. My testing seemed to confirm this.

Doom9
15th June 2005, 21:42
Note: that CodeProject article says ReadToEnd() won't work because the status update in the GUI has to be synchronous and realtime with the external process's stdout.correct.. you can use ReadToEnd to get everything until the process exits.. but that method only returns when the process has exited.

Anyway, thanks and I'll look at it once I have the next release ready (hopefully tomorrow.. I have audio and video encoding done.. now working on getting the auto mode to work properly again). and I want to move around profile creation as well.

Doom9
18th June 2005, 18:19
Just letting you know that I've added the sources of the latest published version to the first post.

xtknight
18th June 2005, 19:25
I got ahold of assembler gray-scale code. I'll see if I can get C# to execute it. I have VB.NET code to execute inline assembly so it shouldn't be too hard. ;) It should be fast enough to do gray-sacle in realtime.

Doom9
18th June 2005, 19:35
Uh.. grayscale why? Because of the sample I posted? I'm never using grayscale conversion and your code seems just fine. Better look at one of the other features that are still missing.

xtknight
18th June 2005, 20:19
Uh.. grayscale why? Because of the sample I posted? I'm never using grayscale conversion and your code seems just fine. Better look at one of the other features that are still missing.

oh...ok...I just happened to stumble across grayscale ASM code by mistake. This code generally just multiplies each R,G,B pixel by a factor. So technically it could be used for whatever you were intending ("marking" pixels?) I never knew what you were trying to do but if the code you have is fast enough already I guess there's no need.

Doom9
18th June 2005, 21:37
mixing managed code with Assembly? that must be real ugly.

Anyway, I finally integrated your code and it really speeds things up. And as you can see I'm already working on some other stuff but I still could use some help with other items.

xtknight
19th June 2005, 00:41
mixing managed code with Assembly? that must be real ugly.

Properly written assembler isn't any worse than unmanaged C++. It's not exactly a 'fashion statement', though. :P

Anyway, I finally integrated your code and it really speeds things up. And as you can see I'm already working on some other stuff but I still could use some help with other items.

Give credit to berrinam, he wrote that code, not me. :)

berrinam
19th June 2005, 02:47
D2V Creator: tracks selected for demux should be filled in as audio source in the main GUI and from there to the muxing window in auto mode (so that the language is pre-selected)
Any idea as to how to find the filename of the demuxed audio? It seems that all of the filename can be worked out from the Stream Information except for the bitrate of the audio. Should I just look for standard bitrates (448kbps, 384kbps, etc) or is there some way to get DGIndex to print the filenames to stdout?

Doom9
19th June 2005, 02:55
It calls the files as follows:

projectname <audio format> <track> <channel_format> <bitrate>bps DELAY <delay>ms.extension

basically track is important (T01, T02, T03). So, I'd do a directory lookup (Directory.something) to get files that contain the track identifier and project name.. I think that should get you enough info to find the actual file.

xtknight
19th June 2005, 04:32
I don't completely understand what you want with the languages thing. I've never worked with DVDs before but I do have a full list of every DVD language if you want it. From what I could tell from your to-do list you already have a language selection (because you said instead of checkboxes)? What is the language used for? .ifo files? What do I do once I know what language the user has chosen?

Did you get around to thoroughly testing the MP4Box progress bar? I just don't know what to do with the subtitles you sent me...I'm real inexperienced with DVDs. I understand what vob,ifo files are I just don't know what's in the ifo files and where/how subtitles are stored. I read the doom9 dvd newbie guide on it but it didn't really explain the subtitles for me.

And yet another one: the x264cli encoder should get the video bitrate (encoder tells you at the end), and from that derive the mp4 overhead and save it to the mp4stats file (and since direct mp4 output is now possible, I guess the mp4stats in the mp4 muxer will have to be adapted to take mp4 video input into account).

So, currently, x264.exe does not get the bitrate when it's called from your app? Just a quick question: what's CLI mean?

Hey, BTW I love the new interface on the latest MeGUI!

berrinam
19th June 2005, 08:27
Can more than 2 audio tracks be put into mp4? Is there a reason that MeGUI limits it to two?

I'm asking because I want to know what should happen when the user chooses more than two audio tracks -- which ones get put into the inputs?

Also, about zones in the new interface: it doesn't seem very practical. Where do you get the frame numbers from for the zones? I would presume from the avspreview window. But this is inaccessible while the zones window is open. Also, setting credit start doesn't appear to be adding a zone at the end.

Doom9
19th June 2005, 11:05
I don't completely understand what you want with the languages thing. I've never worked with DVDs before but I do have a full list of every DVD language if you want it. From what I could tell from your to-do list you already have a language selection (because you said instead of checkboxes)? What is the language used for? .ifo files? What do I do once I know what language the user has chosen?Alright.. if you go to the settings, you'll find two empty language dropdowns. I will fill them in the next release. Based on that info, in the d2v creator, once you've parsed the info file, you can auto check the tracks that match the prfered language from the settings.
Then once you have created the dgindex project and close the window, the two audio tracks (if they match the languages from the preferences take those two, if there's only one match, take that and the first "other".. if there's no match take the first two, or if it's only one you only take one) and plug them into the audioFiles array in the main GUI.

Did you get around to thoroughly testing the MP4Box progress bar? I just don't know what to do with the subtitles you sent me...I'm real inexperienced with DVDs. I understand what vob,ifo files are I just don't know what's in the ifo files and where/how subtitles are stored. I read the doom9 dvd newbie guide on it but it didn't really explain the subtitles for me.Here's how to mux 2 audio tracks and 3 subs and chapters into an mp4:

mp4box -add video.264 -add audio1.mp4;lang=eng -add audio2.mp4;lang=ger -add subtitle1.srt;lang=eng -add subtitle2.srt;lang=ger -add subtitle3.srt;lang=fre -chap chapters.txt -spf 23.976 -new output.mp4

And no, I haven't gotten around to testing it.

Can more than 2 audio tracks be put into mp4? Is there a reason that MeGUI limits it to two?There is no limit. However, there is a limit in a practical sense.. most people watch movies in one lanugage. If it's a foreign language move they may at times want an additional track but 3 or more tracks are simply not practical.. most people don't speak as many languages. This also corresponds with how most other programs handle things and a poll on the AutoGK site on the subject. While I've now basically rewritten the audio selection code to be as flexible as the subtitle code (thus it wouldn't be a big issue to add a track, I'm just not sure about the bitrate updates), I will not do that.

But this is inaccessible while the zones window is open. Wait and you'll see.. I'm already working on it and I'm sure people will like the way it is done. Naturally it won't be the regular preview window but one you have to open from the codec configuration window.

Also, setting credit start doesn't appear to be adding a zone at the end.It does.. just not at the point you'd think. Because I don't want to put a zone into each codec configuration I only add it at the very end when you're queueing the job. There is a basic conflict between zones and credits though.. do you show it when you enter the configuration dialog? what to do if the configuration dialog is never entered, what to do if the codec is changed (remove it in the previous codec, or leave it). So I was thinking about the following: credits (and intro in the future) will not be shown in the configuration and once a job is created, if the credits zone intersects with an existing one, the credits zone has been configured manually and thus won't do anything.. if the credits zone would be the last one it would be added. There are of course a few alternatives.. I'm not a 100% sure which would be the best one. There's also the question about profiles and zones.. right now they are saved because they're part of the settings.. but does that make sense or should zones be removed if something is saved as a profile?

Doom9
19th June 2005, 13:35
I've added a few design studies for some of the features on the todo list.

Doom9
19th June 2005, 23:07
So, currently, x264.exe does not get the bitrate when it's called from your app? Just a quick question: what's CLI mean?
cli = commandline interface, and of course I send the bitrate to x264.exe. But at the end of encoding, x264.exe shows the following line (amongst others):

encoded 43 frames, 22.02 fps, 1095.94 kb/s

from that you can get the actual video bitrate (without container overhead) and put into the log (you can also get the container overhead from this of course... ). mencoder writes something similar. It's really no big deal, just a little commandline parsing.

If you're working on the d2v creator, make sure you use the latest sources.. the language selections in the settings can finally be made.

berrinam
19th June 2005, 23:10
If you're working on the d2v creator, make sure you use the latest sources.. the language selections in the settings can finally be made.

Will do.

Doom9
19th June 2005, 23:18
and there's another one if you're already working on that class.. run dgindex minimized.. the solution can be either found in the development forum or the avi.net thread.. I'm a participant in both discussions. Or perhaps it's in the old megui thread. Either way the solution is aready around, and it's a real easy fix

LigH
20th June 2005, 08:30
In case someone did not yet notice: Microsofts default Windows filters (after a fresh install) don't convert YV12 in general, planar video formats are rather unusual. But DivX 5 or XviD - once installed - take this job, and I even got some ATI codecs some long time ago.

ffdshow's raw video conversion is just another way to go. Who knows how many more filters or codecs can be used as "helpers"...