Index: loader/dshow/guids.c =================================================================== --- loader/dshow/guids.c.orig 2007-02-07 22:28:38.000000000 -0800 +++ loader/dshow/guids.c 2007-02-07 22:57:57.000000000 -0800 @@ -26,6 +26,8 @@ {0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0}}; const GUID FORMAT_VideoInfo={0x05589f80, 0xc356, 0x11ce, {0xbf, 0x01, 0x00, 0xaa, 0x00, 0x55, 0x59, 0x5a}}; +const GUID FORMAT_MPEG2Video={0xe06d80e3, 0xdb46, 0x11cf, + {0xb4, 0xd1, 0x00, 0x80, 0x5f, 0x6c, 0xbb, 0xea}}; const GUID MEDIASUBTYPE_RGB1={0xe436eb78, 0x524f, 0x11ce, {0x9f, 0x53, 0x00, 0x20, 0xaf, 0x0b, 0xa7, 0x70}}; const GUID MEDIASUBTYPE_RGB4={0xe436eb79, 0x524f, 0x11ce, Index: loader/dshow/guids.h =================================================================== --- loader/dshow/guids.h.orig 2007-02-07 22:28:38.000000000 -0800 +++ loader/dshow/guids.h 2007-02-07 22:57:57.000000000 -0800 @@ -58,6 +58,7 @@ extern const GUID MEDIATYPE_Video; extern const GUID GUID_NULL; extern const GUID FORMAT_VideoInfo; +extern const GUID FORMAT_MPEG2Video; extern const GUID MEDIASUBTYPE_RGB1; extern const GUID MEDIASUBTYPE_RGB4; extern const GUID MEDIASUBTYPE_RGB8; Index: loader/dshow/DS_VideoDecoder.c =================================================================== --- loader/dshow/DS_VideoDecoder.c.orig 2007-02-07 22:53:50.000000000 -0800 +++ loader/dshow/DS_VideoDecoder.c 2007-02-07 22:57:57.000000000 -0800 @@ -86,6 +86,93 @@ }; +DWORD avc_quant(BYTE *src, BYTE *dst, int len) +{ + //Stolen from libavcodec h264.c + BYTE *p = src, *d = dst; + int cnt; + cnt = *(p+5) & 0x1f; // Number of sps + if(src[0] != 0x01 || cnt > 1) { + memcpy(dst, src, len); + return len; + } + p += 6; + //cnt > 1 not supported? + cnt = (*p << 8) | *(p+1) + 2; + memcpy(d, p, cnt); + d+=cnt; + p+=cnt; + //assume pps cnt == 1 too + p++; + cnt = (*p << 8) | *(p+1) + 2; + memcpy(d, p, cnt); + return d + cnt - dst; + +} +#define is_avc(cc) (cc == mmioFOURCC('A', 'V', 'C', '1') || \ + cc == mmioFOURCC('a', 'v', 'c', '1')) +char *ConvertVIHtoMPEG2VI(VIDEOINFOHEADER *vih, int *size) +{ + struct VIDEOINFOHEADER2 { + RECT32 rcSource; + RECT32 rcTarget; + DWORD dwBitRate; + DWORD dwBitErrorRate; + REFERENCE_TIME AvgTimePerFrame; + DWORD dwInterlaceFlags; + DWORD dwCopyProtectFlags; + DWORD dwPictAspectRatioX; + DWORD dwPictAspectRatioY; + union { + DWORD dwControlFlags; + DWORD dwReserved1; + }; + DWORD dwReserved2; + BITMAPINFOHEADER bmiHeader; + }; + struct MPEG2VIDEOINFO { + struct VIDEOINFOHEADER2 hdr; + DWORD dwStartTimeCode; + DWORD cbSequenceHeader; + DWORD dwProfile; + DWORD dwLevel; + DWORD dwFlags; + DWORD dwSequenceHeader[1]; + } *mp2vi; + unsigned char data[256]; + int extra = 0; + if(vih->bmiHeader.biSize > sizeof(BITMAPINFOHEADER)) { + extra = vih->bmiHeader.biSize-sizeof(BITMAPINFOHEADER); + } + mp2vi = (struct MPEG2VIDEOINFO *)malloc(sizeof(struct MPEG2VIDEOINFO)+extra-4); + memset(mp2vi, 0, sizeof(struct MPEG2VIDEOINFO)); + mp2vi->hdr.rcSource = vih->rcSource; + mp2vi->hdr.rcTarget = vih->rcTarget; + mp2vi->hdr.dwBitRate = vih->dwBitRate; + mp2vi->hdr.dwBitErrorRate = vih->dwBitErrorRate; + mp2vi->hdr.AvgTimePerFrame = vih->AvgTimePerFrame; + mp2vi->hdr.dwPictAspectRatioX = vih->bmiHeader.biWidth; + mp2vi->hdr.dwPictAspectRatioY = vih->bmiHeader.biHeight; + memcpy(&mp2vi->hdr.bmiHeader, &vih->bmiHeader, sizeof(BITMAPINFOHEADER)); + mp2vi->hdr.bmiHeader.biSize = sizeof(BITMAPINFOHEADER); + if(extra) { + int i; + if(is_avc(vih->bmiHeader.biCompression)) { + mp2vi->dwFlags = 4; //What does this mean? + mp2vi->cbSequenceHeader = avc_quant( + (BYTE *)(&vih->bmiHeader) + sizeof(BITMAPINFOHEADER), + (BYTE *)(&mp2vi->dwSequenceHeader[0]), extra); + } else { + mp2vi->cbSequenceHeader = extra; + memcpy(&mp2vi->dwSequenceHeader[0], + (BYTE *)(&vih->bmiHeader) + sizeof(BITMAPINFOHEADER), extra); + } + } + // The '4' is from the allocated space of dwSequenceHeader + *size = sizeof(struct MPEG2VIDEOINFO) + mp2vi->cbSequenceHeader - 4; + return (char *)mp2vi; +} + DS_VideoDecoder * DS_VideoDecoder_Open(char* dllname, GUID* guid, BITMAPINFOHEADER * format, int flip, int maxauto) { DS_VideoDecoder *this; @@ -143,6 +230,13 @@ this->m_sOurType.pUnk = 0; this->m_sOurType.cbFormat = bihs; this->m_sOurType.pbFormat = (char*)this->m_sVhdr; + if(is_avc(this->m_sVhdr->bmiHeader.biCompression)) { + int size; + this->m_sOurType.formattype = FORMAT_MPEG2Video; + this->m_sOurType.pbFormat = + (char*)ConvertVIHtoMPEG2VI(this->m_sVhdr, &size); + this->m_sOurType.cbFormat = size; + } this->m_sVhdr2 = (VIDEOINFOHEADER*)(malloc(sizeof(VIDEOINFOHEADER)+12)); memcpy(this->m_sVhdr2, this->m_sVhdr, sizeof(VIDEOINFOHEADER));