Skip to content

Commit 2f5fbe9

Browse files
+ TTML: better support files with SMPTE timecode and ticks instead of frame rate
1 parent e4517da commit 2f5fbe9

File tree

1 file changed

+38
-18
lines changed

1 file changed

+38
-18
lines changed

Source/MediaInfo/Text/File_Ttml.cpp

Lines changed: 38 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -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

Comments
 (0)