[matroska] r770 - trunk/DvdMenuXtractor
[email protected] Thu, 9 Sep 2004 15:29:53 +0400 (MSD)
Newsgroups
gmane.comp.multimedia.matroska.cvs
Message-ID
<[email protected] >
Author: robux4
Date: 2004-09-09 15:29:53 +0400 (Thu, 09 Sep 2004)
New Revision: 770
Modified:
trunk/DvdMenuXtractor/DvdMenuXtractor.cpp
Log:
code factorisation, better handling of start/stop timecodes
Modified: trunk/DvdMenuXtractor/DvdMenuXtractor.cpp
===================================================================
--- trunk/DvdMenuXtractor/DvdMenuXtractor.cpp 2004-09-09 08:58:31 UTC (rev 769)
+++ trunk/DvdMenuXtractor/DvdMenuXtractor.cpp 2004-09-09 11:29:53 UTC (rev 770)
@@ -869,6 +869,10 @@
return result;
}
+ uint64_t OutputProgram(int lvl, wxTextFile & XmlFile, const pgc_program_map_t * program, uint64_t start_time)
+ {
+ }
+
uint64_t OutputPGC(int lvl, wxTextFile & XmlFile, const pgc_t * pgc, uint64_t start_time, uint16_t pgc_num, unsigned char pgc_type)
{
static unsigned char _PrivatePGC[] = {0x20, 0x00, 0x00, 0x00};
@@ -890,15 +894,77 @@
// PGC commands
AddCommands(lvl, XmlFile, pgc->command_tbl);
- // TODO: handle the PROGRAMS in the PGC
+ // TODO: handle the PROGRAMS/Cells in the PGC
+ for (int i=0; i< pgc->nr_of_programs; i++)
+ {
+ XmlFile.AddLine(IndentString(lvl)+"<!-- Program #"+wxString::Format("%d",i)+" in this PGC -->");
+ XmlFile.AddLine(IndentString(lvl)+"<ChapterAtom>");
+ lvl++;
+ // TODO
+ OutputProgram(lvl, XmlFile, &pgc->program_map[i], start_time);
+ lvl--;
+ XmlFile.AddLine(IndentString(lvl)+"</ChapterAtom>");
+ }
- // TODO: PGC start/end times
- XmlFile.AddLine(IndentString(lvl)+"<ChapterTimeStart>00:00:00.000000000</ChapterTimeStart>");
- XmlFile.AddLine(IndentString(lvl)+"<ChapterTimeEnd>00:00:00.000000000</ChapterTimeEnd>");
+ // PGC start/end times
+ DisplayTime(lvl, XmlFile, start_time, start_time+ DvdTimecodeToNano(pgc->playback_time));
lvl--;
- return start_time;
+ return start_time + DvdTimecodeToNano(pgc->playback_time);
}
+
+// Macro to convert Binary Coded Decimal to Decimal
+#define BCD2D(__x__) (((__x__ & 0xf0) >> 4) * 10 + (__x__ & 0x0f))
+ uint64_t DvdTimecodeToNano(dvd_time_t dtime)
+ {
+ uint64_t nano_duration = 0;
+ nano_duration += uint64_t(BCD2D(dtime.hour)) * 60 * 60 * 1000000000;
+ nano_duration += uint64_t(BCD2D(dtime.minute)) * 60 * 1000000000;
+ nano_duration += uint64_t(BCD2D(dtime.second)) * 1000000000;
+
+ float fps;
+ switch((dtime.frame_u & 0xc0) >> 6)
+ {
+ case 1:
+ fps = 25.0;
+ break;
+ case 3:
+ fps = 29.97;
+ break;
+ default:
+ fps = 2500.0;
+ assert(0);
+ break;
+ }
+ double _ms = BCD2D(dtime.frame_u&0x3f) * 1000.0 / fps;
+ nano_duration += uint64_t(_ms * 1000000.0);
+
+ return nano_duration;
+ }
+
+ /// times in nanoseconds
+ void DisplayTime(int lvl, wxTextFile & XmlFile, uint64_t start_time, uint64_t end_time)
+ {
+ int hour, min, sec;
+ uint32_t nano;
+
+ nano = start_time % 1000000000;
+ start_time /= 1000000000;
+ sec = start_time % 60;
+ start_time /= 60;
+ min = start_time % 60;
+ hour = start_time / 60;
+ XmlFile.AddLine(IndentString(lvl)+"<ChapterTimeStart>"+wxString::Format("%02d:%02d:%02d.%09d", hour, min, sec, nano)+"</ChapterTimeStart>");
+
+ nano = end_time % 1000000000;
+ end_time /= 1000000000;
+ sec = end_time % 60;
+ end_time /= 60;
+ min = end_time % 60;
+ hour = end_time / 60;
+ XmlFile.AddLine(IndentString(lvl)+"<ChapterTimeEnd>"+wxString::Format("%02d:%02d:%02d.%09d", hour, min, sec, nano)+"</ChapterTimeEnd>");
+ }
+
void GenerateXMLScript()
{
CellListElem* cle;
@@ -923,6 +989,7 @@
XmlFile.AddLine("");
int lvl = 0, i,j;
+ uint64_t timecode_startA = 0, timecode_endA = 0;
XmlFile.AddLine("<Chapters>");
lvl++;
@@ -941,8 +1008,7 @@
wxString _myUID = CreateUID();
XmlFile.AddLine(IndentString(lvl)+"<ChapterUID>"+_myUID+"</ChapterUID>");
// the First Play PGC has no cell and no time
- XmlFile.AddLine(IndentString(lvl)+"<ChapterTimeStart>00:00:00.000000000</ChapterTimeStart>");
- XmlFile.AddLine(IndentString(lvl)+"<ChapterTimeEnd>00:00:00.000000000</ChapterTimeEnd>");
+ DisplayTime(lvl, XmlFile, timecode_startA, timecode_endA);
// display the UID for the lazy rippers
XmlFile.AddLine(IndentString(lvl)+"<ChapterDisplay>");
lvl++;
@@ -958,6 +1024,8 @@
lvl--;
}
+ timecode_startA = timecode_endA;
+
// Language Units
if (IfoFile->LanguageUnits() && IfoFile->LanguageUnits()->nr_of_lus)
{
@@ -967,8 +1035,8 @@
lvl++;
wxString _myUIDa = CreateUID();
XmlFile.AddLine(IndentString(lvl)+"<ChapterUID>"+_myUIDa+"</ChapterUID>");
- XmlFile.AddLine(IndentString(lvl)+"<ChapterTimeStart>00:00:00.000000000</ChapterTimeStart>");
XmlFile.AddLine(IndentString(lvl)+"<ChapterProcessPrivate>"+encodebase64(_PrivateVM,2)+"</ChapterProcessPrivate>");
+ uint64_t timecode_startB = timecode_startA, timecode_endB = timecode_startA;
for (i=0 ;i<IfoFile->LanguageUnits()->nr_of_lus; i++)
{
XmlFile.AddLine(IndentString(lvl)+"<!-- Language Units -->");
@@ -983,7 +1051,6 @@
wxString _myUIDb = CreateUID();
XmlFile.AddLine(IndentString(lvl)+"<ChapterUID>"+_myUIDb+"</ChapterUID>");
- XmlFile.AddLine(IndentString(lvl)+"<ChapterTimeStart>00:00:00.000000000</ChapterTimeStart>");
XmlFile.AddLine(IndentString(lvl)+"<ChapterProcessPrivate>"+encodebase64(_PrivateLU,4)+"</ChapterProcessPrivate>");
// display the UID for the lazy rippers
XmlFile.AddLine(IndentString(lvl)+"<ChapterDisplay>");
@@ -994,25 +1061,28 @@
if (_LU.pgcit)
{
- uint64_t timecode = 0;
for (j=0; j<_LU.pgcit->nr_of_pgci_srp; j++)
{
const pgci_srp_t &_PGC_SRP = _LU.pgcit->pgci_srp[j];
- XmlFile.AddLine(IndentString(lvl)+"<!-- PGC type "+GetPGCType(_PGC_SRP.entry_id)+" -->");
+ XmlFile.AddLine("\n"+IndentString(lvl)+"<!-- PGC type "+GetPGCType(_PGC_SRP.entry_id)+" -->");
XmlFile.AddLine(IndentString(lvl)+"<ChapterAtom>");
- timecode += OutputPGC(lvl, XmlFile, _PGC_SRP.pgc, timecode, j, _PGC_SRP.entry_id);
+ timecode_endB = OutputPGC(lvl, XmlFile, _PGC_SRP.pgc, timecode_endB, j, _PGC_SRP.entry_id);
XmlFile.AddLine(IndentString(lvl)+"</ChapterAtom>");
}
}
-
+ DisplayTime(lvl, XmlFile, timecode_startB, timecode_endB);
+ timecode_startB = timecode_endB;
+ timecode_endA = timecode_endB;
lvl--;
}
XmlFile.AddLine(IndentString(lvl)+"</ChapterAtom>");
+ DisplayTime(lvl, XmlFile, timecode_startA, timecode_endA);
lvl--;
XmlFile.AddLine(IndentString(lvl)+"</ChapterAtom>");
lvl--;
}
+ timecode_startA = timecode_endA;
// Write the Video Manager