- Main Page
- Namespaces
- Classes
- Files
- Directories

- File List
- File Members

# 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 }