Menu

How to crop a captured video stream

2015-03-12
2015-03-15
  • Warner Young

    Warner Young - 2015-03-12

    Hi all, I'm trying to crop a camera's video stream from 16x9 ratio to 4x3. From MSDN, it looks like the Color Converter DMO filter should do what I want, using its IWMColorConvProps interface. In my app, I have the camera's output connected to the ColorConverterDMO's input, then I call IWMColorConvProps.SetFullCroppingParam() to set the cropping region I want.

    However, the result on screen is a 16x9 rectangle, with a 4x3 area on the left side containing video signal, and the rest of it is black. When I check any of the filters downstream (my own SampleGrabber, SmartTee, etc.) for the pin media types, it looks like they're all still getting an AMMediaType object with the 16x9 dimensions.

    So the ColorConverterDMO seems to be cropping, but something isn't set properly. Can anyone suggest what might be the problem? Or has anyone had success cropping a video stream correctly?

     
  • snarfle

    snarfle - 2015-03-12

    Well, a couple of thoughts:

    1) Are you setting the size before you connect the downstream filters?
    2) What are the specific parameters you are sending to SetFullCroppingParam?
    3) Where are you getting your c# definition for IWMColorConvProps? Perhaps something is incorrectly defined?

     
  • Warner Young

    Warner Young - 2015-03-13

    Hi Snarfle,

    1) I tried setting the size before AND after, and it makes no difference.

    2) I had to write the C# definition based on the wmcodecdsp.h file. I've done the same thing for some other COM interfaces before, so I think I have a good idea how to do it. Plus, the SetFullCroppingParam() call succeeds (doesn't return error, doesn't cause an exception), and it clearly is doing SOME kind of cropping. Just not the way I want or expect.

    Okay, so it turns out SetFullCroppingParam doesn't work the way I had expected. I wanted something that would (as an example) take a 1920x1080 stream and produce a 1440x1080 video stream, and do it by cropping the left/right sides of the image. It turns out the result depends on what I use for the destCropLeft and destCropTop params. If they're set to 0, I get a 1440x1080 image in the left side of a 1920x1080 frame, with black on the right side. If I set destCropLeft/Top to srcCropLeft/Top, I get a pillarboxed image. Basically, covering up the left and right sides with black, but leaving a 1920x1080 stream.

    So the problem becomes, how do I get this "cropped" image changed so it's truly a 1440x1080 stream, once I have it cropped?

     
  • snarfle

    snarfle - 2015-03-15

    Well, I found some c++ code to do this and turned it into c#. I have extracted the relevant bits and attached it to this message. Note that it uses the Video Resizer DSP instead of the Color Converter.

    Seems to work for me, but you'll need to experiment to be sure it gives you the results you want. Pay particular attention to the spots that work with newwidth and newheight. Unlike the original c++ code, there are lots of comments, so hopefully it's easy to follow what it is doing and why.

    While there might be easier ways, at least this should get you started.

     

Log in to post a comment.