NutFile.cpp

00001 #include "StdAfx.h"
00002 #include "NutFile.h"
00003 
00004 CNutFile::CNutFile(IAsyncReader* pAsyncReader, HRESULT& hr)
00005         : CBaseSplitterFile(pAsyncReader, hr)
00006 {
00007         if(FAILED(hr)) return;
00008         hr = Init();
00009 }
00010 
00011 HRESULT CNutFile::Init()
00012 {
00013         Seek(0);
00014 
00015         if(BitRead(64) != NUTM)
00016                 return E_FAIL;
00017 
00018         m_streams.RemoveAll();
00019 
00020         Seek(0);
00021 
00022         while(GetPos() < GetLength())
00023         {
00024                 frame_header fh;
00025                 fh.checksum_flag = 1;
00026 
00027                 UINT64 id = 0;
00028 
00029                 if(BitRead(1, true) == 0
00030                 || (id = BitRead(64)) == NUTK)
00031                         break;
00032 
00033                 packet_header ph;
00034                 Read(ph);
00035 
00036                 if(id == NUTM)
00037                 {
00038                         Read(m_mh);
00039                 }
00040                 else if(id == NUTS)
00041                 {
00042                         CAutoPtr<stream_header> sh(new stream_header());
00043                         Read(*sh);
00044                         if(sh->stream_class == SC_VIDEO) Read(sh->vsh);
00045                         else if(sh->stream_class == SC_AUDIO) Read(sh->ash);
00046                         // else if(sh->stream_class == SC_SUBTITLE) ; // nothing to do
00047                         m_streams.AddTail(sh);
00048                 }
00049                 else if(id == NUTX)
00050                 {
00051                         index_header ih;
00052                         Read(ih);
00053                 }
00054                 else if(id == NUTI)
00055                 {
00056                         info_header ih;
00057                         Read(ih);
00058                 }
00059                 else if(id == 0) // frame
00060                 {
00061                         ASSERT(0);
00062                         break;
00063                 }
00064 
00065                 if(fh.checksum_flag)
00066                 {
00067                         Seek(ph.pos + ph.fptr - 4);
00068                         ph.checksum = (UINT32)BitRead(32);
00069                 }
00070 
00071                 Seek(ph.pos + ph.fptr);
00072         }
00073 
00074         Seek(0);
00075 
00076         return m_streams.GetCount() ? S_OK : E_FAIL;
00077 }
00078 
00079 void CNutFile::Read(vint& vi)
00080 {
00081         vi = 0;
00082         bool more;
00083         do {more = !!BitRead(1); vi = (vi << 7) | BitRead(7);}
00084         while(more);
00085 }
00086 
00087 void CNutFile::Read(svint& svi)
00088 {
00089         vint vi;
00090         Read(vi);
00091         vi++;
00092         if(vi&1) svi = -((svint)vi>>1);
00093         else svi = ((svint)vi>>1);
00094 }
00095 
00096 void CNutFile::Read(binary& b)
00097 {
00098         vint len;
00099         Read(len);
00100         b.SetSize((INT_PTR)len);
00101         for(BYTE* buff = b.GetData(); len-- > 0; *buff++ = (BYTE)BitRead(8));
00102 }
00103 
00104 void CNutFile::Read(packet_header& ph)
00105 {
00106         ph.pos = GetPos();
00107         Read(ph.fptr);
00108         Read(ph.bptr);
00109 }
00110 
00111 void CNutFile::Read(main_header& mh)
00112 {
00113         Read(mh.version);
00114         Read(mh.stream_count);
00115 }
00116 
00117 void CNutFile::Read(stream_header& sh)
00118 {
00119         Read(sh.stream_id);
00120         Read(sh.stream_class);
00121     Read(sh.fourcc);
00122     Read(sh.average_bitrate);
00123     Read(sh.language_code);
00124     Read(sh.time_base_nom);
00125     Read(sh.time_base_denom);
00126     Read(sh.msb_timestamp_shift);
00127     Read(sh.shuffle_type);
00128     sh.fixed_fps = BitRead(1);
00129     sh.index_flag = BitRead(1);
00130     sh.reserved = BitRead(6);
00131         while(1)
00132         {
00133                 CAutoPtr<codec_specific> p(new codec_specific());
00134                 Read(p->type);
00135                 if(p->type == 0) break;
00136                 Read(p->data);
00137                 sh.cs.AddTail(p);
00138         }
00139 }
00140 
00141 void CNutFile::Read(video_stream_header& vsh)
00142 {
00143         Read(vsh.width);
00144         Read(vsh.height);
00145         Read(vsh.sample_width);
00146         Read(vsh.sample_height);
00147         Read(vsh.colorspace_type);
00148 }
00149 
00150 void CNutFile::Read(audio_stream_header& ash)
00151 {
00152         Read(ash.samplerate_mul);
00153         Read(ash.channel_count);
00154 }
00155 
00156 void CNutFile::Read(index_header& ih)
00157 {
00158         Read(ih.stream_id);
00159 
00160         vint len;
00161         Read(len);
00162         ih.ie.SetSize((INT_PTR)len);
00163         for(index_entry* p = ih.ie.GetData(); len-- > 0;)
00164         {
00165                 Read(p->timestamp);
00166                 Read(p->position);
00167         }
00168 }
00169 
00170 void CNutFile::Read(info_header& ih)
00171 {
00172         // TODO
00173 /*
00174         for(;;){
00175                 id                              v
00176                 if(id==0) break
00177                 name= info_table[id][0]
00178                 type= info_table[id][1]
00179                 if(type==NULL)
00180                         type                    b
00181                 if(name==NULL)
00182                         name                    b
00183                 if(type=="v")
00184                         value                   v
00185                 else if(type=="s")
00186                         value                   s
00187                 else
00188                         value                   b
00189         }
00190 */
00191 }

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