1 /*  Copyright (c) MediaArea.net SARL. All Rights Reserved.
2  *
3  *  Use of this source code is governed by a BSD-style license that can
4  *  be found in the License.html file in the root of the source tree.
5  */
6 
7 //+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
8 //
9 // Elements part
10 //
11 // Contributor: Lionel Duchateau, kurtnoise@free.fr
12 //
13 //+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
14 
15 //---------------------------------------------------------------------------
16 // Pre-compilation
17 #include "MediaInfo/PreComp.h"
18 #ifdef __BORLANDC__
19     #pragma hdrstop
20 #endif
21 //---------------------------------------------------------------------------
22 
23 //---------------------------------------------------------------------------
24 #include "MediaInfo/Setup.h"
25 #include "tinyxml2.h"
26 #include <ZenLib/Ztring.h>
27 #include <string>
28 #include <algorithm>
29 using namespace tinyxml2;
30 using namespace std;
31 using namespace ZenLib;
32 //---------------------------------------------------------------------------
33 
34 //***************************************************************************
35 // Infos
36 //***************************************************************************
37 
38 //---------------------------------------------------------------------------
39 #if defined(MEDIAINFO_RIFF_YES) || defined(MEDIAINFO_MK_YES)
40 //---------------------------------------------------------------------------
41 
42 namespace MediaInfoLib
43 {
44 
45 //---------------------------------------------------------------------------
ExtensibleWave_ChannelMask(int32u ChannelMask)46 std::string ExtensibleWave_ChannelMask (int32u ChannelMask)
47 {
48     std::string Text;
49     if ((ChannelMask&0x0007)!=0x0000)
50         Text+="Front:";
51     if (ChannelMask&0x0001)
52         Text+=" L";
53     if (ChannelMask&0x0004)
54         Text+=" C";
55     if (ChannelMask&0x0002)
56         Text+=" R";
57 
58     if ((ChannelMask&0x0600)!=0x0000)
59         Text+=", Side:";
60     if (ChannelMask&0x0200)
61         Text+=" L";
62     if (ChannelMask&0x0400)
63         Text+=" R";
64 
65     if ((ChannelMask&0x0130)!=0x0000)
66         Text+=", Back:";
67     if (ChannelMask&0x0010)
68         Text+=" L";
69     if (ChannelMask&0x0100)
70         Text+=" C";
71     if (ChannelMask&0x0020)
72         Text+=" R";
73 
74     if ((ChannelMask&0x0008)!=0x0000)
75         Text+=", LFE";
76 
77     return Text;
78 }
79 
80 //---------------------------------------------------------------------------
ExtensibleWave_ChannelMask2(int32u ChannelMask)81 std::string ExtensibleWave_ChannelMask2 (int32u ChannelMask)
82 {
83     std::string Text;
84     int8u Count=0;
85     if (ChannelMask&0x0001)
86         Count++;
87     if (ChannelMask&0x0004)
88         Count++;
89     if (ChannelMask&0x0002)
90         Count++;
91     Text+=Ztring::ToZtring(Count).To_UTF8();
92     Count=0;
93 
94     if (ChannelMask&0x0200)
95         Count++;
96     if (ChannelMask&0x0400)
97         Count++;
98     Text+="/"+Ztring::ToZtring(Count).To_UTF8();
99     Count=0;
100 
101     if (ChannelMask&0x0010)
102         Count++;
103     if (ChannelMask&0x0100)
104         Count++;
105     if (ChannelMask&0x0020)
106         Count++;
107     Text+="/"+Ztring::ToZtring(Count).To_UTF8();
108     Count=0;
109 
110     if (ChannelMask&0x0008)
111         Text+=".1";
112 
113     return Text;
114 }
115 
116 //---------------------------------------------------------------------------
117 static const size_t ExtensibleWave_ChannelLayoutNames_Size=18;
118 const char* ExtensibleWave_ChannelLayoutNames[ExtensibleWave_ChannelLayoutNames_Size]=
119 {
120     "FL",
121     "FR",
122     "FC",
123     "LFE",
124     "BL",
125     "BR",
126     "FLC",
127     "FRC",
128     "BC",
129     "SL",
130     "SR",
131     "TC",
132     "TFL",
133     "TFC",
134     "TFR",
135     "TBL",
136     "TBC",
137     "TBR",
138 };
ExtensibleWave_ChannelMask_ChannelLayout(int32u ChannelMask)139 std::string ExtensibleWave_ChannelMask_ChannelLayout(int32u ChannelMask)
140 {
141     std::string Text;
142 
143     for (size_t i=0; i<ExtensibleWave_ChannelLayoutNames_Size; i++)
144         if (ChannelMask&(1<<i))
145         {
146             if (!Text.empty())
147                 Text+=' ';
148             Text+=ExtensibleWave_ChannelLayoutNames[i];
149         }
150 
151     return Text;
152 }
153 
154 }
155 
156 //---------------------------------------------------------------------------
157 #endif
158 //---------------------------------------------------------------------------
159 
160 //---------------------------------------------------------------------------
161 #ifdef MEDIAINFO_RIFF_YES
162 //---------------------------------------------------------------------------
163 
164 //---------------------------------------------------------------------------
165 #include "MediaInfo/Multiple/File_Riff.h"
166 #if defined(MEDIAINFO_DVDIF_YES)
167     #include "MediaInfo/Multiple/File_DvDif.h"
168 #endif
169 #if defined(MEDIAINFO_OGG_YES)
170     #include "MediaInfo/Multiple/File_Ogg.h"
171     #include "MediaInfo/Multiple/File_Ogg_SubElement.h"
172 #endif
173 #if defined(MEDIAINFO_CINEFORM_YES)
174     #include "MediaInfo/Video/File_CineForm.h"
175 #endif
176 #if defined(MEDIAINFO_FFV1_YES)
177     #include "MediaInfo/Video/File_Ffv1.h"
178 #endif
179 #if defined(MEDIAINFO_HUFFYUV_YES)
180     #include "MediaInfo/Video/File_HuffYuv.h"
181 #endif
182 #if defined(MEDIAINFO_MPEG4V_YES)
183     #include "MediaInfo/Video/File_Mpeg4v.h"
184 #endif
185 #if defined(MEDIAINFO_MPEGV_YES)
186     #include "MediaInfo/Video/File_Mpegv.h"
187 #endif
188 #if defined(MEDIAINFO_PRORES_YES)
189     #include "MediaInfo/Video/File_ProRes.h"
190 #endif
191 #if defined(MEDIAINFO_AVC_YES)
192     #include "MediaInfo/Video/File_Avc.h"
193 #endif
194 #if defined(MEDIAINFO_CANOPUS_YES)
195     #include "MediaInfo/Video/File_Canopus.h"
196 #endif
197 #if defined(MEDIAINFO_FRAPS_YES)
198     #include "MediaInfo/Video/File_Fraps.h"
199 #endif
200 #if defined(MEDIAINFO_LAGARITH_YES)
201     #include "MediaInfo/Video/File_Lagarith.h"
202 #endif
203 #if defined(MEDIAINFO_MPEGA_YES)
204     #include "MediaInfo/Audio/File_Mpega.h"
205 #endif
206 #if defined(MEDIAINFO_AAC_YES)
207     #include "MediaInfo/Audio/File_Aac.h"
208 #endif
209 #if defined(MEDIAINFO_AC3_YES)
210     #include "MediaInfo/Audio/File_Ac3.h"
211 #endif
212 #if defined(MEDIAINFO_ADM_YES)
213     #include "MediaInfo/Audio/File_Adm.h"
214 #endif
215 #if defined(MEDIAINFO_DTS_YES)
216     #include "MediaInfo/Audio/File_Dts.h"
217 #endif
218 #if defined(MEDIAINFO_JPEG_YES)
219     #include "MediaInfo/Image/File_Jpeg.h"
220 #endif
221 #if defined(MEDIAINFO_SUBRIP_YES)
222     #include "MediaInfo/Text/File_SubRip.h"
223 #endif
224 #if defined(MEDIAINFO_OTHERTEXT_YES)
225     #include "MediaInfo/Text/File_OtherText.h"
226 #endif
227 #if defined(MEDIAINFO_ADPCM_YES)
228     #include "MediaInfo/Audio/File_Adpcm.h"
229 #endif
230 #if defined(MEDIAINFO_PCM_YES)
231     #include "MediaInfo/Audio/File_Pcm.h"
232 #endif
233 #if defined(MEDIAINFO_SMPTEST0337_YES)
234     #include "MediaInfo/Audio/File_SmpteSt0337.h"
235     #include "MediaInfo/Audio/File_ChannelSplitting.h"
236 #endif
237 #if defined(MEDIAINFO_ID3_YES)
238     #include "MediaInfo/Tag/File_Id3.h"
239 #endif
240 #if defined(MEDIAINFO_ID3V2_YES)
241     #include "MediaInfo/Tag/File_Id3v2.h"
242 #endif
243 #if defined(MEDIAINFO_GXF_YES)
244     #if defined(MEDIAINFO_CDP_YES)
245         #include "MediaInfo/Text/File_Cdp.h"
246         #include <cstring>
247     #endif
248 #endif //MEDIAINFO_GXF_YES
249 #include "MediaInfo/Audio/File_DolbyAudioMetadata.h"
250 #include <vector>
251 #include "MediaInfo/MediaInfo_Config_MediaInfo.h"
252 #if defined(MEDIAINFO_ADM_YES)
253     #include <zlib.h>
254 #endif
255 using namespace std;
256 //---------------------------------------------------------------------------
257 
258 namespace MediaInfoLib
259 {
260 
261 //***************************************************************************
262 // Const
263 //***************************************************************************
264 
265 namespace Elements
266 {
267     const int32u FORM=0x464F524D;
268     const int32u LIST=0x4C495354;
269     const int32u ON2_=0x4F4E3220;
270     const int32u RIFF=0x52494646;
271     const int32u RF64=0x52463634;
272 
273     const int32u AIFC=0x41494643;
274     const int32u AIFC_COMM=0x434F4D4D;
275     const int32u AIFC_COMT=0x434F4D54;
276     const int32u AIFC_FVER=0x46564552;
277     const int32u AIFC_SSND=0x53534E44;
278     const int32u AIFF=0x41494646;
279     const int32u AIFF_COMM=0x434F4D4D;
280     const int32u AIFF_COMT=0x434F4D54;
281     const int32u AIFF_SSND=0x53534E44;
282     const int32u AIFF__c__=0x28632920;
283     const int32u AIFF_ANNO=0x414E4E4F;
284     const int32u AIFF_AUTH=0x41555448;
285     const int32u AIFF_NAME=0x4E414D45;
286     const int32u AIFF_ID3_=0x49443320;
287     const int32u AVI_=0x41564920;
288     const int32u AVI__cset=0x63736574;
289     const int32u AVI__Cr8r=0x43723872;
290     const int32u AVI__exif=0x65786966;
291     const int32u AVI__exif_ecor=0x65636F72;
292     const int32u AVI__exif_emdl=0x656D646C;
293     const int32u AVI__exif_emnt=0x656D6E74;
294     const int32u AVI__exif_erel=0x6572656C;
295     const int32u AVI__exif_etim=0x6574696D;
296     const int32u AVI__exif_eucm=0x6575636D;
297     const int32u AVI__exif_ever=0x65766572;
298     const int32u AVI__goog=0x676F6F67;
299     const int32u AVI__goog_GDAT=0x47444154;
300     const int32u AVI__GMET=0x474D4554;
301     const int32u AVI__hdlr=0x6864726C;
302     const int32u AVI__hdlr_avih=0x61766968;
303     const int32u AVI__hdlr_JUNK=0x4A554E4B;
304     const int32u AVI__hdlr_strl=0x7374726C;
305     const int32u AVI__hdlr_strl_indx=0x696E6478;
306     const int32u AVI__hdlr_strl_JUNK=0x4A554E4B;
307     const int32u AVI__hdlr_strl_strd=0x73747264;
308     const int32u AVI__hdlr_strl_strf=0x73747266;
309     const int32u AVI__hdlr_strl_strh=0x73747268;
310     const int32u AVI__hdlr_strl_strh_auds=0x61756473;
311     const int32u AVI__hdlr_strl_strh_iavs=0x69617673;
312     const int32u AVI__hdlr_strl_strh_mids=0x6D696473;
313     const int32u AVI__hdlr_strl_strh_vids=0x76696473;
314     const int32u AVI__hdlr_strl_strh_txts=0x74787473;
315     const int32u AVI__hdlr_strl_strn=0x7374726E;
316     const int32u AVI__hdlr_strl_vprp=0x76707270;
317     const int32u AVI__hdlr_odml=0x6F646D6C;
318     const int32u AVI__hdlr_odml_dmlh=0x646D6C68;
319     const int32u AVI__hdlr_ON2h=0x4F4E3268;
320     const int32u AVI__idx1=0x69647831;
321     const int32u AVI__INFO=0x494E464F;
322     const int32u AVI__INFO_IARL=0x4941524C;
323     const int32u AVI__INFO_IART=0x49415254;
324     const int32u AVI__INFO_IAS1=0x49415331;
325     const int32u AVI__INFO_IAS2=0x49415332;
326     const int32u AVI__INFO_IAS3=0x49415333;
327     const int32u AVI__INFO_IAS4=0x49415334;
328     const int32u AVI__INFO_IAS5=0x49415335;
329     const int32u AVI__INFO_IAS6=0x49415336;
330     const int32u AVI__INFO_IAS7=0x49415337;
331     const int32u AVI__INFO_IAS8=0x49415338;
332     const int32u AVI__INFO_IAS9=0x49415339;
333     const int32u AVI__INFO_ICDS=0x49434453;
334     const int32u AVI__INFO_ICMS=0x49434D53;
335     const int32u AVI__INFO_ICMT=0x49434D54;
336     const int32u AVI__INFO_ICNT=0x49434E54;
337     const int32u AVI__INFO_ICOP=0x49434F50;
338     const int32u AVI__INFO_ICNM=0x49434E4D;
339     const int32u AVI__INFO_ICRD=0x49435244;
340     const int32u AVI__INFO_ICRP=0x49435250;
341     const int32u AVI__INFO_IDIM=0x4944494D;
342     const int32u AVI__INFO_IDIT=0x49444954;
343     const int32u AVI__INFO_IDPI=0x49445049;
344     const int32u AVI__INFO_IDST=0x49445354;
345     const int32u AVI__INFO_IEDT=0x49454454;
346     const int32u AVI__INFO_IENG=0x49454E47;
347     const int32u AVI__INFO_IFRM=0x4946524D;
348     const int32u AVI__INFO_IGNR=0x49474E52;
349     const int32u AVI__INFO_IID3=0x49494433;
350     const int32u AVI__INFO_IKEY=0x494B4559;
351     const int32u AVI__INFO_ILGT=0x494C4754;
352     const int32u AVI__INFO_ILNG=0x494C4E47;
353     const int32u AVI__INFO_ILYC=0x494C5943;
354     const int32u AVI__INFO_IMED=0x494D4544;
355     const int32u AVI__INFO_IMP3=0x494D5033;
356     const int32u AVI__INFO_IMUS=0x494D5553;
357     const int32u AVI__INFO_INAM=0x494E414D;
358     const int32u AVI__INFO_IPLT=0x49504C54;
359     const int32u AVI__INFO_IPDS=0x49504453;
360     const int32u AVI__INFO_IPRD=0x49505244;
361     const int32u AVI__INFO_IPRT=0x49505254;
362     const int32u AVI__INFO_IPRO=0x4950524F;
363     const int32u AVI__INFO_IRTD=0x49525444;
364     const int32u AVI__INFO_ISBJ=0x4953424A;
365     const int32u AVI__INFO_ISGN=0x4953474E;
366     const int32u AVI__INFO_ISTD=0x49535444;
367     const int32u AVI__INFO_ISTR=0x49535452;
368     const int32u AVI__INFO_ISFT=0x49534654;
369     const int32u AVI__INFO_ISHP=0x49534850;
370     const int32u AVI__INFO_ISMP=0x49534D50;
371     const int32u AVI__INFO_ISRC=0x49535243;
372     const int32u AVI__INFO_ISRF=0x49535246;
373     const int32u AVI__INFO_ITCH=0x49544348;
374     const int32u AVI__INFO_IWEB=0x49574542;
375     const int32u AVI__INFO_IWRI=0x49575249;
376     const int32u AVI__INFO_JUNK=0x4A554E4B;
377     const int32u AVI__JUNK=0x4A554E4B;
378     const int32u AVI__MD5_=0x4D443520;
379     const int32u AVI__movi=0x6D6F7669;
380     const int32u AVI__movi_rec_=0x72656320;
381     const int32u AVI__movi_xxxx_____=0x00005F5F;
382     const int32u AVI__movi_xxxx___db=0x00006462;
383     const int32u AVI__movi_xxxx___dc=0x00006463;
384     const int32u AVI__movi_xxxx___sb=0x00007362;
385     const int32u AVI__movi_xxxx___tx=0x00007478;
386     const int32u AVI__movi_xxxx___wb=0x00007762;
387     const int32u AVI__PrmA=0x50726D41;
388     const int32u AVI__Tdat=0x54646174;
389     const int32u AVI__Tdat_rn_A=0x726E5F41;
390     const int32u AVI__Tdat_rn_O=0x726E5F4F;
391     const int32u AVI__Tdat_tc_A=0x74635F41;
392     const int32u AVI__Tdat_tc_O=0x74635F4F;
393     const int32u AVIX=0x41564958;
394     const int32u AVIX_idx1=0x69647831;
395     const int32u AVIX_movi=0x6D6F7669;
396     const int32u AVIX_movi_rec_=0x72656320;
397     const int32u CADP=0x43414450;
398     const int32u CDDA=0x43444441;
399     const int32u CDDA_fmt_=0x666D7420;
400     const int32u CMJP=0x434D4A50;
401     const int32u CMP4=0x434D5034;
402     const int32u IDVX=0x49445658;
403     const int32u INDX=0x494E4458;
404     const int32u JUNK=0x4A554E4B;
405     const int32u menu=0x6D656E75;
406     const int32u MThd=0x4D546864;
407     const int32u MTrk=0x4D54726B;
408     const int32u PAL_=0x50414C20;
409     const int32u QLCM=0x514C434D;
410     const int32u QLCM_fmt_=0x666D7420;
411     const int32u rcrd=0x72637264;
412     const int32u rcrd_desc=0x64657363;
413     const int32u rcrd_fld_=0x666C6420;
414     const int32u rcrd_fld__anc_=0x616E6320;
415     const int32u rcrd_fld__anc__pos_=0x706F7320;
416     const int32u rcrd_fld__anc__pyld=0x70796C64;
417     const int32u rcrd_fld__finf=0x66696E66;
418     const int32u RDIB=0x52444942;
419     const int32u RMID=0x524D4944;
420     const int32u RMMP=0x524D4D50;
421     const int32u RMP3=0x524D5033;
422     const int32u RMP3_data=0x64617461;
423     const int32u RMP3_INFO=0x494E464F;
424     const int32u RMP3_INFO_IID3=0x49494433;
425     const int32u RMP3_INFO_ILYC=0x494C5943;
426     const int32u RMP3_INFO_IMP3=0x494D5033;
427     const int32u RMP3_INFO_JUNK=0x4A554E4B;
428     const int32u SMV0=0x534D5630;
429     const int32u SMV0_xxxx=0x534D563A;
430     const int32u WAVE=0x57415645;
431     const int32u WAVE__pmx=0x20786D70;
432     const int32u WAVE_adtl=0x6164746C;
433     const int32u WAVE_adtl_labl=0x6C61626C;
434     const int32u WAVE_adtl_ltxt=0x6C747874;
435     const int32u WAVE_adtl_note=0x6E6F7465;
436     const int32u WAVE_axml=0x61786D6C;
437     const int32u WAVE_bext=0x62657874;
438     const int32u WAVE_bxml=0x62786D6C;
439     const int32u WAVE_cue_=0x63756520;
440     const int32u WAVE_data=0x64617461;
441     const int32u WAVE_dbmd=0x64626D64;
442     const int32u WAVE_ds64=0x64733634;
443     const int32u WAVE_fact=0x66616374;
444     const int32u WAVE_fmt_=0x666D7420;
445     const int32u WAVE_ID3_=0x49443320;
446     const int32u WAVE_id3_=0x69643320;
447     const int32u WAVE_INFO=0x494E464F;
448     const int32u WAVE_iXML=0x69584D4C;
449     const int32u WAVE_mext=0x6D657874;
450     const int32u wave=0x77617665;
451     const int32u wave_data=0x64617461;
452     const int32u wave_fmt_=0x666D7420;
453     const int32u W3DI=0x57334449;
454 
455     #define UUID(NAME, PART1, PART2, PART3, PART4, PART5) \
456         const int64u NAME   =((int64u(0x##PART1))&0xFF)<<56 | ((int64u(0x##PART1)>>8)&0xFF)<<48 | ((int64u(0x##PART1)>>16)&0xFF)<<40 | ((int64u(0x##PART1)>>24)&0xFF)<<32 | ((int64u(0x##PART2))&0xFF)<<24 | ((int64u(0x##PART2)>>8)&0xFF)<<16 | ((int64u(0x##PART3))&0xFF)<<8 | ((int64u(0x##PART3)>>8)&0xFF); \
457         const int64u NAME##2=0x##PART4##PART5##ULL; \
458 
459     UUID(QLCM_QCELP1,                                           5E7F6D41, B115, 11D0, BA91, 00805FB4B97E)
460     UUID(QLCM_QCELP2,                                           5E7F6D42, B115, 11D0, BA91, 00805FB4B97E)
461     UUID(QLCM_EVRC,                                             E689D48D, 9076, 46B5, 91EF, 736A5100CEB4)
462     UUID(QLCM_SMV,                                              8D7C2B75, A797, ED49, 985E, D53C8CC75F84)
463 }
464 
465 //***************************************************************************
466 // Format
467 //***************************************************************************
468 
469 //---------------------------------------------------------------------------
Data_Parse()470 void File_Riff::Data_Parse()
471 {
472     //Alignement specific
473     if (Alignement_ExtraByte<=Element_Size)
474         Element_Size-=Alignement_ExtraByte;
475 
476     DATA_BEGIN
477     LIST(AIFC)
478         ATOM_BEGIN
479         ATOM(AIFC_COMM)
480         ATOM(AIFC_COMT)
481         ATOM(AIFC_FVER)
482         ATOM(AIFC_SSND)
483         ATOM_DEFAULT(AIFC_xxxx)
484         ATOM_END_DEFAULT
485     LIST(AIFF)
486         ATOM_BEGIN
487         ATOM(AIFF_COMM)
488         ATOM(AIFF_COMT)
489         ATOM(AIFF_ID3_)
490         LIST_SKIP(AIFF_SSND)
491         ATOM_DEFAULT(AIFF_xxxx)
492         ATOM_END_DEFAULT
493     LIST(AVI_)
494         ATOM_BEGIN
495         ATOM(AVI__Cr8r);
496         ATOM(AVI__cset)
497         LIST(AVI__exif)
498             ATOM_DEFAULT_ALONE(AVI__exif_xxxx)
499         LIST(AVI__goog)
500             ATOM_BEGIN
501             ATOM(AVI__goog_GDAT)
502             ATOM_END
503         ATOM(AVI__GMET)
504         LIST(AVI__hdlr)
505             ATOM_BEGIN
506             ATOM(AVI__hdlr_avih)
507             ATOM(AVI__hdlr_JUNK)
508             LIST(AVI__hdlr_strl)
509                 ATOM_BEGIN
510                 ATOM(AVI__hdlr_strl_indx)
511                 ATOM(AVI__hdlr_strl_JUNK)
512                 ATOM(AVI__hdlr_strl_strd)
513                 ATOM(AVI__hdlr_strl_strf)
514                 ATOM(AVI__hdlr_strl_strh)
515                 ATOM(AVI__hdlr_strl_strn)
516                 ATOM(AVI__hdlr_strl_vprp)
517                 ATOM_END
518             LIST(AVI__hdlr_odml)
519                 ATOM_BEGIN
520                 ATOM(AVI__hdlr_odml_dmlh)
521                 ATOM_END
522             ATOM(AVI__hdlr_ON2h)
523             LIST(AVI__INFO)
524                 ATOM_BEGIN
525                 ATOM(AVI__INFO_IID3)
526                 ATOM(AVI__INFO_ILYC)
527                 ATOM(AVI__INFO_IMP3)
528                 ATOM(AVI__INFO_JUNK)
529                 ATOM_DEFAULT(AVI__INFO_xxxx)
530                 ATOM_END_DEFAULT
531             ATOM_DEFAULT(AVI__hdlr_xxxx)
532             ATOM_END_DEFAULT
533         ATOM(AVI__idx1)
534         LIST(AVI__INFO)
535             ATOM_BEGIN
536             ATOM(AVI__INFO_IID3)
537             ATOM(AVI__INFO_ILYC)
538             ATOM(AVI__INFO_IMP3)
539             ATOM(AVI__INFO_JUNK)
540             ATOM_DEFAULT(AVI__INFO_xxxx)
541             ATOM_END_DEFAULT
542         ATOM(AVI__JUNK)
543         ATOM(AVI__MD5_)
544         LIST(AVI__movi)
545             ATOM_BEGIN
546             LIST(AVI__movi_rec_)
547                 ATOM_DEFAULT_ALONE(AVI__movi_xxxx)
548             ATOM_DEFAULT(AVI__movi_xxxx)
549             ATOM_END_DEFAULT
550         ATOM(AVI__PrmA);
551         LIST(AVI__Tdat)
552             ATOM_BEGIN
553             ATOM(AVI__Tdat_rn_A)
554             ATOM(AVI__Tdat_rn_O)
555             ATOM(AVI__Tdat_tc_A)
556             ATOM(AVI__Tdat_tc_O)
557             ATOM_END
558         ATOM_DEFAULT(AVI__xxxx)
559         ATOM_END_DEFAULT
560     LIST(AVIX) //OpenDML
561         ATOM_BEGIN
562         ATOM(AVIX_idx1)
563         LIST(AVIX_movi)
564             ATOM_BEGIN
565             LIST(AVIX_movi_rec_)
566                 ATOM_DEFAULT_ALONE(AVIX_movi_xxxx)
567             ATOM_DEFAULT(AVIX_movi_xxxx)
568             ATOM_END_DEFAULT
569         ATOM_END
570     ATOM_PARTIAL(CADP)
571     LIST(CDDA)
572         ATOM_BEGIN
573         ATOM(CDDA_fmt_)
574         ATOM_END
575     ATOM_PARTIAL(CMJP)
576     ATOM(CMP4)
577     ATOM(IDVX)
578     LIST(INDX)
579         ATOM_DEFAULT_ALONE(INDX_xxxx)
580     LIST_SKIP(JUNK)
581     LIST_SKIP(menu)
582     ATOM(MThd)
583     LIST_SKIP(MTrk)
584     LIST_SKIP(PAL_)
585     LIST(QLCM)
586         ATOM_BEGIN
587         ATOM(QLCM_fmt_)
588         ATOM_END
589     #if defined(MEDIAINFO_GXF_YES)
590     LIST(rcrd)
591         ATOM_BEGIN
592         ATOM(rcrd_desc)
593         LIST(rcrd_fld_)
594             ATOM_BEGIN
595             LIST(rcrd_fld__anc_)
596                 ATOM_BEGIN
597                 ATOM(rcrd_fld__anc__pos_)
598                 ATOM(rcrd_fld__anc__pyld)
599                 ATOM_END
600             ATOM(rcrd_fld__finf)
601             ATOM_END
602         ATOM_END
603     #endif //defined(MEDIAINFO_GXF_YES)
604     LIST_SKIP(RDIB)
605     LIST_SKIP(RMID)
606     LIST_SKIP(RMMP)
607     LIST(RMP3)
608         ATOM_BEGIN
609         LIST(RMP3_data)
610             break;
611         LIST(RMP3_INFO)
612             ATOM_BEGIN
613             ATOM(RMP3_INFO_IID3)
614             ATOM(RMP3_INFO_ILYC)
615             ATOM(RMP3_INFO_IMP3)
616             ATOM(RMP3_INFO_JUNK)
617             ATOM_DEFAULT(RMP3_INFO_xxxx)
618             ATOM_END_DEFAULT
619         ATOM_END
620     ATOM(SMV0)
621     ATOM(SMV0_xxxx)
622     ATOM(W3DI)
623     LIST(WAVE)
624         ATOM_BEGIN
625         ATOM(WAVE__pmx)
626         LIST(WAVE_adtl)
627             ATOM_BEGIN
628             ATOM(WAVE_adtl_labl)
629             ATOM(WAVE_adtl_ltxt)
630             ATOM(WAVE_adtl_note)
631             ATOM_END
632         LIST(WAVE_axml)
633             break;
634         ATOM(WAVE_bext)
635         LIST(WAVE_bxml)
636             break;
637         LIST(WAVE_data)
638             break;
639         ATOM(WAVE_cue_)
640         ATOM(WAVE_dbmd)
641         ATOM(WAVE_ds64)
642         ATOM(WAVE_fact)
643         ATOM(WAVE_fmt_)
644         ATOM(WAVE_ID3_)
645         ATOM(WAVE_id3_)
646         LIST(WAVE_INFO)
647             ATOM_DEFAULT_ALONE(WAVE_INFO_xxxx)
648         ATOM(WAVE_iXML)
649         ATOM(WAVE_mext)
650         ATOM_END
651     LIST(wave)
652         ATOM_BEGIN
653         LIST(wave_data)
654             break;
655         ATOM(wave_fmt_)
656         ATOM_END
657     DATA_END
658 
659     if (Alignement_ExtraByte)
660     {
661         Element_Size+=Alignement_ExtraByte;
662         if (Element_Offset+Alignement_ExtraByte==Element_Size)
663             Skip_XX(Alignement_ExtraByte,                       "Alignement");
664     }
665 }
666 
667 //***************************************************************************
668 // Elements
669 //***************************************************************************
670 
671 //---------------------------------------------------------------------------
AIFC()672 void File_Riff::AIFC()
673 {
674     Data_Accept("AIFF Compressed");
675     Element_Name("AIFF Compressed");
676 
677     //Filling
678     Fill(Stream_General, 0, General_Format, "AIFF");
679     Stream_Prepare(Stream_Audio);
680     Kind=Kind_Aiff;
681     #if MEDIAINFO_EVENTS
682         StreamIDs_Width[0]=0;
683     #endif //MEDIAINFO_EVENTS
684 }
685 
686 //---------------------------------------------------------------------------
AIFC_COMM()687 void File_Riff::AIFC_COMM()
688 {
689     AIFF_COMM();
690 }
691 
692 //---------------------------------------------------------------------------
AIFC_COMT()693 void File_Riff::AIFC_COMT()
694 {
695     AIFF_COMT();
696 }
697 
698 //---------------------------------------------------------------------------
AIFC_FVER()699 void File_Riff::AIFC_FVER()
700 {
701     Element_Name("Format Version");
702 
703     //Parsing
704     Skip_B4(                                                    "Version");
705 }
706 
707 //---------------------------------------------------------------------------
AIFC_SSND()708 void File_Riff::AIFC_SSND()
709 {
710     AIFF_SSND();
711 }
712 
713 //---------------------------------------------------------------------------
AIFC_xxxx()714 void File_Riff::AIFC_xxxx()
715 {
716     AIFF_xxxx();
717 }
718 
719 //---------------------------------------------------------------------------
AIFF()720 void File_Riff::AIFF()
721 {
722     Data_Accept("AIFF");
723     Element_Name("AIFF");
724 
725     //Filling
726     Fill(Stream_General, 0, General_Format, "AIFF");
727     Stream_Prepare(Stream_Audio);
728     Kind=Kind_Aiff;
729     #if MEDIAINFO_EVENTS
730         StreamIDs_Width[0]=0;
731     #endif //MEDIAINFO_EVENTS
732 }
733 
734 //---------------------------------------------------------------------------
AIFF_COMM()735 void File_Riff::AIFF_COMM()
736 {
737     Element_Name("Common");
738 
739     int32u numSampleFrames;
740     int16u numChannels, sampleSize;
741     float80 sampleRate80;
742     float64 sampleRate;
743     //Parsing
744     Get_B2 (numChannels,                                    "numChannels");
745     Get_B4 (numSampleFrames,                                "numSampleFrames");
746     Get_B2 (sampleSize,                                     "sampleSize");
747     Get_BF10(sampleRate80,                                  "sampleRate");
748     sampleRate=(float64)sampleRate80;
749     if (Data_Remain()) //AIFC
750     {
751         int32u compressionType;
752         Get_C4 (compressionType,                            "compressionType");
753         Skip_PA(                                            "compressionName");
754 
755         //Filling
756         CodecID_Fill(Ztring().From_CC4(compressionType), Stream_Audio, StreamPos_Last, InfoCodecID_Format_Mpeg4);
757         Fill(Stream_Audio, StreamPos_Last, Audio_Codec, Ztring().From_CC4(compressionType));
758     }
759     else
760     {
761         //Filling
762         Fill(Stream_Audio, StreamPos_Last, Audio_Format, "PCM");
763         Fill(Stream_Audio, StreamPos_Last, Audio_Codec, "PCM");
764     }
765 
766     //Filling
767     Fill(Stream_Audio, StreamPos_Last, Audio_Channel_s_, numChannels);
768     Fill(Stream_Audio, StreamPos_Last, Audio_BitDepth, sampleSize);
769     if (sampleRate)
770         Fill(Stream_Audio, StreamPos_Last, Audio_Duration, numSampleFrames/sampleRate*1000, 0);
771     Fill(Stream_Audio, StreamPos_Last, Audio_SamplingRate, sampleRate, 0);
772 
773     //Compute the current codec ID
774     Element_Code=(int64u)-1;
775     Stream_ID=(int32u)-1;
776     stream_Count=1;
777 
778     //Specific cases
779     #if defined(MEDIAINFO_PCM_YES) || defined(MEDIAINFO_DTS_YES) || defined(MEDIAINFO_SMPTEST0337_YES)
780         stream& StreamItem=Stream[Stream_ID];
781         Ztring Codec=Retrieve(Stream_Audio, StreamPos_Last, Audio_CodecID);
782         Parser_Pcm(StreamItem, numChannels, sampleSize, sampleSize, sampleRate, (Codec.empty() || Codec==__T("NONE"))?'B':'\0');
783     #endif
784 
785     #if MEDIAINFO_DEMUX
786         unsigned int ComputedBlockAlign=numChannels*sampleSize/8;
787         if (ComputedBlockAlign<0x10000)
788         {
789             BlockAlign=(int16u)ComputedBlockAlign;
790             AvgBytesPerSec=(int32u)float64_int64s(ComputedBlockAlign*sampleRate);
791         }
792     #endif //MEDIAINFO_DEMUX
793 
794     Element_Code=(int64u)-1;
795     Open_Buffer_Init_All();
796 }
797 
798 //---------------------------------------------------------------------------
AIFF_COMT()799 void File_Riff::AIFF_COMT()
800 {
801     //Parsing
802     int16u numComments;
803     Get_B2(numComments,                                         "numComments");
804     for (int16u Pos=0; Pos<=numComments; Pos++)
805     {
806         Ztring text;
807         int16u count;
808         Element_Begin1("Comment");
809         Skip_B4(                                                "timeStamp");
810         Skip_B4(                                                "marker");
811         Get_B2 (count,                                          "count");
812         count+=count%1; //always even
813         Get_Local(count, text,                                  "text");
814         Element_End0();
815 
816         //Filling
817         Fill(Stream_General, 0, General_Comment, text);
818     }
819 }
820 
821 //---------------------------------------------------------------------------
AIFF_SSND()822 void File_Riff::AIFF_SSND()
823 {
824     Skip_B4(                                                    "offset"); //TODO: support offset
825     Skip_B4(                                                    "blockSize");
826     Buffer_DataToParse_Begin+=Element_Offset;
827     WAVE_data();
828 }
829 
830 //---------------------------------------------------------------------------
AIFF_SSND_Continue()831 void File_Riff::AIFF_SSND_Continue()
832 {
833     WAVE_data_Continue();
834 }
835 
836 //---------------------------------------------------------------------------
AIFF_xxxx()837 void File_Riff::AIFF_xxxx()
838 {
839     #define ELEMENT_CASE(_ELEMENT, _NAME) \
840         case Elements::_ELEMENT : Element_Name(_NAME); Name=_NAME; break;
841 
842     //Known?
843     std::string Name;
844     switch(Element_Code)
845     {
846         ELEMENT_CASE(AIFF__c__, "Copyright");
847         ELEMENT_CASE(AIFF_ANNO, "Comment");
848         ELEMENT_CASE(AIFF_AUTH, "Performer");
849         ELEMENT_CASE(AIFF_NAME, "Title");
850         default : Skip_XX(Element_Size,                         "Unknown");
851                   return;
852     }
853 
854     //Parsing
855     Ztring text;
856     Get_Local(Element_Size, text,                               "text");
857 
858     //Filling
859     Fill(Stream_General, 0, Name.c_str(), text);
860 }
861 
862 //---------------------------------------------------------------------------
AVI_()863 void File_Riff::AVI_()
864 {
865     Element_Name("AVI");
866 
867     //Test if there is only one AVI chunk
868     if (Status[IsAccepted])
869     {
870         Element_Info1("Problem: 2 AVI chunks, this is not normal");
871         Skip_XX(Element_TotalSize_Get(),                        "Data");
872         return;
873     }
874 
875     Data_Accept("AVI");
876 
877     //Filling
878     Fill(Stream_General, 0, General_Format, "AVI");
879     Kind=Kind_Avi;
880 
881     //Configuration
882     Buffer_MaximumSize=64*1024*1024; //Some big frames are possible (e.g YUV 4:2:2 10 bits 1080p)
883 }
884 
885 //---------------------------------------------------------------------------
AVI__Cr8r()886 void File_Riff::AVI__Cr8r()
887 {
888     Element_Name("Adobe Premiere Cr8r");
889 
890     //Parsing
891     Skip_C4(                                                    "FourCC");
892     Skip_B4(                                                    "Size");
893     Skip_XX(Element_Size-Element_Offset,                        "Unknown");
894 }
895 
896 //---------------------------------------------------------------------------
AVI__cset()897 void File_Riff::AVI__cset()
898 {
899     Element_Name("Regional settings");
900 
901     //Parsing
902     Skip_L2(                                                    "CodePage"); //TODO: take a look about IBM/MS RIFF/MCI Specification 1.0
903     Skip_L2(                                                    "CountryCode");
904     Skip_L2(                                                    "LanguageCode");
905     Skip_L2(                                                    "Dialect");
906 }
907 
908 //---------------------------------------------------------------------------
AVI__exif()909 void File_Riff::AVI__exif()
910 {
911     Element_Name("Exif (Exchangeable Image File Format)");
912 }
913 
914 //---------------------------------------------------------------------------
AVI__exif_xxxx()915 void File_Riff::AVI__exif_xxxx()
916 {
917     Element_Name("Value");
918 
919     //Parsing
920     Ztring Value;
921     Get_Local(Element_Size, Value,                              "Value");
922 
923     //Filling
924     switch (Element_Code)
925     {
926         case Elements::AVI__exif_ecor : Fill(Stream_General, 0, "Make", Value); break;
927         case Elements::AVI__exif_emdl : Fill(Stream_General, 0, "Model", Value); break;
928         case Elements::AVI__exif_emnt : Fill(Stream_General, 0, "MakerNotes", Value); break;
929         case Elements::AVI__exif_erel : Fill(Stream_General, 0, "RelatedImageFile", Value); break;
930         case Elements::AVI__exif_etim : Fill(Stream_General, 0, "Written_Date", Value); break;
931         case Elements::AVI__exif_eucm : Fill(Stream_General, 0, General_Comment, Value); break;
932         case Elements::AVI__exif_ever : break; //Exif version
933         default:                    Fill(Stream_General, 0, Ztring().From_CC4((int32u)Element_Code).To_Local().c_str(), Value);
934     }
935 }
936 
937 //---------------------------------------------------------------------------
AVI__goog()938 void File_Riff::AVI__goog()
939 {
940     Element_Name("Google specific");
941 
942     //Filling
943     Fill(Stream_General, 0, General_Format, "Google Video", Unlimited, true, true);
944 }
945 
946 //---------------------------------------------------------------------------
AVI__goog_GDAT()947 void File_Riff::AVI__goog_GDAT()
948 {
949     Element_Name("Google datas");
950 }
951 
952 //---------------------------------------------------------------------------
953 // Google Metadata
954 //
AVI__GMET()955 void File_Riff::AVI__GMET()
956 {
957     Element_Name("Google Metadatas");
958 
959     //Parsing
960     Ztring Value; Value.From_UTF8((const char*)(Buffer+Buffer_Offset+0), (size_t)Element_Size);
961     ZtringListList List;
962     List.Separator_Set(0, __T("\n"));
963     List.Separator_Set(1, __T(":"));
964     List.Max_Set(1, 2);
965     List.Write(Value);
966 
967     //Details
968     #if MEDIAINFO_TRACE
969         if (Config_Trace_Level)
970         {
971             //for (size_t Pos=0; Pos<List.size(); Pos++)
972             //    Details_Add_Info(Pos, List(Pos, 0).To_Local().c_str(), List(Pos, 1));
973         }
974     #endif //MEDIAINFO_TRACE
975 
976     //Filling
977     for (size_t Pos=0; Pos<List.size(); Pos++)
978     {
979         if (List(Pos, 0)==__T("title"))          Fill(Stream_General, 0, General_Title, List(Pos, 1));
980         if (List(Pos, 0)==__T("description"))    Fill(Stream_General, 0, General_Title_More, List(Pos, 1));
981         if (List(Pos, 0)==__T("url"))            Fill(Stream_General, 0, General_Title_Url, List(Pos, 1));
982         if (List(Pos, 0)==__T("docid"))          Fill(Stream_General, 0, General_UniqueID, List(Pos, 1));
983     }
984 }
985 
986 //---------------------------------------------------------------------------
AVI__hdlr()987 void File_Riff::AVI__hdlr()
988 {
989     Element_Name("AVI Header");
990 }
991 
992 //---------------------------------------------------------------------------
AVI__hdlr_avih()993 void File_Riff::AVI__hdlr_avih()
994 {
995     Element_Name("File header");
996 
997     //Parsing
998     int32u MicrosecPerFrame, Flags;
999     Get_L4 (MicrosecPerFrame,                                   "MicrosecPerFrame");
1000     Skip_L4(                                                    "MaxBytesPerSec");
1001     Skip_L4(                                                    "PaddingGranularity");
1002     Get_L4 (Flags,                                              "Flags");
1003         Skip_Flags(Flags,  4,                                   "HasIndex");
1004         Skip_Flags(Flags,  5,                                   "MustUseIndex");
1005         Skip_Flags(Flags,  8,                                   "IsInterleaved");
1006         Skip_Flags(Flags,  9,                                   "UseCKTypeToFindKeyFrames");
1007         Skip_Flags(Flags, 11,                                   "TrustCKType");
1008         Skip_Flags(Flags, 16,                                   "WasCaptureFile");
1009         Skip_Flags(Flags, 17,                                   "Copyrighted");
1010     Get_L4 (avih_TotalFrame,                                    "TotalFrames");
1011     Skip_L4(                                                    "InitialFrames");
1012     Skip_L4(                                                    "StreamsCount");
1013     Skip_L4(                                                    "SuggestedBufferSize");
1014     Skip_L4(                                                    "Width");
1015     Skip_L4(                                                    "Height");
1016     Skip_L4(                                                    "Reserved");
1017     Skip_L4(                                                    "Reserved");
1018     Skip_L4(                                                    "Reserved");
1019     Skip_L4(                                                    "Reserved");
1020     if(Element_Offset<Element_Size)
1021         Skip_XX(Element_Size-Element_Offset,                    "Unknown");
1022 
1023     //Filling
1024     if (MicrosecPerFrame>0)
1025         avih_FrameRate=1000000.0/MicrosecPerFrame;
1026 }
1027 
1028 //---------------------------------------------------------------------------
AVI__hdlr_JUNK()1029 void File_Riff::AVI__hdlr_JUNK()
1030 {
1031     Element_Name("Garbage");
1032 }
1033 
1034 //---------------------------------------------------------------------------
AVI__hdlr_odml()1035 void File_Riff::AVI__hdlr_odml()
1036 {
1037     Element_Name("OpenDML");
1038 }
1039 
1040 //---------------------------------------------------------------------------
AVI__hdlr_odml_dmlh()1041 void File_Riff::AVI__hdlr_odml_dmlh()
1042 {
1043     Element_Name("OpenDML Header");
1044 
1045     //Parsing
1046     Get_L4(dmlh_TotalFrame,                                     "GrandFrames");
1047     if (Element_Offset<Element_Size)
1048         Skip_XX(Element_Size-Element_Offset,                    "Unknown");
1049 }
1050 
1051 //---------------------------------------------------------------------------
AVI__hdlr_ON2h()1052 void File_Riff::AVI__hdlr_ON2h()
1053 {
1054     Element_Name("On2 header");
1055 
1056     //Parsing
1057     Skip_XX(Element_Size,                                       "Unknown");
1058 }
1059 
1060 //---------------------------------------------------------------------------
AVI__hdlr_strl()1061 void File_Riff::AVI__hdlr_strl()
1062 {
1063     Element_Name("Stream info");
1064     Element_Info1(stream_Count);
1065 
1066     //Clean up
1067     StreamKind_Last=Stream_Max;
1068     StreamPos_Last=(size_t)-1;
1069 
1070     //Compute the current codec ID
1071     Stream_ID=(('0'+stream_Count/10)*0x01000000
1072               +('0'+stream_Count   )*0x00010000);
1073     stream_Count++;
1074 }
1075 
1076 //---------------------------------------------------------------------------
AVI__hdlr_strl_indx()1077 void File_Riff::AVI__hdlr_strl_indx()
1078 {
1079     Element_Name("Index");
1080 
1081     int32u Entry_Count, ChunkId;
1082     int16u LongsPerEntry;
1083     int8u  IndexType, IndexSubType;
1084     Get_L2 (LongsPerEntry,                                      "LongsPerEntry"); //Size of each entry in aIndex array
1085     Get_L1 (IndexSubType,                                       "IndexSubType");
1086     Get_L1 (IndexType,                                          "IndexType");
1087     Get_L4 (Entry_Count,                                        "EntriesInUse"); //Index of first unused member in aIndex array
1088     Get_C4 (ChunkId,                                            "ChunkId"); //FCC of what is indexed
1089 
1090     //Depends of size of structure...
1091     switch (IndexType)
1092     {
1093         case 0x01 : //AVI_INDEX_OF_CHUNKS
1094                     switch (IndexSubType)
1095                     {
1096                         case 0x00 : AVI__hdlr_strl_indx_StandardIndex(Entry_Count, ChunkId); break;
1097                         case 0x01 : AVI__hdlr_strl_indx_FieldIndex(Entry_Count, ChunkId); break; //AVI_INDEX_2FIELD
1098                         default: Skip_XX(Element_Size-Element_Offset, "Unknown");
1099                     }
1100                     break;
1101         case 0x0 : //AVI_INDEX_OF_INDEXES
1102                     switch (IndexSubType)
1103                     {
1104                         case 0x00 :
1105                         case 0x01 : AVI__hdlr_strl_indx_SuperIndex(Entry_Count, ChunkId); break; //AVI_INDEX_2FIELD
1106                         default: Skip_XX(Element_Size-Element_Offset, "Unknown");
1107                     }
1108                     break;
1109         default: Skip_XX(Element_Size-Element_Offset,           "Unknown");
1110     }
1111 }
1112 
1113 //---------------------------------------------------------------------------
AVI__hdlr_strl_indx_StandardIndex(int32u Entry_Count,int32u ChunkId)1114 void File_Riff::AVI__hdlr_strl_indx_StandardIndex(int32u Entry_Count, int32u ChunkId)
1115 {
1116     Element_Name("Standard Index");
1117 
1118     //Parsing
1119     int64u BaseOffset, StreamSize=0;
1120     Get_L8 (BaseOffset,                                         "BaseOffset");
1121     Skip_L4(                                                    "Reserved3");
1122     for (int32u Pos=0; Pos<Entry_Count; Pos++)
1123     {
1124         //Is too slow
1125         /*
1126         Element_Begin1("Index");
1127         int32u Offset, Size;
1128         Get_L4 (Offset,                                         "Offset"); //BaseOffset + this is absolute file offset
1129         Get_L4 (Size,                                           "Size"); //Bit 31 is set if this is NOT a keyframe
1130         Element_Info1(Size&0x7FFFFFFF);
1131         if (Size)
1132             Element_Info1("KeyFrame");
1133         Element_End0();
1134         */
1135 
1136         //Faster method
1137         if (Element_Offset+8>Element_Size)
1138             break; //Malformed index
1139         int32u Offset=LittleEndian2int32u(Buffer+Buffer_Offset+(size_t)Element_Offset  );
1140         int32u Size  =LittleEndian2int32u(Buffer+Buffer_Offset+(size_t)Element_Offset+4)&0x7FFFFFFF;
1141         Element_Offset+=8;
1142 
1143         //Stream Position and size
1144         if (Pos<300 || Config->ParseSpeed>=1.0)
1145         {
1146             stream_structure& Stream_Structure_Item=Stream_Structure[BaseOffset+Offset-8];
1147             Stream_Structure_Item.Name=ChunkId&0xFFFF0000;
1148             Stream_Structure_Item.Size=Size;
1149         }
1150         StreamSize+=(Size&0x7FFFFFFF);
1151         Stream[ChunkId&0xFFFF0000].PacketCount++;
1152 
1153         //Interleaved
1154         if (Pos==  0 && (ChunkId&0xFFFF0000)==0x30300000 && Interleaved0_1  ==0)
1155             Interleaved0_1 =BaseOffset+Offset-8;
1156         if (Pos==Entry_Count/10 && (ChunkId&0xFFFF0000)==0x30300000 && Interleaved0_10==0)
1157             Interleaved0_10=BaseOffset+Offset-8;
1158         if (Pos==  0 && (ChunkId&0xFFFF0000)==0x30310000 && Interleaved1_1  ==0)
1159             Interleaved1_1 =BaseOffset+Offset-8;
1160         if (Pos==Entry_Count/10 && (ChunkId&0xFFFF0000)==0x30310000 && Interleaved1_10==0)
1161             Interleaved1_10=BaseOffset+Offset-8;
1162     }
1163     Stream[ChunkId&0xFFFF0000].StreamSize+=StreamSize;
1164     if (Element_Offset<Element_Size)
1165         Skip_XX(Element_Size-Element_Offset,                    "Garbage");
1166 }
1167 
1168 //---------------------------------------------------------------------------
AVI__hdlr_strl_indx_FieldIndex(int32u Entry_Count,int32u)1169 void File_Riff::AVI__hdlr_strl_indx_FieldIndex(int32u Entry_Count, int32u)
1170 {
1171     Element_Name("Field Index");
1172 
1173     //Parsing
1174     Skip_L8(                                                    "Offset");
1175     Skip_L4(                                                    "Reserved2");
1176     for (int32u Pos=0; Pos<Entry_Count; Pos++)
1177     {
1178         Element_Begin1("Index");
1179         Skip_L4(                                                "Offset"); //BaseOffset + this is absolute file offset
1180         Skip_L4(                                                "Size"); //Bit 31 is set if this is NOT a keyframe
1181         Skip_L4(                                                "OffsetField2"); //Offset to second field
1182         Element_End0();
1183     }
1184 }
1185 
1186 //---------------------------------------------------------------------------
AVI__hdlr_strl_indx_SuperIndex(int32u Entry_Count,int32u ChunkId)1187 void File_Riff::AVI__hdlr_strl_indx_SuperIndex(int32u Entry_Count, int32u ChunkId)
1188 {
1189     Element_Name("Index of Indexes");
1190 
1191     //Parsing
1192     int64u Offset;
1193     Skip_L4(                                                    "Reserved0");
1194     Skip_L4(                                                    "Reserved1");
1195     Skip_L4(                                                    "Reserved2");
1196     stream& StreamItem = Stream[Stream_ID];
1197     for (int32u Pos=0; Pos<Entry_Count; Pos++)
1198     {
1199         int32u Duration;
1200         Element_Begin1("Index of Indexes");
1201         Get_L8 (Offset,                                         "Offset");
1202         Skip_L4(                                                "Size"); //Size of index chunk at this offset
1203         Get_L4 (Duration,                                       "Duration"); //time span in stream ticks
1204         Index_Pos[Offset]=ChunkId;
1205         StreamItem.indx_Duration+=Duration;
1206         Element_End0();
1207     }
1208 
1209     //We needn't anymore Old version
1210     NeedOldIndex=false;
1211 }
1212 
1213 //---------------------------------------------------------------------------
AVI__hdlr_strl_JUNK()1214 void File_Riff::AVI__hdlr_strl_JUNK()
1215 {
1216     Element_Name("Garbage");
1217 }
1218 
1219 //---------------------------------------------------------------------------
AVI__hdlr_strl_strd()1220 void File_Riff::AVI__hdlr_strl_strd()
1221 {
1222     Element_Name("Stream datas");
1223 
1224     //Parsing
1225     Skip_XX(Element_Size,                                       "Unknown");
1226 }
1227 
1228 //---------------------------------------------------------------------------
AVI__hdlr_strl_strf()1229 void File_Riff::AVI__hdlr_strl_strf()
1230 {
1231     Element_Name("Stream format");
1232 
1233     //Parse depending of kind of stream
1234     stream& StreamItem = Stream[Stream_ID];
1235     switch (StreamItem.fccType)
1236     {
1237         case Elements::AVI__hdlr_strl_strh_auds : AVI__hdlr_strl_strf_auds(); break;
1238         case Elements::AVI__hdlr_strl_strh_iavs : AVI__hdlr_strl_strf_iavs(); break;
1239         case Elements::AVI__hdlr_strl_strh_mids : AVI__hdlr_strl_strf_mids(); break;
1240         case Elements::AVI__hdlr_strl_strh_txts : AVI__hdlr_strl_strf_txts(); break;
1241         case Elements::AVI__hdlr_strl_strh_vids : AVI__hdlr_strl_strf_vids(); break;
1242         default :                                 Element_Info1("Unknown");
1243     }
1244 
1245     //Registering stream
1246     StreamItem.StreamKind=StreamKind_Last;
1247     StreamItem.StreamPos=StreamPos_Last;
1248 }
1249 
1250 //---------------------------------------------------------------------------
AVI__hdlr_strl_strf_auds()1251 void File_Riff::AVI__hdlr_strl_strf_auds()
1252 {
1253     Element_Info1("Audio");
1254 
1255     //Parsing
1256     #if !MEDIAINFO_DEMUX
1257         int32u AvgBytesPerSec;
1258     #endif //!MEDIAINFO_DEMUX
1259     int16u FormatTag, Channels;
1260     BitsPerSample=0;
1261     Get_L2 (FormatTag,                                          "FormatTag");
1262     Get_L2 (Channels,                                           "Channels");
1263     Get_L4 (SamplesPerSec,                                      "SamplesPerSec");
1264     Get_L4 (AvgBytesPerSec,                                     "AvgBytesPerSec");
1265     Get_L2 (BlockAlign,                                         "BlockAlign");
1266     if (Element_Offset+2<=Element_Size)
1267         Get_L2 (BitsPerSample,                                  "BitsPerSample");
1268 
1269     if (FormatTag==1) //Only for PCM
1270     {
1271         //Coherancy
1272         if (BitsPerSample && SamplesPerSec*BitsPerSample*Channels/8==AvgBytesPerSec*8)
1273             AvgBytesPerSec*=8; //Found in one file. TODO: Provide information to end user about such error
1274 
1275         //Computing of missing value
1276         if (!BitsPerSample && AvgBytesPerSec && SamplesPerSec && Channels)
1277             BitsPerSample=(int16u)(AvgBytesPerSec*8/SamplesPerSec/Channels);
1278     }
1279 
1280     //Filling
1281     Stream_Prepare(Stream_Audio);
1282     stream& StreamItem = Stream[Stream_ID];
1283     StreamItem.Compression=FormatTag;
1284     Ztring Codec; Codec.From_Number(FormatTag, 16);
1285     Codec.MakeUpperCase();
1286     CodecID_Fill(Codec, Stream_Audio, StreamPos_Last, InfoCodecID_Format_Riff);
1287     Fill(Stream_Audio, StreamPos_Last, Audio_Codec, Codec); //May be replaced by codec parser
1288     Fill(Stream_Audio, StreamPos_Last, Audio_Codec_CC, Codec);
1289     if (Channels)
1290     {
1291         Ztring Format=MediaInfoLib::Config.CodecID_Get(Stream_Audio, InfoCodecID_Format_Riff, Codec);
1292         if (!(Channels==5 && (Format==__T("AC-3") || Format==__T("DTS")))) //Lot of 5.1 streams fill 5 here, but we don't know if it is 5.1 or 5.0, so we let info from container blank. TODO: streams without crosscheck error should be only with 5 or 6 channels
1293             Fill(Stream_Audio, StreamPos_Last, Audio_Channel_s_, Channels);
1294     }
1295     if (SamplesPerSec)
1296         Fill(Stream_Audio, StreamPos_Last, Audio_SamplingRate, SamplesPerSec);
1297     if (AvgBytesPerSec)
1298         Fill(Stream_Audio, StreamPos_Last, Audio_BitRate, AvgBytesPerSec*8);
1299     if (BitsPerSample)
1300         Fill(Stream_Audio, StreamPos_Last, Audio_BitDepth, BitsPerSample);
1301     StreamItem.AvgBytesPerSec=AvgBytesPerSec; //Saving bitrate for each stream
1302     if (SamplesPerSec && TimeReference!=(int64u)-1)
1303     {
1304         Fill(Stream_Audio, 0, Audio_Delay, float64_int64s(((float64)TimeReference)*1000/SamplesPerSec));
1305         Fill(Stream_Audio, 0, Audio_Delay_Source, "Container (bext)");
1306     }
1307 
1308     //Creating the parser
1309          if (0);
1310     #if defined(MEDIAINFO_MPEGA_YES)
1311     else if (MediaInfoLib::Config.CodecID_Get(Stream_Audio, InfoCodecID_Format_Riff, Codec)==__T("MPEG Audio"))
1312     {
1313         File_Mpega* Parser=new File_Mpega;
1314         Parser->CalculateDelay=true;
1315         Parser->ShouldContinueParsing=true;
1316         StreamItem.Parsers.push_back(Parser);
1317     }
1318     #endif
1319     #if defined(MEDIAINFO_AC3_YES)
1320     else if (MediaInfoLib::Config.CodecID_Get(Stream_Audio, InfoCodecID_Format_Riff, Codec)==__T("AC-3"))
1321     {
1322         File_Ac3* Parser=new File_Ac3;
1323         Parser->Frame_Count_Valid=2;
1324         Parser->CalculateDelay=true;
1325         Parser->ShouldContinueParsing=true;
1326         StreamItem.Parsers.push_back(Parser);
1327     }
1328     #endif
1329     #if defined(MEDIAINFO_DTS_YES)
1330     else if (MediaInfoLib::Config.CodecID_Get(Stream_Audio, InfoCodecID_Format_Riff, Codec)==__T("DTS"))
1331     {
1332         File_Dts* Parser=new File_Dts;
1333         Parser->Frame_Count_Valid=2;
1334         Parser->ShouldContinueParsing=true;
1335         StreamItem.Parsers.push_back(Parser);
1336     }
1337     #endif
1338     #if defined(MEDIAINFO_AAC_YES)
1339     else if (MediaInfoLib::Config.CodecID_Get(Stream_Audio, InfoCodecID_Format_Riff, Codec)==__T("AAC"))
1340     {
1341         File_Aac* Parser=new File_Aac;
1342         Parser->Mode=File_Aac::Mode_ADTS;
1343         Parser->Frame_Count_Valid=1;
1344         Parser->ShouldContinueParsing=true;
1345         StreamItem.Parsers.push_back(Parser);
1346     }
1347     #endif
1348     #if defined(MEDIAINFO_PCM_YES) || defined(MEDIAINFO_DTS_YES) || defined(MEDIAINFO_SMPTEST0337_YES)
1349     if (MediaInfoLib::Config.CodecID_Get(Stream_Audio, InfoCodecID_Format_Riff, Codec) == __T("PCM"))
1350     {
1351         Parser_Pcm(StreamItem, Channels, BitsPerSample, BitsPerSample, SamplesPerSec);
1352     }
1353     #endif
1354     #if defined(MEDIAINFO_ADPCM_YES)
1355     else if (MediaInfoLib::Config.CodecID_Get(Stream_Audio, InfoCodecID_Format_Riff, Codec)==__T("ADPCM"))
1356     {
1357         //Creating the parser
1358         File_Adpcm MI;
1359         MI.Codec=Codec;
1360 
1361         //Parsing
1362         Open_Buffer_Init(&MI);
1363         Open_Buffer_Continue(&MI, 0);
1364 
1365         //Filling
1366         Finish(&MI);
1367         Merge(MI, StreamKind_Last, 0, StreamPos_Last);
1368     }
1369     #endif
1370     #if defined(MEDIAINFO_OGG_YES)
1371     else if (MediaInfoLib::Config.CodecID_Get(Stream_Audio, InfoCodecID_Format_Riff, Codec)==__T("Vorbis")
1372           && FormatTag!=0x566F) //0x566F has config in this chunk
1373     {
1374         File_Ogg* Parser=new File_Ogg;
1375         Parser->ShouldContinueParsing=true;
1376         StreamItem.Parsers.push_back(Parser);
1377     }
1378     #endif
1379     Open_Buffer_Init_All();
1380 
1381     //Options
1382     if (Element_Offset+2>Element_Size)
1383         return; //No options
1384 
1385     //Parsing
1386     int16u Option_Size;
1387     Get_L2 (Option_Size,                                        "cbSize");
1388 
1389     //Filling
1390     if (Option_Size>0)
1391     {
1392              if (0);
1393         else if (MediaInfoLib::Config.CodecID_Get(Stream_Audio, InfoCodecID_Format_Riff, Codec)==__T("MPEG Audio"))
1394         {
1395             if (Option_Size==12)
1396                 AVI__hdlr_strl_strf_auds_Mpega();
1397             else
1398                 Skip_XX(Option_Size,                            "MPEG Audio - Uknown");
1399         }
1400         else if (Codec==__T("AAC") || Codec==__T("FF") || Codec==__T("8180"))
1401             AVI__hdlr_strl_strf_auds_Aac();
1402         else if (FormatTag==0x566F) //Vorbis with Config in this chunk
1403             AVI__hdlr_strl_strf_auds_Vorbis();
1404         else if (FormatTag==0x6750) //Vorbis with Config in this chunk
1405             AVI__hdlr_strl_strf_auds_Vorbis2();
1406         else if (FormatTag==0xFFFE) //Extensible Wave
1407             AVI__hdlr_strl_strf_auds_ExtensibleWave(BitsPerSample);
1408         else if (Element_Offset+Option_Size<=Element_Size)
1409             Skip_XX(Option_Size,                               "Unknown");
1410         else if (Element_Offset!=Element_Size)
1411             Skip_XX(Element_Size-Element_Offset,               "Error");
1412     }
1413 
1414     if (Retrieve(Stream_Audio, 0, Audio_Format)==__T("PCM"))
1415     {
1416         //BlockAlign
1417         int32u ComputedBlockAlign=Channels*BitsPerSample/8;
1418         if (BlockAlign && BlockAlign==(int16u)-1)
1419         {
1420             if (BlockAlign!=ComputedBlockAlign)
1421                 Fill(Stream_Audio, StreamKind_Last, "BlockAlignIssue", Ztring::ToZtring(BlockAlign)+__T(", expected ")+Ztring::ToZtring(ComputedBlockAlign));
1422         }
1423         else // For WAVE data
1424             BlockAlign=ComputedBlockAlign;
1425     }
1426 }
1427 
1428 //---------------------------------------------------------------------------
AVI__hdlr_strl_strf_auds_Mpega()1429 void File_Riff::AVI__hdlr_strl_strf_auds_Mpega()
1430 {
1431     //Parsing
1432     Element_Begin1("MPEG Audio options");
1433     Skip_L2(                                                    "ID");
1434     Skip_L4(                                                    "Flags");
1435     Skip_L2(                                                    "BlockSize");
1436     Skip_L2(                                                    "FramesPerBlock");
1437     Skip_L2(                                                    "CodecDelay");
1438     Element_End0();
1439 }
1440 
1441 //---------------------------------------------------------------------------
AVI__hdlr_strl_strf_auds_Aac()1442 void File_Riff::AVI__hdlr_strl_strf_auds_Aac()
1443 {
1444     //Parsing
1445     Element_Begin1("AAC options");
1446     #if defined(MEDIAINFO_AAC_YES)
1447         File_Aac* MI=new File_Aac();
1448         MI->Mode=File_Aac::Mode_AudioSpecificConfig;
1449         Open_Buffer_Init(MI);
1450         Open_Buffer_Continue(MI);
1451         Finish(MI);
1452         Merge(*MI, StreamKind_Last, 0, StreamPos_Last);
1453         delete MI; //MI=NULL;
1454     #else //MEDIAINFO_MPEG4_YES
1455         Skip_XX(Element_Size-Element_Offset,                    "(AudioSpecificConfig)");
1456     #endif
1457     Element_End0();
1458 }
1459 
1460 //---------------------------------------------------------------------------
AVI__hdlr_strl_strf_auds_Vorbis()1461 void File_Riff::AVI__hdlr_strl_strf_auds_Vorbis()
1462 {
1463     //Parsing
1464     Element_Begin1("Vorbis options");
1465     #if defined(MEDIAINFO_OGG_YES)
1466         File_Ogg_SubElement MI;
1467         Open_Buffer_Init(&MI);
1468         Element_Begin1("Element sizes");
1469             //All elements parsing, except last one
1470             std::vector<size_t> Elements_Size;
1471             size_t Elements_TotalSize=0;
1472             int8u Elements_Count;
1473             Get_L1(Elements_Count,                                  "Element count");
1474             Elements_Size.resize(Elements_Count+1); //+1 for the last block
1475             for (int8u Pos=0; Pos<Elements_Count; Pos++)
1476             {
1477                 int8u Size;
1478                 Get_L1(Size,                                        "Size");
1479                 Elements_Size[Pos]=Size;
1480                 Elements_TotalSize+=Size;
1481             }
1482         Element_End0();
1483         if (Element_Offset+Elements_TotalSize>Element_Size)
1484             return;
1485         //Adding the last block
1486         Elements_Size[Elements_Count]=(size_t)(Element_Size-(Element_Offset+Elements_TotalSize));
1487         Elements_Count++;
1488         //Parsing blocks
1489         for (int8u Pos=0; Pos<Elements_Count; Pos++)
1490         {
1491             Open_Buffer_Continue(&MI, Elements_Size[Pos]);
1492             Open_Buffer_Continue(&MI, 0);
1493             Element_Offset+=Elements_Size[Pos];
1494         }
1495         //Finalizing
1496         Finish(&MI);
1497         Merge(MI, StreamKind_Last, 0, StreamPos_Last);
1498         Clear(Stream_Audio, StreamPos_Last, Audio_BitDepth); //Resolution is not valid for Vorbis
1499         Element_Show();
1500     #else //MEDIAINFO_MPEG4_YES
1501         Skip_XX(Element_Size-Element_Offset,                    "(Vorbis headers)");
1502     #endif
1503     Element_End0();
1504 }
1505 
1506 //---------------------------------------------------------------------------
AVI__hdlr_strl_strf_auds_Vorbis2()1507 void File_Riff::AVI__hdlr_strl_strf_auds_Vorbis2()
1508 {
1509     //Parsing
1510     Skip_XX(8,                                                  "Vorbis Unknown");
1511     Element_Begin1("Vorbis options");
1512     #if defined(MEDIAINFO_OGG_YES)
1513         stream& StreamItem = Stream[Stream_ID];
1514         Open_Buffer_Continue(StreamItem.Parsers[0]);
1515         Open_Buffer_Continue(StreamItem.Parsers[0], 0);
1516         Finish(StreamItem.Parsers[0]);
1517         Merge(*StreamItem.Parsers[0], StreamKind_Last, 0, StreamPos_Last);
1518         Element_Show();
1519     #else //MEDIAINFO_MPEG4_YES
1520         Skip_XX(Element_Size-Element_Offset,                    "(Vorbis headers)");
1521     #endif
1522     Element_End0();
1523 }
1524 
1525 //---------------------------------------------------------------------------
AVI__hdlr_strl_strf_auds_ExtensibleWave(int16u BitsPerSample)1526 void File_Riff::AVI__hdlr_strl_strf_auds_ExtensibleWave(int16u BitsPerSample)
1527 {
1528     //Parsing
1529     int128u SubFormat;
1530     int32u ChannelMask;
1531     int16u ValidBitsPerSample;
1532     Get_L2 (ValidBitsPerSample,                                 "ValidBitsPerSample / SamplesPerBlock");
1533     Get_L4 (ChannelMask,                                        "ChannelMask");
1534     Get_GUID(SubFormat,                                         "SubFormat");
1535 
1536     FILLING_BEGIN();
1537         if ((SubFormat.hi&0x0000FFFFFFFFFFFFLL)==0x0000000000001000LL && SubFormat.lo==0x800000AA00389B71LL)
1538         {
1539             int16u LegacyCodecID=(int16u)((((SubFormat.hi>>48)&0xFF)<<8) | (SubFormat.hi>>56)); // It is Little Endian
1540             CodecID_Fill(Ztring().From_Number(LegacyCodecID, 16), Stream_Audio, StreamPos_Last, InfoCodecID_Format_Riff);
1541             Fill(Stream_Audio, StreamPos_Last, Audio_CodecID, Ztring().From_GUID(SubFormat), true);
1542             Fill(Stream_Audio, StreamPos_Last, Audio_Codec, MediaInfoLib::Config.Codec_Get(Ztring().From_Number(LegacyCodecID, 16)), true);
1543 
1544             //Creating the parser
1545             stream& StreamItem=Stream[Stream_ID];
1546                  if (0);
1547             #if defined(MEDIAINFO_PCM_YES) || defined(MEDIAINFO_DTS_YES) || defined(MEDIAINFO_SMPTEST0337_YES)
1548             else if (MediaInfoLib::Config.CodecID_Get(Stream_Audio, InfoCodecID_Format_Riff, Ztring().From_Number(LegacyCodecID, 16))==__T("PCM"))
1549             {
1550                 int16u Channels=Retrieve(Stream_Audio, StreamPos_Last, "Channel(s)").To_int16u();
1551                 Parser_Pcm(StreamItem, Channels, BitsPerSample, ValidBitsPerSample, SamplesPerSec);
1552             }
1553             #endif
1554             Open_Buffer_Init_All();
1555         }
1556         else
1557         {
1558             CodecID_Fill(Ztring().From_GUID(SubFormat), Stream_Audio, StreamPos_Last, InfoCodecID_Format_Riff);
1559         }
1560         Fill(Stream_Audio, StreamPos_Last, Audio_ChannelPositions, ExtensibleWave_ChannelMask(ChannelMask));
1561         Fill(Stream_Audio, StreamPos_Last, Audio_ChannelPositions_String2, ExtensibleWave_ChannelMask2(ChannelMask));
1562         Fill(Stream_Audio, StreamPos_Last, Audio_ChannelLayout, ExtensibleWave_ChannelMask_ChannelLayout(ChannelMask));
1563     FILLING_END();
1564 }
1565 
1566 //---------------------------------------------------------------------------
AVI__hdlr_strl_strf_iavs()1567 void File_Riff::AVI__hdlr_strl_strf_iavs()
1568 {
1569     //Standard video header before Iavs?
1570     if (Element_Size==72)
1571     {
1572         Element_Begin0();
1573             AVI__hdlr_strl_strf_vids();
1574         Element_End0();
1575     }
1576 
1577     Element_Info1("Interleaved Audio/Video");
1578 
1579     #ifdef MEDIAINFO_DVDIF_YES
1580         if (Element_Size<8*4)
1581             return;
1582 
1583         //Parsing
1584         DV_FromHeader=new File_DvDif();
1585         Open_Buffer_Init(DV_FromHeader);
1586 
1587         //DVAAuxSrc
1588         ((File_DvDif*)DV_FromHeader)->AuxToAnalyze=0x50; //Audio source
1589         Open_Buffer_Continue(DV_FromHeader, 4);
1590         //DVAAuxCtl
1591         ((File_DvDif*)DV_FromHeader)->AuxToAnalyze=0x51; //Audio control
1592         Open_Buffer_Continue(DV_FromHeader, Buffer+Buffer_Offset+(size_t)Element_Offset, 4);
1593         Element_Offset+=4;
1594         //DVAAuxSrc1
1595         Skip_L4(                                                "DVAAuxSrc1");
1596         //DVAAuxCtl1
1597         Skip_L4(                                                "DVAAuxCtl1");
1598         //DVVAuxSrc
1599         ((File_DvDif*)DV_FromHeader)->AuxToAnalyze=0x60; //Video source
1600         Open_Buffer_Continue(DV_FromHeader, 4);
1601         //DVAAuxCtl
1602         ((File_DvDif*)DV_FromHeader)->AuxToAnalyze=0x61; //Video control
1603         Open_Buffer_Continue(DV_FromHeader, 4);
1604         //Reserved
1605         if (Element_Offset<Element_Size)
1606         {
1607             Skip_L4(                                            "DVReserved");
1608             Skip_L4(                                            "DVReserved");
1609         }
1610 
1611         Finish(DV_FromHeader);
1612 
1613         Stream_Prepare(Stream_Video);
1614         stream& StreamItem = Stream[Stream_ID];
1615         StreamItem.Parsers.push_back(new File_DvDif);
1616         Open_Buffer_Init(StreamItem.Parsers[0]);
1617 
1618     #else //MEDIAINFO_DVDIF_YES
1619         //Parsing
1620         Skip_L4(                                                "DVAAuxSrc");
1621         Skip_L4(                                                "DVAAuxCtl");
1622         Skip_L4(                                                "DVAAuxSrc1");
1623         Skip_L4(                                                "DVAAuxCtl1");
1624         Skip_L4(                                                "DVVAuxSrc");
1625         Skip_L4(                                                "DVVAuxCtl");
1626         Skip_L4(                                                "DVReserved");
1627         Skip_L4(                                                "DVReserved");
1628 
1629         //Filling
1630         Ztring Codec; Codec.From_CC4(Stream[Stream_ID].fccHandler);
1631         Stream_Prepare(Stream_Video);
1632         float32 FrameRate=Retrieve(Stream_Video, StreamPos_Last, Video_FrameRate).To_float32();
1633         Fill(Stream_Video, StreamPos_Last, Video_Codec, Codec); //May be replaced by codec parser
1634         Fill(Stream_Video, StreamPos_Last, Video_Codec_CC, Codec);
1635              if (Codec==__T("dvsd")
1636               || Codec==__T("dvsl"))
1637         {
1638                                         Fill(Stream_Video, StreamPos_Last, Video_Width,  720);
1639                  if (FrameRate==25.000) Fill(Stream_Video, StreamPos_Last, Video_Height, 576);
1640             else if (FrameRate==29.970) Fill(Stream_Video, StreamPos_Last, Video_Height, 480);
1641             Fill(Stream_Video, StreamPos_Last, Video_DisplayAspectRatio, 4.0/3, 3, true);
1642         }
1643         else if (Codec==__T("dvhd"))
1644         {
1645                                         Fill(Stream_Video, StreamPos_Last, Video_Width,  1440);
1646                  if (FrameRate==25.000) Fill(Stream_Video, StreamPos_Last, Video_Height, 1152);
1647             else if (FrameRate==30.000) Fill(Stream_Video, StreamPos_Last, Video_Height,  960);
1648             Fill(Stream_Video, StreamPos_Last, Video_DisplayAspectRatio, 4.0/3, 3, true);
1649         }
1650         Stream_Prepare(Stream_Audio);
1651         CodecID_Fill(Codec, Stream_Audio, StreamPos_Last, InfoCodecID_Format_Riff);
1652         Fill(Stream_Audio, StreamPos_Last, Audio_Codec, Codec); //May be replaced by codec parser
1653         Fill(Stream_Audio, StreamPos_Last, Audio_Codec_CC, Codec);
1654     #endif //MEDIAINFO_DVDIF_YES
1655 }
1656 
1657 //---------------------------------------------------------------------------
AVI__hdlr_strl_strf_mids()1658 void File_Riff::AVI__hdlr_strl_strf_mids()
1659 {
1660     Element_Info1("Midi");
1661 
1662     //Filling
1663     Stream_Prepare(Stream_Audio);
1664     Fill(Stream_Audio, StreamPos_Last, Audio_Format, "MIDI");
1665     Fill(Stream_Audio, StreamPos_Last, Audio_Codec, "Midi");
1666 }
1667 
1668 //---------------------------------------------------------------------------
AVI__hdlr_strl_strf_txts()1669 void File_Riff::AVI__hdlr_strl_strf_txts()
1670 {
1671     Element_Info1("Text");
1672 
1673     //Parsing
1674     Ztring Format;
1675     if (Element_Size)
1676     {
1677         Get_Local(10, Format,                                   "Format");
1678         Skip_XX(22,                                             "Unknown");
1679     }
1680 
1681     FILLING_BEGIN_PRECISE();
1682         Stream_Prepare(Stream_Text);
1683 
1684         if (Element_Size==0)
1685         {
1686             //Creating the parser
1687             stream& StreamItem = Stream[Stream_ID];
1688             #if defined(MEDIAINFO_SUBRIP_YES)
1689             StreamItem.Parsers.push_back(new File_SubRip);
1690             #endif
1691             #if defined(MEDIAINFO_OTHERTEXT_YES)
1692             StreamItem.Parsers.push_back(new File_OtherText); //For SSA
1693             #endif
1694 
1695             Open_Buffer_Init_All();
1696         }
1697         else
1698         {
1699             Fill(Stream_Text, StreamPos_Last, Text_Format, Format);
1700         }
1701     FILLING_END();
1702 }
1703 
1704 //---------------------------------------------------------------------------
AVI__hdlr_strl_strf_vids()1705 void File_Riff::AVI__hdlr_strl_strf_vids()
1706 {
1707     Element_Info1("Video");
1708 
1709     //Parsing
1710     int32u Size, Compression, Width, Height;
1711     int16u Resolution;
1712     Get_L4 (Size,                                               "Size");
1713     Get_L4 (Width,                                              "Width");
1714     Get_L4 (Height,                                             "Height");
1715     Skip_L2(                                                    "Planes");
1716     Get_L2 (Resolution,                                         "BitCount"); //Do not use it
1717     Get_C4 (Compression,                                        "Compression");
1718     Skip_L4(                                                    "SizeImage");
1719     Skip_L4(                                                    "XPelsPerMeter");
1720     Skip_L4(                                                    "YPelsPerMeter");
1721     Skip_L4(                                                    "ClrUsed");
1722     Skip_L4(                                                    "ClrImportant");
1723 
1724     //Filling
1725     Stream[Stream_ID].Compression=Compression;
1726 
1727     if (Compression==CC4("DXSB"))
1728     {
1729         //Divx.com hack for subtitle, this is a text stream in a DivX Format
1730         Fill(Stream_General, 0, General_Format, "DivX", Unlimited, true, true);
1731         Stream_Prepare(Stream_Text);
1732     }
1733     else
1734         Stream_Prepare(Stream_Video);
1735 
1736     //Filling
1737     CodecID_Fill(Ztring().From_CC4(Compression), StreamKind_Last, StreamPos_Last, InfoCodecID_Format_Riff);
1738     Fill(StreamKind_Last, StreamPos_Last, Fill_Parameter(StreamKind_Last, Generic_Codec), Ztring().From_CC4(Compression).To_UTF8().c_str()); //FormatTag, may be replaced by codec parser
1739     Fill(StreamKind_Last, StreamPos_Last, Fill_Parameter(StreamKind_Last, Generic_Codec_CC), Ztring().From_CC4(Compression).To_UTF8().c_str()); //FormatTag
1740     Fill(StreamKind_Last, StreamPos_Last, "Width", Width, 10, true);
1741     Fill(StreamKind_Last, StreamPos_Last, "Height", Height>=0x80000000?(-((int32s)Height)):Height, 10, true); // AVI can use negative height for raw to signal that it's coded top-down, not bottom-up
1742     if (Resolution==32 && Compression==0x74736363) //tscc
1743         Fill(StreamKind_Last, StreamPos_Last, "BitDepth", 8);
1744     else if (Compression==0x44495633) //DIV3
1745         Fill(StreamKind_Last, StreamPos_Last, "BitDepth", 8);
1746     else if (MediaInfoLib::Config.CodecID_Get(StreamKind_Last, InfoCodecID_Format_Riff, Ztring().From_CC4(Compression)).find(__T("Canopus"))!=std::string::npos) //Canopus codecs
1747         Fill(StreamKind_Last, StreamPos_Last, "BitDepth", Resolution/3);
1748         else if (Compression==0x44585342) //DXSB
1749         Fill(StreamKind_Last, StreamPos_Last, "BitDepth", Resolution);
1750     else if (MediaInfoLib::Config.CodecID_Get(StreamKind_Last, InfoCodecID_Format_Riff, Ztring().From_CC4(Compression), InfoCodecID_ColorSpace).find(__T("RGBA"))!=std::string::npos) //RGB codecs
1751         Fill(StreamKind_Last, StreamPos_Last, "BitDepth", Resolution/4);
1752     else if (Compression==0x00000000 //RGB
1753             || MediaInfoLib::Config.CodecID_Get(StreamKind_Last, InfoCodecID_Format_Riff, Ztring().From_CC4(Compression), InfoCodecID_ColorSpace).find(__T("RGB"))!=std::string::npos) //RGB codecs
1754     {
1755         if (Resolution==32)
1756         {
1757             Fill(StreamKind_Last, StreamPos_Last, Fill_Parameter(StreamKind_Last, Generic_Format), "RGBA", Unlimited, true, true);
1758             if (StreamKind_Last==Stream_Video)
1759                 Fill(Stream_Video, StreamPos_Last, Video_ColorSpace, "RGBA", Unlimited, true, true);
1760             Fill(StreamKind_Last, StreamPos_Last, "BitDepth", Resolution/4); //With Alpha
1761         }
1762         else
1763         {
1764             Fill(StreamKind_Last, StreamPos_Last, Fill_Parameter(StreamKind_Last, Generic_Format), "RGB", Unlimited, true, true);
1765             if (StreamKind_Last==Stream_Video)
1766                 Fill(Stream_Video, StreamPos_Last, Video_ColorSpace, "RGB", Unlimited, true, true);
1767             Fill(StreamKind_Last, StreamPos_Last, "BitDepth", Resolution<=16?8:(Resolution/3)); //indexed or normal
1768         }
1769     }
1770     else if (Compression==0x56503632 //VP62
1771             || MediaInfoLib::Config.CodecID_Get(StreamKind_Last, InfoCodecID_Format_Riff, Ztring().From_CC4(Compression), InfoCodecID_Format)==__T("H.263") //H.263
1772             || MediaInfoLib::Config.CodecID_Get(StreamKind_Last, InfoCodecID_Format_Riff, Ztring().From_CC4(Compression), InfoCodecID_Format)==__T("VC-1")) //VC-1
1773         Fill(StreamKind_Last, StreamPos_Last, "BitDepth", Resolution/3);
1774     Stream[Stream_ID].StreamKind=StreamKind_Last;
1775 
1776     //Creating the parser
1777          if (0);
1778     #if defined(MEDIAINFO_FFV1_YES)
1779     else if (MediaInfoLib::Config.CodecID_Get(Stream_Video, InfoCodecID_Format_Riff, Ztring().From_CC4(Compression), InfoCodecID_Format)==__T("FFV1"))
1780     {
1781         File_Ffv1* Parser=new File_Ffv1;
1782         Parser->Width=Width;
1783         Parser->Height=Height;
1784         Stream[Stream_ID].Parsers.push_back(Parser);
1785     }
1786     #endif
1787     #if defined(MEDIAINFO_CINEFORM_YES)
1788     else if (MediaInfoLib::Config.CodecID_Get(Stream_Video, InfoCodecID_Format_Riff, Ztring().From_CC4(Compression), InfoCodecID_Format)==__T("CineForm"))
1789     {
1790         File_CineForm* Parser=new File_CineForm;
1791         Stream[Stream_ID].Parsers.push_back(Parser);
1792     }
1793     #endif
1794     #if defined(MEDIAINFO_HUFFYUV_YES)
1795     else if (MediaInfoLib::Config.CodecID_Get(Stream_Video, InfoCodecID_Format_Riff, Ztring().From_CC4(Compression), InfoCodecID_Format)==__T("HuffYUV"))
1796     {
1797         File_HuffYuv* Parser=new File_HuffYuv;
1798         Stream[Stream_ID].Parsers.push_back(Parser);
1799     }
1800     #endif
1801     #if defined(MEDIAINFO_MPEGV_YES)
1802     else if (MediaInfoLib::Config.CodecID_Get(Stream_Video, InfoCodecID_Format_Riff, Ztring().From_CC4(Compression), InfoCodecID_Format)==__T("MPEG Video"))
1803     {
1804         File_Mpegv* Parser=new File_Mpegv;
1805         Parser->FrameIsAlwaysComplete=true;
1806         Parser->TimeCodeIsNotTrustable=true;
1807         Stream[Stream_ID].Parsers.push_back(Parser);
1808     }
1809     #endif
1810     #if defined(MEDIAINFO_MPEG4V_YES)
1811     else if (MediaInfoLib::Config.CodecID_Get(Stream_Video, InfoCodecID_Format_Riff, Ztring().From_CC4(Compression))==__T("MPEG-4 Visual"))
1812     {
1813         File_Mpeg4v* Parser=new File_Mpeg4v;
1814         Stream[Stream_ID].Specific_IsMpeg4v=true;
1815         Parser->FrameIsAlwaysComplete=true;
1816         if (Config->ParseSpeed>=0.5)
1817             Parser->ShouldContinueParsing=true;
1818         Stream[Stream_ID].Parsers.push_back(Parser);
1819     }
1820     #endif
1821     #if defined(MEDIAINFO_PRORES_YES)
1822     else if (MediaInfoLib::Config.CodecID_Get(Stream_Video, InfoCodecID_Format_Riff, Ztring().From_CC4(Compression), InfoCodecID_Format)==__T("ProRes"))
1823     {
1824         File_ProRes* Parser=new File_ProRes;
1825         Stream[Stream_ID].Parsers.push_back(Parser);
1826     }
1827     #endif
1828     #if defined(MEDIAINFO_AVC_YES)
1829     else if (MediaInfoLib::Config.CodecID_Get(Stream_Video, InfoCodecID_Format_Riff, Ztring().From_CC4(Compression))==__T("AVC"))
1830     {
1831         File_Avc* Parser=new File_Avc;
1832         Parser->FrameIsAlwaysComplete=true;
1833         Stream[Stream_ID].Parsers.push_back(Parser);
1834     }
1835     #endif
1836     #if defined(MEDIAINFO_CANOPUS_YES)
1837     else if (MediaInfoLib::Config.CodecID_Get(Stream_Video, InfoCodecID_Format_Riff, Ztring().From_CC4(Compression))==__T("Canopus HQ"))
1838     {
1839         File_Canopus* Parser=new File_Canopus;
1840         Stream[Stream_ID].Parsers.push_back(Parser);
1841     }
1842     #endif
1843     #if defined(MEDIAINFO_JPEG_YES)
1844     else if (MediaInfoLib::Config.CodecID_Get(Stream_Video, InfoCodecID_Format_Riff, Ztring().From_CC4(Compression))==__T("JPEG"))
1845     {
1846         File_Jpeg* Parser=new File_Jpeg;
1847         Parser->StreamKind=Stream_Video;
1848         Stream[Stream_ID].Parsers.push_back(Parser);
1849     }
1850     #endif
1851     #if defined(MEDIAINFO_DVDIF_YES)
1852     else if (MediaInfoLib::Config.CodecID_Get(Stream_Video, InfoCodecID_Format_Riff, Ztring().From_CC4(Compression))==__T("DV"))
1853     {
1854         File_DvDif* Parser=new File_DvDif;
1855         Parser->IgnoreAudio=true;
1856         Stream[Stream_ID].Parsers.push_back(Parser);
1857     }
1858     #endif
1859     #if defined(MEDIAINFO_FRAPS_YES)
1860     else if (Compression==0x46505331) //"FPS1"
1861     {
1862         File_Fraps* Parser=new File_Fraps;
1863         Stream[Stream_ID].Parsers.push_back(Parser);
1864     }
1865     #endif
1866     else if (Compression==0x48465955) //"HFUY"
1867     {
1868         switch (Resolution)
1869         {
1870             case 16 : Fill(Stream_Video, StreamPos_Last, Video_ColorSpace, "YUV"); Fill(Stream_Video, StreamPos_Last, Video_ChromaSubsampling, "4:2:2"); Fill(Stream_Video, StreamPos_Last, Video_BitDepth, 8); break;
1871             case 24 : Fill(Stream_Video, StreamPos_Last, Video_ColorSpace, "RGB"); Fill(Stream_Video, StreamPos_Last, Video_BitDepth, 8); break;
1872             case 32 : Fill(Stream_Video, StreamPos_Last, Video_ColorSpace, "RGBA"); Fill(Stream_Video, StreamPos_Last, Video_BitDepth, 8); break;
1873             default : ;
1874         }
1875     }
1876     #if defined(MEDIAINFO_LAGARITH_YES)
1877     else if (Compression==0x4C414753) //"LAGS"
1878     {
1879         File_Lagarith* Parser=new File_Lagarith;
1880         Stream[Stream_ID].Parsers.push_back(Parser);
1881     }
1882     #endif
1883     Open_Buffer_Init_All();
1884 
1885     //Options
1886     if (Element_Offset>=Element_Size)
1887         return; //No options
1888 
1889     //Filling
1890     int32u Element_Size_Save=0;
1891     if (Size<Element_Size)
1892     {
1893         Element_Size_Save=Element_Size;
1894         Element_Size=Size;
1895     }
1896          if (0);
1897     else if (MediaInfoLib::Config.CodecID_Get(Stream_Video, InfoCodecID_Format_Riff, Ztring().From_CC4(Compression))==__T("AVC"))
1898         AVI__hdlr_strl_strf_vids_Avc();
1899     else if (MediaInfoLib::Config.CodecID_Get(Stream_Video, InfoCodecID_Format_Riff, Ztring().From_CC4(Compression))==__T("FFV1"))
1900         AVI__hdlr_strl_strf_vids_Ffv1();
1901     else if (MediaInfoLib::Config.CodecID_Get(Stream_Video, InfoCodecID_Format_Riff, Ztring().From_CC4(Compression))==__T("HuffYUV"))
1902         AVI__hdlr_strl_strf_vids_HuffYUV(Resolution, Height);
1903     else Skip_XX(Element_Size-Element_Offset,                   "Unknown");
1904     if (Element_Size_Save)
1905         Element_Size=Element_Size_Save;
1906     Skip_XX(Element_Size-Element_Offset,                        "Unknown");
1907 }
1908 
1909 //---------------------------------------------------------------------------
AVI__hdlr_strl_strf_vids_Avc()1910 void File_Riff::AVI__hdlr_strl_strf_vids_Avc()
1911 {
1912     //Parsing
1913     Element_Begin1("AVC options");
1914     #if defined(MEDIAINFO_AVC_YES)
1915         //Can be sized block or with 000001
1916         stream& StreamItem = Stream[Stream_ID];
1917         File_Avc* Parser=(File_Avc*)StreamItem.Parsers[0];
1918         Parser->MustParse_SPS_PPS=false;
1919         Parser->SizedBlocks=false;
1920         Parser->MustSynchronize=true;
1921         int64u Element_Offset_Save=Element_Offset;
1922         Open_Buffer_Continue(Parser);
1923         if (!Parser->Status[IsAccepted])
1924         {
1925             Element_Offset=Element_Offset_Save;
1926             delete StreamItem.Parsers[0]; StreamItem.Parsers[0]=new File_Avc;
1927             Parser=(File_Avc*)StreamItem.Parsers[0];
1928             Open_Buffer_Init(Parser);
1929             Parser->FrameIsAlwaysComplete=true;
1930             Parser->MustParse_SPS_PPS=true;
1931             Parser->SizedBlocks=true;
1932             Parser->MustSynchronize=false;
1933             Open_Buffer_Continue(Parser);
1934             Element_Show();
1935         }
1936     #else //MEDIAINFO_AVC_YES
1937         Skip_XX(Element_Size-Element_Offset,                    "(AVC headers)");
1938     #endif
1939     Element_End0();
1940 }
1941 
1942 //---------------------------------------------------------------------------
AVI__hdlr_strl_strf_vids_Ffv1()1943 void File_Riff::AVI__hdlr_strl_strf_vids_Ffv1()
1944 {
1945     //Parsing
1946     Element_Begin1("FFV1 options");
1947     #if defined(MEDIAINFO_FFV1_YES)
1948         Open_Buffer_OutOfBand(Stream[Stream_ID].Parsers[0]);
1949     #else //MEDIAINFO_FFV1_YES
1950         Skip_XX(Element_Size-Element_Offset,                    "(FFV1 headers)");
1951     #endif
1952     Element_End0();
1953 }
1954 
1955 //---------------------------------------------------------------------------
AVI__hdlr_strl_strf_vids_HuffYUV(int16u BitCount,int32u Height)1956 void File_Riff::AVI__hdlr_strl_strf_vids_HuffYUV(int16u BitCount, int32u Height)
1957 {
1958     //Parsing
1959     Element_Begin1("HuffYUV options");
1960     #if defined(MEDIAINFO_HUFFYUV_YES)
1961         File_HuffYuv* Parser=(File_HuffYuv*)Stream[Stream_ID].Parsers[0];
1962         Parser->BitCount=BitCount;
1963         Parser->Height=Height;
1964         Open_Buffer_OutOfBand(Parser);
1965     #else //MEDIAINFO_HUFFYUV_YES
1966         Skip_XX(Element_Size-Element_Offset,                    "(HuffYUV headers)");
1967     #endif
1968     Element_End0();
1969 }
1970 
1971 //---------------------------------------------------------------------------
AVI__hdlr_strl_strh()1972 void File_Riff::AVI__hdlr_strl_strh()
1973 {
1974     Element_Name("Stream header");
1975 
1976     //Parsing
1977     int32u fccType, fccHandler, Scale, Rate, Start, Length;
1978     int16u Left, Top, Right, Bottom;
1979     Get_C4 (fccType,                                            "fccType");
1980     switch (fccType)
1981     {
1982         case Elements::AVI__hdlr_strl_strh_auds :
1983             Get_L4 (fccHandler,                                 "fccHandler");
1984             break;
1985         default:
1986             Get_C4 (fccHandler,                                 "fccHandler");
1987     }
1988     Skip_L4(                                                    "Flags");
1989     Skip_L2(                                                    "Priority");
1990     Skip_L2(                                                    "Language");
1991     Skip_L4(                                                    "InitialFrames");
1992     Get_L4 (Scale,                                              "Scale");
1993     Get_L4 (Rate,                                               "Rate"); //Rate/Scale is stream tick rate in ticks/sec
1994     Get_L4 (Start,                                              "Start");
1995     Get_L4 (Length,                                             "Length");
1996     Skip_L4(                                                    "SuggestedBufferSize");
1997     Skip_L4(                                                    "Quality");
1998     Skip_L4(                                                    "SampleSize");
1999     Get_L2 (Left,                                               "Frame_Left");
2000     Get_L2 (Top,                                                "Frame_Top");
2001     Get_L2 (Right,                                              "Frame_Right");
2002     Get_L2 (Bottom,                                             "Frame_Bottom");
2003     if(Element_Offset<Element_Size)
2004         Skip_XX(Element_Size-Element_Offset,                    "Unknown");
2005 
2006     //Filling
2007     float32 FrameRate=0;
2008     if (Rate>0 && Scale>0)
2009     {
2010         //FrameRate (without known value detection)
2011         FrameRate=((float32)Rate)/Scale;
2012         if (FrameRate>1)
2013         {
2014             float32 Rest=FrameRate-(int32u)FrameRate;
2015             if (Rest<0.01)
2016                 FrameRate-=Rest;
2017             else if (Rest>0.99)
2018                 FrameRate+=1-Rest;
2019             else
2020             {
2021                 float32 Rest1001=FrameRate*1001/1000-(int32u)(FrameRate*1001/1000);
2022                 if (Rest1001<0.001)
2023                     FrameRate=(float32)((int32u)(FrameRate*1001/1000))*1000/1001;
2024                 if (Rest1001>0.999)
2025                     FrameRate=(float32)((int32u)(FrameRate*1001/1000)+1)*1000/1001;
2026             }
2027         }
2028 
2029         //Duration
2030         if (FrameRate)
2031         {
2032             int64u Duration=float32_int64s((1000*(float32)Length)/FrameRate);
2033             if (avih_TotalFrame>0 //avih_TotalFrame is here because some files have a wrong Audio Duration if TotalFrame==0 (which is a bug, of course!)
2034             && (avih_FrameRate==0 || Duration<((float32)avih_TotalFrame)/avih_FrameRate*1000*1.10)  //Some file have a nearly perfect header, except that the value is false, trying to detect it (false if 10% more than 1st video)
2035             && (avih_FrameRate==0 || Duration>((float32)avih_TotalFrame)/avih_FrameRate*1000*0.90)) //Some file have a nearly perfect header, except that the value is false, trying to detect it (false if 10% less than 1st video)
2036             {
2037                 Fill(StreamKind_Last, StreamPos_Last, "Duration", Duration);
2038             }
2039         }
2040     }
2041     switch (fccType)
2042     {
2043         case Elements::AVI__hdlr_strl_strh_vids :
2044             if (FrameRate>0)  Fill(Stream_Video, StreamPos_Last, Video_FrameRate, FrameRate, 3);
2045             if (Right-Left>0) Fill(Stream_Video, StreamPos_Last, Video_Width,  Right-Left, 10, true);
2046             if (Bottom-Top>0) Fill(Stream_Video, StreamPos_Last, Video_Height, Bottom-Top, 10, true);
2047             break;
2048         case Elements::AVI__hdlr_strl_strh_txts :
2049             if (Right-Left>0) Fill(Stream_Text, StreamPos_Last, Text_Width,  Right-Left, 10, true);
2050             if (Bottom-Top>0) Fill(Stream_Text, StreamPos_Last, Text_Height, Bottom-Top, 10, true);
2051             break;
2052         default: ;
2053     }
2054     stream& StreamItem = Stream[Stream_ID];
2055     StreamItem.fccType=fccType;
2056     StreamItem.fccHandler=fccHandler;
2057     StreamItem.Scale=Scale;
2058     StreamItem.Rate=Rate;
2059     StreamItem.Start=Start;
2060     StreamItem.Length=Length;
2061 }
2062 
2063 //---------------------------------------------------------------------------
AVI__hdlr_strl_strn()2064 void File_Riff::AVI__hdlr_strl_strn()
2065 {
2066     Element_Name("Stream name");
2067 
2068     //Parsing
2069     Ztring Title;
2070     Get_Local(Element_Size, Title,                              "StreamName");
2071 
2072     //Filling
2073     Fill(StreamKind_Last, StreamPos_Last, "Title", Title);
2074 }
2075 
2076 //---------------------------------------------------------------------------
AVI__hdlr_strl_vprp()2077 void File_Riff::AVI__hdlr_strl_vprp()
2078 {
2079     Element_Name("Video properties");
2080 
2081     //Parsing
2082     int32u FieldPerFrame;
2083     int16u FrameAspectRatio_H, FrameAspectRatio_W;
2084     Skip_L4(                                                    "VideoFormatToken");
2085     Skip_L4(                                                    "VideoStandard");
2086     Skip_L4(                                                    "VerticalRefreshRate");
2087     Skip_L4(                                                    "HTotalInT");
2088     Skip_L4(                                                    "VTotalInLines");
2089     Get_L2 (FrameAspectRatio_H,                                 "FrameAspectRatio Height");
2090     Get_L2 (FrameAspectRatio_W,                                 "FrameAspectRatio Width");
2091     Skip_L4(                                                    "FrameWidthInPixels");
2092     Skip_L4(                                                    "FrameHeightInLines");
2093     Get_L4 (FieldPerFrame,                                      "FieldPerFrame");
2094     vector<int32u> VideoYValidStartLines;
2095     for (int32u Pos=0; Pos<FieldPerFrame; Pos++)
2096     {
2097         Element_Begin1("Field");
2098         int32u VideoYValidStartLine;
2099         Skip_L4(                                                "CompressedBMHeight");
2100         Skip_L4(                                                "CompressedBMWidth");
2101         Skip_L4(                                                "ValidBMHeight");
2102         Skip_L4(                                                "ValidBMWidth");
2103         Skip_L4(                                                "ValidBMXOffset");
2104         Skip_L4(                                                "ValidBMYOffset");
2105         Skip_L4(                                                "VideoXOffsetInT");
2106         Get_L4 (VideoYValidStartLine,                           "VideoYValidStartLine");
2107         VideoYValidStartLines.push_back(VideoYValidStartLine);
2108         Element_End0();
2109     }
2110     if(Element_Offset<Element_Size)
2111         Skip_XX(Element_Size-Element_Offset,                    "Unknown");
2112 
2113     FILLING_BEGIN();
2114         if (FrameAspectRatio_H && FrameAspectRatio_W)
2115             Fill(Stream_Video, 0, Video_DisplayAspectRatio, ((float32)FrameAspectRatio_W)/FrameAspectRatio_H, 3);
2116         switch (FieldPerFrame)
2117         {
2118             case 1 :
2119                         Fill(Stream_Video, 0, Video_ScanType, "Progressive");
2120                         break;
2121             case 2 :
2122                         Fill(Stream_Video, 0, Video_ScanType, "Interlaced");
2123                         if (VideoYValidStartLines.size()==2 && VideoYValidStartLines[0]<VideoYValidStartLines[1])
2124                             Fill(Stream_Video, 0, Video_ScanOrder, "TFF");
2125                         if (VideoYValidStartLines.size()==2 && VideoYValidStartLines[0]>VideoYValidStartLines[1])
2126                             Fill(Stream_Video, 0, Video_ScanOrder, "BFF");
2127             default: ;
2128         }
2129     FILLING_END();
2130 }
2131 
2132 //---------------------------------------------------------------------------
AVI__hdlr_xxxx()2133 void File_Riff::AVI__hdlr_xxxx()
2134 {
2135     AVI__INFO_xxxx();
2136 }
2137 
2138 //---------------------------------------------------------------------------
AVI__idx1()2139 void File_Riff::AVI__idx1()
2140 {
2141     Element_Name("Index (old)");
2142 
2143     //Tests
2144     if (!NeedOldIndex || Idx1_Offset==(int64u)-1)
2145     {
2146         Skip_XX(Element_Size,                                   "Data");
2147         return;
2148     }
2149 
2150     //Testing malformed index (index is based on start of the file, wrong)
2151     if (16<=Element_Size && Idx1_Offset+4==LittleEndian2int32u(Buffer+Buffer_Offset+(size_t)Element_Offset+ 8))
2152         Idx1_Offset=0; //Fixing base of movi atom, the index think it is the start of the file
2153 
2154     //Parsing
2155     while (Element_Offset+16<=Element_Size)
2156     {
2157         //Is too slow
2158         /*
2159         int32u ChunkID, Offset, Size;
2160         Element_Begin1("Index");
2161         Get_C4 (ChunkID,                                        "ChunkID"); //Bit 31 is set if this is NOT a keyframe
2162         Info_L4(Flags,                                          "Flags");
2163             Skip_Flags(Flags, 0,                                "NoTime");
2164             Skip_Flags(Flags, 1,                                "Lastpart");
2165             Skip_Flags(Flags, 2,                                "Firstpart");
2166             Skip_Flags(Flags, 3,                                "Midpart");
2167             Skip_Flags(Flags, 4,                                "KeyFrame");
2168         Get_L4 (Offset,                                         "Offset"); //qwBaseOffset + this is absolute file offset
2169         Get_L4 (Size,                                           "Size"); //Bit 31 is set if this is NOT a keyframe
2170         Element_Info1(Ztring().From_CC4(ChunkID));
2171         Element_Info1(Size);
2172 
2173         //Stream Pos and Size
2174         int32u StreamID=(ChunkID&0xFFFF0000);
2175         Stream[StreamID].StreamSize+=Size;
2176         Stream[StreamID].PacketCount++;
2177         Stream_Structure[Idx1_Offset+Offset].Name=StreamID;
2178         Stream_Structure[Idx1_Offset+Offset].Size=Size;
2179         Element_End0();
2180         */
2181 
2182         //Faster method
2183         int32u StreamID=BigEndian2int32u   (Buffer+Buffer_Offset+(size_t)Element_Offset   )&0xFFFF0000;
2184         int32u Offset  =LittleEndian2int32u(Buffer+Buffer_Offset+(size_t)Element_Offset+ 8);
2185         int32u Size    =LittleEndian2int32u(Buffer+Buffer_Offset+(size_t)Element_Offset+12);
2186         stream& Stream_Item=Stream[StreamID];
2187         Stream_Item.StreamSize+=Size;
2188         Stream_Item.PacketCount++;
2189         stream_structure& Stream_Structure_Item=Stream_Structure[Idx1_Offset+Offset];
2190         Stream_Structure_Item.Name=StreamID;
2191         Stream_Structure_Item.Size=Size;
2192         Element_Offset+=16;
2193     }
2194 
2195     //Interleaved
2196     size_t Pos0=0;
2197     size_t Pos1=0;
2198     for (std::map<int64u, stream_structure>::iterator Temp=Stream_Structure.begin(); Temp!=Stream_Structure.end(); ++Temp)
2199     {
2200         switch (Temp->second.Name)
2201         {
2202             case 0x30300000 :
2203                 if (Interleaved0_1==0) Interleaved0_1=Temp->first;
2204                 if (Interleaved0_10==0)
2205                 {
2206                     Pos0++;
2207                     if (Pos0>1)
2208                         Interleaved0_10=Temp->first;
2209                 }
2210                 break;
2211             case 0x30310000 :
2212                 if (Interleaved1_1==0) Interleaved1_1=Temp->first;
2213                 if (Interleaved1_10==0)
2214                 {
2215                     Pos1++;
2216                     if (Pos1>1)
2217                         Interleaved1_10=Temp->first;
2218                 }
2219                 break;
2220             default:;
2221         }
2222     }
2223 }
2224 
2225 //---------------------------------------------------------------------------
AVI__INFO()2226 void File_Riff::AVI__INFO()
2227 {
2228     Element_Name("Tags");
2229 }
2230 
2231 //---------------------------------------------------------------------------
AVI__INFO_IID3()2232 void File_Riff::AVI__INFO_IID3()
2233 {
2234     Element_Name("ID3 Tag");
2235 
2236     //Parsing
2237     #if defined(MEDIAINFO_ID3_YES)
2238         File_Id3 MI;
2239         Open_Buffer_Init(&MI);
2240         Open_Buffer_Continue(&MI);
2241         Finish(&MI);
2242         Merge(MI, Stream_General, 0, 0);
2243     #endif
2244 }
2245 
2246 //---------------------------------------------------------------------------
AVI__INFO_ILYC()2247 void File_Riff::AVI__INFO_ILYC()
2248 {
2249     Element_Name("Lyrics");
2250 }
2251 
2252 //---------------------------------------------------------------------------
AVI__INFO_IMP3()2253 void File_Riff::AVI__INFO_IMP3()
2254 {
2255     Element_Name("MP3 Information");
2256 }
2257 
2258 //---------------------------------------------------------------------------
AVI__INFO_JUNK()2259 void File_Riff::AVI__INFO_JUNK()
2260 {
2261     Element_Name("Garbage");
2262 }
2263 
2264 //---------------------------------------------------------------------------
2265 // List of information atoms
2266 // Name                             X bytes, Pos=0
2267 //
AVI__INFO_xxxx()2268 void File_Riff::AVI__INFO_xxxx()
2269 {
2270     //Parsing
2271     Ztring Value;
2272     Get_Local(Element_Size, Value,                              "Value");
2273 
2274     //Filling
2275     stream_t StreamKind=Stream_General;
2276     size_t StreamPos=0;
2277     size_t Parameter=(size_t)-1;
2278     switch (Element_Code)
2279     {
2280         case 0x00000000               : Parameter=General_Comment; break;
2281         case Elements::AVI__INFO_IARL : Parameter=General_Archival_Location; break;
2282         case Elements::AVI__INFO_IART : Parameter=General_Director; break;
2283         case Elements::AVI__INFO_IAS1 : Parameter=Audio_Language; StreamKind=Stream_Audio; StreamPos=0; break;
2284         case Elements::AVI__INFO_IAS2 : Parameter=Audio_Language; StreamKind=Stream_Audio; StreamPos=1; break;
2285         case Elements::AVI__INFO_IAS3 : Parameter=Audio_Language; StreamKind=Stream_Audio; StreamPos=2; break;
2286         case Elements::AVI__INFO_IAS4 : Parameter=Audio_Language; StreamKind=Stream_Audio; StreamPos=3; break;
2287         case Elements::AVI__INFO_IAS5 : Parameter=Audio_Language; StreamKind=Stream_Audio; StreamPos=4; break;
2288         case Elements::AVI__INFO_IAS6 : Parameter=Audio_Language; StreamKind=Stream_Audio; StreamPos=5; break;
2289         case Elements::AVI__INFO_IAS7 : Parameter=Audio_Language; StreamKind=Stream_Audio; StreamPos=6; break;
2290         case Elements::AVI__INFO_IAS8 : Parameter=Audio_Language; StreamKind=Stream_Audio; StreamPos=7; break;
2291         case Elements::AVI__INFO_IAS9 : Parameter=Audio_Language; StreamKind=Stream_Audio; StreamPos=8; break;
2292         case Elements::AVI__INFO_ICDS : Parameter=General_CostumeDesigner; break;
2293         case Elements::AVI__INFO_ICMS : Parameter=General_CommissionedBy; break;
2294         case Elements::AVI__INFO_ICMT : Parameter=General_Comment; break;
2295         case Elements::AVI__INFO_ICNM : Parameter=General_DirectorOfPhotography; break;
2296         case Elements::AVI__INFO_ICNT : Parameter=General_Movie_Country; break;
2297         case Elements::AVI__INFO_ICOP : Parameter=General_Copyright; break;
2298         case Elements::AVI__INFO_ICRD : Parameter=General_Recorded_Date; Value.Date_From_String(Value.To_UTF8().c_str()); break;
2299         case Elements::AVI__INFO_ICRP : Parameter=General_Cropped; break;
2300         case Elements::AVI__INFO_IDIM : Parameter=General_Dimensions; break;
2301         case Elements::AVI__INFO_IDIT : Parameter=General_Mastered_Date; Value.Date_From_String(Value.To_UTF8().c_str()); break;
2302         case Elements::AVI__INFO_IDPI : Parameter=General_DotsPerInch; break;
2303         case Elements::AVI__INFO_IDST : Parameter=General_DistributedBy; break;
2304         case Elements::AVI__INFO_IEDT : Parameter=General_EditedBy; break;
2305         case Elements::AVI__INFO_IENG : Parameter=General_EncodedBy; break;
2306         case Elements::AVI__INFO_IGNR : Parameter=General_Genre; break;
2307         case Elements::AVI__INFO_IFRM : Parameter=General_Part_Position_Total; break;
2308         case Elements::AVI__INFO_IKEY : Parameter=General_Keywords; break;
2309         case Elements::AVI__INFO_ILGT : Parameter=General_Lightness; break;
2310         case Elements::AVI__INFO_ILNG : Parameter=Audio_Language; StreamKind=Stream_Audio; break;
2311         case Elements::AVI__INFO_IMED : Parameter=General_OriginalSourceMedium; break;
2312         case Elements::AVI__INFO_IMUS : Parameter=General_MusicBy; break;
2313         case Elements::AVI__INFO_INAM : Parameter=General_Title; break;
2314         case Elements::AVI__INFO_IPDS : Parameter=General_ProductionDesigner; break;
2315         case Elements::AVI__INFO_IPLT : Parameter=General_OriginalSourceForm_NumColors; break;
2316         case Elements::AVI__INFO_IPRD : Parameter=General_OriginalSourceForm_Name; break;
2317         case Elements::AVI__INFO_IPRO : Parameter=General_Producer; break;
2318         case Elements::AVI__INFO_IPRT : Parameter=General_Part_Position; break;
2319         case Elements::AVI__INFO_IRTD : Parameter=General_LawRating; break;
2320         case Elements::AVI__INFO_ISBJ : Parameter=General_Subject; break;
2321         case Elements::AVI__INFO_ISFT : Parameter=General_Encoded_Application; break;
2322         case Elements::AVI__INFO_ISGN : Parameter=General_Genre; break;
2323         case Elements::AVI__INFO_ISHP : Parameter=General_OriginalSourceForm_Sharpness; break;
2324         case Elements::AVI__INFO_ISRC : Parameter=General_OriginalSourceForm_DistributedBy; break;
2325         case Elements::AVI__INFO_ISRF : Parameter=General_OriginalSourceForm; break;
2326         case Elements::AVI__INFO_ISTD : Parameter=General_ProductionStudio; break;
2327         case Elements::AVI__INFO_ISTR : Parameter=General_Performer; break;
2328         case Elements::AVI__INFO_ITCH : Parameter=General_EncodedBy; break;
2329         case Elements::AVI__INFO_IWEB : Parameter=General_Movie_Url; break;
2330         case Elements::AVI__INFO_IWRI : Parameter=General_WrittenBy; break;
2331         default                       : ;
2332     }
2333     Element_Name(MediaInfoLib::Config.Info_Get(StreamKind, Parameter, Info_Name));
2334     Element_Info1(Value);
2335 
2336     switch (Element_Code)
2337     {
2338         case Elements::AVI__INFO_ISMP : INFO_ISMP=Value;
2339                                         break;
2340         case Elements::AVI__INFO_IGNR :
2341                                         {
2342                                             Ztring ISGN=Retrieve(Stream_General, 0, General_Genre);
2343                                             Clear(Stream_General, 0, General_Genre);
2344                                             Fill(StreamKind, StreamPos, General_Genre, Value);
2345                                             if (!ISGN.empty())
2346                                                 Fill(StreamKind, StreamPos, General_Genre, ISGN);
2347                                         }
2348                                         break;
2349         default                      :
2350                                         if (!Value.empty())
2351                                         {
2352                                             if (Parameter!=(size_t)-1)
2353                                                 Fill(StreamKind, StreamPos, Parameter, Value);
2354                                             else
2355                                                 Fill(StreamKind, StreamPos, Ztring().From_CC4((int32u)Element_Code).To_UTF8().c_str(), Value, true);
2356                                         }
2357     }
2358 }
2359 
2360 //---------------------------------------------------------------------------
AVI__JUNK()2361 void File_Riff::AVI__JUNK()
2362 {
2363     Element_Name("Garbage"); //Library defined size for padding, often used to store library name
2364 
2365     if (Element_Size<8)
2366     {
2367         Skip_XX(Element_Size,                                   "Junk");
2368         return;
2369     }
2370 
2371     //Detect DivX files
2372          if (CC5(Buffer+Buffer_Offset)==CC5("DivX "))
2373     {
2374         Fill(Stream_General, 0, General_Format, "DivX", Unlimited, true, true);
2375     }
2376     //MPlayer
2377     else if (CC8(Buffer+Buffer_Offset)==CC8("[= MPlay") && Retrieve(Stream_General, 0, General_Encoded_Library).empty())
2378         Fill(Stream_General, 0, General_Encoded_Library, "MPlayer");
2379     //Scenalyzer
2380     else if (CC8(Buffer+Buffer_Offset)==CC8("scenalyz") && Retrieve(Stream_General, 0, General_Encoded_Library).empty())
2381         Fill(Stream_General, 0, General_Encoded_Library, "Scenalyzer");
2382     //FFMpeg broken files detection
2383     else if (CC8(Buffer+Buffer_Offset)==CC8("odmldmlh"))
2384         dmlh_TotalFrame=0; //this is not normal to have this string in a JUNK block!!! and in files tested, in this case TotalFrame is broken too
2385     //VirtualDubMod
2386     else if (CC8(Buffer+Buffer_Offset)==CC8("INFOISFT"))
2387     {
2388         int32u Size=LittleEndian2int32u(Buffer+Buffer_Offset+8);
2389         if (Size>Element_Size-12)
2390             Size=(int32u)Element_Size-12;
2391         Fill(Stream_General, 0, General_Encoded_Library, (const char*)(Buffer+Buffer_Offset+12), Size);
2392     }
2393     else if (CC8(Buffer+Buffer_Offset)==CC8("INFOIENG"))
2394     {
2395         int32u Size=LittleEndian2int32u(Buffer+Buffer_Offset+8);
2396         if (Size>Element_Size-12)
2397             Size=(int32u)Element_Size-12;
2398         Fill(Stream_General, 0, General_Encoded_Library, (const char*)(Buffer+Buffer_Offset+12), Size);
2399     }
2400     //Other libraries?
2401     else if (CC1(Buffer+Buffer_Offset)>=CC1("A") && CC1(Buffer+Buffer_Offset)<=CC1("z") && Retrieve(Stream_General, 0, General_Encoded_Library).empty())
2402         Fill(Stream_General, 0, General_Encoded_Library, (const char*)(Buffer+Buffer_Offset), (size_t)Element_Size);
2403 
2404     Skip_XX(Element_Size,                                       "Data");
2405 }
2406 
2407 //---------------------------------------------------------------------------
AVI__MD5_()2408 void File_Riff::AVI__MD5_()
2409 {
2410     //Parsing
2411     while (Element_Offset<Element_Size)
2412     {
2413         int128u MD5Stored;
2414         Get_L16   (MD5Stored,                                   "MD5");
2415         Ztring MD5_PerItem;
2416         MD5_PerItem.From_UTF8(uint128toString(MD5Stored, 16));
2417         while (MD5_PerItem.size()<32)
2418             MD5_PerItem.insert(MD5_PerItem.begin(), '0'); //Padding with 0, this must be a 32-byte string
2419         MD5_PerItem.MakeLowerCase();
2420         MD5s.push_back(MD5_PerItem);
2421     }
2422 }
2423 
2424 //---------------------------------------------------------------------------
AVI__movi()2425 void File_Riff::AVI__movi()
2426 {
2427     Element_Name("Datas");
2428 
2429     //Only the first time, no need in AVIX
2430     if (movi_Size==0)
2431     {
2432         Idx1_Offset=File_Offset+Buffer_Offset-4;
2433         BookMark_Set(); //Remenbering this place, for stream parsing in phase 2
2434 
2435         //For each stream
2436         std::map<int32u, stream>::iterator Temp=Stream.begin();
2437         while (Temp!=Stream.end())
2438         {
2439             if ((Temp->second.Parsers.empty() || Temp->second.Parsers[0]==NULL) && Temp->second.fccType!=Elements::AVI__hdlr_strl_strh_txts)
2440             {
2441                 Temp->second.SearchingPayload=false;
2442                 stream_Count--;
2443             }
2444             ++Temp;
2445         }
2446     }
2447 
2448     //Probing rec (with index, this is not always tested in the flow
2449     if (Element_Size<12)
2450     {
2451         Element_WaitForMoreData();
2452         return;
2453     }
2454     if (CC4(Buffer+Buffer_Offset+8)==0x72656320) //"rec "
2455         rec__Present=true;
2456 
2457     //Filling
2458     if (!SecondPass)
2459         movi_Size+=Element_TotalSize_Get();
2460 
2461     //We must parse moov?
2462     if (NeedOldIndex || (stream_Count==0 && Index_Pos.empty()))
2463     {
2464         //Jumping
2465         #if MEDIAINFO_TRACE
2466             if (Trace_Activated)
2467                 Param("Data", Ztring("(")+Ztring::ToZtring(Element_TotalSize_Get())+Ztring(" bytes)"));
2468         #endif //MEDIAINFO_TRACE
2469         Element_Offset=Element_TotalSize_Get(); //Not using Skip_XX() because we want to skip data we don't have, and Skip_XX() does a test on size of buffer
2470         return;
2471     }
2472 
2473     //Jump to next useful data
2474     AVI__movi_StreamJump();
2475 }
2476 
2477 //---------------------------------------------------------------------------
AVI__movi_rec_()2478 void File_Riff::AVI__movi_rec_()
2479 {
2480     Element_Name("Syncronisation");
2481 
2482     rec__Present=true;
2483 }
2484 
2485 //---------------------------------------------------------------------------
AVI__movi_rec__xxxx()2486 void File_Riff::AVI__movi_rec__xxxx()
2487 {
2488     AVI__movi_xxxx();
2489 }
2490 
2491 //---------------------------------------------------------------------------
AVI__movi_xxxx()2492 void File_Riff::AVI__movi_xxxx()
2493 {
2494     if (Element_Code==Elements::AVI__JUNK)
2495     {
2496         Skip_XX(Element_Size,                                    "Junk");
2497         AVI__movi_StreamJump();
2498         return;
2499     }
2500 
2501     if (Element_Code!=(int64u)-1)
2502         Stream_ID=(int32u)(Element_Code&0xFFFF0000);
2503     else
2504         Stream_ID=(int32u)-1;
2505 
2506     if (Stream_ID==0x69780000) //ix..
2507     {
2508         //AVI Standard Index Chunk
2509         AVI__hdlr_strl_indx();
2510         Stream_ID=(int32u)(Element_Code&0x0000FFFF)<<16;
2511         AVI__movi_StreamJump();
2512         return;
2513     }
2514     if ((Element_Code&0x0000FFFF)==0x00006978) //..ix (Out of specs, but found in a Adobe After Effects CS4 DV file
2515     {
2516         //AVI Standard Index Chunk
2517         AVI__hdlr_strl_indx();
2518         Stream_ID=(int32u)(Element_Code&0xFFFF0000);
2519         AVI__movi_StreamJump();
2520         return;
2521     }
2522 
2523     stream& StreamItem = Stream[Stream_ID];
2524     #if MEDIAINFO_DEMUX
2525         if (StreamItem.Rate) //AVI
2526         {
2527             int64u Element_Code_Old=Element_Code;
2528             Element_Code=((Element_Code_Old>>24)&0xF)*10+((Element_Code_Old>>16)&0xF);
2529             Frame_Count_NotParsedIncluded= StreamItem.PacketPos;
2530             FrameInfo.DTS=Frame_Count_NotParsedIncluded*1000000000* StreamItem.Scale/ StreamItem.Rate;
2531             Demux(Buffer+Buffer_Offset, (size_t)Element_Size, ContentType_MainStream);
2532             Element_Code=Element_Code_Old;
2533             Frame_Count_NotParsedIncluded=(int64u)-1;
2534         }
2535         else //WAV
2536         {
2537             //TODO
2538         }
2539     #endif //MEDIAINFO_DEMUX
2540 
2541         StreamItem.PacketPos++;
2542 
2543     //Finished?
2544     if (!StreamItem.SearchingPayload)
2545     {
2546         Element_DoNotShow();
2547         AVI__movi_StreamJump();
2548         return;
2549     }
2550 
2551     #if MEDIAINFO_TRACE
2552         if (Config_Trace_Level)
2553         {
2554             switch (Element_Code&0x0000FFFF) //2 last bytes
2555             {
2556                 case Elements::AVI__movi_xxxx_____ : Element_Info1("DV"); break;
2557                 case Elements::AVI__movi_xxxx___db :
2558                 case Elements::AVI__movi_xxxx___dc : Element_Info1("Video"); break;
2559                 case Elements::AVI__movi_xxxx___sb :
2560                 case Elements::AVI__movi_xxxx___tx : Element_Info1("Text"); break;
2561                 case Elements::AVI__movi_xxxx___wb : Element_Info1("Audio"); break;
2562                 default :                            Element_Info1("Unknown"); break;
2563             }
2564             Element_Info1(Stream[Stream_ID].PacketPos);
2565         }
2566     #endif //MEDIAINFO_TRACE
2567 
2568     //Some specific stuff
2569     switch (Element_Code&0x0000FFFF) //2 last bytes
2570     {
2571         case Elements::AVI__movi_xxxx___tx : AVI__movi_xxxx___tx(); break;
2572         default : ;
2573     }
2574 
2575     //Parsing
2576     for (size_t Pos=0; Pos<StreamItem.Parsers.size(); Pos++)
2577         if (StreamItem.Parsers[Pos])
2578         {
2579             if (FrameInfo.PTS!=(int64u)-1)
2580                 StreamItem.Parsers[Pos]->FrameInfo.PTS=FrameInfo.PTS;
2581             if (FrameInfo.DTS!=(int64u)-1)
2582                 StreamItem.Parsers[Pos]->FrameInfo.DTS=FrameInfo.DTS;
2583 
2584             Open_Buffer_Continue(StreamItem.Parsers[Pos], Buffer+Buffer_Offset+(size_t)Element_Offset, (size_t)(Element_Size-Element_Offset));
2585             Element_Show();
2586             if (StreamItem.Parsers.size()==1 && StreamItem.Parsers[Pos]->Buffer_Size>0)
2587                 StreamItem.ChunksAreComplete=false;
2588 
2589             if (StreamItem.Parsers.size()>1)
2590             {
2591                 if (!StreamItem.Parsers[Pos]->Status[IsAccepted] && StreamItem.Parsers[Pos]->Status[IsFinished])
2592                 {
2593                     delete *(StreamItem.Parsers.begin()+Pos);
2594                     StreamItem.Parsers.erase(StreamItem.Parsers.begin()+Pos);
2595                     Pos--;
2596                 }
2597                 else if (StreamItem.Parsers.size()>1 && StreamItem.Parsers[Pos]->Status[IsAccepted])
2598                 {
2599                     File__Analyze* Parser= StreamItem.Parsers[Pos];
2600                     for (size_t Pos2=0; Pos2<StreamItem.Parsers.size(); Pos2++)
2601                     {
2602                         if (Pos2!=Pos)
2603                             delete *(StreamItem.Parsers.begin()+Pos2);
2604                     }
2605                     StreamItem.Parsers.clear();
2606                     StreamItem.Parsers.push_back(Parser);
2607                     Pos=0;
2608                 }
2609             }
2610 
2611             #if MEDIAINFO_DEMUX
2612                 if (Config->Demux_EventWasSent)
2613                 {
2614                     Demux_Parser= StreamItem.Parsers[Pos];
2615                     return;
2616                 }
2617             #endif //MEDIAINFO_DEMUX
2618         }
2619     Element_Offset=Element_Size;
2620 
2621     //Some specific stuff
2622     switch (Element_Code&0x0000FFFF) //2 last bytes
2623     {
2624         case Elements::AVI__movi_xxxx_____ :
2625         case Elements::AVI__movi_xxxx___db :
2626         case Elements::AVI__movi_xxxx___dc : AVI__movi_xxxx___dc(); break;
2627         case Elements::AVI__movi_xxxx___wb : AVI__movi_xxxx___wb(); break;
2628         default : ;
2629     }
2630 
2631     //We must always parse moov?
2632     AVI__movi_StreamJump();
2633 
2634     Element_Show();
2635 }
2636 
2637 //---------------------------------------------------------------------------
AVI__movi_xxxx___dc()2638 void File_Riff::AVI__movi_xxxx___dc()
2639 {
2640     //Finish (if requested)
2641     stream& StreamItem = Stream[Stream_ID];
2642     if (StreamItem.Parsers.empty()
2643      || StreamItem.Parsers[0]->Status[IsFinished]
2644      || (StreamItem.PacketPos>=300 && Config->ParseSpeed<1.00))
2645     {
2646         StreamItem.SearchingPayload=false;
2647         stream_Count--;
2648         return;
2649     }
2650 }
2651 
2652 //---------------------------------------------------------------------------
AVI__movi_xxxx___tx()2653 void File_Riff::AVI__movi_xxxx___tx()
2654 {
2655     //Parsing
2656     int32u Name_Size;
2657     Ztring Value;
2658     int32u GAB2;
2659     Peek_B4(GAB2);
2660     if (GAB2==0x47414232 && Element_Size>=17)
2661     {
2662         Skip_C4(                                                    "GAB2");
2663         Skip_L1(                                                    "Zero");
2664         Skip_L2(                                                    "CodePage"); //2=Unicode
2665         Get_L4 (Name_Size,                                          "Name_Size");
2666         Skip_UTF16L(Name_Size,                                      "Name");
2667         Skip_L2(                                                    "Four");
2668         Skip_L4(                                                    "File_Size");
2669 
2670         if (Element_Offset>Element_Size)
2671             Element_Offset=Element_Size; //Problem
2672     }
2673 
2674     //Skip it
2675     Stream[Stream_ID].SearchingPayload=false;
2676     stream_Count--;
2677 }
2678 
2679 //---------------------------------------------------------------------------
AVI__movi_xxxx___wb()2680 void File_Riff::AVI__movi_xxxx___wb()
2681 {
2682     //Finish (if requested)
2683     stream& StreamItem = Stream[Stream_ID];
2684     if (StreamItem.PacketPos>=4 //For having the chunk alignement
2685      && (StreamItem.Parsers.empty()
2686       || StreamItem.Parsers[0]->Status[IsFinished]
2687       || (StreamItem.PacketPos>=300 && Config->ParseSpeed<1.00)))
2688     {
2689         StreamItem.SearchingPayload=false;
2690         stream_Count--;
2691     }
2692 }
2693 
2694 //---------------------------------------------------------------------------
AVI__movi_StreamJump()2695 void File_Riff::AVI__movi_StreamJump()
2696 {
2697     //Jump to next useful data
2698     if (!Index_Pos.empty())
2699     {
2700         if (Index_Pos.begin()->first<=File_Offset+Buffer_Offset && Element_Code!=Elements::AVI__movi)
2701             Index_Pos.erase(Index_Pos.begin());
2702         int64u ToJump=File_Size;
2703         if (!Index_Pos.empty())
2704             ToJump=Index_Pos.begin()->first;
2705         if (ToJump>File_Size)
2706             ToJump=File_Size;
2707         if (ToJump>=File_Offset+Buffer_Offset+Element_TotalSize_Get(Element_Level-2)) //We want always Element movi
2708         {
2709             #if MEDIAINFO_HASH
2710                 if (Config->File_Hash_Get().to_ulong() && SecondPass)
2711                     Hash_ParseUpTo=File_Offset+Buffer_Offset+Element_TotalSize_Get(Element_Level-2);
2712                 else
2713             #endif //MEDIAINFO_HASH
2714                     GoTo(File_Offset+Buffer_Offset+Element_TotalSize_Get(Element_Level-2), "AVI"); //Not in this chunk
2715         }
2716         else if (ToJump!=File_Offset+Buffer_Offset+(Element_Code==Elements::AVI__movi?0:Element_Size))
2717         {
2718             #if MEDIAINFO_HASH
2719                 if (Config->File_Hash_Get().to_ulong() && SecondPass)
2720                     Hash_ParseUpTo=File_Offset+Buffer_Offset+Element_TotalSize_Get(Element_Level-2);
2721                 else
2722             #endif //MEDIAINFO_HASH
2723                     GoTo(ToJump, "AVI"); //Not just after
2724         }
2725     }
2726     else if (stream_Count==0)
2727     {
2728         //Jumping
2729         Element_Show();
2730         if (rec__Present)
2731             Element_End0();
2732         Info("movi, Jumping to end of chunk");
2733         if (SecondPass)
2734         {
2735             std::map<int32u, stream>::iterator Temp=Stream.begin();
2736             while (Temp!=Stream.end())
2737             {
2738                 for (size_t Pos=0; Pos<Temp->second.Parsers.size(); ++Pos)
2739                 {
2740                     Temp->second.Parsers[Pos]->Fill();
2741                     Temp->second.Parsers[Pos]->Open_Buffer_Unsynch();
2742                 }
2743                 ++Temp;
2744             }
2745             Finish("AVI"); //The rest is already parsed
2746         }
2747         else
2748             GoTo(File_Offset+Buffer_Offset+Element_TotalSize_Get(), "AVI");
2749     }
2750     else if (Stream_Structure_Temp!=Stream_Structure.end())
2751     {
2752         do
2753             Stream_Structure_Temp++;
2754         while (Stream_Structure_Temp!=Stream_Structure.end() && !(Stream[(int32u)Stream_Structure_Temp->second.Name].SearchingPayload && Config->ParseSpeed<1.0));
2755         if (Stream_Structure_Temp!=Stream_Structure.end())
2756         {
2757             int64u ToJump=Stream_Structure_Temp->first;
2758             if (ToJump>=File_Offset+Buffer_Offset+Element_TotalSize_Get(Element_Level-2))
2759             {
2760                 #if MEDIAINFO_HASH
2761                     if (Config->File_Hash_Get().to_ulong() && SecondPass)
2762                         Hash_ParseUpTo=File_Offset+Buffer_Offset+Element_TotalSize_Get(Element_Level-2);
2763                     else
2764                 #endif //MEDIAINFO_HASH
2765                         GoTo(File_Offset+Buffer_Offset+Element_TotalSize_Get(Element_Level-2), "AVI"); //Not in this chunk
2766             }
2767             else if (ToJump!=File_Offset+Buffer_Offset+Element_Size)
2768             {
2769                 #if MEDIAINFO_HASH
2770                     if (Config->File_Hash_Get().to_ulong() && SecondPass)
2771                         Hash_ParseUpTo=ToJump;
2772                     else
2773                 #endif //MEDIAINFO_HASH
2774                         GoTo(ToJump, "AVI"); //Not just after
2775             }
2776         }
2777         else
2778             Finish("AVI");
2779     }
2780 }
2781 
2782 //---------------------------------------------------------------------------
AVI__PrmA()2783 void File_Riff::AVI__PrmA()
2784 {
2785     Element_Name("Adobe Premiere PrmA");
2786 
2787     //Parsing
2788     int32u FourCC, Size;
2789     Get_C4 (FourCC,                                             "FourCC");
2790     Get_B4 (Size,                                               "Size");
2791     switch (FourCC)
2792     {
2793         case 0x50415266:
2794                         if (Size==20)
2795                         {
2796                         int32u PAR_X, PAR_Y;
2797                         Skip_B4(                                                    "Unknown");
2798                         Get_B4 (PAR_X,                                              "PAR_X");
2799                         Get_B4 (PAR_Y,                                              "PAR_Y");
2800 
2801                         if (PAR_Y)
2802                             PAR=((float64)PAR_X)/PAR_Y;
2803                         }
2804                         else
2805                             Skip_XX(Element_Size-Element_Offset,                    "Unknown");
2806                         break;
2807         default:
2808                         for (int32u Pos=8; Pos<Size; Pos++)
2809                             Skip_B4(                                                "Unknown");
2810     }
2811 }
2812 
2813 //---------------------------------------------------------------------------
AVI__Tdat()2814 void File_Riff::AVI__Tdat()
2815 {
2816     Element_Name("Adobe Premiere Tdat");
2817 }
2818 
2819 //---------------------------------------------------------------------------
AVI__Tdat_tc_A()2820 void File_Riff::AVI__Tdat_tc_A()
2821 {
2822     Element_Name("tc_A");
2823 
2824     //Parsing
2825     Ztring Value;
2826     Get_UTF8(Element_Size, Value,                               "Unknown");
2827 
2828     if (Value.find_first_not_of(__T("0123456789:;"))==string::npos)
2829         Tdat_tc_A=Value;
2830 }
2831 
2832 //---------------------------------------------------------------------------
AVI__Tdat_tc_O()2833 void File_Riff::AVI__Tdat_tc_O()
2834 {
2835     Element_Name("tc_O");
2836 
2837     //Parsing
2838     Ztring Value;
2839     Get_UTF8(Element_Size, Value,                               "Unknown");
2840 
2841     if (Value.find_first_not_of(__T("0123456789:;"))==string::npos)
2842         Tdat_tc_O=Value;
2843 }
2844 
2845 //---------------------------------------------------------------------------
AVI__Tdat_rn_A()2846 void File_Riff::AVI__Tdat_rn_A()
2847 {
2848     Element_Name("rn_A");
2849 
2850     //Parsing
2851     Skip_UTF8(Element_Size,                                     "Unknown");
2852 }
2853 
2854 //---------------------------------------------------------------------------
AVI__Tdat_rn_O()2855 void File_Riff::AVI__Tdat_rn_O()
2856 {
2857     Element_Name("rn_O");
2858 
2859     //Parsing
2860     Skip_UTF8(Element_Size,                                     "Unknown");
2861 }
2862 
2863 //---------------------------------------------------------------------------
AVI__xxxx()2864 void File_Riff::AVI__xxxx()
2865 {
2866     Stream_ID=(int32u)(Element_Code&0xFFFF0000);
2867 
2868     if (Stream_ID==0x69780000) //ix..
2869     {
2870         //AVI Standard Index Chunk
2871         AVI__hdlr_strl_indx();
2872         Stream_ID=(int32u)(Element_Code&0x0000FFFF)<<16;
2873         AVI__movi_StreamJump();
2874         return;
2875     }
2876     if ((Element_Code&0x0000FFFF)==0x00006978) //..ix (Out of specs, but found in a Adobe After Effects CS4 DV file
2877     {
2878         //AVI Standard Index Chunk
2879         AVI__hdlr_strl_indx();
2880         Stream_ID=(int32u)(Element_Code&0xFFFF0000);
2881         AVI__movi_StreamJump();
2882         return;
2883     }
2884 }
2885 
2886 //---------------------------------------------------------------------------
AVIX()2887 void File_Riff::AVIX()
2888 {
2889     //Filling
2890     Fill(Stream_General, 0, General_Format_Profile, "OpenDML", Unlimited, true, true);
2891 }
2892 
2893 //---------------------------------------------------------------------------
AVIX_idx1()2894 void File_Riff::AVIX_idx1()
2895 {
2896     AVI__idx1();
2897 }
2898 
2899 //---------------------------------------------------------------------------
AVIX_movi()2900 void File_Riff::AVIX_movi()
2901 {
2902     AVI__movi();
2903 }
2904 
2905 //---------------------------------------------------------------------------
AVIX_movi_rec_()2906 void File_Riff::AVIX_movi_rec_()
2907 {
2908     AVI__movi_rec_();
2909 }
2910 
2911 //---------------------------------------------------------------------------
AVIX_movi_rec__xxxx()2912 void File_Riff::AVIX_movi_rec__xxxx()
2913 {
2914     AVIX_movi_xxxx();
2915 }
2916 
2917 //---------------------------------------------------------------------------
AVIX_movi_xxxx()2918 void File_Riff::AVIX_movi_xxxx()
2919 {
2920     AVI__movi_xxxx();
2921 }
2922 
2923 //---------------------------------------------------------------------------
CADP()2924 void File_Riff::CADP()
2925 {
2926     Element_Name("CMP4 - ADPCM");
2927 
2928     //Testing if we have enough data
2929     if (Element_Size<4)
2930     {
2931         Element_WaitForMoreData();
2932         return;
2933     }
2934 
2935     //Parsing
2936     int32u Codec;
2937     Get_C4 (Codec,                                              "Codec");
2938     #if MEDIAINFO_TRACE
2939         if (Trace_Activated)
2940             Param("Data", Ztring("(")+Ztring::ToZtring(Element_TotalSize_Get()-Element_Offset)+Ztring(" bytes)"));
2941     #endif //MEDIAINFO_TRACE
2942     Element_Offset=Element_TotalSize_Get(); //Not using Skip_XX() because we want to skip data we don't have, and Skip_XX() does a test on size of buffer
2943 
2944     FILLING_BEGIN();
2945         Stream_Prepare(Stream_Audio);
2946         if (Codec==0x41647063) //Adpc
2947             Fill(Stream_Audio, StreamPos_Last, Audio_Format, "ADPCM");
2948         Fill(Stream_Audio, StreamPos_Last, Audio_StreamSize, Element_TotalSize_Get());
2949     FILLING_END();
2950 }
2951 
2952 //---------------------------------------------------------------------------
CDDA()2953 void File_Riff::CDDA()
2954 {
2955     Element_Name("Compact Disc for Digital Audio");
2956 
2957     //Filling
2958     Accept("CDDA");
2959 }
2960 
2961 //---------------------------------------------------------------------------
CDDA_fmt_()2962 void File_Riff::CDDA_fmt_()
2963 {
2964     //Specs: http://fr.wikipedia.org/wiki/Compact_Disc_Audio_track
2965     //Specs: http://www.moon-soft.com/program/FORMAT/sound/cda.htm
2966 
2967     Element_Name("Stream format");
2968 
2969     //Parsing
2970     int32u id;
2971     int16u Version, tracknb=1;
2972     int8u TPositionF=0, TPositionS=0, TPositionM=0, TDurationF=0, TDurationS=0, TDurationM=0;
2973     Get_L2 (Version,                                            "Version"); // Always 1
2974     if (Version!=1)
2975     {
2976         //Not supported
2977         Skip_XX(Element_Size-2,                                 "Data");
2978         return;
2979     }
2980     Get_L2 (tracknb,                                            "Number"); // Start at 1
2981     Get_L4 (id,                                                 "id");
2982     Skip_L4(                                                    "offset"); // in frames //Priority of FSM format
2983     Skip_L4(                                                    "Duration"); // in frames //Priority of FSM format
2984     Get_L1 (TPositionF,                                         "Track_PositionF"); // in frames
2985     Get_L1 (TPositionS,                                         "Track_PositionS"); // in seconds
2986     Get_L1 (TPositionM,                                         "Track_PositionM"); // in minutes
2987     Skip_L1(                                                    "empty");
2988     Get_L1 (TDurationF,                                         "Track_DurationF"); // in frames
2989     Get_L1 (TDurationS,                                         "Track_DurationS"); // in seconds
2990     Get_L1 (TDurationM,                                         "Track_DurationM"); // in minutes
2991     Skip_L1(                                                    "empty");
2992 
2993     FILLING_BEGIN();
2994         int32u TPosition=TPositionM*60*75+TPositionS*75+TPositionF;
2995         int32u TDuration=TDurationM*60*75+TDurationS*75+TDurationF;
2996 
2997         Fill(Stream_General, 0, General_Track_Position, tracknb);
2998         Fill(Stream_General, 0, General_Format, "CDDA");
2999         Fill(Stream_General, 0, General_Format_Info, "Compact Disc for Digital Audio");
3000         Fill(Stream_General, 0, General_UniqueID, id);
3001         Fill(Stream_General, 0, General_FileSize, File_Size+TDuration*2352, 10, true);
3002 
3003         Stream_Prepare(Stream_Audio);
3004         Fill(Stream_Audio, 0, Audio_Format, "PCM");
3005         Fill(Stream_Audio, 0, Audio_Format_Settings_Endianness, "Little");
3006         Fill(Stream_Audio, 0, Audio_BitDepth, 16);
3007         Fill(Stream_Audio, 0, Audio_Channel_s_, 2);
3008         Fill(Stream_Audio, 0, Audio_SamplingRate, 44100);
3009         Fill(Stream_Audio, 0, Audio_FrameRate, (float)75);
3010         Fill(Stream_Audio, 0, Audio_BitRate, 1411200);
3011         Fill(Stream_Audio, 0, Audio_Compression_Mode, "Lossless");
3012         Fill(Stream_Audio, 0, Audio_FrameCount, TDuration);
3013         Fill(Stream_Audio, 0, Audio_Duration, float32_int32s(((float32)TDuration)*1000/75));
3014         Fill(Stream_Audio, 0, Audio_Delay, float32_int32s(((float32)TPosition)*1000/75));
3015 
3016         //No more need data
3017         Finish("CDDA");
3018     FILLING_END();
3019 }
3020 
3021 //---------------------------------------------------------------------------
CMJP()3022 void File_Riff::CMJP()
3023 {
3024     Element_Name("CMP4 - JPEG");
3025 
3026     //Parsing
3027     #ifdef MEDIAINFO_JPEG_YES
3028         Stream_ID=0;
3029         File_Jpeg* Parser=new File_Jpeg;
3030         Open_Buffer_Init(Parser);
3031         Parser->StreamKind=Stream_Video;
3032         Open_Buffer_Continue(Parser);
3033         Element_Offset=Element_TotalSize_Get(); //Not using Skip_XX() because we want to skip data we don't have, and Skip_XX() does a test on size of buffer
3034 
3035         FILLING_BEGIN();
3036             Stream_Prepare(Stream_Video);
3037             Fill(Stream_Video, StreamPos_Last, Video_StreamSize, Element_TotalSize_Get());
3038             Finish(Parser);
3039             Merge(*Parser, StreamKind_Last, 0, StreamPos_Last);
3040         FILLING_END();
3041 
3042         Stream[Stream_ID].Parsers.push_back(Parser);
3043     #else
3044         Element_Offset=Element_TotalSize_Get(); //Not using Skip_XX() because we want to skip data we don't have, and Skip_XX() does a test on size of buffer
3045 
3046         FILLING_BEGIN();
3047             Stream_Prepare(Stream_Video);
3048             Fill(Stream_Video, StreamPos_Last, Video_Format, "JPEG");
3049             Fill(Stream_Video, StreamPos_Last, Video_StreamSize, Element_TotalSize_Get());
3050         FILLING_END();
3051     #endif
3052 }
3053 
3054 //---------------------------------------------------------------------------
CMP4()3055 void File_Riff::CMP4()
3056 {
3057     Accept("CMP4");
3058     Element_Name("CMP4 - Header");
3059 
3060     //Parsing
3061     Ztring Title;
3062     Get_Local(Element_Size, Title,                              "Title");
3063 
3064     FILLING_BEGIN();
3065         Fill(Stream_General, 0, General_Format, "CMP4");
3066         Fill(Stream_General, 0, "Title", Title);
3067     FILLING_END();
3068 }
3069 
3070 //---------------------------------------------------------------------------
IDVX()3071 void File_Riff::IDVX()
3072 {
3073     Element_Name("Tags");
3074 }
3075 
3076 //---------------------------------------------------------------------------
INDX()3077 void File_Riff::INDX()
3078 {
3079     Element_Name("Index (from which spec?)");
3080 }
3081 
3082 //---------------------------------------------------------------------------
INDX_xxxx()3083 void File_Riff::INDX_xxxx()
3084 {
3085     Stream_ID=(int32u)(Element_Code&0xFFFF0000);
3086 
3087     if (Stream_ID==0x69780000) //ix..
3088     {
3089         //Index
3090         int32u Entry_Count, ChunkId;
3091         int16u LongsPerEntry;
3092         int8u  IndexType, IndexSubType;
3093         Get_L2 (LongsPerEntry,                                      "LongsPerEntry"); //Size of each entry in aIndex array
3094         Get_L1 (IndexSubType,                                       "IndexSubType");
3095         Get_L1 (IndexType,                                          "IndexType");
3096         Get_L4 (Entry_Count,                                        "EntriesInUse"); //Index of first unused member in aIndex array
3097         Get_C4 (ChunkId,                                            "ChunkId"); //FCC of what is indexed
3098 
3099         Skip_L4(                                                    "Unknown");
3100         Skip_L4(                                                    "Unknown");
3101         Skip_L4(                                                    "Unknown");
3102 
3103         for (int32u Pos=0; Pos<Entry_Count; Pos++)
3104         {
3105             Skip_L8(                                                "Offset");
3106             Skip_L4(                                                "Size");
3107             Skip_L4(                                                "Frame number?");
3108             Skip_L4(                                                "Frame number?");
3109             Skip_L4(                                                "Zero");
3110         }
3111     }
3112 
3113     //Currently, we do not use the index
3114     //TODO: use the index
3115     Stream_Structure.clear();
3116 }
3117 
3118 //---------------------------------------------------------------------------
JUNK()3119 void File_Riff::JUNK()
3120 {
3121     Element_Name("Junk");
3122 
3123     //Parse
3124     #if MEDIAINFO_TRACE
3125         if (Trace_Activated)
3126             Param("Junk", Ztring("(")+Ztring::ToZtring(Element_TotalSize_Get())+Ztring(" bytes)"));
3127     #endif //MEDIAINFO_TRACE
3128     Element_Offset=Element_TotalSize_Get(); //Not using Skip_XX() because we want to skip data we don't have, and Skip_XX() does a test on size of buffer
3129 }
3130 
3131 //---------------------------------------------------------------------------
menu()3132 void File_Riff::menu()
3133 {
3134     Element_Name("DivX Menu");
3135 
3136     //Filling
3137     Stream_Prepare(Stream_Menu);
3138     Fill(Stream_Menu, StreamPos_Last, Menu_Format, "DivX Menu");
3139     Fill(Stream_Menu, StreamPos_Last, Menu_Codec, "DivX");
3140 }
3141 
3142 //---------------------------------------------------------------------------
MThd()3143 void File_Riff::MThd()
3144 {
3145     Element_Name("MIDI header");
3146 
3147     //Parsing
3148     Skip_B2(                                                    "format");
3149     Skip_B2(                                                    "ntrks");
3150     Skip_B2(                                                    "division");
3151 
3152     FILLING_BEGIN_PRECISE();
3153         Accept("MIDI");
3154         Fill(Stream_General, 0, General_Format, "MIDI");
3155     FILLING_ELSE();
3156         Reject("MIDI");
3157     FILLING_END();
3158 }
3159 
3160 //---------------------------------------------------------------------------
MTrk()3161 void File_Riff::MTrk()
3162 {
3163     Element_Name("MIDI Track");
3164 
3165     //Parsing
3166     #if MEDIAINFO_TRACE
3167         if (Trace_Activated)
3168             Param("Data", Ztring("(")+Ztring::ToZtring(Element_TotalSize_Get())+Ztring(" bytes)"));
3169     #endif //MEDIAINFO_TRACE
3170     Element_Offset=Element_TotalSize_Get(); //Not using Skip_XX() because we want to skip data we don't have, and Skip_XX() does a test on size of buffer
3171 
3172     FILLING_BEGIN();
3173         Stream_Prepare(Stream_Audio);
3174         Fill(Stream_Audio, StreamPos_Last, Audio_Format, "MIDI");
3175         Fill(Stream_Audio, StreamPos_Last, Audio_Codec, "Midi");
3176 
3177         Finish("MIDI");
3178     FILLING_END();
3179 }
3180 
3181 //---------------------------------------------------------------------------
PAL_()3182 void File_Riff::PAL_()
3183 {
3184     Data_Accept("RIFF Palette");
3185     Element_Name("RIFF Palette");
3186 
3187     //Filling
3188     Fill(Stream_General, 0, General_Format, "RIFF Palette");
3189 }
3190 
3191 //---------------------------------------------------------------------------
QLCM()3192 void File_Riff::QLCM()
3193 {
3194     Data_Accept("QLCM");
3195     Element_Name("QLCM");
3196 
3197     //Filling
3198     Fill(Stream_General, 0, General_Format, "QLCM");
3199 }
3200 
3201 //---------------------------------------------------------------------------
QLCM_fmt_()3202 void File_Riff::QLCM_fmt_()
3203 {
3204     //Parsing
3205     Ztring codec_name;
3206     int128u codec_guid;
3207     int32u num_rates;
3208     int16u codec_version, average_bps, packet_size, block_size, sampling_rate, sample_size;
3209     int8u major, minor;
3210     Get_L1 (major,                                              "major");
3211     Get_L1 (minor,                                              "minor");
3212     Get_GUID(codec_guid,                                        "codec-guid");
3213     Get_L2 (codec_version,                                      "codec-version");
3214     Get_UTF8(80, codec_name,                                    "codec-name");
3215     Get_L2 (average_bps,                                        "average-bps");
3216     Get_L2 (packet_size,                                        "packet-size");
3217     Get_L2 (block_size,                                         "block-size");
3218     Get_L2 (sampling_rate,                                      "sampling-rate");
3219     Get_L2 (sample_size,                                        "sample-size");
3220     Element_Begin1("rate-map-table");
3221         Get_L4 (num_rates,                                      "num-rates");
3222         for (int32u rate=0; rate<num_rates; rate++)
3223         {
3224             Skip_L2(                                            "rate-size");
3225             Skip_L2(                                            "rate-octet");
3226         }
3227     Element_End0();
3228     Skip_L4(                                                    "Reserved");
3229     Skip_L4(                                                    "Reserved");
3230     Skip_L4(                                                    "Reserved");
3231     Skip_L4(                                                    "Reserved");
3232     if (Element_Offset<Element_Size)
3233         Skip_L4(                                                "Reserved"); //Some files don't have the 5th reserved dword
3234 
3235     FILLING_BEGIN_PRECISE();
3236         Stream_Prepare (Stream_Audio);
3237         switch (codec_guid.hi)
3238         {
3239             case Elements::QLCM_QCELP1 :
3240             case Elements::QLCM_QCELP2 : Fill(Stream_Audio, 0, Audio_Format, "QCELP"); Fill(Stream_Audio, 0, Audio_Codec, "QCELP"); break;
3241             case Elements::QLCM_EVRC   : Fill(Stream_Audio, 0, Audio_Format, "EVRC"); Fill(Stream_Audio, 0, Audio_Codec, "EVRC"); break;
3242             case Elements::QLCM_SMV    : Fill(Stream_Audio, 0, Audio_Format, "SMV"); Fill(Stream_Audio, 0, Audio_Codec, "SMV"); break;
3243             default :                    ;
3244         }
3245         Fill(Stream_Audio, 0, Audio_BitRate, average_bps);
3246         Fill(Stream_Audio, 0, Audio_SamplingRate, sampling_rate);
3247         Fill(Stream_Audio, 0, Audio_BitDepth, sample_size);
3248         Fill(Stream_Audio, 0, Audio_Channel_s_, 1);
3249     FILLING_END();
3250 }
3251 
3252 #if defined(MEDIAINFO_GXF_YES)
3253 //---------------------------------------------------------------------------
rcrd()3254 void File_Riff::rcrd()
3255 {
3256     Data_Accept("Ancillary media packets");
3257     Element_Name("Ancillary media packets");
3258 
3259     //Filling
3260     if (Retrieve(Stream_General, 0, General_Format).empty())
3261         Fill(Stream_General, 0, General_Format, "Ancillary media packets"); //GXF, RDD14-2007
3262 
3263     //Clearing old data
3264     if (Ancillary)
3265     {
3266         (*Ancillary)->FrameInfo.DTS=FrameInfo.DTS;
3267         Open_Buffer_Continue(*Ancillary, Buffer, 0);
3268     }
3269 }
3270 
3271 //---------------------------------------------------------------------------
rcrd_desc()3272 void File_Riff::rcrd_desc()
3273 {
3274     Element_Name("Ancillary media packet description");
3275 
3276     //Parsing
3277     int32u Version;
3278     Get_L4 (Version,                                            "Version");
3279     if (Version==2)
3280     {
3281         Skip_L4(                                                "Number of fields");
3282         Skip_L4(                                                "Length of the ancillary data field descriptions");
3283         Skip_L4(                                                "Byte size of the complete ancillary media packet");
3284         Skip_L4(                                                "Format of the video");
3285     }
3286     else
3287         Skip_XX(Element_Size-Element_Offset,                    "Unknown");
3288 }
3289 
3290 //---------------------------------------------------------------------------
rcrd_fld_()3291 void File_Riff::rcrd_fld_()
3292 {
3293     Element_Name("Ancillary data field description");
3294 }
3295 
3296 //---------------------------------------------------------------------------
rcrd_fld__anc_()3297 void File_Riff::rcrd_fld__anc_()
3298 {
3299     Element_Name("Ancillary data sample description");
3300 
3301     rcrd_fld__anc__pos__LineNumber=(int32u)-1;
3302 }
3303 
3304 //---------------------------------------------------------------------------
rcrd_fld__anc__pos_()3305 void File_Riff::rcrd_fld__anc__pos_()
3306 {
3307     Element_Name("Ancillary data sample description");
3308 
3309     //Parsing
3310     Get_L4 (rcrd_fld__anc__pos__LineNumber,                     "Video line number");
3311     Skip_L4(                                                    "Ancillary video color difference or luma space");
3312     Skip_L4(                                                    "Ancillary video space");
3313 }
3314 
3315 //---------------------------------------------------------------------------
rcrd_fld__anc__pyld()3316 void File_Riff::rcrd_fld__anc__pyld()
3317 {
3318     Element_Name("Ancillary data sample payload");
3319 
3320     if (Ancillary)
3321     {
3322         (*Ancillary)->FrameInfo.DTS=FrameInfo.DTS;
3323         (*Ancillary)->LineNumber=rcrd_fld__anc__pos__LineNumber;
3324         Open_Buffer_Continue(*Ancillary);
3325     }
3326 }
3327 
3328 //---------------------------------------------------------------------------
rcrd_fld__finf()3329 void File_Riff::rcrd_fld__finf()
3330 {
3331     Element_Name("Data field description");
3332 
3333     //Parsing
3334     Skip_L4(                                                    "Video field identifier");
3335 }
3336 #endif //MEDIAINFO_GXF_YES
3337 
3338 //---------------------------------------------------------------------------
RDIB()3339 void File_Riff::RDIB()
3340 {
3341     Data_Accept("RIFF DIB");
3342     Element_Name("RIFF DIB");
3343 
3344     //Filling
3345     Fill(Stream_General, 0, General_Format, "RIFF DIB");
3346 }
3347 
3348 //---------------------------------------------------------------------------
RMID()3349 void File_Riff::RMID()
3350 {
3351     Data_Accept("RIFF MIDI");
3352     Element_Name("RIFF MIDI");
3353 
3354     //Filling
3355     Fill(Stream_General, 0, General_Format, "RIFF MIDI");
3356 }
3357 
3358 //---------------------------------------------------------------------------
RMMP()3359 void File_Riff::RMMP()
3360 {
3361     Data_Accept("RIFF MMP");
3362     Element_Name("RIFF MMP");
3363 
3364     //Filling
3365     Fill(Stream_General, 0, General_Format, "RIFF MMP");
3366 }
3367 
3368 //---------------------------------------------------------------------------
RMP3()3369 void File_Riff::RMP3()
3370 {
3371     Data_Accept("RMP3");
3372     Element_Name("RMP3");
3373 
3374     //Filling
3375     Fill(Stream_General, 0, General_Format, "RMP3");
3376     Kind=Kind_Rmp3;
3377 }
3378 
3379 //---------------------------------------------------------------------------
RMP3_data()3380 void File_Riff::RMP3_data()
3381 {
3382     Element_Name("Raw datas");
3383 
3384     Fill(Stream_Audio, 0, Audio_StreamSize, Buffer_DataToParse_End-Buffer_DataToParse_Begin);
3385     Stream_Prepare(Stream_Audio);
3386 
3387     //Creating parser
3388     #if defined(MEDIAINFO_MPEGA_YES)
3389         File_Mpega* Parser=new File_Mpega;
3390         Parser->CalculateDelay=true;
3391         Parser->ShouldContinueParsing=true;
3392         Open_Buffer_Init(Parser);
3393         stream& StreamItem=Stream[(int32u)-1];
3394         StreamItem.StreamKind=Stream_Audio;
3395         StreamItem.StreamPos=0;
3396         StreamItem.Parsers.push_back(Parser);
3397     #else //MEDIAINFO_MPEG4_YES
3398         Fill(Stream_Audio, 0, Audio_Format, "MPEG Audio");
3399         Skip_XX(Buffer_DataToParse_End-Buffer_DataToParse_Begin, "Data");
3400     #endif
3401 }
3402 
3403 //---------------------------------------------------------------------------
RMP3_data_Continue()3404 void File_Riff::RMP3_data_Continue()
3405 {
3406     #if MEDIAINFO_DEMUX
3407         if (Element_Size)
3408         {
3409             Demux_random_access=true;
3410             Demux(Buffer+Buffer_Offset, (size_t)Element_Size, ContentType_MainStream);
3411         }
3412     #endif //MEDIAINFO_DEMUX
3413 
3414     Element_Code=(int64u)-1;
3415     AVI__movi_xxxx();
3416 }
3417 
3418 //---------------------------------------------------------------------------
SMV0()3419 void File_Riff::SMV0()
3420 {
3421     Accept("SMV");
3422 
3423     //Parsing
3424     int8u Version;
3425     Skip_C1(                                                    "Identifier (continuing)");
3426     Get_C1 (Version,                                            "Version");
3427     Skip_C3(                                                    "Identifier (continuing)");
3428     if (Version=='1')
3429     {
3430         int32u Width, Height, FrameRate, BlockSize, FrameCount;
3431         Get_B3 (Width,                                          "Width");
3432         Get_B3 (Height,                                         "Height");
3433         Skip_B3(                                                "0x000010");
3434         Skip_B3(                                                "0x000001");
3435         Get_B3 (BlockSize,                                      "Block size");
3436         Get_B3 (FrameRate,                                      "Frame rate");
3437         Get_B3 (FrameCount,                                     "Frame count");
3438         Skip_B3(                                                "0x000000");
3439         Skip_B3(                                                "0x000000");
3440         Skip_B3(                                                "0x000000");
3441         Skip_B3(                                                "0x010101");
3442         Skip_B3(                                                "0x010101");
3443         Skip_B3(                                                "0x010101");
3444         Skip_B3(                                                "0x010101");
3445 
3446         //Filling
3447         Fill(Stream_General, 0, General_Format_Profile, "SMV v1");
3448         Stream_Prepare(Stream_Video);
3449         Fill(Stream_Video, 0, Video_MuxingMode, "SMV v1");
3450         Fill(Stream_Video, 0, Video_Width, Width);
3451         Fill(Stream_Video, 0, Video_Height, Height);
3452         Fill(Stream_Video, 0, Video_FrameRate, (float)FrameRate);
3453         Fill(Stream_Video, 0, Video_FrameCount, FrameCount);
3454 
3455         Finish("SMV");
3456     }
3457     else if (Version=='2')
3458     {
3459         int32u Width, Height, FrameRate;
3460         Get_L3 (Width,                                          "Width");
3461         Get_L3 (Height,                                         "Height");
3462         Skip_L3(                                                "0x000010");
3463         Skip_L3(                                                "0x000001");
3464         Get_L3 (SMV_BlockSize,                                  "Block size");
3465         Get_L3 (FrameRate,                                      "Frame rate");
3466         Get_L3 (SMV_FrameCount,                                 "Frame count");
3467         Skip_L3(                                                "0x000001");
3468         Skip_L3(                                                "0x000000");
3469         Skip_L3(                                                "Frame rate");
3470         Skip_L3(                                                "0x010101");
3471         Skip_L3(                                                "0x010101");
3472         Skip_L3(                                                "0x010101");
3473         Skip_L3(                                                "0x010101");
3474 
3475         //Filling
3476         SMV_BlockSize+=3;
3477         SMV_FrameCount++;
3478         Fill(Stream_General, 0, General_Format_Profile, "SMV v2");
3479         Stream_Prepare(Stream_Video);
3480         Fill(Stream_Video, 0, Video_Format, "JPEG");
3481         Fill(Stream_Video, 0, Video_Codec,  "JPEG");
3482         Fill(Stream_Video, 0, Video_MuxingMode, "SMV v2");
3483         Fill(Stream_Video, 0, Video_Width, Width);
3484         Fill(Stream_Video, 0, Video_Height, Height);
3485         Fill(Stream_Video, 0, Video_FrameRate, FrameRate);
3486         Fill(Stream_Video, 0, Video_FrameCount, SMV_FrameCount);
3487         Fill(Stream_Video, 0, Video_StreamSize, SMV_BlockSize*SMV_FrameCount);
3488     }
3489     else
3490         Finish("SMV");
3491 }
3492 
3493 //---------------------------------------------------------------------------
SMV0_xxxx()3494 void File_Riff::SMV0_xxxx()
3495 {
3496     //Parsing
3497     int32u Size;
3498     Get_L3 (Size,                                              "Size");
3499     #if defined(MEDIAINFO_JPEG_YES)
3500         //Creating the parser
3501         File_Jpeg MI;
3502         Open_Buffer_Init(&MI);
3503 
3504         //Parsing
3505         Open_Buffer_Continue(&MI, Size);
3506 
3507         //Filling
3508         Finish(&MI);
3509         Merge(MI, Stream_Video, 0, StreamPos_Last);
3510 
3511         //Positioning
3512         Element_Offset+=Size;
3513     #else
3514         //Parsing
3515         Skip_XX(Size,                                           "JPEG data");
3516     #endif
3517     Skip_XX(Element_Size-Element_Offset,                        "Padding");
3518 
3519     //Filling
3520     #if MEDIAINFO_HASH
3521         if (Config->File_Hash_Get().to_ulong())
3522             Element_Offset=Element_Size+(SMV_FrameCount-1)*SMV_BlockSize;
3523     #endif //MEDIAINFO_HASH
3524             Data_GoTo(File_Offset+Buffer_Offset+(size_t)Element_Size+(SMV_FrameCount-1)*SMV_BlockSize, "SMV");
3525     SMV_BlockSize=0;
3526 }
3527 
3528 //---------------------------------------------------------------------------
WAVE()3529 void File_Riff::WAVE()
3530 {
3531     Data_Accept("Wave");
3532     Element_Name("Wave");
3533 
3534     //Filling
3535     Fill(Stream_General, 0, General_Format, "Wave");
3536     Kind=Kind_Wave;
3537     #if MEDIAINFO_EVENTS
3538         StreamIDs_Width[0]=0;
3539     #endif //MEDIAINFO_EVENTS
3540 }
3541 
3542 //---------------------------------------------------------------------------
WAVE__pmx()3543 void File_Riff::WAVE__pmx()
3544 {
3545     Element_Name("XMP");
3546 
3547     //Parsing
3548     Ztring XML_Data;
3549     Get_UTF8(Element_Size, XML_Data,                            "XML data");
3550 }
3551 
3552 //---------------------------------------------------------------------------
3553 static const char* profile_names[]=
3554 {
3555     "profileName",
3556     "profileVersion",
3557     "profileID",
3558     "levelID",
3559 };
3560 static const int profile_names_size=(int)sizeof(profile_names)/sizeof(const char*);
3561 static const char* profile_names_InternalID[profile_names_size]=
3562 {
3563     "Format",
3564     "Version",
3565     "Profile",
3566     "Level",
3567 };
3568 struct profile_info
3569 {
3570     string Strings[4];
profile_info_buildMediaInfoLib::profile_info3571     string profile_info_build(size_t Max=profile_names_size)
3572     {
3573         bool HasParenthsis=false;
3574         string ToReturn;
3575         for (size_t i=0; i<Max; i++)
3576         {
3577             if (!Strings[i].empty())
3578             {
3579                 if (!ToReturn.empty())
3580                 {
3581                     if (i==1)
3582                         ToReturn+=", Version";
3583                     if (!HasParenthsis)
3584                         ToReturn+=' ';
3585                 }
3586                 if (i>=2)
3587                 {
3588                     if (!HasParenthsis)
3589                     {
3590                         ToReturn+='(';
3591                         HasParenthsis=true;
3592                     }
3593                     else
3594                     {
3595                         ToReturn+=',';
3596                         ToReturn+=' ';
3597                     }
3598                 }
3599                 if (i>=2)
3600                 {
3601                     ToReturn+=profile_names[i];
3602                     ToReturn+='=';
3603                 }
3604                 ToReturn+=Strings[i];
3605             }
3606         }
3607         if (HasParenthsis)
3608             ToReturn+=')';
3609         return ToReturn;
3610     }
3611 };
3612 
WAVE_axml()3613 void File_Riff::WAVE_axml()
3614 {
3615     int64u Element_TotalSize=Element_TotalSize_Get();
3616     if (Element_Size!=Element_TotalSize-Alignement_ExtraByte)
3617     {
3618         if (Buffer_MaximumSize<Element_TotalSize)
3619             Buffer_MaximumSize+=Element_TotalSize;
3620         size_t* File_Buffer_Size_Hint_Pointer=Config->File_Buffer_Size_Hint_Pointer_Get();
3621         if (File_Buffer_Size_Hint_Pointer)
3622             (*File_Buffer_Size_Hint_Pointer)=(size_t)(Element_TotalSize-Element_Size);
3623         Element_WaitForMoreData();
3624         return; //Must wait for more data
3625     }
3626 
3627     int8u* UncompressedData;
3628     size_t UncompressedData_Size;
3629     if (Element_Code==Elements::WAVE_bxml)
3630     {
3631         Element_Name("Compressed AXML");
3632 
3633         //Header
3634         int16u Version; // Maybe...
3635         Get_L2 (Version,                                        "Version");
3636         if (Version!=1)
3637         {
3638             Skip_XX(Element_Size-Element_Offset,                "Data (Unsuported)");
3639             return;
3640         }
3641 
3642         //Uncompress init
3643         z_stream strm;
3644         strm.next_in=(Bytef*)Buffer+Buffer_Offset+2;
3645         strm.avail_in=(uInt)Element_Size-2;
3646         strm.next_out=NULL;
3647         strm.avail_out=0;
3648         strm.total_out=0;
3649         strm.zalloc=Z_NULL;
3650         strm.zfree=Z_NULL;
3651         inflateInit2(&strm, 15+16); // 15 + 16 are magic values for gzip
3652 
3653         //Prepare out
3654         strm.avail_out=0x10000; //Blocks of 64 KiB, arbitrary chosen, as a begin
3655         strm.next_out=(Bytef*)new Bytef[strm.avail_out];
3656 
3657         //Parse compressed data, with handling of the case the output buffer is not big enough
3658         for (;;)
3659         {
3660             //inflate
3661             int inflate_Result=inflate(&strm, Z_NO_FLUSH);
3662             if (inflate_Result<0)
3663                 break;
3664 
3665             //Check if we need to stop
3666             if (strm.avail_out || inflate_Result)
3667                 break;
3668 
3669             //Need to increase buffer
3670             size_t UncompressedData_NewMaxSize=strm.total_out*4;
3671             int8u* UncompressedData_New=new int8u[UncompressedData_NewMaxSize];
3672             memcpy(UncompressedData_New, strm.next_out-strm.total_out, strm.total_out);
3673             delete[] (strm.next_out-strm.total_out); strm.next_out=UncompressedData_New;
3674             strm.next_out=strm.next_out+strm.total_out;
3675             strm.avail_out=UncompressedData_NewMaxSize-strm.total_out;
3676         }
3677         UncompressedData=strm.next_out-strm.total_out;
3678         UncompressedData_Size=strm.total_out;
3679     }
3680     else
3681     {
3682         Element_Name("AXML");
3683 
3684         UncompressedData=(int8u*)Buffer+Buffer_Offset;
3685         UncompressedData_Size=(size_t)Element_Size;
3686     }
3687 
3688     //Parsing
3689     File_Adm* Adm_New=new File_Adm;
3690     Adm_New->MuxingMode=(Element_Code==Elements::WAVE_bxml)?'b':'a';
3691     Adm_New->MuxingMode+="xml";
3692     Open_Buffer_Init(Adm_New);
3693     Open_Buffer_Continue(Adm_New, UncompressedData, UncompressedData_Size);
3694     Finish(Adm_New);
3695     if (Adm_New->Status[IsAccepted])
3696     {
3697         delete Adm;
3698         Adm=Adm_New;
3699     }
3700 
3701     //Parsing
3702     Skip_UTF8(Element_Size, "XML data");
3703 }
3704 
3705 //---------------------------------------------------------------------------
WAVE_adtl()3706 void File_Riff::WAVE_adtl()
3707 {
3708     Element_Name("Associated Data List");
3709 }
3710 
3711 //---------------------------------------------------------------------------
WAVE_adtl_labl()3712 void File_Riff::WAVE_adtl_labl()
3713 {
3714     Element_Name("Label");
3715 
3716     //Parsing
3717     Skip_L4(                                                    "Cue Point ID");
3718     Skip_UTF8(Element_Size-Element_Offset,                      "Text");
3719 }
3720 
3721 //---------------------------------------------------------------------------
WAVE_adtl_ltxt()3722 void File_Riff::WAVE_adtl_ltxt()
3723 {
3724     Element_Name("Labeled Text");
3725 
3726     //Parsing
3727     Skip_L4(                                                    "Cue Point ID");
3728     Skip_L4(                                                    "Sample Length");
3729     Skip_C4(                                                    "Purpose ID");
3730     Skip_L2(                                                    "Country");
3731     Skip_L2(                                                    "Language");
3732     Skip_L2(                                                    "Dialect");
3733     Skip_L2(                                                    "Code Page");
3734     Skip_UTF8(Element_Size-Element_Offset,                      "Text");
3735 }
3736 
3737 //---------------------------------------------------------------------------
WAVE_adtl_note()3738 void File_Riff::WAVE_adtl_note()
3739 {
3740     Element_Name("Note");
3741 
3742     //Parsing
3743     Skip_L4(                                                    "Cue Point ID");
3744     Skip_UTF8(Element_Size-Element_Offset,                      "Text");
3745 }
3746 
3747 //---------------------------------------------------------------------------
WAVE_bext()3748 void File_Riff::WAVE_bext()
3749 {
3750     Element_Name("Broadcast extension");
3751 
3752     //Parsing
3753     Ztring Description, Originator, OriginatorReference, OriginationDate, OriginationTime, History;
3754     int128u UMID1, UMID2, UMID3, UMID4;
3755     int16u Version, LoudnessValue=0x7FFF, LoudnessRange=0x7FFF, MaxTruePeakLevel=0x7FFF, MaxMomentaryLoudness=0x7FFF, MaxShortTermLoudness=0x7FFF;
3756     Get_Local(256, Description,                                 "Description");
3757     Get_Local( 32, Originator,                                  "Originator");
3758     Get_Local( 32, OriginatorReference,                         "OriginatorReference");
3759     Get_Local( 10, OriginationDate,                             "OriginationDate");
3760     Get_Local(  8, OriginationTime,                             "OriginationTime");
3761     Get_L8   (     TimeReference,                               "TimeReference"); //To be divided by SamplesPerSec
3762     Get_L2   (     Version,                                     "Version");
3763     if (Version>=1)
3764     {
3765         Get_UUID (UMID1,                                        "UMID");
3766         Get_UUID (UMID2,                                        "UMID");
3767         Get_UUID (UMID3,                                        "UMID");
3768         Get_UUID (UMID4,                                        "UMID");
3769     }
3770     if (Version>=2)
3771     {
3772         Get_L2 (LoudnessValue,                                  "LoudnessValue");
3773         Get_L2 (LoudnessRange,                                  "LoudnessRange");
3774         Get_L2 (MaxTruePeakLevel,                               "MaxTruePeakLevel");
3775         Get_L2 (MaxMomentaryLoudness,                           "MaxMomentaryLoudness");
3776         Get_L2 (MaxShortTermLoudness,                           "MaxShortTermLoudness");
3777     }
3778     Skip_XX  (602-Element_Offset,                               "Reserved");
3779     if (Element_Offset<Element_Size)
3780         Get_Local(Element_Size-Element_Offset, History,         "History");
3781 
3782     FILLING_BEGIN();
3783         // Handle some buggy OriginationDate/OriginalTime, prefixed 0 are sometimes missing e.g. 2015-3-2
3784         if (OriginationDate.size()!=10
3785          && OriginationDate.size()>=8
3786          && OriginationDate[0]>=__T('0') && OriginationDate[0]<=__T('9')
3787          && OriginationDate[1]>=__T('0') && OriginationDate[1]<=__T('9')
3788          && OriginationDate[2]>=__T('0') && OriginationDate[2]<=__T('9')
3789          && OriginationDate[3]>=__T('0') && OriginationDate[3]<=__T('9')
3790          && OriginationDate[4]==__T('-')
3791          && OriginationDate[5]>=__T('0') && OriginationDate[5]<=__T('9'))
3792         {
3793             Ztring Modified(OriginationDate);
3794             if (Modified[6]==__T('-'))
3795                 Modified.insert(5, 1, __T('0'));
3796             if (Modified.size()==10
3797              && Modified[8]>=__T('0') && Modified[8]<=__T('9')
3798              && Modified[9]>=__T('0') && Modified[9]<=__T('9'))
3799                 OriginationDate=Modified;
3800             if (Modified.size()==9
3801              && Modified[8]>=__T('0') && Modified[8]<=__T('9'))
3802             {
3803                 Modified.insert(8, 1, __T('0'));
3804                 OriginationDate=Modified;
3805             }
3806         }
3807         if (OriginationTime.size()!=8
3808          && OriginationTime.size()>=6
3809          && OriginationTime[0]>=__T('0') && OriginationTime[0]<=__T('9')
3810          && OriginationTime[1]>=__T('0') && OriginationTime[1]<=__T('9')
3811          && OriginationTime[2]==__T(':')
3812          && OriginationTime[3]>=__T('0') && OriginationTime[3]<=__T('9'))
3813         {
3814             Ztring Modified(OriginationTime);
3815             if (Modified[4]==__T(':'))
3816                 Modified.insert(3, 1, __T('0'));
3817             if (Modified.size()==8
3818              && Modified[6]>=__T('0') && Modified[6]<=__T('9')
3819              && Modified[7]>=__T('0') && Modified[7]<=__T('9'))
3820                 OriginationTime=Modified;
3821             if (Modified.size()==7
3822              && Modified[6]>=__T('0') && Modified[6]<=__T('9'))
3823             {
3824                 Modified.insert(6, 1, __T('0'));
3825                 OriginationTime=Modified;
3826             }
3827         }
3828 
3829         Fill(Stream_General, 0, "bext_Present", "Yes");
3830         Fill_SetOptions(Stream_General, 0, "bext_Present", "N NT");
3831         Fill(Stream_General, 0, "bext_Version", Version);
3832         Fill_SetOptions(Stream_General, 0, "bext_Version", "N NIY");
3833         Fill(Stream_General, 0, General_Description, Description);
3834         Fill(Stream_General, 0, General_Producer, Originator);
3835         Fill(Stream_General, 0, "Producer_Reference", OriginatorReference);
3836         Fill(Stream_General, 0, General_Encoded_Date, OriginationDate+__T(' ')+OriginationTime);
3837         Fill(Stream_General, 0, General_Encoded_Library_Settings, History);
3838         if (SamplesPerSec && TimeReference!=(int64u)-1)
3839         {
3840             Fill(Stream_Audio, 0, Audio_Delay, ((float64)TimeReference*1000/SamplesPerSec), 6);
3841             Fill(Stream_Audio, 0, Audio_Delay_Source, "Container (bext)");
3842         }
3843         if (Version>=1 && UMID1 != 0 && UMID2 != 0)
3844         {
3845             Ztring UMID=__T("0x")+Ztring().From_UTF8(uint128toString(UMID1, 16))+Ztring().From_UTF8(uint128toString(UMID2, 16));
3846             if ((UMID1.lo&0xFF000000)==0x33000000)
3847                 UMID+=Ztring().From_UTF8(uint128toString(UMID3, 16))+Ztring().From_UTF8(uint128toString(UMID4, 16));
3848             Fill(Stream_General, 0, "UMID", UMID);
3849         }
3850         if (Version>=2)
3851         {
3852             if (LoudnessValue!=0x7FFF)
3853                 Fill(Stream_Audio, 0, "LoudnessValue", (float)((int16s)LoudnessValue)/100, 2);
3854             if (LoudnessRange!=0x7FFF)
3855                 Fill(Stream_Audio, 0, "LoudnessRange", (float)((int16s)LoudnessRange)/100, 2);
3856             if (MaxTruePeakLevel!=0x7FFF)
3857                 Fill(Stream_Audio, 0, "MaxTruePeakLevel", (float)((int16s)MaxTruePeakLevel)/100, 2);
3858             if (MaxMomentaryLoudness!=0x7FFF)
3859                 Fill(Stream_Audio, 0, "MaxMomentaryLoudness", (float)((int16s)MaxMomentaryLoudness)/100, 2);
3860             if (MaxShortTermLoudness!=0x7FFF)
3861                 Fill(Stream_Audio, 0, "MaxShortTermLoudness", (float)((int16s)MaxShortTermLoudness)/100, 2);
3862         }
3863     FILLING_END();
3864 }
3865 
3866 //---------------------------------------------------------------------------
WAVE_cue_()3867 void File_Riff::WAVE_cue_()
3868 {
3869     Element_Name("Cue points");
3870 
3871     //Parsing
3872     int32u numCuePoints;
3873     Get_L4(numCuePoints,                                        "numCuePoints");
3874     for (int32u Pos=0; Pos<numCuePoints; Pos++)
3875     {
3876         Element_Begin1("Cue point");
3877         Skip_L4(                                                "ID");
3878         Skip_L4(                                                "Position");
3879         Skip_C4(                                                "DataChunkID");
3880         Skip_L4(                                                "ChunkStart");
3881         Skip_L4(                                                "BlockStart");
3882         Skip_L4(                                                "SampleOffset");
3883         Element_End0();
3884     }
3885 }
3886 
3887 //---------------------------------------------------------------------------
WAVE_data()3888 void File_Riff::WAVE_data()
3889 {
3890     Element_Name("Raw datas");
3891 
3892     if (Buffer_DataToParse_End-Buffer_DataToParse_Begin<100)
3893     {
3894         Skip_XX(Buffer_DataToParse_End-Buffer_Offset,           "Unknown");
3895         return; //This is maybe embeded in another container, and there is only the header (What is the junk?)
3896     }
3897 
3898     //Parsing
3899     Element_Code=(int64u)-1;
3900 
3901     FILLING_BEGIN();
3902         int64u StreamSize=Buffer_DataToParse_End-Buffer_DataToParse_Begin;
3903         Fill(Stream_Audio, 0, Audio_StreamSize, StreamSize, 10, true);
3904         if (Retrieve(Stream_Audio, 0, Audio_Format)==__T("PCM") && BlockAlign)
3905             Fill(Stream_Audio, 0, Audio_SamplingCount, StreamSize/BlockAlign, 10, true);
3906         float64 Duration=Retrieve(Stream_Audio, 0, Audio_Duration).To_float64();
3907         float64 BitRate=Retrieve(Stream_Audio, 0, Audio_BitRate).To_float64();
3908         if (Duration)
3909         {
3910             float64 BitRate_New=((float64)StreamSize)*8*1000/Duration;
3911             if (BitRate_New<BitRate*0.95 || BitRate_New>BitRate*1.05)
3912                 Fill(Stream_Audio, 0, Audio_BitRate, BitRate_New, 10, true); //Correcting the bitrate, it was false in the header
3913         }
3914         else if (BitRate)
3915         {
3916             if (IsSub)
3917                 //Retrieving "data" real size, in case of truncated files and/or wave header in another container
3918                 Duration=((float64)LittleEndian2int32u(Buffer+Buffer_Offset-4))*8*1000/BitRate; //TODO: RF64 is not handled
3919             else
3920                 Duration=((float64)StreamSize)*8*1000/BitRate;
3921             Fill(Stream_General, 0, General_Duration, Duration, 0, true);
3922             Fill(Stream_Audio, 0, Audio_Duration, Duration, 0, true);
3923         }
3924     FILLING_END();
3925 }
3926 
3927 //---------------------------------------------------------------------------
WAVE_data_Continue()3928 void File_Riff::WAVE_data_Continue()
3929 {
3930     #if MEDIAINFO_DEMUX
3931         Element_Code=(int64u)-1;
3932         if (AvgBytesPerSec && Demux_Rate)
3933         {
3934             FrameInfo.DTS=float64_int64s((File_Offset+Buffer_Offset-Buffer_DataToParse_Begin)*1000000000.0/AvgBytesPerSec);
3935             FrameInfo.PTS=FrameInfo.DTS;
3936             Frame_Count_NotParsedIncluded=float64_int64s(((float64)FrameInfo.DTS)/1000000000.0*Demux_Rate);
3937         }
3938         Demux_random_access=true;
3939         Demux(Buffer+Buffer_Offset, (size_t)Element_Size, ContentType_MainStream);
3940         Frame_Count_NotParsedIncluded=(int64u)-1;
3941     #endif //MEDIAINFO_DEMUX
3942 
3943     Element_Code=(int64u)-1;
3944     AVI__movi_xxxx();
3945 }
3946 
3947 //---------------------------------------------------------------------------
WAVE_dbmd()3948 void File_Riff::WAVE_dbmd()
3949 {
3950     Element_Name("Dolby Audio Metadata");
3951 
3952     //Parsing
3953     File_DolbyAudioMetadata* DolbyAudioMetadata_New=new File_DolbyAudioMetadata;
3954     Open_Buffer_Init(DolbyAudioMetadata_New);
3955     Open_Buffer_Continue(DolbyAudioMetadata_New);
3956     if (DolbyAudioMetadata_New->Status[IsAccepted])
3957     {
3958         delete DolbyAudioMetadata;
3959         DolbyAudioMetadata=DolbyAudioMetadata_New;
3960     }
3961 }
3962 
3963 //---------------------------------------------------------------------------
WAVE_ds64()3964 void File_Riff::WAVE_ds64()
3965 {
3966     Element_Name("DataSize64");
3967 
3968     //Parsing
3969     int64u dataSize, sampleCount;
3970     int32u tableLength;
3971     Skip_L8(                                                    "riffSize"); //Is directly read from the header parser
3972     Get_L8 (dataSize,                                           "dataSize");
3973     Get_L8 (sampleCount,                                        "sampleCount");
3974     Get_L4 (tableLength,                                        "tableLength");
3975     for (int32u Pos=0; Pos<tableLength; Pos++)
3976         Skip_L8(                                                "table[]");
3977 
3978     FILLING_BEGIN();
3979         if (dataSize && dataSize<File_Size)
3980         {
3981             WAVE_data_Size=dataSize;
3982             if (Retrieve(Stream_Audio, 0, Audio_StreamSize).empty()) // Not the priority
3983                 Fill(Stream_Audio, 0, Audio_StreamSize, WAVE_data_Size);
3984         }
3985         if (sampleCount && sampleCount<File_Size)
3986         {
3987             WAVE_fact_samplesCount=sampleCount;
3988             if (WAVE_fact_samplesCount && WAVE_fact_samplesCount<File_Size && Retrieve(Stream_Audio, 0, Audio_SamplingCount).empty()) // Not the priority
3989                 Fill(Stream_Audio, 0, Audio_SamplingCount, WAVE_fact_samplesCount);
3990         }
3991         if (WAVE_data_Size && WAVE_data_Size<File_Size && WAVE_fact_samplesCount && WAVE_fact_samplesCount<File_Size)
3992         {
3993             int64u ComputedBlockAlign=WAVE_data_Size/WAVE_fact_samplesCount;
3994             if (ComputedBlockAlign<0x10000)
3995                 BlockAlign=ComputedBlockAlign;
3996         }
3997     FILLING_END();
3998 }
3999 
4000 //---------------------------------------------------------------------------
WAVE_fact()4001 void File_Riff::WAVE_fact()
4002 {
4003     Element_Name("Sample count");
4004 
4005     //Parsing
4006     int32u SamplesCount;
4007     Get_L4 (SamplesCount,                                       "SamplesCount");
4008 
4009     FILLING_BEGIN();
4010         if (!Retrieve(Stream_Audio, 0, Audio_SamplingCount).empty()) // Not the priority
4011         {
4012         int64u SamplesCount64=SamplesCount==(int32u)-1?WAVE_fact_samplesCount:SamplesCount;
4013         float64 SamplingRate=Retrieve(Stream_Audio, 0, Audio_SamplingRate).To_float64();
4014         if (SamplesCount64!=(int64u)-1 && SamplingRate)
4015         {
4016             //Calculating
4017             float64 Duration=((float64)SamplesCount64)*1000/SamplingRate;
4018 
4019             //Coherency test
4020             bool IsOK=true;
4021             if (File_Size!=(int64u)-1)
4022             {
4023                 float64 BitRate=Retrieve(Stream_Audio, 0, Audio_BitRate).To_float64();
4024                 if (BitRate)
4025                 {
4026                     int64u Duration_FromBitRate = File_Size * 8 * 1000 / BitRate;
4027                     if (Duration_FromBitRate > Duration*1.02 || Duration_FromBitRate < Duration*0.98)
4028                         IsOK = false;
4029                 }
4030             }
4031 
4032             //Filling
4033             if (IsOK)
4034                 Fill(Stream_Audio, 0, Audio_SamplingCount, SamplesCount, 10, true);
4035         }
4036         }
4037     FILLING_END();
4038 }
4039 
4040 //---------------------------------------------------------------------------
WAVE_fmt_()4041 void File_Riff::WAVE_fmt_()
4042 {
4043     //Compute the current codec ID
4044     Element_Code=(int64u)-1;
4045     Stream_ID=(int32u)-1;
4046     stream_Count=1;
4047 
4048     Stream[(int32u)-1].fccType=Elements::AVI__hdlr_strl_strh_auds;
4049     AVI__hdlr_strl_strf();
4050 }
4051 
4052 //---------------------------------------------------------------------------
WAVE_ID3_()4053 void File_Riff::WAVE_ID3_()
4054 {
4055     Element_Name("ID3v2 tags");
4056 
4057     //Parsing
4058     #if defined(MEDIAINFO_ID3V2_YES)
4059         File_Id3v2 MI;
4060         Open_Buffer_Init(&MI);
4061         Open_Buffer_Continue(&MI);
4062         Finish(&MI);
4063         Merge(MI, Stream_General, 0, 0);
4064     #endif
4065 }
4066 
4067 //---------------------------------------------------------------------------
WAVE_iXML()4068 void File_Riff::WAVE_iXML()
4069 {
4070     Element_Name("iXML");
4071 
4072     //Parsing
4073     Skip_UTF8(Element_Size,                                     "XML data");
4074 }
4075 
4076 //---------------------------------------------------------------------------
WAVE_mext()4077 void File_Riff::WAVE_mext()
4078 {
4079     Element_Name("MPEG Audio extension");
4080 
4081     //Parsing
4082     Info_L2(       SoundInformation,                            "SoundInformation");
4083         Skip_Flags(SoundInformation,  0,                        "Homogeneous sound data");
4084         Skip_Flags(SoundInformation,  1,                        "Padding bit is used");
4085         Skip_Flags(SoundInformation,  2,                        "File contains a sequence of frames with padding bit set to 0");
4086         Skip_Flags(SoundInformation,  3,                        "Free format is used");
4087     Skip_L2(                                                    "FrameSize");
4088     Skip_L2(                                                    "AncillaryDataLength");
4089     Info_L2(       AncillaryDataDef,                            "AncillaryDataDef");
4090         Skip_Flags(AncillaryDataDef,  0,                        "Energy of left channel present");
4091         Skip_Flags(AncillaryDataDef,  1,                        "A private byte is free for internal use");
4092         Skip_Flags(AncillaryDataDef,  2,                        "Energy of right channel present ");
4093     Skip_L4(                                                    "Reserved");
4094 }
4095 
4096 //---------------------------------------------------------------------------
wave()4097 void File_Riff::wave()
4098 {
4099     Data_Accept("Wave64");
4100     Element_Name("Wave64");
4101 
4102     //Filling
4103     Fill(Stream_General, 0, General_Format, "Wave64");
4104 }
4105 
4106 //---------------------------------------------------------------------------
W3DI()4107 void File_Riff::W3DI()
4108 {
4109     Element_Name("IDVX tags (Out of specs!)");
4110 
4111     //Parsing
4112     int32u Size=(int32u)Element_Size;
4113     Ztring Title, Artist, Album, Unknown, Genre, Comment;
4114     int32u TrackPos;
4115     Get_Local(Size, Title,                                      "Title");
4116     Element_Offset=(int32u)Title.size();
4117     Size-=(int32u)Title.size();
4118     if (Size==0) return;
4119     Skip_L1(                                                    "Zero"); Size--; //NULL char
4120     Get_Local(Size, Artist,                                     "Artist");
4121     Element_Offset=(int32u)Title.size()+1+(int32u)Artist.size();
4122     Size-=(int32u)Artist.size();
4123     if (Size==0) return;
4124     Skip_L1(                                                    "Zero"); Size--; //NULL char
4125     Get_Local(Size, Album,                                      "Album");
4126     Element_Offset=(int32u)Title.size()+1+(int32u)Artist.size()+1+(int32u)Album.size();
4127     Size-=(int32u)Album.size();
4128     if (Size==0) return;
4129     Skip_L1(                                                    "Zero"); Size--; //NULL char
4130     Get_Local(Size, Unknown,                                    "Unknown");
4131     Element_Offset=(int32u)Title.size()+1+(int32u)Artist.size()+1+(int32u)Album.size()+1+(int32u)Unknown.size();
4132     Size-=(int32u)Unknown.size();
4133     if (Size==0) return;
4134     Skip_L1(                                                    "Zero"); Size--; //NULL char
4135     Get_Local(Size, Genre,                                      "Genre");
4136     Element_Offset=(int32u)Title.size()+1+(int32u)Artist.size()+1+(int32u)Album.size()+1+(int32u)Unknown.size()+1+(int32u)Genre.size();
4137     Size-=(int32u)Genre.size();
4138     if (Size==0) return;
4139     Skip_L1(                                                    "Zero"); Size--; //NULL char
4140     Get_Local(Size, Comment,                                    "Comment");
4141     Element_Offset=(int32u)Title.size()+1+(int32u)Artist.size()+1+(int32u)Album.size()+1+(int32u)Unknown.size()+1+(int32u)Genre.size()+1+(int32u)Comment.size();
4142     Size-=(int32u)Comment.size();
4143     if (Size==0) return;
4144     Skip_L1(                                                    "Zero"); Size--; //NULL char
4145     Get_L4 (TrackPos,                                           "Track_Position");
4146     if(Element_Offset+8<Element_Size)
4147         Skip_XX(Element_Size-Element_Offset,                    "Unknown");
4148     Element_Begin1("Footer");
4149         Skip_L4(                                                "Size");
4150         Skip_C4(                                                "Name");
4151     Element_End0();
4152 
4153     //Filling
4154     Fill(Stream_General, 0, General_Track, Title);
4155     Fill(Stream_General, 0, General_Performer, Artist);
4156     Fill(Stream_General, 0, General_Album, Album);
4157     Fill(Stream_General, 0, "Unknown", Unknown);
4158     Fill(Stream_General, 0, General_Genre, Genre);
4159     Fill(Stream_General, 0, General_Comment, Comment);
4160     Fill(Stream_General, 0, General_Track_Position, TrackPos);
4161 }
Open_Buffer_Init_All()4162 void File_Riff::Open_Buffer_Init_All()
4163 {
4164     stream& StreamItem = Stream[Stream_ID];
4165     for (size_t Pos = 0; Pos<StreamItem.Parsers.size(); Pos++)
4166         Open_Buffer_Init(StreamItem.Parsers[Pos]);
4167 }
4168 
4169 //---------------------------------------------------------------------------
Parser_Pcm(stream & StreamItem,int16u Channels,int16u BitsPerSample,int16u ValidBitsPerSample,int32u SamplesPerSec,char Endianness)4170 void File_Riff::Parser_Pcm(stream& StreamItem, int16u Channels, int16u BitsPerSample, int16u ValidBitsPerSample, int32u SamplesPerSec, char Endianness)
4171 {
4172     #if defined(MEDIAINFO_DTS_YES)
4173     {
4174         File_Dts* Parser=new File_Dts;
4175         Parser->Frame_Count_Valid=2;
4176         Parser->ShouldContinueParsing=true;
4177         #if MEDIAINFO_DEMUX
4178             if (Config->Demux_Unpacketize_Get() && Retrieve(Stream_General, 0, General_Format)==__T("Wave"))
4179             {
4180                 Parser->Demux_Level=2; //Container
4181                 Parser->Demux_UnpacketizeContainer=true;
4182                 Demux_Level=4; //Intermediate
4183             }
4184         #endif //MEDIAINFO_DEMUX
4185         StreamItem.Parsers.push_back(Parser);
4186     }
4187     #endif
4188 
4189     #if defined(MEDIAINFO_SMPTEST0337_YES)
4190     if (Channels==2 && BitsPerSample<=32 && SamplesPerSec==48000) //Some SMPTE ST 337 streams are hidden in PCM stream
4191     {
4192         File_SmpteSt0337* Parser=new File_SmpteSt0337;
4193         Parser->Container_Bits=(int8u)BitsPerSample;
4194         Parser->Aligned=true;
4195         Parser->ShouldContinueParsing=true;
4196         #if MEDIAINFO_DEMUX
4197             if (Config->Demux_Unpacketize_Get() && Retrieve(Stream_General, 0, General_Format)==__T("Wave"))
4198             {
4199                 Parser->Demux_Level=2; //Container
4200                 Parser->Demux_UnpacketizeContainer=true;
4201                 Demux_Level=4; //Intermediate
4202             }
4203         #endif //MEDIAINFO_DEMUX
4204         StreamItem.Parsers.push_back(Parser);
4205     }
4206     if (Channels>=2 && BitsPerSample<=32 && SamplesPerSec==48000) //Some SMPTE ST 337 streams are hidden in PCM stream
4207     {
4208         File_ChannelSplitting* Parser=new File_ChannelSplitting;
4209         Parser->Codec=Retrieve(Stream_Audio, StreamPos_Last, Audio_CodecID);
4210         Parser->BitDepth=(int8u)BitsPerSample;
4211         Parser->Endianness=Endianness;
4212         Parser->Channel_Total=(int8u)Channels;
4213         Parser->ShouldContinueParsing=true;
4214         Parser->SamplingRate=48000;
4215         #if MEDIAINFO_DEMUX
4216             if (Config->Demux_Unpacketize_Get())
4217             {
4218                 Parser->Demux_Level=2; //Container
4219                 Parser->Demux_UnpacketizeContainer=true;
4220                 Demux_Level=4; //Intermediate
4221             }
4222         #endif //MEDIAINFO_DEMUX
4223         Stream[Stream_ID].Parsers.push_back(Parser);
4224     }
4225     #endif
4226 
4227     #if defined(MEDIAINFO_PCM_YES)
4228         File_Pcm* Parser=new File_Pcm;
4229         Parser->Codec=Retrieve(Stream_Audio, StreamPos_Last, Audio_CodecID);
4230         if (Endianness)
4231             Parser->Endianness=Endianness;
4232         Parser->BitDepth=(int8u)BitsPerSample;
4233         if (ValidBitsPerSample!=BitsPerSample)
4234             Parser->BitDepth_Significant=(int8u)ValidBitsPerSample;
4235         #if MEDIAINFO_DEMUX
4236             if (Config->Demux_Unpacketize_Get())
4237             {
4238                 Parser->Demux_Level=2; //Container
4239                 Parser->Demux_UnpacketizeContainer=true;
4240                 Demux_Level=4; //Intermediate
4241             }
4242         #else //MEDIAINFO_DEMUX
4243             Parser->Frame_Count_Valid=(int64u)-1; //Disabling it, waiting for SMPTE ST 337 parser reject
4244         #endif //MEDIAINFO_DEMUX
4245         StreamItem.Parsers.push_back(Parser);
4246         StreamItem.IsPcm=true;
4247         StreamItem.StreamKind=Stream_Audio;
4248     #endif
4249 }
4250 
4251 //***************************************************************************
4252 // C++
4253 //***************************************************************************
4254 
4255 } //NameSpace
4256 
4257 #endif //MEDIAINFO_RIFF_YES
4258 
4259 
4260