views:

814

answers:

4

How do I programmatically find out the width and height of the video in an mpeg-2 transport stream file?
Thanks.
Edit: I am using C++, but am happy for examples in any language.

A: 

You haven't said what language you want to use so I doubt you'll get any code samples.

Have a look at the following links. The first describes the MPEG-2 file format, the other is the RFC on transporting MPEG via RTP.

http://www.fh-friedberg.de/fachbereiche/e2/telekom-labor/zinke/mk/mpeg2beg/beginnzi.htm

http://www.ietf.org/rfc/rfc2250.txt

Winston Smith
Thanks for the links, but they don't appear to mention how/where the image dimensions are encodedI am using C++, but am happy for examples in any language
hamishmcn
+1  A: 

Check out the source code to libmpeg2, a F/OSS MPEG2 decoder. It appears that the width and height are set in the mpeg2_header_sequence() function in header.c. I'm not sure how control flows to that particular function, though. I'd suggest opening up an MPEG2 file in something using libmpeg2 (such as MPlayer) and attaching a debugger to see more closely exactly what it's doing.

Adam Rosenfield
That's what I was needed, Thanks!
hamishmcn
+1  A: 

If you are using DirectX, there is a method in the VMRWindowlessControl interface:

piwc->GetNativeVideoSize(&w, &h, NULL, NULL);

Or the IBasicVideo interface:

pivb->GetVideoSize(&w, &h);
+1  A: 

for MPEG2 Video the horizontal & vertical size can be found in the Video Sequence Header (from the video bit stream). The sequence header code is 0x000001B3. Some example code below. However it does not take into account the horizontal/vertical size extension if specified in sequence extension header.

#define VIDEO_SEQUENCE_HDR  0xB3
#define HOR_SIZE_MASK       0xFFF00000
#define HOR_SIZE_SHIFT      20
#define VER_SIZE_MASK       0x000FFF00
#define VER_SIZE_SHIFT      8

unsigned char *pTmp = tsPacket;
int len = 188;
int horizontal, vertical;

 while(len>0 && !horizontal && !vertical)
 {        
        if(*pTmp == 0 && *(pTmp+1) == 0
           && *(pTmp+2)== 0x01 && *(pTmp+3) == 0xB3 && (len-1) >0)
        {
            unsigned int *pHdr = (unsigned int *)pTmp;    
            pHdr++ ; 
            unsigned int secondByte = ntohl(*pHdr);
            horizontal = (secondByte & HOR_SIZE_MASK) >> HOR_SIZE_SHIFT;
            vertical = (secondByte & VER_SIZE_MASK) >> VER_SIZE_SHIFT;           
            break;
        }
        pTmp++;
        len--;
    }
Andrew
Good stuff, thanks Andrew
hamishmcn