Welcome to Doom9's Forum, THE in-place to be for everyone interested in DVD conversion. Before you start posting please read the forum rules. By posting to this forum you agree to abide by the rules. |
11th June 2005, 14:28 | #1 | Link |
clueless n00b
Join Date: Oct 2001
Location: somewhere over the rainbow
Posts: 10,579
|
MeGUI development
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
You can get the source code from Sourceforge And here is the current TODO list
__________________
For the web's most comprehensive collection of DVD backup guides go to www.doom9.org |
12th June 2005, 04:51 | #2 | Link |
Registered User
Join Date: Oct 2001
Location: Melbourne, Australia
Posts: 2,171
|
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. |
12th June 2005, 07:28 | #3 | Link |
Registered User
Join Date: Apr 2005
Posts: 1,740
|
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. |
12th June 2005, 13:37 | #4 | Link | |
clueless n00b
Join Date: Oct 2001
Location: somewhere over the rainbow
Posts: 10,579
|
@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.
Quote:
__________________
For the web's most comprehensive collection of DVD backup guides go to www.doom9.org |
|
12th June 2005, 19:20 | #6 | Link |
clueless n00b
Join Date: Oct 2001
Location: somewhere over the rainbow
Posts: 10,579
|
since I'm apparently struck by blindness.. what's the option and default value?
__________________
For the web's most comprehensive collection of DVD backup guides go to www.doom9.org |
13th June 2005, 02:38 | #8 | Link | |
Registered User
Join Date: May 2005
Posts: 33
|
Quote:
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 Last edited by xtknight; 13th June 2005 at 03:21. |
|
13th June 2005, 08:23 | #9 | Link | |
clueless n00b
Join Date: Oct 2001
Location: somewhere over the rainbow
Posts: 10,579
|
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. Quote:
__________________
For the web's most comprehensive collection of DVD backup guides go to www.doom9.org |
|
13th June 2005, 09:39 | #10 | Link |
Registered User
Join Date: Apr 2005
Posts: 1,740
|
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? |
13th June 2005, 09:58 | #11 | Link |
clueless n00b
Join Date: Oct 2001
Location: somewhere over the rainbow
Posts: 10,579
|
@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.
|
13th June 2005, 23:07 | #12 | Link |
Registered User
Join Date: May 2005
Posts: 33
|
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: PHP Code:
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? Last edited by xtknight; 14th June 2005 at 01:42. |
14th June 2005, 02:56 | #13 | Link |
Registered User
Join Date: Apr 2005
Posts: 1,740
|
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.
Code:
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); } |
14th June 2005, 07:00 | #14 | Link |
Registered User
Join Date: Jun 2002
Location: On thin ice
Posts: 6,837
|
you don't have to manipulate images unless you are having fun with it . 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
Code:
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; } } }
__________________
https://github.com/stax76/software-list https://www.youtube.com/@stax76/playlists |
14th June 2005, 08:36 | #16 | Link |
clueless n00b
Join Date: Oct 2001
Location: somewhere over the rainbow
Posts: 10,579
|
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)
__________________
For the web's most comprehensive collection of DVD backup guides go to www.doom9.org |
14th June 2005, 10:19 | #18 | Link | |||
clueless n00b
Join Date: Oct 2001
Location: somewhere over the rainbow
Posts: 10,579
|
Quote:
Quote:
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. Quote:
__________________
For the web's most comprehensive collection of DVD backup guides go to www.doom9.org |
|||
14th June 2005, 14:15 | #19 | Link | |
Registered User
Join Date: Jun 2002
Location: On thin ice
Posts: 6,837
|
Quote:
__________________
https://github.com/stax76/software-list https://www.youtube.com/@stax76/playlists |
|
14th June 2005, 16:39 | #20 | Link |
clueless n00b
Join Date: Oct 2001
Location: somewhere over the rainbow
Posts: 10,579
|
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).
__________________
For the web's most comprehensive collection of DVD backup guides go to www.doom9.org |
Tags |
development, megui, not a help thread |
|
|