@@ -315,6 +315,7 @@ void File_Ttml::Read_Buffer_Continue()
315315 // Root attributes
316316 bool IsSmpteTt=false , IsEbuTt=false , IsImsc1=false ;
317317 int32u tickRate=0 ;
318+ int32u TimeCodeFrameMax=0 ;
318319 const char * Tt_Attribute;
319320 Tt_Attribute=Root->Attribute (" ittp:aspectRatio" );
320321 if (!Tt_Attribute)
@@ -370,24 +371,6 @@ void File_Ttml::Read_Buffer_Continue()
370371 Fill (Stream_Text, 0 , Text_FrameRate_Num, FrameRate_Int*FrameRateMultiplier_Num, 10 , true );
371372 Fill (Stream_Text, 0 , Text_FrameRate_Den, FrameRateMultiplier_Den, 10 , true );
372373 }
373- if (!FrameRate_Int && !tickRate)
374- {
375- #if MEDIAINFO_ADVANCED
376- float64 FrameRate_F=Video_FrameRate_Rounded (Config->File_DefaultFrameRate_Get ());
377- if (!FrameRate_F)
378- FrameRate_F=30 ; // "if no application defined frame rate applies, then thirty (30) frames per second" https://www.w3.org/TR/2018/REC-ttml2-20181108/#parameter-attribute-frameRate
379- #else // MEDIAINFO_ADVANCED
380- const float64 FrameRate_F=30 ;
381- #endif // MEDIAINFO_ADVANCED
382- FrameRate_Int=float64_int64s (FrameRate_F);
383- if (FrameRate_Int != FrameRate_F)
384- {
385- FrameRateMultiplier_Num=1000 ;
386- FrameRateMultiplier_Den=float64_int64s (FrameRate_Int/FrameRate_F*1000 );
387- if (FrameRateMultiplier_Num==1000 && FrameRateMultiplier_Den==1001 )
388- FrameRate_Is1001=true ;
389- }
390- }
391374 Tt_Attribute=Root->Attribute (" xml:lang" );
392375 if (!Tt_Attribute)
393376 Tt_Attribute=Root->Attribute (" lang" );
@@ -428,6 +411,13 @@ void File_Ttml::Read_Buffer_Continue()
428411 {
429412 Fill (Stream_General, 0 , General_Format_Profile, " SMPTE-TT" );
430413 Fill (Stream_Text, 0 , Text_Format_Profile, " SMPTE-TT" );
414+ if (!FrameRate_Int && tickRate >= 2000 )
415+ {
416+ // Not clear but it seems that tickRate is actually frame rate x 1000 in several files without frame rate
417+ auto Temp = float64_int64s (tickRate / 1000.0 ) - 1 ;
418+ if (Temp <= numeric_limits<int32u>::max ())
419+ TimeCodeFrameMax = Temp;
420+ }
431421 }
432422 if (IsEbuTt)
433423 {
@@ -439,6 +429,24 @@ void File_Ttml::Read_Buffer_Continue()
439429 Fill (Stream_General, 0 , General_Format_Profile, " IMSC1" );
440430 Fill (Stream_Text, 0 , Text_Format_Profile, " IMSC1" );
441431 }
432+ if (!FrameRate_Int && !tickRate)
433+ {
434+ #if MEDIAINFO_ADVANCED
435+ float64 FrameRate_F=Video_FrameRate_Rounded (Config->File_DefaultFrameRate_Get ());
436+ if (!FrameRate_F)
437+ FrameRate_F=30 ; // "if no application defined frame rate applies, then thirty (30) frames per second" https://www.w3.org/TR/2018/REC-ttml2-20181108/#parameter-attribute-frameRate
438+ #else // MEDIAINFO_ADVANCED
439+ const float64 FrameRate_F=30 ;
440+ #endif // MEDIAINFO_ADVANCED
441+ FrameRate_Int=float64_int64s (FrameRate_F);
442+ if (FrameRate_Int != FrameRate_F)
443+ {
444+ FrameRateMultiplier_Num=1000 ;
445+ FrameRateMultiplier_Den=float64_int64s (FrameRate_Int/FrameRate_F*1000 );
446+ if (FrameRateMultiplier_Num==1000 && FrameRateMultiplier_Den==1001 )
447+ FrameRate_Is1001=true ;
448+ }
449+ }
442450 string Rosetta_Profile, Rosetta_Version;
443451
444452 tinyxml2::XMLElement* div=NULL ;
@@ -467,6 +475,8 @@ void File_Ttml::Read_Buffer_Continue()
467475 {
468476 if (!Time_Begin_New.FromString (Attribute))
469477 {
478+ if (TimeCodeFrameMax && !Time_Begin_New.IsTimed ())
479+ Time_Begin_New.SetFramesMax (TimeCodeFrameMax);
470480 if (!Time_Begin.IsSet () || Time_Begin>Time_Begin_New)
471481 Time_Begin=Time_Begin_New;
472482 if (!Time_End.IsSet () || Time_End<Time_Begin_New)
@@ -477,6 +487,8 @@ void File_Ttml::Read_Buffer_Continue()
477487 {
478488 if (!Time_End_New.FromString (Attribute))
479489 {
490+ if (TimeCodeFrameMax && !Time_End_New.IsTimed ())
491+ Time_End_New.SetFramesMax (TimeCodeFrameMax);
480492 if (!Time_Begin.IsSet () || Time_Begin>Time_End_New)
481493 Time_Begin=Time_End_New;
482494 if (!Time_End.IsSet () || Time_End<Time_End_New)
@@ -488,6 +500,8 @@ void File_Ttml::Read_Buffer_Continue()
488500 TimeCode Time_Dur_New=Time_Template;
489501 if (Time_Begin.IsSet () && !Time_Dur_New.FromString (Attribute))
490502 {
503+ if (TimeCodeFrameMax && !Time_Dur_New.IsTimed ())
504+ Time_Dur_New.SetFramesMax (TimeCodeFrameMax);
491505 Time_End_New=Time_Begin_New;
492506 Time_End_New+=Time_Dur_New;
493507 if (!Time_Begin.IsSet () || Time_Begin>Time_End_New)
@@ -506,6 +520,8 @@ void File_Ttml::Read_Buffer_Continue()
506520 {
507521 if (!Time_Begin_New.FromString (Attribute))
508522 {
523+ if (TimeCodeFrameMax && !Time_Begin_New.IsTimed ())
524+ Time_Begin_New.SetFramesMax (TimeCodeFrameMax);
509525 if (!Time_Begin.IsSet () || Time_Begin>Time_Begin_New)
510526 Time_Begin=Time_Begin_New;
511527 if (!Time_End.IsSet () || Time_End<Time_Begin_New)
@@ -516,6 +532,8 @@ void File_Ttml::Read_Buffer_Continue()
516532 {
517533 if (!Time_End_New.FromString (Attribute))
518534 {
535+ if (TimeCodeFrameMax && !Time_End_New.IsTimed ())
536+ Time_End_New.SetFramesMax (TimeCodeFrameMax);
519537 if (!Time_Begin.IsSet () || Time_Begin>Time_End_New)
520538 Time_Begin=Time_End_New;
521539 if (!Time_End.IsSet () || Time_End<Time_End_New)
@@ -527,6 +545,8 @@ void File_Ttml::Read_Buffer_Continue()
527545 TimeCode Time_Dur_New=Time_Template;
528546 if (Time_Begin.IsSet () && !Time_Dur_New.FromString (Attribute))
529547 {
548+ if (TimeCodeFrameMax && !Time_Dur_New.IsTimed ())
549+ Time_Dur_New.SetFramesMax (TimeCodeFrameMax);
530550 Time_End_New=Time_Begin_New;
531551 Time_End_New+=Time_Dur_New;
532552 if (!Time_Begin.IsSet () || Time_Begin>Time_End_New)
0 commit comments