DiracSplitterFile.cpp

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) // KW-DIRAC
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;// dvih->hdr.AvgTimePerFrame * decoder->seq_params.num_frames; // WTF
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         // TODO: make sure we are at a start code right now
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 }

Generated on Tue Dec 13 14:47:11 2005 for guliverkli by  doxygen 1.4.5