none
How to use Resizer DMO to resize any video ?

    Question

  • Hi,
    I'm trying to use the Resizer DMO (CLSID_CResizeDMO).
    I want the input video stream to be resized to a dimension larger or smaller than the original dimension.
    (i.e. say the video stream is of 720x480, then i want it to be resized to 320x240 or 800x600)
    For configuring the DMO I'm using the IWMResizerProps interface.
    But m not getting the desired results.
    I have a rendered graph, which I need to modify, to add the Resizer DMO.
    So I disconnect the connection between the WM Decoder DMO and the VMR9 and add the resizer DMO
    between the 2 filters.
    Before connecting the DMO, first I set the input media type with src and target rectangle same as the original dimension,
    then I set the output media type with source and target rectangle set to the desired output dimension.
    And lastly I use the IWMResizerProps.SetFullCropRegion() method.
    Following this method I'm able to resize some WMV HD - 1280x720 dimension files and AVI files to any dimesion smaller than it.
    But it does not resize the video to a dimension larger than its original dimension.
    Also for other files the output pin of the DMO doesn't render to any filter.
    I tried to resize a wmv file of dimension 720x480, the DMO output pin renders neither to VMR9 nor to a default renderer.
    But a file with the same format but having 1280x720 dimension does render.
    When I try to connect the DMO output pin it returns a negative hresult, saying No combination of filters could be found to render the stream.
    This happens even when tried in GraphEdit.
    Why does the Resizer DMO pin connects for some files but not for other?
    Why it does not resize to a larger dimension?
    Is it because the IWMResizerProps.SetFullCropRegion() method just crops the video frame?
    If so how do I properly resize the video using the Resizer DMO?
    Tuesday, June 7, 2011 11:26 AM

Answers

  • Can you give a full picture? Full input media type, your SetFullCropRegion args, and the output type (ok, this one is in the post above).

    The key things here is that you cannot use Connect, Render etc. All of these would internally end up in Connect, which in its turn would call EnumMediaTypes and it will pick a wrong media type (even if MS fixes this now, the problem has already been out there for years).

    So you have to be sure that you are:

    1. using correct media type
    2. using ConnectDirect
    3. using a downstream filter which can immediately, without intermediate filters, accept this media type

    It sounds sort of weird, but it's how a workaround looks like. Behind all that, I think that video resizer as a Media Foundation component was not originally intended to be used as DirectShow fitler and this use case was never tested.


    http://alax.info/blog/tag/directshow
    • Marked as answer by Neha Pawar Friday, August 12, 2011 5:17 AM
    Thursday, June 9, 2011 12:02 PM

