Question

I have a C# application which plays videos using the DirectShowNet library. When I debug my application using Visual C# on my laptop, the video is stretched to fit the container's dimensions i.e. the aspect ratio of the video is not maintained. When I load and run my application on a different computer (same operating system), the aspect ratio is maintained and black bars are created on the screen.

I do not want the aspect ratio to be maintained. I want the other computer to display the video the same way my computer is displaying it.

Why do you think the two computer's act differently and/or how do I fix this?

When I first saw this behaviour on the other computer, I updated that computer's DirectX to no avail. The exact same videos are being run on both systems.

EDIT #1: Could it possibly be some missing filter on the other computer? I assumed the default behaviour of DirectShow was not to maintain the Aspect Ratio.

EDIT #2: When I attempted to use IVMRWindowlessControl (VMR-7 & VMR-9), the cast from the VMR to the IVMRWindowlessControl kept on resulting in a NULL variable. As a result I tried IVMRAspectRatioControl with VMR-7 and it worked on one of the computers. The other computer stayed in Letterbox mode despite the call to remove the Aspect Ratio preservation.

EDIT #3: Here is the code using IVMRAspectRatioControl with VMR-7:

int hr = 0;

this.graphBuilder = (IGraphBuilder)new FilterGraph();

this.vmr = new VideoMixingRenderer();

this.graphBuilder.AddFilter((IBaseFilter)vmr, "VMR");

this.aspectRatioControl = (IVMRAspectRatioControl)this.vmr;

hr = this.aspectRatioControl.SetAspectRatioMode(VMRAspectRatioMode.None);
DsError.ThrowExceptionForHR(hr);

hr = this.graphBuilder.RenderFile(filename, null);
DsError.ThrowExceptionForHR(hr);  

I am then using IVideoWindow to display the video.

When attempting to use the IVMRWindowlessControl9, the this.windowlessControl evaluated to NULL after the cast on the 4th line. I get the same NULL error when I tried it with VMR-7. The following uses VMR-9:

this.graphBuilder = (IGraphBuilder)new FilterGraph();

this.vmr = new VideoMixingRenderer9();

this.graphBuilder.AddFilter((IBaseFilter)vmr, "VMR");

this.filterConfig = (IVMRFilterConfig9)vmr;

hr = this.filterConfig.SetNumberOfStreams(1);
DsError.ThrowExceptionForHR(hr); 
hr = this.filterConfig.SetRenderingMode(VMR9Mode.Windowless);
DsError.ThrowExceptionForHR(hr);  

this.windowlessControl = (IVMRWindowlessControl9)this.vmr;

hr = this.windowlessControl.SetAspectRatioMode(VMR9AspectRatioMode.None);
DsError.ThrowExceptionForHR(hr);

hr = this.graphBuilder.RenderFile(filename, null);
DsError.ThrowExceptionForHR(hr);  

I'm not entirely sure how it works, but could it be possible that the second computer does not support VMR-7 for the IVMRAspectRatioControl? The operating systems on both computers are the same, however the first computer (which works) is where I'm writing the software (it has the IDE). The second computer had a fresh install of Windows. On the second computer, I also updated DirectX as mentioned earlier.

Was it helpful?

Solution

Video renderers can be configured to preserve or not preserve aspect ratio. Configuration method (and, perhaps, default setting, which can also depend on internal mode of the renderer such as overlay/offscreen surface) is dependent on video renderer version you are using, e.g. for VMR-7 you will use IVMRWindowlessControl::SetAspectRatioMode's (or, IVMRAspectRatioControl::SetAspectRatioMode if your VMR is in windowed mode) DirectShow.NET equivalent/wrapper. VMR-9, EVR has similar methods.

With VMR-9 you will use IVMRAspectRatioControl9::SetAspectRatioMode. With EVR it is IMFVideoDisplayControl::SetAspectRatioMode.

If you don't want any letterboxing and aspect ration preservation, you just disable it explicitly when you set the video renderer up.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top