@@ -56,6 +56,13 @@ static string to_hexstring(uint16_t value)
5656// Helpers
5757// ***************************************************************************
5858
59+ // ---------------------------------------------------------------------------
60+ enum format {
61+ Format_Unknown,
62+ Format_DV,
63+ Format_DAT,
64+ };
65+
5966// ---------------------------------------------------------------------------
6067static void Dseq_Begin (string& Text, size_t o, int Dseq)
6168{
@@ -244,22 +251,30 @@ return_value Output_Xml(ostream& Out, std::vector<file*>& PerFile, bitset<Option
244251 Text += Merge_InputFileNames[0 ];
245252 Text += ' \" ' ;
246253 }
254+ auto Format_G = File->MI .Get (Stream_General, 0 , __T (" Format" ));
255+ auto Format_V = File->MI .Get (Stream_Video, 0 , __T (" Format" ));
256+ format Format;
257+ if (Format_G == __T (" DAT" ))
258+ Format = Format_DAT;
259+ else if (Format_V == __T (" DV" ))
260+ Format = Format_DV;
261+ else
262+ Format = Format_Unknown;
247263 if (File->CaptureMode == Capture_Mode_DV)
248264 {
249- if (File->PerFrame .empty () || File->PerChange .empty ())
265+ if (Format == Format_Unknown || File->PerFrame .empty () || File->PerChange .empty ())
250266 {
251- if (File-> MI . Get (Stream_Video, 0 , __T ( " Format" )) != __T ( " DV " ) )
252- Text += " error=\" not DV \" " ;
267+ if (Format == Format_Unknown )
268+ Text += " error=\" not supported \" " ;
253269 else
254270 Text += " error=\" no frame received\" " ;
255271 Text += " />\n " ;
256272 continue ; // Show the file only if there is some DV content
257273 }
258- auto Format = File->MI .Get (Stream_General, 0 , __T (" Format" ));
259- if (!Format.empty ())
274+ if (!Format_G.empty ())
260275 {
261276 Text += " format=\" " ;
262- Text += Ztring (Format ).To_UTF8 ();
277+ Text += Ztring (Format_G ).To_UTF8 ();
263278 Text += ' \" ' ;
264279 }
265280 auto FileSize = File->MI .Get (Stream_General, 0 , __T (" FileSize" ));
@@ -489,8 +504,72 @@ return_value Output_Xml(ostream& Out, std::vector<file*>& PerFile, bitset<Option
489504 queue<size_t > Captions_Partial[2 ]; // 0 = Out, 1 = In
490505 for (const auto & Frame : File->PerFrame )
491506 {
507+ string abst;
508+ auto AbstBf = abst_bf (Frame->AbstBf );
509+ if (AbstBf.HasAbsoluteTrackNumberValue ())
510+ abst = to_string (AbstBf.AbsoluteTrackNumber ());
511+ auto abst_r = AbstBf.Repeat ();
512+ auto abst_nc = AbstBf.NonConsecutive ();
513+ string tc;
514+ auto TimeCode = timecode (Frame);
515+ if (TimeCode.HasValue ())
516+ timecode_to_string (tc, TimeCode.TimeInSeconds (), TimeCode.DropFrame (), TimeCode.Frames ());
517+ auto tc_r = TimeCode.Repeat ();
518+ int tc_nc = TimeCode.NonConsecutive ();
519+ if (tc_nc && TimeCode.NonConsecutive_IsLess ())
520+ tc_nc++;
521+
522+ if (Frame->MoreData )
523+ {
524+ const auto MoreData = Frame->MoreData ;
525+ size_t MoreData_Offset = sizeof (size_t );
526+ size_t MoreData_TotalSize = MoreData_Offset + *((size_t *)MoreData);
527+ while (MoreData_Offset < MoreData_TotalSize)
528+ {
529+ auto Size = MoreData[MoreData_Offset++];
530+ if (Size >= 0x80 )
531+ break ;
532+ auto Name = MoreData[MoreData_Offset++];
533+ if (Name >= 0x80 )
534+ break ;
535+ switch (Name)
536+ {
537+ case MediaInfo_Event_Analysis_Frame_TimeCode:
538+ if (Size >= 4 )
539+ {
540+ uint32_t Value = *((int32_t *)(MoreData + MoreData_Offset));
541+ uint32_t MoreFlags = 0 ;
542+ bool IsAbst = false ;
543+ if (Size >= 8 )
544+ {
545+ MoreFlags = *((int32_t *)(MoreData + MoreData_Offset + 4 ));
546+ if (Size >= 9 )
547+ {
548+ IsAbst = MoreData[MoreData_Offset + 8 ] == 1 ;
549+ }
550+ }
551+ timecode TimeCode (Value, MoreFlags);
552+ if (IsAbst && abst.empty ())
553+ {
554+ timecode_to_string (abst, TimeCode.TimeInSeconds (), TimeCode.DropFrame (), TimeCode.Frames ());
555+ abst_r = TimeCode.Repeat ();
556+ abst_nc = TimeCode.NonConsecutive ();
557+ }
558+ else if (!IsAbst && tc.empty ())
559+ {
560+ timecode_to_string (tc, TimeCode.TimeInSeconds (), TimeCode.DropFrame (), TimeCode.Frames ());
561+ tc_r = TimeCode.Repeat ();
562+ tc_nc = TimeCode.NonConsecutive ();
563+ }
564+ }
565+ break ;
566+ }
567+ MoreData_Offset += Size;
568+ }
569+ }
570+
492571 decltype (FrameNumber_Max) FrameNumber = &Frame - &*File->PerFrame .begin ();
493- auto ShowFrame = ShowFrames || FrameNumber == FrameNumber_Max || Frame_HasErrors (Frame);
572+ auto ShowFrame = ShowFrames || FrameNumber == FrameNumber_Max || Frame_HasErrors (Frame) || abst_r || abst_nc || tc_r || tc_nc ;
494573
495574 if (ShowFrames)
496575 {
@@ -642,6 +721,12 @@ return_value Output_Xml(ostream& Out, std::vector<file*>& PerFile, bitset<Option
642721 Text += to_string (Change->AudioChannels );
643722 Text += ' \" ' ;
644723 }
724+ if (Change->AudioBitDepth )
725+ {
726+ Text += " audio_bitdepth=\" " ;
727+ Text += to_string (Change->AudioBitDepth );
728+ Text += ' \" ' ;
729+ }
645730 if (!Captions_Partial[0 ].empty () || !Captions_Partial[1 ].empty ())
646731 {
647732 Text += " captions=\" p\" " ;
@@ -661,6 +746,48 @@ return_value Output_Xml(ostream& Out, std::vector<file*>& PerFile, bitset<Option
661746 Text += to_string (DvSpeed);
662747 Text += ' \" ' ;
663748 }
749+ if (Change->MoreData )
750+ {
751+ const auto MoreData = Change->MoreData ;
752+ size_t MoreData_Offset = sizeof (size_t );
753+ size_t MoreData_TotalSize = MoreData_Offset + *((size_t *)MoreData);
754+ while (MoreData_Offset < MoreData_TotalSize)
755+ {
756+ auto Size = MoreData[MoreData_Offset++];
757+ if (Size >= 0x80 )
758+ break ;
759+ auto Name = MoreData[MoreData_Offset++];
760+ if (Name >= 0x80 )
761+ break ;
762+ switch (Name)
763+ {
764+ case MediaInfo_Event_Change_MoreData_Emphasis:
765+ if (Size)
766+ {
767+ auto emphasis = MoreData[MoreData_Offset];
768+ if (emphasis < 2 )
769+ {
770+ Text += " emphasis=\" " ;
771+ Text += emphasis ? " 50/15 ms" : " off" ;
772+ Text += ' \" ' ;
773+ }
774+ }
775+ break ;
776+ case MediaInfo_Event_Change_MoreData_ProgramNumber:
777+ if (Size > 1 )
778+ {
779+ auto program_number = to_hexstring (*((int16_t *)(MoreData + MoreData_Offset)));
780+ if (program_number.size () == 6 && program_number[0 ] == ' 0' && program_number[1 ] == ' x' && program_number[2 ] == ' 0' )
781+ program_number.erase (0 , 3 );
782+ Text += " program_number=\" " ;
783+ Text += program_number;
784+ Text += ' \" ' ;
785+ }
786+ break ;
787+ }
788+ MoreData_Offset += Size;
789+ }
790+ }
664791 Text += " >\n " ;
665792 }
666793
@@ -700,40 +827,37 @@ return_value Output_Xml(ostream& Out, std::vector<file*>& PerFile, bitset<Option
700827 }
701828
702829 // Absolute track number + Blank flag
703- auto AbstBf = abst_bf (Frame->AbstBf );
704- if (AbstBf.HasAbsoluteTrackNumberValue ())
830+ if (!abst.empty ())
705831 {
706832 Text += " abst=\" " ;
707- Text += to_string (AbstBf. AbsoluteTrackNumber ()) ;
833+ Text += abst ;
708834 Text += ' \" ' ;
709835 }
710- if (AbstBf. Repeat () )
836+ if (abst_r )
711837 {
712838 Text += " abst_r=\" 1\" " ;
713839 }
714- if (AbstBf. NonConsecutive () )
840+ if (abst_nc )
715841 {
716842 Text += " abst_nc=\" 1\" " ;
717843 }
718844
719845 // TimeCode
720- auto TimeCode = timecode (Frame);
721- if (TimeCode.HasValue ())
846+ if (!tc.empty ())
722847 {
723848 Text += " tc=\" " ;
724- timecode_to_string ( Text, TimeCode. TimeInSeconds (), TimeCode. DropFrame (), TimeCode. Frames ()) ;
849+ Text += tc ;
725850 Text += ' \" ' ;
726851 }
727- if (TimeCode. Repeat () )
852+ if (tc_r )
728853 {
729854 Text += " tc_r=\" 1\" " ;
730855 }
731- if (TimeCode. NonConsecutive () )
856+ if (tc_nc )
732857 {
733- if (TimeCode.NonConsecutive_IsLess ())
734- Text += " tc_nc=\" 2\" " ;
735- else
736- Text += " tc_nc=\" 1\" " ;
858+ Text += " tc=\" " ;
859+ Text += ' 0' + tc_nc;
860+ Text += ' \" ' ;
737861 }
738862
739863 // RecDate/RecTime
@@ -885,6 +1009,14 @@ return_value Output_Xml(ostream& Out, std::vector<file*>& PerFile, bitset<Option
8851009 }
8861010 }
8871011 }
1012+ else if (Coherency.conceal_aud_l ())
1013+ {
1014+ Text += " conceal_aud_value=\" l\" " ;
1015+ }
1016+ else if (Coherency.conceal_aud_r ())
1017+ {
1018+ Text += " conceal_aud_value=\" r\" " ;
1019+ }
8881020 }
8891021
8901022 // Errors
0 commit comments