All replies

  • Additionally to SetFullCropRegion, set explicitly proper media type on the DMO wrapper output pin - and you'll be fine.

    http://alax.info/blog/tag/directshow
    Tuesday, June 7, 2011 11:53 AM
  • Additionally to SetFullCropRegion, set explicitly proper media type on the DMO wrapper output pin - and you'll be fine.

    http://alax.info/blog/tag/directshow

    By proper media type, do u mean that I need to set media type according to the video being rendered?
    Because the media type I m using works for one .avi file but not for other .avi file.
    For some media files the pins do connect even without configuring the media type of the DMO output pin.
    So why the pins don't connect for other media files using intelligent connect?
    Also I m still not able to resize the video to a dimension larger than its actual dimension.
    What about that?
    Wednesday, June 8, 2011 7:19 AM
  • The DMO and the wrapper will accept a media type on the input, and you will also be able to use IWMResizerProps to request actual resizing.

    However what the DMO does NOT do, is that it does not advertise proper output media type, and so does the wrapper. Whatever your sizing/cropping request is, you will have to build the output media type yourself and do ConnectDirect to connect the output pin with this correct media type.


    http://alax.info/blog/tag/directshow
    Wednesday, June 8, 2011 7:46 AM
  • Hi Roman,
    Thanks for the reply.

    But I m still stuck.
    Now I m configuring the output mediatype correctly.
    Well I suppose so, since objIMediaObject->SetOutputType(0, newMediaType, NULL);
    returns S_OK.
    But still as you suggested, when I try to do ConnectDirect with this media type
    it returns E_FAIL.
    If the DMO output media type is correctly set, then what m I missing now?
    I even tried using Connect() and Render().
    If I render the DMO output pin in GraphEdit an AVI Decampressor and a Color Space Converter
    get added between the Resizer DMO and VMR9.
    So why the pins don't connect using my code?

    I m configuring the media type as below:

    DMO_MEDIA_TYPE newMediaType;
    ZeroMemory(&newMediaType, sizeof(DMO_MEDIA_TYPE));
    newMediaType.majortype = MEDIATYPE_Video;
    newMediaType.subtype = MEDIASUBTYPE_YV12;
         
    if (inputMediaType.formattype == FORMAT_VideoInfo)
    {
     // Set format headers.
     newMediaType.pbFormat = (BYTE*)CoTaskMemAlloc(sizeof(VIDEOINFOHEADER));
     if (newMediaType.pbFormat == NULL)
     {
      return E_OUTOFMEMORY;
     }

     VIDEOINFOHEADER *vInfoHeader1 = (VIDEOINFOHEADER*)(newMediaType.pbFormat);
     ZeroMemory(vInfoHeader1, sizeof(VIDEOINFOHEADER));
     vInfoHeader1->bmiHeader.biWidth = outputVideoWidth;
     vInfoHeader1->bmiHeader.biHeight = outputVideoHeight;
     vInfoHeader1->bmiHeader.biBitCount = 12;
     vInfoHeader1->bmiHeader.biPlanes = 1;
     vInfoHeader1->bmiHeader.biCompression = MAKEFOURCC('Y', 'V', '1', '2');
     vInfoHeader1->bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
     vInfoHeader1->bmiHeader.biSizeImage = vInfoHeader1->bmiHeader.biWidth * vInfoHeader1->bmiHeader.biHeight * 3 / 2;
         
     // Set the format type and size.
     newMediaType.formattype = FORMAT_VideoInfo;
     newMediaType.cbFormat = sizeof(VIDEOINFOHEADER);     
     
     // Set the sample size.
     newMediaType.bFixedSizeSamples = TRUE;
     newMediaType.lSampleSize= vInfoHeader1->bmiHeader.biWidth * vInfoHeader1->bmiHeader.biHeight * 3 / 2;
    }

    Thursday, June 9, 2011 9:54 AM
  • Can you give a full picture? Full input media type, your SetFullCropRegion args, and the output type (ok, this one is in the post above).

    The key things here is that you cannot use Connect, Render etc. All of these would internally end up in Connect, which in its turn would call EnumMediaTypes and it will pick a wrong media type (even if MS fixes this now, the problem has already been out there for years).

    So you have to be sure that you are:

    1. using correct media type
    2. using ConnectDirect
    3. using a downstream filter which can immediately, without intermediate filters, accept this media type

    It sounds sort of weird, but it's how a workaround looks like. Behind all that, I think that video resizer as a Media Foundation component was not originally intended to be used as DirectShow fitler and this use case was never tested.


    http://alax.info/blog/tag/directshow
    • Marked as answer by Neha Pawar Friday, August 12, 2011 5:17 AM
    Thursday, June 9, 2011 12:02 PM
  • Here's the information you asked for:

    The actual graph is:
    source -> WMVideo Decoder DMO -> VMR9
    And I need to change it as:
    source -> WMVideo Decoder DMO -> DMO Resizer -> VMR9

    for the actual graph:
    Source:
    Major Type: Video
    Sub Type: WMV3
    Format: WMV3 1280x720, 24 bits

    WMVideo Decoder DMO:
    Major Type: Video
    Sub Type: NV12
    Format: NV12 1280x720, 12 bits

    Same for VMR9.

    For my graph:
    WMVideo Decoder DMO:
    Major Type: Video
    Sub Type: YV12
    Format: YV12 1280x720, 12 bits

    Resizer DMO:
    Major Type: Video
    Sub Type: YV12
    Format: YV12 1280x720, 12 bits

    SetFullCropRegion(0,0,1280,720,0,0,320,180)
    -----------------------------------------------------------------------

    Well, it seems using Resizer DMO in DirectShow isn't an easy job.
    Even for the files that render and resize successfully, there's another issue.
    The resized video is displayed in the upper left corner, well that I can change by setting the left and top of the target rectangle,
    but the problem is that the remaining window is still of the original dimension.
    When I played a resized AVI file, the video was being displayed in the upper left corner
    and the remaining window is displayed in green color.
    This same issue has been discussed on the forum.
    Any view on that?

    Thursday, June 9, 2011 1:16 PM
  • This is exactly the same issue. With the media type supplied by the DMO by default, smaller video is in the top left corner and larger video does not fit the buffer and just fails. This is the behavior workable around by ConnectDirect.

    http://alax.info/blog/tag/directshow
    Thursday, June 9, 2011 2:05 PM