00001 #include "StdAfx.h"
00002 #include <mmreg.h>
00003 #include "DiracSplitterFile.h"
00004
00005 #include <initguid.h>
00006 #include "..\..\..\..\include\moreuuids.h"
00007
00008 CDiracSplitterFile::CDiracSplitterFile(IAsyncReader* pAsyncReader, HRESULT& hr)
00009 : CBaseSplitterFile(pAsyncReader, hr)
00010 , m_rtDuration(0)
00011 {
00012 if(SUCCEEDED(hr)) hr = Init();
00013 m_pBuff.SetSize(1024, 1024);
00014 }
00015
00016 HRESULT CDiracSplitterFile::Init()
00017 {
00018 HRESULT hr = E_FAIL;
00019
00020 Seek(0);
00021
00022 UINT64 hdr;
00023 if(FAILED(Read((BYTE*)&hdr, sizeof(hdr))) || hdr != 0x43415249442D574Bui64)
00024 return E_FAIL;
00025
00026 dirac_decoder_t* decoder = dirac_decoder_init(0);
00027
00028 __int64 limit = min(GetLength(), 2048);
00029
00030 while(GetPos() < limit)
00031 {
00032 BYTE b;
00033 if(!Next(b)) {ASSERT(0); break;}
00034
00035 if(b == RAP_START_CODE)
00036 {
00037 __int64 pos = GetPos() - 5;
00038 if(!Next(b)) {ASSERT(0); break;}
00039 __int64 len = GetPos() - pos;
00040 Seek(pos);
00041
00042 m_mt.majortype = MEDIATYPE_Video;
00043 m_mt.subtype = MEDIASUBTYPE_DiracVideo;
00044 m_mt.formattype = FORMAT_DiracVideoInfo;
00045 m_mt.SetSampleSize(1);
00046
00047 DIRACINFOHEADER* dvih = (DIRACINFOHEADER*)m_mt.AllocFormatBuffer(FIELD_OFFSET(DIRACINFOHEADER, dwSequenceHeader) + len);
00048 memset(m_mt.Format(), 0, m_mt.FormatLength());
00049
00050 dvih->cbSequenceHeader = len - 5;
00051 Read((BYTE*)&dvih->dwSequenceHeader[0], len);
00052
00053 dirac_buffer(decoder, (BYTE*)&dvih->dwSequenceHeader[0], (BYTE*)&dvih->dwSequenceHeader[0] + len);
00054 if(dirac_parse(decoder) != STATE_SEQUENCE) {ASSERT(0); break;}
00055
00056 if(decoder->seq_params.frame_rate.denominator)
00057 dvih->hdr.AvgTimePerFrame = 10000000i64 * decoder->seq_params.frame_rate.denominator / decoder->seq_params.frame_rate.numerator;
00058 dvih->hdr.bmiHeader.biSize = sizeof(dvih->hdr.bmiHeader);
00059 dvih->hdr.bmiHeader.biWidth = decoder->seq_params.width;
00060 dvih->hdr.bmiHeader.biHeight = decoder->seq_params.height;
00061 dvih->hdr.bmiHeader.biCompression = m_mt.subtype.Data1;
00062 dvih->hdr.dwInterlaceFlags = 0;
00063 if(decoder->seq_params.interlace) dvih->hdr.dwInterlaceFlags |= AMINTERLACE_IsInterlaced;
00064 if(decoder->seq_params.topfieldfirst) dvih->hdr.dwInterlaceFlags |= AMINTERLACE_Field1First;
00065 dvih->hdr.dwPictAspectRatioX = dvih->hdr.bmiHeader.biWidth;
00066 dvih->hdr.dwPictAspectRatioY = dvih->hdr.bmiHeader.biHeight;
00067
00068 m_rtDuration = 0;
00069
00070 hr = S_OK;
00071
00072 break;
00073 }
00074 }
00075
00076 dirac_decoder_close(decoder);
00077
00078 return hr;
00079 }
00080
00081 UINT64 CDiracSplitterFile::UnsignedGolombDecode()
00082 {
00083 int M = 0;
00084 while(M < 64 && !BitRead(1))
00085 M++;
00086
00087 UINT64 info = 0;
00088 for(int i = 0; i < M; i++)
00089 info |= BitRead(1) << i;
00090
00091 return (1ui64<<M)-1 + info;
00092 }
00093
00094 bool CDiracSplitterFile::Next(BYTE& code, __int64 len)
00095 {
00096 BitByteAlign();
00097 UINT64 qw = -1;
00098 do
00099 {
00100 if(len-- == 0 || GetPos() >= GetLength()) return(false);
00101 qw = (qw << 8) | (BYTE)BitRead(8);
00102 }
00103 while((qw&0xffffffff00) != ((UINT64)START_CODE_PREFIX<<8));
00104 code = (BYTE)(qw & 0xff);
00105 return(true);
00106 }
00107
00108 const BYTE* CDiracSplitterFile::NextBlock(BYTE& code, int& size, int& fnum)
00109 {
00110 BYTE* pBuff = m_pBuff.GetData();
00111 code = NOT_START_CODE;
00112 size = 0;
00113
00114
00115
00116 while(GetPos() < GetLength())
00117 {
00118 if(GetPos() <= GetLength() - 5)
00119 {
00120 UINT64 qw = BitRead(40, true);
00121
00122 if(size == 0)
00123 {
00124 if((qw & 0xffffffff00) == ((UINT64)START_CODE_PREFIX<<8) && (qw & 0xff) != NOT_START_CODE)
00125 code = (BYTE)(qw & 0xff);
00126
00127 if(isFrameStartCode(code))
00128 {
00129 __int64 pos = GetPos();
00130 Seek(pos + 5);
00131 fnum = (int)UnsignedGolombDecode();
00132 Seek(pos);
00133 }
00134 }
00135 else
00136 {
00137 if((qw & 0xffffffff00) == ((UINT64)START_CODE_PREFIX<<8) && (qw & 0xff) != NOT_START_CODE)
00138 break;
00139 }
00140 }
00141
00142 if(size >= m_pBuff.GetSize())
00143 {
00144 int newsize = max(1024, size*2);
00145 m_pBuff.SetSize(newsize, newsize);
00146 pBuff = m_pBuff.GetData();
00147 }
00148
00149 pBuff[size++] = (BYTE)BitRead(8);
00150 }
00151
00152 return pBuff;
00153 }