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