MPEG-4 Support for kernel mode driver

Hi:
I am writing a AVSTREAM driver for a video camera which generate MPEG-4 data.

When I connect my filter to DirectShow Mpeg4s Decoder DMO in GrahpEdit, error code

0x80040217 was returned.

I tried to write a Win32 application to make the connection.

The AM_MEDIA_TYPE support by my source output pin can be accepted by the decoder,
IPin::QueryAccept(…) == S_OK

but both IGraphBuilder::Connect and IGraphBuilder::ConnectDirect failed. (0x80040217)

I have studied the DirectShow 9.0 document = “How Filters Connect”, and make some changes in my driver, but still failed.

I am sure that my driver works perfectly with MJPEG foramt.

What’s the mystery of MPEG-4 in kernel mode driver?

I can render a ASF file(M4S2) with ASF reader filer and Mpeg4s decoder DMO in GraphEdit, so I guess the system did support the correct MPEG-4 decoder codec.

Please help to give me some direction.

Here is the part of my code

#define D_X 704
#define D_Y 576
#define MAX_FR 30
#define MIN_FR 1
#define AVG_FR 30
const
KS_DATARANGE_VIDEO_M4S2
VF_M4S2_320_240 =
{
//KSDATARANGE
{
sizeof(KS_DATARANGE_VIDEO2) + VFCP_DATARANGE_EXTENSION_SIZE, //FormatSize
0, //Flags
0, //SampleSize
0, //Reserved
STATIC_KSDATAFORMAT_TYPE_VIDEO, //MajorFormat,
0x3253344D, 0x0000, 0x0010, 0x80, 0x00, 0x00, 0xaa, 0x00, 0x38, 0x9b, 0x71, //SubFormat M4S2
STATIC_KSDATAFORMAT_SPECIFIER_VIDEOINFO2 //Specifier
},
FALSE, //bFixedSizeSamples
TRUE, //bTemporalCompression,
0, //StreamDescriptionFlags
0, //MemoryAllocationFlags
//KS_VIDEO_STREAM_CONFIG_CAPS
{
STATIC_KSDATAFORMAT_SPECIFIER_VIDEOINFO2,
KS_AnalogVideo_None,
D_X, D_Y,
D_X, D_Y,
D_X, D_Y,
1,
1,
1,
1,
D_X, D_Y,
D_X, D_Y,
1,
1,
0,
0,
0,
0,
10000000 / MAX_FR,
10000000 / MIN_FR,
MIN_FR * 24 * D_X * D_Y,
MAX_FR * 24 * D_X * D_Y
},
//KS_VIDEOINFOHEADER2
{
0, 0, D_X, D_Y, //rcSource
0, 0, D_X, D_Y, //rcTarget
0, //dwBitRate
0, //dwBitErrorRate
10000000 / AVG_FR, //AvgTimePerFrame
0, //InterlacedFlags
0, //CopyProtectFlags
D_X, //PicAspectRatioX
D_Y, //PicAspectRatioY
0, //ControlFlags
0, //Reserved2
sizeof(KS_BITMAPINFOHEADER) + VFCP_DATARANGE_EXTENSION_SIZE, //biSize
D_X, //biWidth
D_Y, //biHeight
1, //biPlanes
24, //biBitCount
FOURCC_M4S2, //biCompression
D_X * D_Y * 3, //biSizeImage
0, //biXPelsPerMeter
0, //biYPelsPerMeter
0, //biClrUsed
0 //biClrImportant
},

const
PKSDATARANGE
VFCPDataRanges[1] =
{
(PKSDATARANGE) &VF_M4S2_704_576
}

DECLARE_SIMPLE_FRAMING_EX(VFCPAllocatorFraming,
STATICGUIDOF(KSMEMORY_TYPE_KERNEL_NONPAGED),
KSALLOCATOR_REQUIREMENTF_SYSTEM_MEMORY | KSALLOCATOR_REQUIREMENTF_PREFERENCES_ONLY,
10, //Frames
0, //Alignment
704*576*3, //MinFrameSize
704*576*3); //MaxFrameSize

xxxxx@msn.com wrote:

I am writing a AVSTREAM driver for a video camera which generate MPEG-4 data.

When I connect my filter to DirectShow Mpeg4s Decoder DMO in GrahpEdit, error code
0x80040217 was returned.

There are a number of MPEG 4 video types and decoders. You might try
several of them to see if you get better results. Have you tried
ffdshow_tryouts instead? They have decoders for a wide variety of video
formats. Are you generating H.264 video? You might try using the
fourcc H264 instead.

I am sure that my driver works perfectly with MJPEG foramt.

Yes, it’s a familiar story. I just finished a project where the device
could produce either MJPEG or H264. MJPEG was easy. H264, not so much.


Tim Roberts, xxxxx@probo.com
Providenza & Boekelheide, Inc.

Tim:
Thanks for your reply.

  1. My device generates H.263 video data.
    a. I packed the video data from my device into a ASF file, and it can be played correctly.
    WM ASF Reader => Mpeg4s Decoder DMO => Video Renderer
    b. My problem now is not the video data can’t be decoded. My driver (Filter) can’t connect to the
    Mpeg4s decoder codec.
    c. Of course I can try other decoders, or even I can try to write a decoder and put it into my
    kernel driver. But I am trying to use the default codec(s) supported by Microsoft Windows.
  2. What should I do to “claim” that the output pin of my driver supports MPEG-4 video format?
    a. In Win32, the AM_MEDIA_TYPE my driver supports can be accepted by MPeg4s Decoder.
    (IPin->QueryAccept(…) == S_OK), but failed in IGraphBuilder->Connect(…).
    b. At the moment, only the IntersectionHandler(…) of my driver was called several times, then,
    no other dispatch function was called.
    c. I guess, there is something I need to do to “claim” that my driver supports MPEG-4 format.
    I have checked KS_DATARANGE_VIDEO, KS_ALLOCATOR_FRAMING of my output pin.
    I tried many different parameters in these structures, but still failed.
  3. Is there any limitation for kernel mode driver to support MPEG-4 format?
    There is no MPEG-4 related description in DDK document and sample codes.

Hello Tim:

I have tried ffdshow.
My driver (filter) can connect to “ffdshow Video Decoder”, but not “Mpeg4s Decoder DMO”.
Should I try to use different codec from Microsoft?
Thanks.

Hank.

xxxxx@msn.com wrote:

I have tried ffdshow.
My driver (filter) can connect to “ffdshow Video Decoder”, but not “Mpeg4s Decoder DMO”.
Should I try to use different codec from Microsoft?

No, you should use a codec that works. Perhaps it’s just a philosophy
thing, but I never think of Microsoft as a source for MPEG codecs. To
be honest, until your message I did not realize that Microsoft had
anything to offer in the MPEG-4 arena.

MPEG-4 is complicated. Really complicated. I have seen valid streams
that work in some decoders, but not in others. I would have no qualms
about searching through all of the available codecs until I found the
ones that worked with my stream, and then recommend that.


Tim Roberts, xxxxx@probo.com
Providenza & Boekelheide, Inc.

xxxxx@msn.com wrote:

Thanks for your reply.
2. What should I do to “claim” that the output pin of my driver supports MPEG-4 video format?

You’re doing it.

a. In Win32, the AM_MEDIA_TYPE my driver supports can be accepted by MPeg4s Decoder.
(IPin->QueryAccept(…) == S_OK), but failed in IGraphBuilder->Connect(…).
b. At the moment, only the IntersectionHandler(…) of my driver was called several times, then,
no other dispatch function was called.

Do your IntersectionHandler calls succeed?

  1. Is there any limitation for kernel mode driver to support MPEG-4 format?
    There is no MPEG-4 related description in DDK document and sample codes.

The framework doesn’t care about your format information at all. The
format is just a GUID with no inherent meaning that is used to connect
two pins.


Tim Roberts, xxxxx@probo.com
Providenza & Boekelheide, Inc.

Tim:
The IntersectionHandler(…) calls successed.

I found something interesting.
I use KS_DATARANGE_VIDEO2 to describe my video output pin, and set the pin
specifier to KSDATAFORMAT_SPECIFIER_VIDEOINFO2.
Beside, I appended 31 bytes at the end of the KS_VIDEOINFOHEADER2.

When I used KS Studio to instantiate the output pin, error occured.
"KSDATAFORMAT.FormatSizie (207) does not match … KSDATAFORMAT_SPECIFIER_VIDEOINFO2 specifier (176).
At this time, I write a Win32 application to call decoder’s IPin::QueryAccept(…) with the AM_MEDIA_TYPE retrived from my output pin, it successed.

Then, if I remove these 31 bytes, KS Studio successed to instantiate pin, but QueryAccept(…) failed.

How to add extension to standard data type?

Thanks for your answer.

xxxxx@msn.com wrote:

I found something interesting.
I use KS_DATARANGE_VIDEO2 to describe my video output pin, and set the pin
specifier to KSDATAFORMAT_SPECIFIER_VIDEOINFO2.
Beside, I appended 31 bytes at the end of the KS_VIDEOINFOHEADER2.

When I used KS Studio to instantiate the output pin, error occured.
"KSDATAFORMAT.FormatSizie (207) does not match … KSDATAFORMAT_SPECIFIER_VIDEOINFO2 specifier (176).
At this time, I write a Win32 application to call decoder’s IPin::QueryAccept(…) with the AM_MEDIA_TYPE retrived from my output pin, it successed.

Then, if I remove these 31 bytes, KS Studio successed to instantiate pin, but QueryAccept(…) failed.

How to add extension to standard data type?

Basically, you don’t. If your data type is not one of the standard
structures, then you create a new KSDATAFORMAT_SPECIFIER GUID for it, so
everyone knows what you’re sending. Of course, that means most
downstream filters won’t connect to you.

What are you planning to add to the end of the header, and who do you
expect to consume that information?


Tim Roberts, xxxxx@probo.com
Providenza & Boekelheide, Inc.

Tim:

  1. My device generate MPEG-4 M4S2 data. I need to pass extra information(31 bytes)
    to the decoder, including…visual object sequence information, video object layer information.

  2. I have a ASF file with data stream generated by my device. I wrote a win32 application to
    get AM_MEDIA_TYPE from the “WM ASF Reader” output pin of this ASF file.
    cbFormat is 0x8F (143), not 0x70 (112 == sizeof(KS_VIDEOINFOHEADER2) )

Queried Media Type
majortype :73646976-0000-0010-800000AA00389B71
subtype :3253344D-0000-0010-800000AA00389B71
bFixedSizeSamples : 0x0
bTemporalCompression : 0x0
lSampleSize : 0x1
formattype :F72A76A0-EB0A-11D0-ACE40000C0CC16BA
cbFormat : 0x8F
00 00 00 00 00 00 00 00 40 01 00 00 F0 00 00 00
00 00 00 00 00 00 00 00 40 01 00 00 F0 00 00 00
00 00 00 00 00 00 00 00 15 16 05 00 00 00 00 00
00 00 00 00 00 00 00 00 40 01 00 00 F0 00 00 00
00 00 00 00 00 00 00 00 47 00 00 00 40 01 00 00
F0 00 00 00 01 00 18 00 4D 34 53 32 00 84 03 00
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
00 00 01 B0 03 00 00 01 B5 09 00 00 01 00 00 00
01 20 00 C4 88 BA 98 63 A9 A2 C0 89 02 88 7F

At this time, if I set cbFormat = 112 in the previous AM_MEDIA_TYPE, this type won’t be
accepted by the decoder (Mpeg4s Decoder DMO). …IPin::QueryAccept(…)

  1. I tried to use KS_DATAFORMAT_MPEGVIDEOINFO2 instead, since there is a bSequenceHeader
    in it. Still failed when I used KsStudio to instantiate my device (filter) output pin.
    KsStudio told me
    “KSDATAFORMAT FormatSize (227) does not match the size of the specified format
    (sizeof(KSDATAFORMAT) = 64)”

227 == sizeof(KS_DATAFORMAT_MPEGVIDEOINFO2) + 27.
(31 == 27 + sizeof(bSequenceHeader)

Part of my KSDATARANGE:

//KSDATARANGE
{
sizeof(KS_DATARANGE_MPEG2_VIDEO) + 27, //FormatSize
0, //Flags
0, //SampleSize
0, //Reserved
STATIC_KSDATAFORMAT_TYPE_VIDEO, //MajorFormat,
0x3253344D, 0x0000, 0x0010, 0x80, 0x00, 0x00, 0xaa, 0x00, 0x38, 0x9b, 0x71, //SubFormat M4S2
STATIC_KSDATAFORMAT_SPECIFIER_MPEG2_VIDEO //Specifier
},
FALSE, //bFixedSizeSamples
TRUE, //bTemporalCompression,
0, //StreamDescriptionFlags
0, //MemoryAllocationFlags



Thanks.

xxxxx@msn.com wrote:

  1. My device generate MPEG-4 M4S2 data. I need to pass extra information(31 bytes)
    to the decoder, including…visual object sequence information, video object layer information.

Where did your device get this information? Isn’t it already embedded
in the data stream? Why can’t the decoder extract it on its own?

If this is static information that your capture driver acquired from
some other source, then you can make it available through a custom KS
property. That’s the kind of thing properties were designed for.


Tim Roberts, xxxxx@probo.com
Providenza & Boekelheide, Inc.