Menu

Find out PID of H.264 PES from a MPEG2 TS

kjj902
2009-11-18
2012-10-29
1 2 > >> (Page 1 of 2)
  • kjj902

    kjj902 - 2009-11-18

    I am try using graphedt to build a graph to preview an H.264 camera, but I
    don't know much details about that camera, so a lot of guess work.

    I am quite sure it pushes MPEG2 TS, since GraphEdt filter properties dialog
    shows that the SubType is MPEG2_TRANSPORT. I also think that the TS packet
    contains nothing but one H.264 Elementary Stream.

    However, I don't know the PID of the H.264 PES. Is there a way for me to find
    out the PID?

    Thank you very much

     
  • Eric

    Eric - 2009-11-18

    When the demux is used with a Transport Stream, it expose the IMPEG2PIDMap
    interface. With IMPEG2PIDMap.EnumPIDMap you can retrieve a IEnumPIDMap
    instance that allow you to have a list of PID embedded in the stream.

     
  • Eric

    Eric - 2009-11-18

    Also, I'm pretty sure (but i can be wrong) that only Windows 7 (or Vista with
    the 2008 TV pack) understand H.264 streams in a MPEG-2 Transport Stream...

     
  • kjj902

    kjj902 - 2009-11-18

    Hi, nowinskie,

    Many thanks for your info. I will try your suggestions and let you know what I
    get.

    However, I am confused by your second message. My understanding is that MPEG2
    TS is just packaging whatever elementary streams and assigning PIDs, such that
    they can be delievered to different pins of MPEG2 demux. After we get H.264
    elementary video from MPEG2 demux, it is the H.264 video decoder filter's job
    to decode H.264 stream, right? Then why does this matter with OS?

    What I am working on is a USB H.264 camera, not a TV source, and I am hoping
    the H.264 video can be decoded by ffdshow once I figured out how to use MPEG2
    demux.

    Please let me know if my thoughts above is incorrect. Many thanks.

     
  • DMAN

    DMAN - 2009-11-18

    It depends on what demuxer you're going to use.
    nowinskie is refering to the microsoft demuxer which when connected to an
    output pin for a capture device producing a transport stream will
    automatically create the audio & video pins for the first pids in the
    transport stream.
    For your simple device this may be all you may need to do.
    DVB cards require TIF filters etc to then scan & map channel pids but like you
    say this is a simple device.

    There are also other demuxers such as the free one from Elecard which will
    list the pids in the demux filter to assist you finding the pid(s) and then
    you can manually use the M$ one and map them accordingly for your application.

     
  • kjj902

    kjj902 - 2009-11-18

    What I am experimenting now is the MS directshow MPEG-2 Demultiplexer,
    possibly the most basic one. It actually doesn't automatically create Audio
    and Video Pins. Is it because my OS is XP-SP3? Or, Can you let me know the
    demux in your mind, which can auto create those pins?

    Also could you please let me know the Elecard filter which can find all pids?

    I have tried "Elecard MPEG Push Demultiplexer" before? It will create an "AVC"
    pin after running the graph for a while. However, after I link this "AVC" to
    ffdshow video decoder, it displays only black screen. I have checked the
    filter's property dialog, it does detect that Stream Type is H264 Video only,
    but doesn't tell me the PID. What is the elecard demux, which can list all
    PID's, in your mind?

    Many thanks.

     
  • kjj902

    kjj902 - 2009-11-18

    Hi, nowinskie,

    I have tried your method of calling IMPEG2PIDMap.EnumPIDMap(). First of all,
    it is the pin, not the filter, which can be casted to IMPEG2PIDMap, right? So,
    what I did is to first create an output, and then cast it to IMPEG2PIDMap.
    However, when I can EnumPIDMap function, the compiler gives me a warning
    saying the follows:

    "Warning 1 'DirectShowLib.BDA.IMPEG2PIDMap.EnumPIDMap(out object)' is
    obsolete: 'Because of bug in DS 9.0c, you can't get the PID map from .NET'".

    I am using DS9.0c. Is this a problem? Many thanks.

     
  • DMAN

    DMAN - 2009-11-18

    You're after the elecard demultiplexer not the push one. Alternatively use the
    elecard stream analyzer with a file recorded with the devices bundled app.

     
  • kjj902

    kjj902 - 2009-11-19

    Thank you very much for your info. I am off today, and will take a careful
    look tomorrow.

     
  • kjj902

    kjj902 - 2009-11-19

    I could not wait till tomorrow to try your suggestions, but both of your
    methods don't seem working for me.

    I have used "Elecard MPEG Demultiplexer" (after regsvr32 empgdmx.ax), but the
    capture pin of the camera doesn't link to Input pin of "Elecard MPEG
    Demultiplexer". I remember this is the reason why I have used "Elecard MPEG
    Push Demultiplexer" before. Any ideas?

    I also have tried "Elecard stream analyzer". The file is dumped from capture
    pin of the camera directly using dump.ax filter. But, it seems to me that the
    file is already H.264 elementary stream. So, I still don't know the PID of
    that H.264 elementary stream when it is packaged inside MPEG-2 Transport
    Stream. Any ideas?

     
  • François MAESEELE

    Hi,
    Like any MPEG TS Source, you have to first run a graph to find out the TS
    content (PMT, PIDs, ES types, etc...)
    To do so, you have to connect your filter to the MS Demux, and configure your
    MS Demux to be connected to a PSI Parser (have a look in the MS Platform SDK
    7.0 and search for the PSIParser sample, which in C++ of course). Then just
    run the graph and you'll get what you look for.
    Once you have these information, just remove the PSIParser filter (I guess you
    cam won't change any of its PIDs while still running) and reconfigure the MS
    Demux accordingly with new PIDs information.

    Also, MS Demux perfectly supports H264, as it is passthrough but only for MPEG
    TS. ie it supports live H264 sources. The problem is more to find a matching
    video decoder. Since Seven, you can now decode everything (MPEG2, H264, AC3,
    AAC).

     
  • kjj902

    kjj902 - 2009-11-19

    Hi, fmaeseele,

    Thanks a lot for your info. I will try your method. On the other hand, if I
    could try it using GraphEdt, that would be much easier.

    I actually have tried using GraphEdt to get PSI info. What I did is as
    follows:

    Add an new output pin (naming it PSI) on MS MPEG2 demux filter, and select
    Media Type to be MPEG2_PSI, and then try to link this PSI pin to the "In" pin
    of "MPEG2 Sections and Tables" filter, but the connection is not allowed due
    to incompatibility of pins.

    Any ideas on how to fix it??

     
  • kjj902

    kjj902 - 2009-11-19

    Hi, Fmaeseele,

    PSI Filter seems the most promising one, but I am still not able to make it
    work. Here is what I have done. Please let me know what goes wrong. Many
    thanks.

    1. Compile the PSIParser example of DirectShow examples of Windows SDK 6.0, which generates PSIParser.dll.
    2. Register PSIParser.dll (regsvr32 PSIParser.dll), and then I do see the newly-registered PSIParser filter in GraphEdt.
    3. Add an output pin to MS MPEG-2 demux. I have selected MPEG2-PSI as the media type and config’ed mapping: PID = 0x0000 and Content = MPEG2 PSI Sections.
    4. Then I do have no problem linking camera, MPEG2 demux and PSI Parser.
    5. Run the graph. According to http://msdn.microsoft.com/en-us/library/dd377479(VS.85).aspx, I should see programs contained in the transport stream listed in the box, right? But, I didn’t. The box is empty. Does this mean that PSIParser doesn’t detect any programs from the TS? But, I am sure there is a H.264 video stream coming out of the camera. So far, only Elecard filters seem be able to detect it, but they don’t show the details of the TS stream.

    Any ideas what to do next? I almost exhausts my options, and don’t know what
    to do next. Many thanks.

     
  • DMAN

    DMAN - 2009-11-19

    I didn't suggest the PSI parser initially because I suspected your stream
    doesnt contain the PSI & therefore PAT & PMT.
    Usually when graph building and adding the m$ demux it would have added the
    PSI parser automatically and setup the video & audio pins based on the first
    pids found.
    Since it din't then alternative methods are required to understand the stream
    container format.
    With the Elecard demux not connecting & the stream analyzer not working either
    then I doubt the stream is MPEG-TS compliant.
    Can you post a small sample? i.e. on www.sendspace.com
    Try and do this from the supplied application if possible rather than
    Graphedit.

    Also, what the the major & sub type from the output pin?
    i.e. Major Type: Stream - Sub Type: MPEG2_TRANSPORT - Format: None ?

     
  • kjj902

    kjj902 - 2009-11-19

    Hi, dman_lfc,

    Yes, the major type is Stream, Sub type is MPEG2_TRANSPORT, and Format is
    None.

    The camera doesn’t connect to Elecard MPEG Demux, but it connects to Elecard
    MPEG Push demux. After I run the graph for a while, an AVC output pin is
    created for Elecard MPEG Push Demux. Then I can check the property of Elecard
    MPEG Push Demux, it contains the following info:

    Stream detection completed: Detected.

    Stream Type: H.264 Video only.

    And a few other parameters, which probably do not matter.

    The camera is still under development, so there are no supplied applications.
    I have to dump the stream into a file using graphedt. I am using dump.ax,
    which connects directly to the capture pin of the camera. Here is a link to
    the dump AVI file:
    http://www.sendspace.com/file/rdvpnn.
    The filename is temp1.avi. I have used elecard stream analyzer, it seems to me
    that the file contains only H.264 Elementary Stream, ie, the TS headers have
    been stripped off.

    Another strange thing is that the file can only be played back by Elecard AVC
    HD Player, but not any other players, which I think I have configured to use
    ffdshow.

    Many thanks.

     
  • kjj902

    kjj902 - 2009-11-19

    Sorry for a mistake. I tried again just now and the temp1.avi can actually
    also be played back by Window Media Player, which I have configured to use
    ffdshow. So, I think once I figure out how to get H.264 elementary stream from
    MPEG2 TS, I should be able to use ffdshow to preview the stream.

    But, it seems I stuck on getting its PID. I have run out of options, not sure
    what to do next.

     
  • DMAN

    DMAN - 2009-11-19

    Thanks for the sample.
    I can confirm this is not MPEG-TS compliant and doesnt have the PSI, PMT & PID
    info.
    Therefore I think the way forward with the m$ demux is to treat this the old
    analogue way.
    i.e. Create a video pin assign it the appropriate Major & Subtypes for
    complaint H.264 codecs.
    Try something like this when the mpeg demux is attached in you application:

    static public AMMediaType GetVideoMpg2Media()
    {
    AMMediaType mediaVideo = new AMMediaType();
    mediaVideo.majorType = MediaType.Video;
    mediaVideo.subType = MediaSubType.Mpeg2Video;
    mediaVideo.formatType = FormatType.Mpeg2Video;
    mediaVideo.unkPtr = IntPtr.Zero;
    mediaVideo.sampleSize = 1;
    mediaVideo.temporalCompression = false;
    mediaVideo.fixedSizeSamples = true;
    mediaVideo.formatSize = Mpeg2ProgramVideo.GetLength(0);
    mediaVideo.formatPtr = Marshal.AllocCoTaskMem(mediaVideo.formatSize);
    Marshal.Copy(Mpeg2ProgramVideo, 0, mediaVideo.formatPtr,
    mediaVideo.formatSize);
    return mediaVideo;
    }

    You may need to adjust the above for the code to suit the codec.
    Then use the below in you graph building:

    IMpeg2Demultiplexer demuxer = (IMpeg2Demultiplexer)_filterMpeg2Demux;
    demuxer.CreateOutputPin(FilterGraphTools.GetVideoMpg2Media(), "Video", out
    _pinVideo);
    IMPEG2StreamIdMap map = (IMPEG2StreamIdMap)_pinVideo;
    map.MapStreamId(224, MPEG2Program.ElementaryStream, 0, 0);

     
  • DMAN

    DMAN - 2009-11-19

    Maybe something like:

    static public AMMediaType GetVideoH264Media()
    {
    AMMediaType mediaVideo = new AMMediaType();
    mediaVideo.majorType = MediaType.Video;
    mediaVideo.subType = MediaSubType.H264;
    mediaVideo.formatType = FormatType.None;
    mediaVideo.unkPtr = IntPtr.Zero;
    mediaVideo.sampleSize = 1;
    mediaVideo.temporalCompression = false;
    mediaVideo.fixedSizeSamples = true;
    mediaVideo.formatSize = H264VideoFormat.GetLength(0);
    mediaVideo.formatPtr = Marshal.AllocCoTaskMem(mediaVideo.formatSize);
    Marshal.Copy(H264VideoFormat, 0, mediaVideo.formatPtr, mediaVideo.formatSize);
    return mediaVideo;
    }

    And then:

    IMpeg2Demultiplexer demuxer = (IMpeg2Demultiplexer)_filterMpeg2Demux;
    demuxer.CreateOutputPin(FilterGraphTools.GetVideoH264Media(), "Video", out
    _pinVideo);
    IMPEG2StreamIdMap map = (IMPEG2StreamIdMap)_pinVideo;
    map.MapStreamId(0xE0, MPEG2Program.ElementaryStream, 0, 0);

     
  • kjj902

    kjj902 - 2009-11-19

    Sorry, but where are Mpeg2ProgramVideo and H264VideoFormat? I am not able to
    find them from any namespace under DirectShowLib.

     
  • DMAN

    DMAN - 2009-11-19

    Sorry forgot to provide that also:

    static byte H264VideoFormat = {
    0x00, 0x00, 0x00, 0x00, // .hdr.rcSource.left = 0x00000000
    0x00, 0x00, 0x00, 0x00, // .hdr.rcSource.top = 0x00000000
    0x00, 0x00, 0x00, 0x00, // .hdr.rcSource.right = 0x00000000
    0x00, 0x00, 0x00, 0x00, // .hdr.rcSource.bottom = 0x00000000
    0x00, 0x00, 0x00, 0x00, // .hdr.rcTarget.left = 0x00000000
    0x00, 0x00, 0x00, 0x00, // .hdr.rcTarget.top = 0x00000000
    0x00, 0x00, 0x00, 0x00, // .hdr.rcTarget.right = 0x00000000
    0x00, 0x00, 0x00, 0x00, // .hdr.rcTarget.bottom = 0x00000000
    0x00, 0x00, 0x00, 0x00, // .hdr.dwBitRate = 0x00000000
    0x00, 0x00, 0x00, 0x00, // .hdr.dwBitErrorRate = 0x00000000
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // .hdr.AvgTimePerFrame =
    0x0000000000061a80
    0x00, 0x00, 0x00, 0x00, // .hdr.bmiHeader.biSize = 0x00000028
    0xD0, 0x02, 0x00, 0x00, // .hdr.bmiHeader.biWidth = 0x000002d0
    0x40, 0x02, 0x00, 0x00, // .hdr.bmiHeader.biHeight = 0x00000240
    0x00, 0x00, // .hdr.bmiHeader.biPlanes = 0x0001
    0x00, 0x00, // .hdr.bmiHeader.biBitCount = 0x0018
    0x48, 0x32, 0x36, 0x34, // .hdr.bmiHeader.biCompression = "H264"
    0x00, 0x00, 0x00, 0x00, // .hdr.bmiHeader.biSizeImage = 0x00000000
    0x00, 0x00, 0x00, 0x00, // .hdr.bmiHeader.biXPelsPerMeter = 0x00000000
    0x00, 0x00, 0x00, 0x00, // .hdr.bmiHeader.biYPelsPerMeter = 0x00000000
    0x00, 0x00, 0x00, 0x00, // .hdr.bmiHeader.biClrUsed = 0x00000000
    0x00, 0x00, 0x00, 0x00, // .hdr.bmiHeader.biClrImportant = 0x00000000
    };

     
  • kjj902

    kjj902 - 2009-11-19

    I got an exception when casting IPin to IMPEG2StreamIdMap at the following
    line of code:

    IMPEG2StreamIdMap map = (IMPEG2StreamIdMap)_pinVideo;

    Because it is an Transport Stream Pin, it doesn't expose StreamIdMap, right?

     
  • DMAN

    DMAN - 2009-11-19

    Hrm... yeah... hrm... could be the previously defined AMMediaType.
    Just use a demuxer that works - i.e. Elecard, Cyberlink or Mainconcept.
    These work with MPEG-TS streams without PSI.

    Just bundle the chosen demuxer with your app.

    Then add it to the graph manually connecting to the output pin of the capture
    device:

    i.e. Define the chosen demuxer & then add it.

    IBaseFilter _filterMpegDeMuxer;
    const string monikerElecardDeMuxer = @"@device:sw:{083863F1-70DE-
    11D0-BD40-00A0C911CE86}{136DCBF5-3874-4B70-AE3E-15997D6334F7}";
    _filterMpegDeMuxer = Marshal.BindToMoniker(monikerElecardDeMuxer) as
    IBaseFilter;
    int hr = _graphBuilder.AddFilter(_filterMpegDeMuxer, "Elecard MPEG
    Demultiplexer");

    Use FilterGraphTools.ConnectPin to connect the capture device to the defined
    demux and then work with the AVC output pin from the demuxer to your chosen
    codec & renderer.

     
  • kjj902

    kjj902 - 2009-11-19

    I know Elecard MPEG Push Demux seems be able to get the H.264 elementary
    stream. When connecting it with elecard AVC video decoder, I do get video
    playback, but it is in very low frame rate (1~2 fps). So, this is still not an
    acceptable solution.

    Furthermore, I prefer to avoid using Elecard video decoder, since it can only
    be used for research purposes. Ffdshow seems to me the only publically
    available H.264 decoder, but when connect it to Elecard MPEG Push Demux, I get
    only black screen, and the render’s property shows that there is no frame
    arrived and rendered actually.

    On the other hand, ffdshow could play back the file containing dumped stream.
    So, I was hoping once I find a way to configure default MS MPEG-2 demux, I
    could use ffdshow to play the stream. But, apparently, this turns out to be
    quite difficult, if not impossible.

     
  • DMAN

    DMAN - 2009-11-19

    The dump file you posted works fine with the Elecard Demuxer (not the push
    one) so I assume you're using an outdated version.
    Playback here of your sample is fine also.
    I tested it with multiple H.264 decoders (even the DivX (free) one) all worked
    find around 60fps.
    FFDShow doesn't do H/W acceleration so you're better off with a codec that
    supports DXVA or DXVA2.

     
  • kjj902

    kjj902 - 2009-11-20

    Play back from a file is a pull mode, right? This may explain why Elecard
    Demux, instead of Elecard Push Demux, is used for play back the sample file. I
    download the latest version from elecard website about 3 weeks ago. That
    should be the latest version, right?

    I was told that the frame rate of that camera should be 30 fps, not sure why
    the frame rate for file playback is 60 fps. There are too many confusions.

    In any case, thank you very much for spending time on helping this. I do have
    learnt a lot from this discussion.

     
1 2 > >> (Page 1 of 2)

Log in to post a comment.