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 }