I have a third party source filter which streams MPEG-2. I
am having trouble creating valid output pins in
Microsoft's MPEG2 Demultiplexer. The problem I think has
to do with the AM_MEDIA_TYPE that I pass to the Demux's
CreateOutputPin() method. I am able to create the output
pins successfully in Graph Edit and get the entire filter
graph running successfully. In Graph Edit I just need to
supply a few bits of information; create an MPEG2 Program
Video pin, give it a stream_id (0xC0), set its type to
Elementary Stream (A/V only), leave Filter Value as None
and Data Offset as 0 and hit the map button. The output
pin is then created and I can connect it to the MPEG-2
Decoder then the Renderer. How does Graph Edit get all the
information it needs to create the pins?
In my code I can only get a limited amount of information
about the media type from the source while building the
filter graph. I can get the resolution, bitrate, (PIDs
when transport
stream), stream type (NTSC or PAL) and audio sampling
rate.
I plug the values I know into the AM_MEDIA_TYPE struct and
zero out the rest and then map the output pins using
IMPEG2StreamIdMap interfaces MapStreamID() method for
program streams. However when I go to connect the Demux's
video output pin to the decoder input pin, the connection
fails. Below is how I am trying to instantiate the
AM_MEDIA_TYPE and create the video output pin.
MPEG2VIDEOINFO videoInfo;
memset( &videoInfo, 0, sizeof(videoInfo) );
videoInfo.dwStartTimeCode = 0 ;
videoInfo.cbSequenceHeader = 0 ;
videoInfo.dwProfile = 2; //MPEG2Profile_Main;
videoInfo.dwLevel = 2; //MPEG2Level_Main;
videoInfo.hdr.dwBitRate = 4000000;
videoInfo.hdr.AvgTimePerFrame = 333000;
videoInfo.hdr.dwInterlaceFlags = AMINTERLACE_IsInterlaced
| AMINTERLACE_FieldPatBothRegular |
AMINTERLACE_DisplayModeBobOrWeave;
videoInfo.hdr.dwPictAspectRatioX = 4;
videoInfo.hdr.dwPictAspectRatioY = 3;
videoInfo.hdr.dwReserved1 = 0;
videoInfo.hdr.dwReserved2 = 0;
videoInfo.hdr.bmiHeader.biHeight = 720;
videoInfo.hdr.bmiHeader.biWidth = 480;
AM_MEDIA_TYPE mediaTypeVideo;
mediaTypeVideo.majortype = MEDIATYPE_Stream;
mediaTypeVideo.subtype = MEDIASUBTYPE_MPEG2_PROGRAM;
mediaTypeVideo.bFixedSizeSamples = FALSE;
mediaTypeVideo.bTemporalCompression = TRUE;
mediaTypeVideo.lSampleSize = 0;
mediaTypeVideo.formattype = FORMAT_MPEG2Video;
mediaTypeVideo.pUnk = NULL;
mediaTypeVideo.cbFormat = sizeof(MPEG2VIDEOINFO);
mediaTypeVideo.pbFormat = (BYTE*)&videoInfo;
CString sDemuxVideoOut = "Video";
BSTR bstrDemuxVideoOut = sDemuxVideoOut.AllocSysString();
m_pDemuxInterface->CreateOutputPin( &mediaTypeVideo,
bstrDemuxVideoOut, &m_pDemuxVideoPin );
m_pDemuxVideoPin->QueryInterface(IID_IMPEG2StreamIdMap,
(void **)&m_pIMPEG2StreamIdMap);
m_pIMPEG2StreamIdMap->MapStreamId( 0xE0, 0x00000001, 0,
0 );
Since the PIDs are not mapped to output pins in the filter graph, the MPEG2
demux discards all packets it receives. In Transport Stream Mode, there's
two ways to map PIDs to output pins.
1. If the filter graph contains a BDA Network Provider source filter, this
filter will automatically create all the necessary output pins on the Demux
and map the PIDs for each pin.
2. If you are providing a transport stream through a custom filter that is
not based on BDA, then either the filter or the application must do this
work.
You third-party source filter in his filter graph, it'sr application's
responsibility to create output pins and map PIDs to these pins.
IMPEG2PIDMap interface on the output pins is used to map PIDs.
Please visit following topic in MSDN documents:
1. Microsoft TV Technologies Internals
2. Testing TV Hardware and Software with GraphEdit
3. DirectX 8.1 Digital TV Filters
This filter would not implement IMpeg2Demultiplexer if the demultiplexer
is connected in pull mode to the upstream filter. This happens if the
upstream filter's output pin exposes a mpeg-2 program stream media type and
implements IAsyncReader.
The correct way to discover the PIDs is to have a downstream filter parse
SI sections as they are delivered. Longer term we plan to write a sample
that can parse PATs and PMTs and so provide basic stream content that can
be sent up to the app so the correct PIDs can be mapped to the output pins.
Unfortunately the sample has not yet been written. The BDA solution has
such a filter but it is tightly integrated with the network provider.
Best Regards
leolin
In order to create output pins in the demux I need to call
its CreateOutputPins() method and pass it a pointer to an
AM_MEDIA_TYPE. Since my source filter does not provide
such a pointer, I figure I need to create an AM_MEDIA_TYPE
struct of my own and pass it to the Demux's CreateOutputPin
() method. How do I accurately do this? As I mentioned in
my first post, I only have limited information about the
stream prior to creating the DirectShow filter graph. The
stream does not exist prior to creating the filter graph.
So what should my AM_MEDIA_TYPE contain? Does it only need
to contain the info I pass to the Demux in GraphEdit? See
next paragraph.
In order to get my graph built and running in GraphEdit I
only need to create two output pins, Audio and Video, (as
mentioned in my first post) and connect those to decoders
and then renderers, and it works fine. I am able to view
my live program stream. Again. How does GraphEdit create
output pins in the Demux when the only information I give
it is as follows; for the vido output pin I give it a
media type of MPEG2 Program Video, for stream_id Mappings
I give it a steam_id of 0xE0, content equals Elementary
Stream, a Filter Value of none, and finally a Data Offset
of zero. That's it. When creating the Audio output pin the
only difference is that the media type is MPEG1 Audio and
the stream_id I use is 0xC0.
"In program stream mode, the mapping is between one stream
ID and one output pin...In other filter graphs, it is the
responsibility of the application to create and configure
the output pins by setting the pin's media type when the
pin is created and mapping the stream IDs (program stream
mode)...The Demux configures itself internally for either
transport or program streams only after some triggering
event occurs that indicates which type of stream the
filter should expect. The typical triggering event occurs
when the first output pin is configured. For example, in
program stream mode, an application will create a new
output pin using the filter's
IMpeg2Demultiplexer::CreateOutputPin method. This method
returns an IPin interface pointer to the pin that was
created. The application then uses this pointer in a call
to QueryInterface to obtain the IMPEG2StreamIdMap
interface. At this point the Demux will configure itself
for program stream mode, because IMPEG2StreamIdMap is
specific to program streams. "
>-----Original Message-----
>Message unavailable
First of all my stream currently operates in Program
stream mode and not Transport. Second my source filter
operates in Push mode, not Pull.
As it says in the MSDN page about the MPEG-2
Demulitplexer, I need to implement the Mpeg2Demultiplexer
interface and its CreateOutputpin in order to create the
output pins (Audio and Video) that I need.
Since my source filter does not provide an AM_MEDIA_TYPE
struct to pass to the CreateOutputPin method I figured I
needed to create one. How do I do that? Please see code
snipit from first post. Am I even on the right track? I
feel like I am in a catch-22. I need to know about the
stream inorder to create the filter graph and the Demux's
output pins, however I don't even have a stream prior to
creating the filter graph.
Thanks for your help.
Brendon...
>.
>
You can go to following URL to know the details:
http://support.microsoft.com/default.aspx?scid=fh;EN-US;OfferProPhone
Thanks
Jian Shen
This posting is provided "AS IS" with no warranties, and confers no rights.