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 // Examples:
10 // http://samples.mplayerhq.hu/FLV/
11 //
12 // Reverse engineering
13 // http://osflash.org/documentation/amf/astypes
14 //
15 //---------------------------------------------------------------------------
16 
17 //---------------------------------------------------------------------------
18 // Pre-compilation
19 #include "MediaInfo/PreComp.h"
20 #ifdef __BORLANDC__
21     #pragma hdrstop
22 #endif
23 //---------------------------------------------------------------------------
24 
25 //---------------------------------------------------------------------------
26 #include "MediaInfo/Setup.h"
27 //---------------------------------------------------------------------------
28 
29 //---------------------------------------------------------------------------
30 #if defined(MEDIAINFO_FLV_YES)
31 //---------------------------------------------------------------------------
32 
33 //---------------------------------------------------------------------------
34 #include "MediaInfo/Multiple/File_Flv.h"
35 #if defined(MEDIAINFO_AVC_YES)
36     #include "MediaInfo/Video/File_Avc.h"
37 #endif
38 #if defined(MEDIAINFO_HEVC_YES)
39     #include "MediaInfo/Video/File_Hevc.h"
40 #endif
41 #if defined(MEDIAINFO_AAC_YES)
42     #include "MediaInfo/Audio/File_Aac.h"
43 #endif
44 #if defined(MEDIAINFO_MPEGA_YES)
45     #include "MediaInfo/Audio/File_Mpega.h"
46 #endif
47 #if defined(MEDIAINFO_RM_YES)
48     #include "MediaInfo/Multiple/File_Rm.h"
49 #endif
50 #include "MediaInfo/MediaInfo_Config_MediaInfo.h"
51 #if MEDIAINFO_EVENTS
52     #include "MediaInfo/MediaInfo_Events.h"
53 #endif //MEDIAINFO_EVENTS
54 #include <algorithm>
55 #if MEDIAINFO_DEMUX
56     #include "ThirdParty/base64/base64.h"
57 #endif //MEDIAINFO_DEMUX
58 //---------------------------------------------------------------------------
59 
60 namespace MediaInfoLib
61 {
62 
63 //---------------------------------------------------------------------------
64 static const int16u  Flv_Channels[]=
65 {
66     1,
67     2,
68 };
69 
70 static const int16u  Flv_Resolution[]=
71 {
72     8,
73     16,
74 };
75 
76 static const int16u Flv_SamplingRate[]=
77 {
78     5500,
79     11025,
80     22050,
81     44100,
82     8000, //Special case for Nellymoser 8kHz mono
83 };
84 
85 static const char* Flv_Format_Audio[16]=
86 {
87     "PCM",
88     "ADPCM",
89     "MPEG Audio",
90     "PCM",
91     "Nellymoser", //16 KHz
92     "Nellymoser", //8 KHz
93     "Nellymoser",
94     "ADPCM",
95     "ADPCM",
96     "",
97     "AAC",
98     "Speex",
99     "",
100     "",
101     "MPEG Audio", //8 KHz
102     "",
103 };
104 
105 static const char* Flv_Format_Profile_Audio[16]=
106 {
107     "",
108     "",
109     "Layer 3",
110     "",
111     "",
112     "",
113     "",
114     "A-law",
115     "U-law",
116     "",
117     "",
118     "",
119     "",
120     "",
121     "Layer 3", //8 KHz
122     "",
123 };
124 
125 static const char* Flv_Codec_Audio[16]=
126 {
127     "Uncompressed",
128     "ADPCM",
129     "MPEG-1 Audio Layer 3",
130     "",
131     "Nellymoser 16kHz mono",
132     "Nellymoser 8kHz mono",
133     "Nellymoser",
134     "ADPCM",
135     "ADPCM",
136     "",
137     "AAC",
138     "Speex",
139     "",
140     "",
141     "MPEG Audio Layer 3",
142     "",
143 };
144 
145 static const char* Flv_CodecID_Hint_Audio[16]=
146 {
147     "",
148     "",
149     "MP3",
150     "",
151     "",
152     "",
153     "",
154     "",
155     "",
156     "",
157     "",
158     "",
159     "",
160     "",
161     "MP3", //8 KHz
162     "",
163 };
164 
165 static const char* Flv_Format_Video[16]=
166 {
167     "",
168     "",
169     "Sorenson Spark",
170     "Screen video",
171     "VP6",
172     "VP6",
173     "Screen video 2",
174     "AVC",
175     "",
176     "",
177     "",
178     "",
179     "HEVC",
180     "",
181     "",
182     "",
183 };
184 
185 static const char* Flv_Format_Profile_Video[16]=
186 {
187     "",
188     "",
189     "",
190     "",
191     "",
192     "Alpha channel",
193     "",
194     "",
195     "",
196     "",
197     "",
198     "",
199     "",
200     "",
201     "",
202     "",
203 };
204 
205 static const char* Flv_Codec_Video[16]=
206 {
207     "",
208     "",
209     "Sorenson H263",
210     "Screen video",
211     "On2 VP6",
212     "On2 VP6 with alpha channel",
213     "Screen video 2",
214     "AVC",
215     "",
216     "",
217     "",
218     "",
219     "HEVC",
220     "",
221     "",
222     "",
223 };
224 
225 static const char* Flv_CodecID_Hint_Video[16]=
226 {
227     "",
228     "",
229     "",
230     "",
231     "",
232     "",
233     "",
234     "",
235     "",
236     "",
237     "",
238     "",
239     "",
240     "",
241     "",
242     "",
243 };
244 
245 static const char* Flv_H263_PictureSize[]=
246 {
247     "custom, 1 byte",
248     "custom, 2 bytes",
249     "CIF (352x288)",
250     "QCIF (176x144)",
251     "SQCIF (128x96)",
252     "320x240",
253     "160x120",
254     "",
255 };
256 
257 static const int16u Flv_H263_WidthHeight[8][2]=
258 {
259     {  0,   0},
260     {  0,   0},
261     {352, 288},
262     {176, 144},
263     {128, 96},
264     {320, 240},
265     {160, 120},
266     {0, 0},
267 };
268 
269 static const char* Flv_H263_PictureType[]=
270 {
271     "IntraFrame",
272     "InterFrame",
273     "InterFrame (Disposable)",
274     "",
275 };
276 static const char* Flv_VP6_FrameMode[]=
277 {
278     "IntraFrame",
279     "",
280 };
281 
282 static const char* Flv_VP6_Marker[]=
283 {
284     "VP6.1/6.2",
285     "VP6.0",
286 };
287 
288 static const char* Flv_VP6_Version[]=
289 {
290     "",
291     "",
292     "",
293     "",
294     "",
295     "",
296     "VP6.0/6.1",
297     "VP6.0 (Electronic Arts)",
298     "VP6.2",
299     "",
300     "",
301     "",
302     "",
303     "",
304     "",
305     "",
306     "",
307     "",
308     "",
309     "",
310     "",
311     "",
312     "",
313     "",
314     "",
315     "",
316     "",
317     "",
318     "",
319     "",
320     "",
321     "",
322 };
323 
324 static const char* Flv_VP6_Version2[]=
325 {
326     "VP6.0",
327     "",
328     "",
329     "VP6.1/6.2",
330 };
331 
332 static const char* Flv_FrameType[]=
333 {
334     "",
335     "KeyFrame",
336     "InterFrame",
337     "InterFrame (Disposable)",
338     "",
339     "",
340     "",
341     "",
342     "",
343     "",
344     "",
345     "",
346     "",
347     "",
348     "",
349     "",
350 };
351 
352 static const char* Flv_TagType[]=
353 {
354     "DOUBLE",
355     "UI8",
356     "SCRIPTDATASTRING",
357     "SCRIPTDATAOBJECT[n]",
358     "SCRIPTDATASTRING defining the MovieClip path",
359     "Null",
360     "Undefined",
361     "UI16",
362     "SCRIPTDATAVARIABLE[ECMAArrayLength]",
363     "EndOfObject",
364     "SCRIPTDATAVARIABLE[n]",
365     "SCRIPTDATADATE",
366     "SCRIPTDATALONGSTRING",
367     "Unsupported",
368     "Recordset",
369     "XML",
370     "TypedObject",
371     "AMF3 data",
372 };
373 
374 static const char* Flv_Amf3Type[]=
375 {
376     "Undefined",
377     "Null",
378     "Boolean-false",
379     "Boolean-true",
380     "Integer",
381     "Number",
382     "String",
383     "XML",
384     "Data",
385     "Array",
386     "Object",
387     "XML String",
388     "ByteArray",
389 };
390 
Flv_AVCPacketType(int8u Value)391 static const char* Flv_AVCPacketType(int8u Value)
392 {
393     switch (Value)
394     {
395         case 0 : return "AVC sequence header";
396         case 1 : return "NALU";
397         case 2 : return "end of sequence";
398         default: return "";
399     }
400 }
401 
Flv_AACPacketType(int8u Value)402 static const char* Flv_AACPacketType(int8u Value)
403 {
404     switch (Value)
405     {
406         case 0 : return "AAC sequence header";
407         case 1 : return "AAC Raw";
408         default: return "";
409     }
410 }
411 
412 //***************************************************************************
413 // Constructor/Destructor
414 //***************************************************************************
415 
416 //---------------------------------------------------------------------------
File_Flv()417 File_Flv::File_Flv()
418 :File__Analyze()
419 {
420     //File__Tags_Helper
421     Base=this;
422 
423     //Configuration
424     ParserName="FLV";
425     #if MEDIAINFO_EVENTS
426         ParserIDs[0]=MediaInfo_Parser_Flv;
427         StreamIDs_Width[0]=2;
428     #endif //MEDIAINFO_EVENTS
429     #if MEDIAINFO_DEMUX
430         Demux_Level=2; //Container
431     #endif //MEDIAINFO_DEMUX
432 
433     //Internal
434     Stream.resize(3); //Null, Video, Audio
435 
436     //Temp
437     Searching_Duration=false;
438     MetaData_NotTrustable=false;
439     PreviousTagSize=(int32u)-1;
440     meta_filesize=(int64u)-1;
441     meta_duration=0;
442 }
443 
444 //***************************************************************************
445 // Streams management
446 //***************************************************************************
447 
448 //---------------------------------------------------------------------------
Streams_Fill()449 void File_Flv::Streams_Fill()
450 {
451     //Coherency
452     if (Count_Get(Stream_Video) && Count_Get(Stream_Audio) && !Retrieve(Stream_Video, 0, Video_BitRate).empty() && Retrieve(Stream_Audio, 0, Audio_BitRate).empty())
453     {
454         Fill(Stream_General, 0, General_OverallBitRate, Retrieve(Stream_Video, 0, Video_BitRate));
455         Clear(Stream_Video, 0, Video_BitRate);
456     }
457 
458     //Trying to detect VFR
459     std::vector<int64u> video_stream_FrameRate_Between;
460     for (size_t Pos=1; Pos<video_stream_FrameRate.size(); Pos++)
461         video_stream_FrameRate_Between.push_back(video_stream_FrameRate[Pos]-video_stream_FrameRate[Pos-1]);
462     std::sort(video_stream_FrameRate_Between.begin(), video_stream_FrameRate_Between.end());
463     if (!video_stream_FrameRate_Between.empty())
464     {
465         if (video_stream_FrameRate_Between[0]*0.9<video_stream_FrameRate_Between[video_stream_FrameRate_Between.size()-1]
466          && video_stream_FrameRate_Between[0]*1.1>video_stream_FrameRate_Between[video_stream_FrameRate_Between.size()-1])
467         {
468             float Time;
469             if (video_stream_FrameRate.size()>30)
470                 Time=((float)(video_stream_FrameRate[30]-video_stream_FrameRate[0]))/30; //30 frames for handling 30 fps rounding problems
471             else
472                 Time=((float)(video_stream_FrameRate[video_stream_FrameRate.size()-1]-video_stream_FrameRate[0]))/(video_stream_FrameRate.size()-1); //30 frames for handling 30 fps rounding problems
473             if (Time)
474             {
475                 Fill(Stream_Video, 0, Video_FrameRate, 1000/Time);
476                 Fill(Stream_Video, 0, Video_FrameRate_Mode, "CFR");
477             }
478         }
479         else
480             Fill(Stream_Video, 0, Video_FrameRate_Mode, "VFR");
481     }
482 
483     //Parsers
484     if (Stream[Stream_Video].Parser!=NULL)
485     {
486         Fill(Stream[Stream_Video].Parser);
487     }
488     if (Stream[Stream_Audio].Parser!=NULL)
489     {
490         Fill(Stream[Stream_Audio].Parser);
491 
492         //Special case: AAC
493         if (Stream[Stream_Audio].Parser->Retrieve(Stream_Audio, 0, Audio_Format)==__T("AAC")
494          || Stream[Stream_Audio].Parser->Retrieve(Stream_Audio, 0, Audio_Format)==__T("MPEG Audio")
495          || Stream[Stream_Audio].Parser->Retrieve(Stream_Audio, 0, Audio_Format)==__T("Vorbis"))
496             Clear(Stream_Audio, 0, Audio_BitDepth); //Resolution is not valid for AAC / MPEG Audio / Vorbis
497     }
498 
499     //Delay
500     if (Stream[Stream_Video].Delay!=(int32u)-1)
501     {
502         Fill(Stream_Video, 0, Video_Delay, Stream[Stream_Video].Delay+Retrieve(Stream_Video, 0, Video_Delay).To_int32u(), 10, true);
503         Fill(Stream_Video, 0, Video_Delay_Source, "Container");
504     }
505     if (Stream[Stream_Audio].Delay!=(int32u)-1)
506     {
507         Fill(Stream_Audio, 0, Audio_Delay, Stream[Stream_Audio].Delay+Retrieve(Stream_Audio, 0, Audio_Delay).To_int32u(), 10, true);
508         Fill(Stream_Audio, 0, Audio_Delay_Source, "Container");
509     }
510 }
511 
512 //---------------------------------------------------------------------------
Streams_Finish()513 void File_Flv::Streams_Finish()
514 {
515     //Duration
516     //if (meta_duration)
517     //    Fill(Stream_General, 0, General_Duration, meta_duration, 10, true);
518     Streams_Finish_PerStream(Stream_Video);
519     Streams_Finish_PerStream(Stream_Audio);
520 
521     /*
522     float64 FrameRate=Retrieve(Stream_Video, 0, Video_FrameRate).To_float64();
523     if (LastFrame_Time!=(int32u)-1 && FirstFrame_Time!=(int32u)-1)
524         Duration_Final=LastFrame_Time-FirstFrame_Time+((LastFrame_Type==9 && FrameRate)?((int64u)(1000/FrameRate)):0);
525     if (Duration_Final)
526     {
527         if (Count_Get(Stream_Video))
528             Fill(Stream_Video, 0, Video_Duration, Duration_Final, 10, true);
529         if (Count_Get(Stream_Audio))
530             Fill(Stream_Audio, 0, Audio_Duration, Duration_Final, 10, true);
531 
532         //Integrity
533         if (Count_Get(Stream_Video) && File_Size!=(int64u)-1 && !Retrieve(Stream_Video, 0, Video_BitRate).empty() && !Retrieve(Stream_Video, 0, Video_Duration).empty())
534         {
535             int64u BitRate_Video_Meta=Retrieve(Stream_Video, 0, Video_BitRate).To_int64u();
536             int64u Duration=Retrieve(Stream_Video, 0, Video_Duration).To_int64u();
537             int64u BitRate_Video_Duration=File_Size*8*1000/Duration;
538             if (Count_Get(Stream_Audio) && !Retrieve(Stream_Audio, 0, Audio_BitRate).empty())
539             {
540                 int64u BitRate_Audio=Retrieve(Stream_Audio, 0, Audio_BitRate).To_int64u();
541                 if (BitRate_Audio<BitRate_Video_Duration)
542                     BitRate_Video_Duration-=BitRate_Audio;
543                 else if (BitRate_Audio)
544                     BitRate_Video_Duration=0; //There is a problem
545             }
546             if (BitRate_Video_Meta<BitRate_Video_Duration/2 || BitRate_Video_Meta>BitRate_Video_Duration*2)
547                 Clear(Stream_Video, 0, Video_BitRate);
548         }
549     }
550     */
551 
552     if (Stream[Stream_Video].Parser!=NULL)
553     {
554         File__Analyze::Finish(Stream[Stream_Video].Parser);
555         Merge(*Stream[Stream_Video].Parser, Stream_Video, 0, 0);
556     }
557     if (Stream[Stream_Audio].Parser!=NULL)
558     {
559         File__Analyze::Finish(Stream[Stream_Audio].Parser);
560         Merge(*Stream[Stream_Audio].Parser, Stream_Audio, 0, 0);
561     }
562 
563     if (Retrieve(Stream_General, 0, General_Duration).empty() && Retrieve(Stream_Video, 0, Video_Duration).empty() && meta_duration)
564         Fill(Stream_General, 0, General_Duration, meta_duration, 0, true);
565 
566     //Purge what is not needed anymore
567     if (!File_Name.empty()) //Only if this is not a buffer, with buffer we can have more data
568         Stream.clear();
569 }
570 
571 //---------------------------------------------------------------------------
Streams_Finish_PerStream(stream_t StreamKind)572 void File_Flv::Streams_Finish_PerStream(stream_t StreamKind)
573 {
574     if (Stream[StreamKind].TimeStamp!=(int32u)-1)
575     {
576         //Calculating the last timestamp (last block included)
577         if (!Stream[StreamKind].Durations.empty())
578         {
579             int64u Durations_Total=0;
580             for (size_t Pos=0; Pos<Stream[StreamKind].Durations.size(); Pos++)
581                 Durations_Total+=Stream[StreamKind].Durations[Pos];
582             int32u Duration_Average=float32_int32s(((float32)Durations_Total)/Stream[StreamKind].Durations.size());
583             Stream[StreamKind].TimeStamp+=Duration_Average;
584         }
585 
586         Fill(StreamKind, 0, "Duration", Stream[StreamKind].TimeStamp, 10, true);
587     }
588 }
589 
590 //***************************************************************************
591 // Buffer - File header
592 //***************************************************************************
593 
594 //---------------------------------------------------------------------------
FileHeader_Begin()595 bool File_Flv::FileHeader_Begin()
596 {
597     if (!File__Tags_Helper::FileHeader_Begin())
598         return false;
599 
600     //Synchro
601     if (Buffer_Offset+3>Buffer_Size)
602         return false;
603     if (Buffer[Buffer_Offset+0]!=0x46 //"FLV"
604      || Buffer[Buffer_Offset+1]!=0x4C
605      || Buffer[Buffer_Offset+2]!=0x56)
606     {
607         File__Analyze::Reject();
608         return false;
609     }
610     if (Buffer_Offset+9>Buffer_Size)
611         return false;
612 
613     return true;
614 }
615 
616 //---------------------------------------------------------------------------
FileHeader_Parse()617 void File_Flv::FileHeader_Parse()
618 {
619     //Parsing
620     Element_Begin1("FLV header");
621     int32u Size;
622     int8u  Version, Flags;
623     Skip_String(3,                                              "Signature");
624     Get_B1 (Version,                                            "Version");
625     Get_B1 (Flags,                                              "Flags");
626         Get_Flags (Flags, 0, video_stream_Count,                "Video");
627         Get_Flags (Flags, 2, audio_stream_Count,                "Audio");
628     Get_B4 (Size,                                               "Size");
629     if (Size>9)
630         Skip_XX(Size-9,                                         "Unknown");
631     Element_End0();
632 
633     FILLING_BEGIN();
634         //Integrity
635         if (Version==0 || Size<9)
636         {
637             File__Analyze::Reject();
638             return;
639         }
640 
641         //Filling
642         File__Analyze::Accept();
643 
644         Fill(Stream_General, 0, General_Format, "Flash Video");
645         if (!video_stream_Count && !audio_stream_Count)
646         {
647             //TODO: quick and awful hack for a file having both bools unset, should detect directly the streams
648             video_stream_Count=true;
649             audio_stream_Count=true;
650         }
651         if (video_stream_Count)
652         {
653             File__Analyze::Stream_Prepare(Stream_Video);
654             #if MEDIAINFO_DEMUX
655                 if (Config->Demux_ForceIds_Get())
656                     Fill(Stream_Video, 0, Video_ID, 9);
657             #endif //MEDIAINFO_DEMUX
658             video_stream_FrameRate_Detected=false;
659         }
660         else
661             video_stream_FrameRate_Detected=true;
662         if (audio_stream_Count)
663         {
664             File__Analyze::Stream_Prepare(Stream_Audio);
665             #if MEDIAINFO_DEMUX
666                 if (Config->Demux_ForceIds_Get())
667                     Fill(Stream_Audio, 0, Audio_ID, 8);
668             #endif //MEDIAINFO_DEMUX
669         }
670 
671         if (Version>1)
672         {
673             File__Analyze::Finish();
674             return; //Version more than 1 is not supported
675         }
676     FILLING_ELSE()
677         File__Analyze::Reject();
678     FILLING_END();
679 }
680 
681 //***************************************************************************
682 // Buffer - Synchro
683 //***************************************************************************
684 
685 //---------------------------------------------------------------------------
Synchronize()686 bool File_Flv::Synchronize()
687 {
688     if (File_Offset+Buffer_Offset+4==File_Size)
689         return true; // Used by seek from end
690 
691     //Synchronizing
692     while (Buffer_Offset+15<=Buffer_Size)
693     {
694         int32u BodyLength=BigEndian2int24u(Buffer+Buffer_Offset+5);
695         if ((Buffer[Buffer_Offset  ]
696             || Buffer[Buffer_Offset+1]
697             || Buffer[Buffer_Offset+2]
698             || Buffer[Buffer_Offset+3]>=11)
699             && File_Offset+Buffer_Offset+15+BodyLength==File_Size)
700             break; //Last block
701         if (File_Offset+Buffer_Offset+15+BodyLength<File_Size)
702         {
703             if (Buffer_Offset+15+BodyLength+15>Buffer_Size)
704                 return false; //Need more data
705 
706             if ((Buffer[Buffer_Offset  ]
707               || Buffer[Buffer_Offset+1]
708               || Buffer[Buffer_Offset+2]
709               || Buffer[Buffer_Offset+3]>=11)
710              && (BigEndian2int32u(Buffer+Buffer_Offset+15+BodyLength)==11+BodyLength // PreviousTagSize
711               || BigEndian2int32u(Buffer+Buffer_Offset+15+BodyLength)==BodyLength)) // PreviousTagSize without 11, found in some buggy files
712             {
713                  PreviousTagSize_Add11=(BigEndian2int32u(Buffer+Buffer_Offset+15+BodyLength)==BodyLength)?0:11;
714                  break;
715             }
716         }
717 
718         Buffer_Offset++;
719     }
720 
721     //Parsing last bytes if needed
722     if (Buffer_Offset+15>Buffer_Size)
723         return false;
724 
725     //Synched
726     return true;
727 }
728 
729 //---------------------------------------------------------------------------
Synched_Test()730 bool File_Flv::Synched_Test()
731 {
732     if (File_Offset+Buffer_Offset+4==File_Size)
733         return true; // Used by seek from end
734 
735     //Must have enough buffer for having header
736     if (Buffer_Offset+15>Buffer_Size)
737         return false;
738 
739     //Quick test of synchro
740     if (Buffer[Buffer_Offset  ]==0
741      && Buffer[Buffer_Offset+1]==0
742      && Buffer[Buffer_Offset+2]==0
743      && Buffer[Buffer_Offset+3]<PreviousTagSize_Add11
744      && File_Offset+Buffer_Offset>9)
745     {
746         if (Searching_Duration)
747         {
748             //Error during parsing, stopping
749             File__Analyze::Finish();
750             Searching_Duration=false;
751             File__Analyze::GoTo(File_Size);
752             return true;
753         }
754 
755         Synched=false;
756         return true;
757     }
758 
759     //We continue
760     return true;
761 }
762 
763 //***************************************************************************
764 // Buffer - Global
765 //***************************************************************************
766 
767 //---------------------------------------------------------------------------
Read_Buffer_Unsynched()768 void File_Flv::Read_Buffer_Unsynched()
769 {
770     if (!Searching_Duration) //If Searching_Duration, we are looking for end in inverse order, no timestamp reset
771     {
772         Stream[Stream_Video].TimeStamp=(int32u)-1;
773         if (Stream[Stream_Video].Parser)
774             Stream[Stream_Video].Parser->Open_Buffer_Unsynch();
775         Stream[Stream_Audio].TimeStamp=(int32u)-1;
776         if (Stream[Stream_Audio].Parser)
777             Stream[Stream_Audio].Parser->Open_Buffer_Unsynch();
778     }
779 }
780 
781 //***************************************************************************
782 // Buffer - Per element
783 //***************************************************************************
784 
785 //---------------------------------------------------------------------------
Header_Parse()786 void File_Flv::Header_Parse()
787 {
788     if (Searching_Duration && File_Offset+Buffer_Offset==File_Size-4)
789     {
790         Get_B4 (PreviousTagSize,                                "PreviousTagSize");
791 
792         //Filling
793         Header_Fill_Code((int64u)-1, "End Of File");
794         Header_Fill_Size(4);
795         return;
796     }
797 
798     //Parsing
799     int32u BodyLength;
800     int8u Type;
801     Get_B4 (PreviousTagSize,                                    "PreviousTagSize");
802     if (File_Offset+Buffer_Offset+4<File_Size)
803     {
804         int32u Timestamp_Base;
805         int8u  Timestamp_Extended;
806         Get_B1 (Type,                                           "Type"); //Param_Info1(Type<19?Flv_Type[Type]:__T("Unknown"));
807         Get_B3 (BodyLength,                                     "BodyLength");
808         Get_B3 (Timestamp_Base,                                 "Timestamp_Base"); //in ms
809         Get_B1 (Timestamp_Extended,                             "Timestamp_Extended"); //TimeStamp = Timestamp_Extended*0x01000000+Timestamp_Base
810         Skip_B3(                                                "StreamID");
811 
812         // For audio, check if it's just an audio config.
813         bool Skip_Timestamps=false;
814         if (Type==0x08)
815         {
816             int16u  Format_Info;
817             Peek_B2(Format_Info);
818             int8u   Format=(Format_Info>>12)&0x0F;
819             if (Format==10 && (Format_Info&0xFF)==0) // AAC sequence header
820                 Skip_Timestamps=true;
821         }
822 
823         //Filling
824         if ((Type==0x08 && !Skip_Timestamps) || Type==0x09)
825         {
826             Time=(((int32u)Timestamp_Extended)<<24)|Timestamp_Base;
827             stream_t StreamKind=(Type==0x08)?Stream_Audio:Stream_Video;
828             if (Stream[StreamKind].Delay==(int32u)-1)
829                 Stream[StreamKind].Delay=Time;
830             else if (Stream[StreamKind].TimeStamp!=(int32u)-1 && Time>Stream[StreamKind].TimeStamp)
831                 Stream[StreamKind].Durations.push_back(Time-Stream[StreamKind].TimeStamp);
832             if (!Searching_Duration || Stream[StreamKind].TimeStamp==(int32u)-1)
833                 Stream[StreamKind].TimeStamp=Time;
834         }
835 
836         if (Type==0)
837             Trusted_IsNot("Wrong type");
838     }
839     else
840     {
841         Type=0;
842         BodyLength=0;
843     }
844 
845     //Filling
846     Header_Fill_Code(Type, Ztring().From_Number(Type, 16));
847     Header_Fill_Size(Element_Offset+BodyLength);
848 }
849 
850 //---------------------------------------------------------------------------
Data_Parse()851 void File_Flv::Data_Parse()
852 {
853     switch (Element_Code)
854     {
855         case 0x00 : Element_Name("End Of File"); break;
856         case 0x08 : audio(); break;
857         case 0x09 : video(); break;
858         case 0x12 : meta(); break;
859         case 0xFA : Rm(); break;
860         case (int64u)-1 :   //When searching the last frame
861                             if (8+PreviousTagSize>File_Size)
862                             {
863                                 Searching_Duration=false;
864                                 Open_Buffer_Unsynch(); //There is a problem, trying to sync
865                                 PreviousTagSize=1024*1024;
866                             }
867                             File__Analyze::GoTo(File_Size-PreviousTagSize-8, "FLV");
868                             return;
869         default : if (Searching_Duration)
870                   {
871                     File__Analyze::Finish(); //This is surely a bad en of file, don't try anymore
872                     return;
873                   }
874 
875     }
876 
877     if (Searching_Duration)
878     {
879         if ((((Count_Get(Stream_Video)==0 || Stream[Stream_Video].TimeStamp!=(int32u)-1)
880            && (Count_Get(Stream_Audio)==0 || Stream[Stream_Audio].TimeStamp!=(int32u)-1))
881           || (File_Size>1024*1024*2 && File_Offset+Buffer_Offset-Header_Size-PreviousTagSize-4<File_Size-1024*1024))
882          && Config->ParseSpeed<1.0)
883             File__Analyze::Finish();
884         else if (Element_Code==0xFA) //RM metadata have a malformed PreviousTagSize, always
885         {
886             //Trying to sync
887             Searching_Duration=false;
888             Open_Buffer_Unsynch(); //There is a problem, trying to sync
889             File__Analyze::GoToFromEnd(Header_Size+Element_Size+1024*1024);
890             return;
891         }
892         else
893             File__Analyze::GoTo(File_Offset+Buffer_Offset-Header_Size-PreviousTagSize-4);
894     }
895     else if (!Status[IsFilled] && !video_stream_Count && !audio_stream_Count && video_stream_FrameRate_Detected && File_Offset+1024*1024*2<File_Size && Config->ParseSpeed<1.0) //All streams are parsed
896     {
897         Fill();
898 
899         //Trying to find the last frame for duration
900         Read_Buffer_Unsynched(); //This is not synched yet, so we call directly this method instead of Open_Buffer_Unsynched
901         File__Analyze::GoToFromEnd(4, "FLV");
902         Searching_Duration=true;
903     }
904 }
905 
906 //***************************************************************************
907 // Elements
908 //***************************************************************************
909 
910 //---------------------------------------------------------------------------
video()911 void File_Flv::video()
912 {
913     Element_Name("Video");
914     Stream[Stream_Video].PacketCount++;
915     Element_Info1(Stream[Stream_Video].PacketCount);
916 
917     //Handling FrameRate
918     if (!video_stream_FrameRate_Detected)
919     {
920         if (video_stream_FrameRate.empty() || Time!=video_stream_FrameRate[video_stream_FrameRate.size()-1]) //if 2 block witht the same timestamp
921             video_stream_FrameRate.push_back(Time);
922         if (video_stream_FrameRate.size()>30)
923             video_stream_FrameRate_Detected=true;
924     }
925 
926     if (Element_Size==0) //Header says that video is present, but there is only one null packet
927     {
928         Element_Info1("Null");
929         return;
930     }
931 
932     //Needed?
933     if (!video_stream_Count && Config->ParseSpeed<1.0)
934         return; //No more need of Video stream
935 
936     //Parsing
937     int8u Codec, FrameType;
938     Element_Begin1("Stream header");
939     BS_Begin();
940     Get_S1 (4, FrameType,                                       "frameType"); Param_Info1(Flv_FrameType[FrameType]);
941     Get_S1 (4, Codec,                                           "codecID"); Param_Info1(Flv_Codec_Video[Codec]); Element_Info1(Flv_Codec_Video[Codec]);
942     BS_End();
943     Element_End0();
944 
945     FILLING_BEGIN();
946         //Filling
947         if (Retrieve(Stream_Video, 0, Video_Format).empty())
948         {
949             if (Count_Get(Stream_Video)==0)
950                 File__Analyze::Stream_Prepare(Stream_Video);
951             Fill(Stream_Video, 0, Video_Format, Flv_Format_Video[Codec]);
952             Fill(Stream_Video, 0, Video_Format_Profile, Flv_Format_Profile_Video[Codec]);
953             Fill(Stream_Video, 0, Video_Codec, Flv_Codec_Video[Codec]);
954             Fill(Stream_Video, 0, Video_CodecID, Codec);
955             Fill(Stream_Video, 0, Video_CodecID_Hint, Flv_CodecID_Hint_Video[Codec]);
956             Fill(Stream_Video, 0, Video_BitDepth, 8); //FLV is not known to support another bit depth
957 
958             MustSynchronize=true; // Now, synchronization test is possible
959         }
960 
961         //Parsing video data
962         switch (Codec)
963         {
964             case  2 : video_H263(); break;
965             case  3 : video_ScreenVideo(1); break;
966             case  4 : video_VP6(false); break;
967             case  5 : video_VP6(true); break;
968             case  6 : video_ScreenVideo(2); break;
969             case  7 : video_AVC(); break;
970             case 12 : video_HEVC(); break;
971             default : Skip_XX(Element_Size-Element_Offset,      "Unknown");
972                       video_stream_Count=false; //No more need of Video stream;
973         }
974     FILLING_END();
975 
976     #if MEDIAINFO_DEMUX
977         int8u Demux_Level_old=Demux_Level;
978         if (Stream[Stream_Video].Parser && Stream[Stream_Video].Parser->Demux_Level==2)
979             Demux_Level=4;
980         Demux(Buffer+Buffer_Offset+1, (size_t)(Element_Size-1), ContentType_MainStream);
981         Demux_Level=Demux_Level_old;
982     #endif //MEDIAINFO_DEMUX
983 }
984 
985 //---------------------------------------------------------------------------
video_H263()986 void File_Flv::video_H263()
987 {
988     //Parsing
989     int16u Width=0, Height=0;
990     int8u  Version, PictureSize, PictureType;
991     bool   ExtraInformationFlag;
992     BS_Begin();
993     Skip_S3(17,                                                 "PictureStartCode");
994     Get_S1 ( 5, Version,                                        "Version");
995     if (Version>1)
996         return;
997     Skip_S1( 8,                                                 "TemporalReference");
998     Get_S1 ( 3, PictureSize,                                    "PictureSize"); Param_Info1(Flv_H263_PictureSize[PictureSize]);
999     switch (PictureSize)
1000     {
1001         case 0 :
1002             Get_S2 ( 8, Width,                                  "Width");
1003             Get_S2 ( 8, Height,                                 "Height");
1004             break;
1005         case 1 :
1006             Get_S2 (16, Width,                                  "Width");
1007             Get_S2 (16, Height,                                 "Height");
1008             break;
1009         default :
1010             if (PictureSize<8)
1011             {
1012                 Width=Flv_H263_WidthHeight[PictureSize][0];
1013                 Height=Flv_H263_WidthHeight[PictureSize][1];
1014             }
1015     }
1016     Get_S1 ( 2, PictureType,                                    "PictureSize"); Param_Info1(Flv_H263_PictureType[PictureType]);
1017     Skip_SB(                                                    "DeblockingFlag");
1018     Skip_S1( 5,                                                 "Quantizer");
1019     Get_SB (    ExtraInformationFlag,                           "ExtraInformationFlag");
1020     while (ExtraInformationFlag)
1021     {
1022         Skip_S1( 8,                                             "ExtraInformation");
1023         Get_SB (    ExtraInformationFlag,                       "ExtraInformationFlag");
1024     }
1025     BS_End();
1026 
1027     FILLING_BEGIN();
1028         Fill(Stream_Video, 0, Video_Width, Width, 10, true);
1029         Fill(Stream_Video, 0, Video_Height, Height, 10, true);
1030         video_stream_Count=false; //No more need of Video stream
1031     FILLING_END();
1032 }
1033 
1034 //---------------------------------------------------------------------------
video_ScreenVideo(int8u Version)1035 void File_Flv::video_ScreenVideo(int8u Version)
1036 {
1037     //Parsing
1038     int16u Width, Height;
1039     BS_Begin();
1040     Info_S1( 4, BlockWidth,                                     "BlockWidth"); Param_Info1((BlockWidth+1)*16);
1041     Get_S2 (12, Width,                                          "ImageWidth");
1042     Info_S1( 4, BlockHeight,                                    "BlockHeight"); Param_Info1((BlockHeight+1)*16);
1043     Get_S2 (12, Height,                                         "ImageHeight");
1044     if (Version==2)
1045     {
1046         Skip_S1(6,                                              "Reserved");
1047         Skip_SB(                                                "has IFrameImage");
1048         Skip_SB(                                                "has PaletteInfo");
1049     }
1050     BS_End();
1051 
1052     FILLING_BEGIN();
1053         Fill(Stream_Video, 0, Video_Width, Width, 10, true);
1054         Fill(Stream_Video, 0, Video_Height, Height, 10, true);
1055         video_stream_Count=false; //No more need of Video stream
1056     FILLING_END();
1057 }
1058 
1059 //---------------------------------------------------------------------------
1060 // From: http://wiki.multimedia.cx/index.php?title=On2_VP6
1061 //
video_VP6(bool WithAlpha)1062 void File_Flv::video_VP6(bool WithAlpha)
1063 {
1064     //Parsing
1065     int8u HorizontalAdjustment, VerticalAdjustment;
1066     bool  FrameMode, Marker;
1067     BS_Begin();
1068     Get_S1 ( 4, HorizontalAdjustment,                           "HorizontalAdjustment");
1069     Get_S1 ( 4, VerticalAdjustment,                             "VerticalAdjustment");
1070     if (WithAlpha)
1071         Skip_S3(24,                                             "OffsetToAlpha");
1072     Get_SB (    FrameMode,                                      "FrameMode"); Param_Info1(Flv_VP6_FrameMode[FrameMode]);
1073     Skip_S1( 6,                                                 "Quantization");
1074     Get_SB (    Marker,                                         "Marker"); Param_Info1(Flv_VP6_Marker[Marker]);
1075     BS_End();
1076     if (FrameMode)
1077     {
1078         if (Marker==1)
1079             Skip_B2(                                            "Offset");
1080     }
1081     else
1082     {
1083         int8u Version, Version2, Width, Height;
1084         BS_Begin();
1085         Get_S1 ( 5, Version,                                    "Version"); Param_Info1(Flv_VP6_Version[Version]);
1086         Get_S1 ( 2, Version2,                                   "Version2"); Param_Info1(Flv_VP6_Version2[Version2]);
1087         Skip_SB(                                                "Interlace");
1088         BS_End();
1089         if (Marker || Version2==0)
1090             Skip_B2(                                            "Offset");
1091         Skip_B1(                                                "MacroBlock_Height");
1092         Skip_B1(                                                "MacroBlock_Width");
1093         Get_B1 (Height,                                         "Height"); Param_Info1(Ztring::ToZtring(Height*16)+__T(" pixels"));
1094         Get_B1 (Width,                                          "Width"); Param_Info1(Ztring::ToZtring(Width*16)+__T(" pixels"));
1095 
1096         FILLING_BEGIN();
1097             if (Width && Height)
1098             {
1099                 Fill(Stream_Video, 0, Video_Width,  Width*16-HorizontalAdjustment, 10, true);
1100                 Fill(Stream_Video, 0, Video_Height, Height*16-VerticalAdjustment, 10, true);
1101             }
1102             video_stream_Count=false; //No more need of Video stream
1103         FILLING_END();
1104     }
1105 }
1106 
1107 //---------------------------------------------------------------------------
video_AVC()1108 void File_Flv::video_AVC()
1109 {
1110     int8u AVCPacketType;
1111     Get_B1 (AVCPacketType,                                      "AVCPacketType"); Param_Info1(Flv_AVCPacketType(AVCPacketType));
1112     Info_B3(CompositionTime,                                    "CompositionTime"); Param_Info1(Ztring::ToZtring((int32s)(CompositionTime+0xFF000000)));
1113 
1114     switch (AVCPacketType)
1115     {
1116         case 0 :
1117                 #ifdef MEDIAINFO_AVC_YES
1118                     if (Stream[Stream_Video].Parser==NULL)
1119                     {
1120                         Stream[Stream_Video].Parser=new File_Avc;
1121                         Open_Buffer_Init(Stream[Stream_Video].Parser);
1122                         ((File_Avc*)Stream[Stream_Video].Parser)->MustParse_SPS_PPS=true;
1123                         ((File_Avc*)Stream[Stream_Video].Parser)->SizedBlocks=true;
1124                         ((File_Avc*)Stream[Stream_Video].Parser)->MustSynchronize=false;
1125                         #if MEDIAINFO_DEMUX
1126                             if (Config->Demux_Avc_Transcode_Iso14496_15_to_Iso14496_10_Get())
1127                             {
1128                                 Stream[Stream_Video].Parser->Demux_Level=2; //Container
1129                                 Stream[Stream_Video].Parser->Demux_UnpacketizeContainer=true;
1130                             }
1131                         #endif //MEDIAINFO_DEMUX
1132                     }
1133 
1134                     //Parsing
1135                     Open_Buffer_Continue(Stream[Stream_Video].Parser);
1136 
1137                     //Demux
1138                     #if MEDIAINFO_DEMUX
1139                         switch (Config->Demux_InitData_Get())
1140                         {
1141                             case 0 :    //In demux event
1142                                         Demux_Level=2; //Container
1143                                         Demux(Buffer+Buffer_Offset+2, (size_t)(Element_Size-2), ContentType_Header);
1144                                         break;
1145                             case 1 :    //In field
1146                                         {
1147                                         std::string Data_Raw((const char*)(Buffer+Buffer_Offset+2), (size_t)(Element_Size-2));
1148                                         std::string Data_Base64(Base64::encode(Data_Raw));
1149                                         Fill(Stream_Video, StreamPos_Last, "Demux_InitBytes", Data_Base64);
1150                                         Fill_SetOptions(Stream_Video, StreamPos_Last, "Demux_InitBytes", "N NT");
1151                                         }
1152                                         break;
1153                             default :   ;
1154                         }
1155                     #endif //MEDIAINFO_DEMUX
1156                 #else
1157                     Skip_XX(Element_Size-Element_Offset,        "AVC Data");
1158                     video_stream_Count=false; //Unable to parse it
1159                 #endif
1160                 break;
1161         case 1 :
1162                 #ifdef MEDIAINFO_AVC_YES
1163                     if (Stream[Stream_Video].Parser==NULL)
1164                     {
1165                         //Data before header, this is wrong
1166                         video_stream_Count=false;
1167                         break;
1168                     }
1169 
1170                     //Parsing
1171                     Open_Buffer_Continue(Stream[Stream_Video].Parser);
1172 
1173                     //Disabling this stream
1174                     if (Stream[Stream_Video].Parser->File_GoTo!=(int64u)-1 || Stream[Stream_Video].Parser->Count_Get(Stream_Video)>0 || (Config->ParseSpeed<1.0 && Stream[Stream_Video].PacketCount>=300))
1175                     {
1176                         Stream[Stream_Video].Parser->Open_Buffer_Unsynch();
1177                         video_stream_Count=false;
1178                     }
1179                 #else
1180                     Skip_XX(Element_Size-Element_Offset,        "AVC Data");
1181                     video_stream_Count=false; //Unable to parse it
1182                 #endif
1183                 break;
1184         default: Skip_XX(Element_Size-Element_Offset,           "Unknown");
1185                  video_stream_Count=false; //Unable to parse it
1186     }
1187 }
1188 
1189 //---------------------------------------------------------------------------
video_HEVC()1190 void File_Flv::video_HEVC()
1191 {
1192     int8u AVCPacketType;
1193     Get_B1 (AVCPacketType,                                      "AVCPacketType"); Param_Info1(Flv_AVCPacketType(AVCPacketType));
1194     Info_B3(CompositionTime,                                    "CompositionTime"); Param_Info1(Ztring::ToZtring((int32s)(CompositionTime+0xFF000000)));
1195 
1196     switch (AVCPacketType)
1197     {
1198         case 0 :
1199                 #ifdef MEDIAINFO_HEVC_YES
1200                     if (Stream[Stream_Video].Parser==NULL)
1201                     {
1202                         Stream[Stream_Video].Parser=new File_Hevc;
1203                         Open_Buffer_Init(Stream[Stream_Video].Parser);
1204                         ((File_Hevc*)Stream[Stream_Video].Parser)->MustParse_VPS_SPS_PPS=true;
1205                         ((File_Hevc*)Stream[Stream_Video].Parser)->MustParse_VPS_SPS_PPS_FromFlv=true;
1206                         ((File_Hevc*)Stream[Stream_Video].Parser)->MustSynchronize=false;
1207                         ((File_Hevc*)Stream[Stream_Video].Parser)->SizedBlocks=true;
1208                         #if MEDIAINFO_DEMUX
1209                             if (Config->Demux_Hevc_Transcode_Iso14496_15_to_AnnexB_Get())
1210                             {
1211                                 Stream[Stream_Video].Parser->Demux_Level=2; //Container
1212                                 Stream[Stream_Video].Parser->Demux_UnpacketizeContainer=true;
1213                             }
1214                         #endif //MEDIAINFO_DEMUX
1215                     }
1216 
1217                     //Parsing
1218                     Open_Buffer_Continue(Stream[Stream_Video].Parser);
1219 
1220                     //Demux
1221                     #if MEDIAINFO_DEMUX
1222                         switch (Config->Demux_InitData_Get())
1223                         {
1224                             case 0 :    //In demux event
1225                                         Demux_Level=2; //Container
1226                                         Demux(Buffer+Buffer_Offset+2, (size_t)(Element_Size-2), ContentType_Header);
1227                                         break;
1228                             case 1 :    //In field
1229                                         {
1230                                         std::string Data_Raw((const char*)(Buffer+Buffer_Offset+2), (size_t)(Element_Size-2));
1231                                         std::string Data_Base64(Base64::encode(Data_Raw));
1232                                         Fill(Stream_Video, StreamPos_Last, "Demux_InitBytes", Data_Base64);
1233                                         Fill_SetOptions(Stream_Video, StreamPos_Last, "Demux_InitBytes", "N NT");
1234                                         }
1235                                         break;
1236                             default :   ;
1237                         }
1238                     #endif //MEDIAINFO_DEMUX
1239                 #else
1240                     Skip_XX(Element_Size-Element_Offset,        "HEVC Data");
1241                     video_stream_Count=false; //Unable to parse it
1242                 #endif
1243                 break;
1244         case 1 :
1245                 #ifdef MEDIAINFO_HEVC_YES
1246                     if (Stream[Stream_Video].Parser==NULL)
1247                     {
1248                         //Data before header, this is wrong
1249                         video_stream_Count=false;
1250                         break;
1251                     }
1252 
1253                     //Parsing
1254                     Open_Buffer_Continue(Stream[Stream_Video].Parser);
1255 
1256                     //Disabling this stream
1257                     if (Stream[Stream_Video].Parser->File_GoTo!=(int64u)-1 || Stream[Stream_Video].Parser->Count_Get(Stream_Video)>0 || (Config->ParseSpeed<1.0 && Stream[Stream_Video].PacketCount>=300))
1258                     {
1259                         Stream[Stream_Video].Parser->Open_Buffer_Unsynch();
1260                         video_stream_Count=false;
1261                     }
1262                 #else
1263                     Skip_XX(Element_Size-Element_Offset,        "HEVC Data");
1264                     video_stream_Count=false; //Unable to parse it
1265                 #endif
1266                 break;
1267         default: Skip_XX(Element_Size-Element_Offset,           "Unknown");
1268                  video_stream_Count=false; //Unable to parse it
1269     }
1270 }
1271 
1272 //---------------------------------------------------------------------------
audio()1273 void File_Flv::audio()
1274 {
1275     Element_Name("Audio");
1276     Stream[Stream_Audio].PacketCount++;
1277     Element_Info1(Stream[Stream_Audio].PacketCount);
1278 
1279     if (Element_Size==0) //Header says that audio is present, but there is only one null packet
1280     {
1281         Element_Info1("Null");
1282         return;
1283     }
1284 
1285     //Needed?
1286     if (!audio_stream_Count && Config->ParseSpeed<1.0)
1287         return; //No more need of Audio stream
1288 
1289     //Parsing
1290     int8u  codec, sampling_rate;
1291     bool   is_16bit, is_stereo;
1292     Element_Begin1("Stream header");
1293     BS_Begin();
1294     Get_S1 (4, codec,                                           "codec"); Param_Info1(Flv_Codec_Audio[codec]); Element_Info1(Flv_Codec_Audio[codec]);
1295     Get_S1 (2, sampling_rate,                                   "sampling_rate"); Param_Info1(Ztring::ToZtring(Flv_SamplingRate[sampling_rate])+__T(" Hz"));
1296     Get_SB (   is_16bit,                                        "is_16bit"); Param_Info1(Ztring::ToZtring(Flv_Resolution[is_16bit])+__T(" bits"));
1297     Get_SB (   is_stereo,                                       "is_stereo"); Param_Info1(Ztring::ToZtring(Flv_Channels[is_stereo])+__T(" channel(s)"));
1298     BS_End();
1299     Element_End0();
1300 
1301     //Special case
1302     if (codec==5) //Nellymoser 8kHz mono
1303     {
1304         sampling_rate=5; //8000 Hz forced
1305         is_stereo=false; //Mono forced
1306     }
1307 
1308     if (codec!=10) // AAC has an header
1309     {
1310         Demux(Buffer+Buffer_Offset+(size_t)(Element_Offset+1), (size_t)(Element_Size-Element_Offset-1), ContentType_MainStream);
1311     }
1312 
1313     FILLING_BEGIN();
1314         if (Retrieve(Stream_Audio, 0, Audio_Format).empty())
1315         {
1316             //Filling
1317             if (Count_Get(Stream_Audio)==0)
1318                 File__Analyze::Stream_Prepare(Stream_Audio);
1319             Fill(Stream_Audio, 0, Audio_Channel_s_, Flv_Channels[is_stereo], 10, true);
1320             if (codec!=2 && codec!=10 && codec!=14) //MPEG Audio and AAC are not fixed bit depth
1321                 Fill(Stream_Audio, 0, Audio_BitDepth, Flv_Resolution[is_16bit], 10, true);
1322             if (sampling_rate<4)
1323                 Fill(Stream_Audio, 0, Audio_SamplingRate, Flv_SamplingRate[sampling_rate], 10, true);
1324             Fill(Stream_Audio, 0, Audio_Format, Flv_Format_Audio[codec]);
1325             Fill(Stream_Audio, 0, Audio_Format_Profile, Flv_Format_Profile_Audio[codec]);
1326             Fill(Stream_Audio, 0, Audio_Codec, Flv_Codec_Audio[codec]);
1327             Fill(Stream_Audio, 0, Audio_CodecID, codec);
1328             Fill(Stream_Audio, 0, Audio_CodecID_Hint, Flv_CodecID_Hint_Audio[codec]);
1329             if (codec==1)
1330             {
1331                 //ADPCM
1332                 Fill(Stream_Audio, 0, Audio_Format_Settings, "ShockWave");
1333                 Fill(Stream_Audio, 0, Audio_Format_Settings_Firm, "ShockWave");
1334                 Fill(Stream_Audio, 0, Audio_Codec_Settings, "SWF");
1335                 Fill(Stream_Audio, 0, Audio_Codec_Settings_Firm, "SWF");
1336 
1337             }
1338 
1339             MustSynchronize=true; // Now, synchronization test is possible
1340         }
1341 
1342         //Parsing audio data
1343         switch (codec)
1344         {
1345             case  2 :
1346             case 14 : audio_MPEG(); break;
1347             case 10 : audio_AAC(); break;
1348             default : Skip_XX(Element_Size-Element_Offset,      "Unknown");
1349                       audio_stream_Count=false; //No more need of Audio stream
1350         }
1351     FILLING_END();
1352 }
1353 
1354 //---------------------------------------------------------------------------
audio_MPEG()1355 void File_Flv::audio_MPEG()
1356 {
1357     #if defined(MEDIAINFO_MPEGA_YES)
1358         if (Stream[Stream_Audio].Parser==NULL)
1359         {
1360             Stream[Stream_Audio].Parser=new File_Mpega;
1361             Open_Buffer_Init(Stream[Stream_Audio].Parser);
1362             ((File_Mpega*)Stream[Stream_Audio].Parser)->FrameIsAlwaysComplete=true;
1363         }
1364 
1365         //Parsing
1366         Open_Buffer_Continue(Stream[Stream_Audio].Parser);
1367 
1368         //Disabling this stream
1369         if (Stream[Stream_Audio].Parser->File_GoTo!=(int64u)-1 || Stream[Stream_Audio].Parser->Count_Get(Stream_Audio)>0)
1370         {
1371             Stream[Stream_Audio].Parser->Open_Buffer_Unsynch();
1372             audio_stream_Count=false;
1373         }
1374     #endif
1375 }
1376 
1377 //---------------------------------------------------------------------------
audio_AAC()1378 void File_Flv::audio_AAC()
1379 {
1380     int8u AACPacketType;
1381     Get_B1 (AACPacketType,                                      "AACPacketType"); Param_Info1(Flv_AACPacketType(AACPacketType));
1382 
1383     switch (AACPacketType)
1384     {
1385         case 0 :
1386                 #if defined(MEDIAINFO_AAC_YES)
1387                     if (Stream[Stream_Audio].Parser==NULL)
1388                     {
1389                         Stream[Stream_Audio].Parser=new File_Aac;
1390                         ((File_Aac*)Stream[Stream_Audio].Parser)->Mode=File_Aac::Mode_AudioSpecificConfig;
1391                         Open_Buffer_Init(Stream[Stream_Audio].Parser);
1392                     }
1393 
1394                     //Parsing
1395                     Open_Buffer_Continue(Stream[Stream_Audio].Parser);
1396 
1397                     //Demux
1398                     #if MEDIAINFO_DEMUX
1399                         switch (Config->Demux_InitData_Get())
1400                         {
1401                             case 0 :    //In demux event
1402                                         Demux_Level=2; //Container
1403                                         Demux(Buffer+Buffer_Offset+2, (size_t)(Element_Size-2), ContentType_Header);
1404                                         break;
1405                             case 1 :    //In field
1406                                         {
1407                                         std::string Data_Raw((const char*)(Buffer+Buffer_Offset+2), (size_t)(Element_Size-2));
1408                                         std::string Data_Base64(Base64::encode(Data_Raw));
1409                                         Fill(Stream_Audio, StreamPos_Last, "Demux_InitBytes", Data_Base64);
1410                                         Fill_SetOptions(Stream_Audio, StreamPos_Last, "Demux_InitBytes", "N NT");
1411                                         }
1412                                         break;
1413                             default :   ;
1414                         }
1415                     #endif //MEDIAINFO_DEMUX
1416                 #else
1417                     Skip_XX(Element_Size-Element_Offset,        "AAC Data");
1418                     audio_stream_Count=false; //Unable to parse it
1419                 #endif
1420                 break;
1421         case 1 :
1422                 //Parsing
1423                 Demux(Buffer+Buffer_Offset+(size_t)Element_Offset, (size_t)(Element_Size-Element_Offset), ContentType_MainStream);
1424                 if (Stream[Stream_Audio].Parser)
1425                 {
1426                     Open_Buffer_Continue(Stream[Stream_Audio].Parser);
1427 
1428                     Stream[Stream_Audio].Parser->Open_Buffer_Unsynch();
1429                 }
1430                 else
1431                     Skip_XX(Element_Size-Element_Offset,        "Decoder config is missing");
1432                 audio_stream_Count=false; //No need of more
1433                 break;
1434         default: Skip_XX(Element_Size-Element_Offset,           "Unknown");
1435                 audio_stream_Count=false; //Unable to parse it
1436     }
1437 }
1438 
1439 //---------------------------------------------------------------------------
meta()1440 void File_Flv::meta()
1441 {
1442     Element_Name("Meta");
1443 
1444     //Parsing
1445     meta_Level=0;
1446     meta_SCRIPTDATAOBJECT();
1447 
1448     if (MetaData_NotTrustable)
1449     {
1450         meta_duration=0;
1451         Clear(Stream_Video, 0, Video_StreamSize);
1452         Clear(Stream_Video, 0, Video_BitRate);
1453         Clear(Stream_Video, 0, Video_Bits__Pixel_Frame_);
1454         Clear(Stream_Audio, 0, Audio_StreamSize);
1455         Clear(Stream_Audio, 0, Audio_BitRate);
1456         Clear(Stream_General, 0, General_Duration);
1457         Clear(Stream_General, 0, General_OverallBitRate);
1458     }
1459 }
1460 
1461 //---------------------------------------------------------------------------
meta_SCRIPTDATAOBJECT()1462 void File_Flv::meta_SCRIPTDATAOBJECT()
1463 {
1464     //Parsing Value
1465     std::string StringData;
1466     meta_SCRIPTDATAVALUE(StringData);
1467     meta_SCRIPTDATAVALUE(StringData);
1468 }
1469 
1470 //---------------------------------------------------------------------------
meta_SCRIPTDATAVARIABLE()1471 void File_Flv::meta_SCRIPTDATAVARIABLE()
1472 {
1473     std::string StringData;
1474     int16u StringLength;
1475     Element_Begin0();
1476     Get_B2 (StringLength,                                       "StringLength");
1477     Get_String(StringLength, StringData,                        "StringData");
1478     Element_Name(StringData.c_str());
1479 
1480     //Parsing Value
1481     meta_SCRIPTDATAVALUE(StringData);
1482     Element_End0();
1483 }
1484 
1485 //---------------------------------------------------------------------------
meta_SCRIPTDATAVALUE(const std::string & StringData)1486 void File_Flv::meta_SCRIPTDATAVALUE(const std::string &StringData)
1487 {
1488     std::string StringDataModified(StringData);
1489     if (!StringDataModified.empty() && StringDataModified[0]==__T('_'))
1490         StringDataModified.erase(StringDataModified.begin());
1491 
1492     //Parsing
1493     int8u Type;
1494     Get_B1 (Type,                                               "Type"); Param_Info1C((Type<0x12), Flv_TagType[Type]);
1495     switch (Type)
1496     {
1497         case 0x00 : //DOUBLE --> 64 bits Big endian float
1498             {
1499                 float64 Value;
1500                 Get_BF8(Value,                                 "Value");
1501                 if (Value==0)
1502                     break;
1503                 std::string ToFill;
1504                 Ztring ValueS;
1505                 stream_t StreamKind=Stream_General;
1506                      if (StringDataModified=="width") {ToFill="Width"; StreamKind=Stream_Video; ValueS.From_Number(Value, 0); video_stream_Count=true;} //1 file with FrameRate tag and video stream but no video present tag
1507                 else if (StringDataModified=="height") {ToFill="Height"; StreamKind=Stream_Video; ValueS.From_Number(Value, 0); video_stream_Count=true;} //1 file with FrameRate tag and video stream but no video present tag
1508                 else if (StringDataModified=="duration") meta_duration=Value*1000;
1509                 else if (StringDataModified=="audiodatarate") {ToFill="BitRate"; StreamKind=Stream_Audio; ValueS.From_Number(Value*1000, 0);}
1510                 else if (StringDataModified=="framerate") {ToFill="FrameRate"; StreamKind=Stream_Video; ValueS.From_Number(Value, 3); video_stream_FrameRate_Detected=true; video_stream_Count=true;} //1 file with FrameRate tag and video stream but no video present tag
1511                 else if (StringDataModified=="videoframerate") {ToFill="FrameRate"; StreamKind=Stream_Video; ValueS.From_Number(Value, 3); video_stream_FrameRate_Detected=true; video_stream_Count=true;} //1 file with FrameRate tag and video stream but no video present tag
1512                 else if (StringDataModified=="filesize") {meta_filesize=(int64u)Value;}
1513                 else if (StringDataModified=="audiosize") {ToFill="StreamSize"; StreamKind=Stream_Audio; ValueS.From_Number(Value, 0); if (Value>File_Size) MetaData_NotTrustable=true;}
1514                 else if (StringDataModified=="videosize") {ToFill="StreamSize"; StreamKind=Stream_Video; ValueS.From_Number(Value, 0); if (Value>File_Size) MetaData_NotTrustable=true; video_stream_Count=true;} //1 file with FrameRate tag and video stream but no video present tag
1515                 else if (StringDataModified=="videodatarate") {ToFill="BitRate"; StreamKind=Stream_Video; ValueS.From_Number(Value*1000, 0); video_stream_Count=true;} //1 file with FrameRate tag and video stream but no video present tag
1516                 else if (StringDataModified=="videocodecid") {; video_stream_Count=true;} //1 file with FrameRate tag and video stream but no video present tag
1517                 else if (StringDataModified=="audiodelay") {ToFill="Delay"; StreamKind=Stream_Audio; if (Value>0) ValueS.From_Number(Value*1000, 0);}
1518                 else if (StringDataModified=="audiosamplerate") {ToFill="SamplingRate"; StreamKind=Stream_Audio; if (Value>0) ValueS.From_Number(Value, 0);}
1519                 else if (StringDataModified=="audiosamplesize") {ToFill="BitDepth"; StreamKind=Stream_Audio; if (Value>0) ValueS.From_Number(Value, 0);}
1520                 else if (StringDataModified=="totalduration") {ToFill="Duration"; StreamKind=Stream_General; ValueS.From_Number(Value*1000, 0);}
1521                 else if (StringDataModified=="totaldatarate") {ToFill="OverallBitRate"; StreamKind=Stream_General; ValueS.From_Number(Value*1000, 0);}
1522                 else if (StringDataModified=="totalframes") {ToFill="FrameCount"; StreamKind=Stream_Video; ValueS.From_Number(Value, 0);}
1523                 else if (StringDataModified=="bytelength") {if (File_Size!=Value) MetaData_NotTrustable=true;}
1524                 else if (!(StringDataModified=="datasize"
1525                        || StringDataModified=="lasttimestamp"
1526                        || StringDataModified=="lastkeyframetimestamp"
1527                        || StringDataModified=="lastkeyframelocation"
1528                        || StringDataModified=="canSeekToEnd"
1529                        || StringDataModified=="keyframes_times"
1530                        || StringDataModified=="keyframes_filepositions"
1531                        || StringDataModified=="aacaot"
1532                        || StringDataModified=="audiochannels"
1533                        || StringDataModified=="audiocodecid"
1534                        || StringDataModified=="avclevel"
1535                        || StringDataModified=="avcprofile"
1536                        || StringDataModified=="moovPosition")) {StreamKind=Stream_General; ToFill=StringData; ValueS.From_Number(Value);}
1537                 #if MEDIAINFO_TRACE
1538                     if (ValueS.empty())
1539                         ValueS.From_Number(Value, 0);
1540                     Element_Info1(ValueS);
1541                 #endif //MEDIAINFO_TRACE
1542                 if (StreamKind==Stream_Video && ToFill=="FrameRate")
1543                 {
1544                     if (Retrieve(Stream_Video, 0, Video_FrameRate).To_float32()<1000 && Value>=1000)
1545                         ToFill.clear(); //Such incoherency was found in 1 file (e.g. 30 then 30000)
1546                 }
1547                 if (!ToFill.empty())
1548                 {
1549                     Fill(StreamKind, 0, ToFill.c_str(), ValueS, true);
1550                     if (ToFill=="FrameRate")
1551                         Fill(StreamKind, 0, "FrameRate_Mode", "CFR", Unlimited, true, true);
1552                 }
1553             }
1554             break;
1555         case 0x01 : //UI8
1556             {
1557                 int8u Value;
1558                 Get_B1 (Value,                                  "Value");
1559                 std::string ToFill;
1560                      if (StringDataModified=="haskeyframes") {}
1561                 else if (StringDataModified=="hasKeyframes") {}
1562                 else if (StringDataModified=="hasVideo") {}
1563                 else if (StringDataModified=="stereo") {}
1564                 else if (StringDataModified=="canSeekToEnd") {}
1565                 else if (StringDataModified=="hasAudio") {}
1566                 else if (StringDataModified=="hasmetadata") {}
1567                 else if (StringDataModified=="hasMetadata") {}
1568                 else if (StringDataModified=="hasCuePoints") {}
1569                 else if (StringDataModified=="canseekontime") {}
1570                 else {ToFill=StringData;}
1571                 Element_Info1(Value);
1572                 Fill(Stream_General, 0, ToFill.c_str(), Value?"Yes":"No", Unlimited, true, true);
1573             }
1574             break;
1575         case 0x02 : //SCRIPTDATASTRING
1576              {
1577                 int16u Value_Size;
1578                 Get_B2 (Value_Size,                             "Value_Size");
1579                 if (Value_Size)
1580                 {
1581                     Ztring Value;
1582                     Get_UTF8(Value_Size, Value,                 "Value");
1583                     size_t ToFill=(size_t)-1;
1584                     std::string ToFillS;
1585                          if (StringDataModified=="creator") {ToFill=General_Encoded_Application;}
1586                     else if (StringDataModified=="creationdate") {ToFill=General_Encoded_Date; Value.Date_From_String(Value.To_UTF8().c_str());}
1587                     else if (StringDataModified=="encoder") {ToFill=General_Encoded_Application;}
1588                     else if (StringDataModified=="Encoded_With") {ToFill=General_Encoded_Application;}
1589                     else if (StringDataModified=="Encoded_By") {ToFill=General_Encoded_Application;}
1590                     else if (StringDataModified=="metadatacreator") {ToFill=General_Tagged_Application;}
1591                     else if (StringDataModified=="title") {ToFill=General_Title;}
1592                     else if (StringDataModified=="creation_time") {ToFill=General_Encoded_Date; Value.insert(0, __T("UTC "));}
1593                     else if (StringDataModified=="sourcedata") {}
1594                     else if (StringDataModified=="audiocodecid") {}
1595                     else if (StringDataModified=="videocodecid") {}
1596                     else if (!(StringDataModified=="major_brand"
1597                             || StringDataModified=="minor_version"
1598                             || StringDataModified=="compatible_brands"))
1599                         ToFillS=StringData;
1600                     if (Value.find(__T('\r'))!=std::string::npos)
1601                         Value.resize(Value.find(__T('\r')));
1602                     if (Value.find(__T('\n'))!=std::string::npos)
1603                         Value.resize(Value.find(__T('\n')));
1604                     Element_Info1(Value);
1605                     if (ToFill!=(size_t)-1)
1606                         Fill(Stream_General, 0, ToFill, Value, true);
1607                     else if (!ToFillS.empty())
1608                         Fill(Stream_General, 0, StringData.c_str(), Value, true);
1609                 }
1610             }
1611             break;
1612         case 0x03 : //SCRIPTDATAOBJECT[n]
1613         case 0x10 : //Typed object - SCRIPTDATAOBJECT[n]
1614             {
1615                 std::string StringData2;
1616                 int16u StringLength2;
1617                 meta_Level++;
1618                 meta_LevelFinished[meta_Level]=false;
1619                 while (!meta_LevelFinished[meta_Level])
1620                 {
1621                     if (Element_Offset>=Element_Size)
1622                         break;
1623                     Element_Begin0();
1624                     Get_B2 (StringLength2,                          "StringLength2");
1625                     Get_String(StringLength2, StringData2,          "StringData2");
1626                     Element_Name(StringData2.empty()?"EndOfObject":StringData2.c_str());
1627                     meta_SCRIPTDATAVALUE(StringData+'_'+StringData2);
1628                     Element_End0();
1629                 }
1630                 meta_Level--;
1631             }
1632             break;
1633         case 0x04 : //SCRIPTDATASTRING defining the MovieClip path
1634             {
1635                 int16u Value_Size;
1636                 Get_B2 (Value_Size,                             "Value_Size");
1637                 if (Value_Size)
1638                 {
1639                     Ztring Value;
1640                     Get_UTF8(Value_Size, Value,                 "Value");
1641                     if (Value==__T("unknown")) Value.clear();
1642                     Element_Info1C((!Value.empty()), Value);
1643                     Fill(Stream_General, 0, StringData.c_str(), Value, true);
1644                 }
1645             }
1646             break;
1647         case 0x05 : //NULL
1648         case 0x06 : //Undefined - NULL
1649         case 0x0D : //Unsupported - NULL
1650             break;
1651         case 0x07 : //UI16
1652             {
1653                 int16u Value;
1654                 Get_B2 (Value,                                  "Value");
1655                 Element_Info1(Value);
1656                 Fill(Stream_General, 0, StringData.c_str(), Value, true);
1657             }
1658             break;
1659         case 0x08 : //SCRIPTDATAVARIABLE[ECMAArrayLength]
1660             {
1661                 int32u ECMAArrayLength;
1662                 Get_B4 (ECMAArrayLength,                        "ECMAArrayLength");
1663                 Element_Info1(Ztring::ToZtring(ECMAArrayLength)+__T(" elements"));
1664                 for (int32u Pos=0; Pos<ECMAArrayLength; Pos++)
1665                 {
1666                     meta_SCRIPTDATAVARIABLE();
1667                     if (meta_LevelFinished[meta_Level])
1668                         Pos=ECMAArrayLength; //Finished
1669                 }
1670             }
1671             break;
1672         case 0x09 :
1673             Element_Info1("EndOfObject");
1674             meta_LevelFinished[meta_Level]=true;
1675             break;
1676         case 0x0A : //SCRIPTDATAVARIABLE[n]
1677         case 0x0E : //RecordSet - SCRIPTDATAVARIABLE[n]
1678             {
1679                 int32u Count;
1680                 Get_B4 (Count,                                  "Count");
1681                 for (int32u Pos=0; Pos<Count; Pos++)
1682                     meta_SCRIPTDATAVALUE(StringData);
1683             }
1684             break;
1685         case 0x0B : //SCRIPTDATADATE
1686             {
1687                 float64 Value;
1688                 Get_BF8(Value,                                 "Value");
1689                 Ztring ValueS;
1690                 ValueS.Date_From_Seconds_1970((int32u)(Value/1000));
1691                 Param_Info1(ValueS);
1692                 Skip_B2(                                        "Local_Offset_Minutes");
1693                 std::string ToFill;
1694                      if (StringData=="metadatadate") {ToFill="Tagged_Date";}
1695                 else {ToFill=StringData;}
1696                 Element_Info1(ValueS);
1697                 Fill(Stream_General, 0, ToFill.c_str(), ValueS, true);
1698             }
1699             break;
1700         case 0x0C : //SCRIPTDATALONGSTRING
1701         case 0x0F : //XML - SCRIPTDATALONGSTRING
1702             {
1703                 int32u Value_Size;
1704                 Get_B4 (Value_Size,                             "Value_Size");
1705                 if (Value_Size)
1706                 {
1707                     Ztring Value;
1708                     Get_UTF16B(Value_Size, Value,               "Value");
1709                     std::string ToFill;
1710                          if (StringData=="creator") {ToFill="Encoded_Application";}
1711                     else if (StringData=="liveXML") {}
1712                     else if (StringData=="metadatacreator") {ToFill="Tagged_Application";}
1713                     else if (StringData=="creationdate") {ToFill="Encoded_Date"; Value.Date_From_String(Value.To_UTF8().c_str());}
1714                     else {ToFill=StringData;}
1715                     Element_Info1(Value);
1716                     if (!ToFill.empty())
1717                         Fill(Stream_General, 0, ToFill.c_str(), Value, true);
1718                 }
1719             }
1720             break;
1721         case 0x11 : //AMF3 data
1722             {
1723                 int32u TypeCode;
1724                 Get_B4 (TypeCode,                               "AMF3 type code"); Param_Info1C((TypeCode<0x0D), Flv_Amf3Type[TypeCode]);
1725                 switch (TypeCode)
1726                 {
1727                     case 0x00 : //undefined
1728                     case 0x01 : //null
1729                     case 0x02 : //boolean-false
1730                     case 0x03 : //boolean-true
1731                         break;
1732                     default : //Not implemented or unknown
1733                         Element_Offset=Element_Size;
1734                 }
1735             }
1736             break;
1737         default : //Unknown
1738             Element_Offset=Element_Size; //Forcing the end of parsing
1739     }
1740 }
1741 
1742 //---------------------------------------------------------------------------
Rm()1743 void File_Flv::Rm()
1744 {
1745     Element_Name("Real Media tags");
1746 
1747     //Creating the parser
1748     File_Rm MI;
1749     Open_Buffer_Init(&MI);
1750 
1751     //Parsing
1752     Open_Buffer_Continue(&MI);
1753 
1754     //Filling
1755     File__Analyze::Finish(&MI);
1756     Merge(MI, Stream_General, 0, 0);
1757 }
1758 
1759 } //NameSpace
1760 
1761 #endif //MEDIAINFO_FLV_YES
1762