[matroska] r994 - trunk/DvdMenuXtractor
[email protected] Sun, 2 Jan 2005 22:15:26 +0300 (MSK)
Newsgroups
gmane.comp.multimedia.matroska.cvs
Message-ID
<[email protected] >
Author: robux4
Date: 2005-01-02 22:15:25 +0300 (Sun, 02 Jan 2005)
New Revision: 994
Modified:
trunk/DvdMenuXtractor/DvdMenuXtractor.cpp
trunk/DvdMenuXtractor/IFOFile.cpp
trunk/DvdMenuXtractor/IFOFile.h
trunk/DvdMenuXtractor/README.txt
trunk/DvdMenuXtractor/VobParser.cpp
trunk/DvdMenuXtractor/VobParser.h
Log:
DMX: support finite still frames and infinite ones are almost done
Modified: trunk/DvdMenuXtractor/DvdMenuXtractor.cpp
===================================================================
--- trunk/DvdMenuXtractor/DvdMenuXtractor.cpp 2005-01-01 17:37:10 UTC (rev 993)
+++ trunk/DvdMenuXtractor/DvdMenuXtractor.cpp 2005-01-02 19:15:25 UTC (rev 994)
@@ -1009,6 +1009,12 @@
XmlFile.AddLine(IndentString(lvl)+wxString::Format("<!-- Program %sCell CN#%d (%d angles) -->",(cell_num==entry_cell_num)?"Entry ":"", cell_num, cell_num - entry_cell_num + 1));
else
XmlFile.AddLine(IndentString(lvl)+wxString::Format("<!-- Program %sCell CN#%d -->",(cell_num==entry_cell_num)?"Entry ":"", cell_num));
+
+ if (cell.still_time == 0xFF)
+ XmlFile.AddLine(IndentString(lvl)+"<!-- Infinite loop Still Cell -->");
+ else if (cell.still_time != 0)
+ XmlFile.AddLine(IndentString(lvl)+wxString::Format("<!-- Still cell (%ds) -->", cell.still_time));
+
XmlFile.AddLine(IndentString(lvl)+"<ChapterAtom>");
lvl++;
wxString _myUID = CreateUID();
@@ -1023,7 +1029,7 @@
//_TODO_: handle the vobID/cellID to determine the real timecode of the cells !
// -> no, done when extracting the content streams, using the same timecode base
- end_time = st_time + DvdTimecodeToNano(cell.playback_time);
+ end_time = st_time + DvdTimecodeToNano(cell.playback_time, cell.still_time);
DisplayTime(lvl, XmlFile, st_time, end_time);
st_time = end_time;
lvl--;
@@ -1102,42 +1108,50 @@
}
XmlFile.AddLine(IndentString(lvl)+"<!-- Program PGN#"+wxString::Format("%d",i+1)+" in this PGC -->");
- st_time = OutputProgram(lvl, XmlFile, pgc, i, st_time);
+ st_time += OutputProgram(lvl, XmlFile, pgc, i, st_time);
}
// PGC start/end times
DisplayTime(lvl, XmlFile, start_time, st_time);
lvl--;
XmlFile.AddLine(IndentString(lvl)+"</ChapterAtom>");
- return start_time + DvdTimecodeToNano(pgc->playback_time);
+ return st_time;
}
// Macro to convert Binary Coded Decimal to Decimal
#define BCD2D(__x__) (((__x__ & 0xf0) >> 4) * 10 + (__x__ & 0x0f))
- uint64_t DvdTimecodeToNano(const dvd_time_t & dtime)
+ uint64_t DvdTimecodeToNano(const dvd_time_t & dtime, uint8_t still_time)
{
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;
+ if (still_time == 0 || still_time == 0xFF)
+ {
+ 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;
- double fps;
- switch((dtime.frame_u & 0xc0) >> 6)
+ double 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);
+ }
+ else
{
- case 1:
- fps = 25.0;
- break;
- case 3:
- fps = 29.97;
- break;
- default:
- fps = 2500.0;
- assert(0);
- break;
+ nano_duration = still_time;
+ nano_duration *= 1000000000.0;
}
- double _ms = BCD2D(dtime.frame_u&0x3f) * 1000.0 / fps;
- nano_duration += uint64_t(_ms * 1000000.0);
return nano_duration;
}
@@ -1291,7 +1305,7 @@
// Write the Video Title Set
for (int title=1; title <= IfoFile->NumberOfTitles(); title++)
{
- timecode_startA = timecode_endA;
+ timecode_startA = 0; // each separate DVD domain has its own standalone segment
// VTS Menu
if (IfoFile->LanguageUnits(title) && IfoFile->LanguageUnits(title)->nr_of_lus)
@@ -1332,7 +1346,7 @@
XmlFile.Write();
}
- timecode_startA = timecode_endA;
+ timecode_startA = 0; // each separate DVD domain has its own standalone segment
// VTS content
wxString Filename = pConfig->Read(OutputDirSaved,"") + wxString::Format("VTS%02d_menu.xml", title);
Modified: trunk/DvdMenuXtractor/IFOFile.cpp
===================================================================
--- trunk/DvdMenuXtractor/IFOFile.cpp 2005-01-01 17:37:10 UTC (rev 993)
+++ trunk/DvdMenuXtractor/IFOFile.cpp 2005-01-02 19:15:25 UTC (rev 994)
@@ -237,10 +237,11 @@
cle->isStill = (srp.pgc->cell_playback[k].still_time > 0);
if (cle->isStill)
{
- if (srp.pgc->cell_playback[k].still_time == 0xFF)
+ myfprintf(stdout, "Still cell (%d.%d) detected. Assuming there is just one frame.", vob_id, cell_id);
+ if (srp.pgc->cell_playback[k].still_time == 0xFF) {
myfprintf(stderr, "Cell %d.%d with still infinite duration !", vob_id, cell_id);
- else {
- myfprintf(stderr, "Cell %d.%d is still %d s (%d frames of %.1f ms)", vob_id, cell_id, srp.pgc->cell_playback[k].still_time, cle->nb_frames, cle->frame_dur);
+ } else {
+ cle->nb_frames = 1; // maybe not true ?
cle->frame_dur = srp.pgc->cell_playback[k].still_time * 1000.0 / cle->nb_frames;
}
}
Modified: trunk/DvdMenuXtractor/IFOFile.h
===================================================================
--- trunk/DvdMenuXtractor/IFOFile.h 2005-01-01 17:37:10 UTC (rev 993)
+++ trunk/DvdMenuXtractor/IFOFile.h 2005-01-02 19:15:25 UTC (rev 994)
@@ -6,6 +6,7 @@
#include "wx/wx.h"
#include "dvdread/ifo_read.h"
+#include "VobParser.h"
// ----------------------------------------------------------------------------
@@ -15,18 +16,6 @@
// ----------------------------------------------------------------------------
-typedef struct
-{
- unsigned int vobid;
- unsigned int cellid;
- unsigned int start_frame;
- unsigned int end_frame;
- unsigned int nb_frames;
- unsigned int first_sector; // sector in vob
- double frame_dur;
- bool isStill;
- //ButtonsListType btt_list;
-} CellListElem;
WX_DECLARE_LIST(CellListElem, CellsListType);
WX_DECLARE_LIST(audio_attr_t, AudioTrackList);
Modified: trunk/DvdMenuXtractor/README.txt
===================================================================
--- trunk/DvdMenuXtractor/README.txt 2005-01-01 17:37:10 UTC (rev 993)
+++ trunk/DvdMenuXtractor/README.txt 2005-01-02 19:15:25 UTC (rev 994)
@@ -2,7 +2,8 @@
* The duration of still frames is not handled yet (only lasts as normal frames)
TODO :
-* fix long frame times in produced M2V files
+* support infinite still frames in the chapter XML file
+* detect when a file was empty and therefore not written
* make use of the cancel buttons
* store the palette for subs
* generate the d2v file ?
Modified: trunk/DvdMenuXtractor/VobParser.cpp
===================================================================
--- trunk/DvdMenuXtractor/VobParser.cpp 2005-01-01 17:37:10 UTC (rev 993)
+++ trunk/DvdMenuXtractor/VobParser.cpp 2005-01-02 19:15:25 UTC (rev 994)
@@ -104,13 +104,13 @@
}
}
-void CompositeDemuxWriter::SetBoundary(uint32_t start_timecode, uint32_t duration, uint16_t vob_id, uint16_t cell_id)
+void CompositeDemuxWriter::SetBoundary(uint32_t start_timecode, uint32_t duration, const CellListElem *cell)
{
for (int i=0; i<256; i++)
{
if (m_muxers[i] != NULL)
{
- m_muxers[i]->SetBoundary(start_timecode, duration, vob_id, cell_id);
+ m_muxers[i]->SetBoundary(start_timecode, duration, cell);
}
}
}
@@ -246,7 +246,7 @@
{
if (m_dsi.nv_pck_scr == 0)
m_pci_vob_timecode_offset = m_pci.vobu_s_ptm / 90;
- m_demuxer.SetBoundary(m_pci.vobu_s_ptm/90 - m_pci_vob_timecode_offset, cell->nb_frames * cell->frame_dur, cell->vobid, cell->cellid);
+ m_demuxer.SetBoundary(m_pci.vobu_s_ptm/90 - m_pci_vob_timecode_offset, cell->nb_frames * cell->frame_dur, cell);
}
}
if (m_pci.btn_ns != 0)
@@ -916,21 +916,29 @@
// ============================================================================
-void VideoDemuxWriter::SetBoundary(uint32_t start_timecode, uint32_t duration, uint16_t vob_id, uint16_t cell_id)
+void VideoDemuxWriter::SetBoundary(uint32_t start_timecode, uint32_t duration, const CellListElem *cell)
{
m_TimecodeFile = GetTimecodeFile();
if (m_end_timecode != 0)
- fprintf(m_TimecodeFile, "%lf\n", (m_end_timecode - m_start_timecode) / 1000.0);
+ {
+ if (m_is_still) {
+ fwrite(" (Still)\n", 1, 9, m_TimecodeFile);
+ fprintf(m_TimecodeFile, "%lf,%lf\n", (m_end_timecode - m_start_timecode) / 1000.0, 1000.0 / (m_end_timecode - m_start_timecode));
+ }
+ else
+ fprintf(m_TimecodeFile, "\n%lf\n", (m_end_timecode - m_start_timecode) / 1000.0);
+ }
m_start_timecode = start_timecode;
m_end_timecode = start_timecode + duration;
m_last_end_timecode = start_timecode;
+ m_is_still = cell->isStill;
- fprintf(m_TimecodeFile, "\n# VOB %d Cell %d\n", vob_id, cell_id);
+ fprintf(m_TimecodeFile, "\n# VOB %d Cell %d", cell->vobid, cell->cellid);
}
-void AC3DemuxWriter::SetBoundary(uint32_t start_timecode, uint32_t duration, uint16_t vob_id, uint16_t cell_id)
+void AC3DemuxWriter::SetBoundary(uint32_t start_timecode, uint32_t duration, const CellListElem *cell)
{
m_TimecodeFile = GetTimecodeFile();
@@ -952,10 +960,10 @@
m_last_end_timecode = start_timecode;
m_last_start_timecode = start_timecode;
- fprintf(m_TimecodeFile, "\n# VOB %d Cell %d\n", vob_id, cell_id);
+ fprintf(m_TimecodeFile, "\n# VOB %d Cell %d\n", cell->vobid, cell->cellid);
}
-void DTSDemuxWriter::SetBoundary(uint32_t start_timecode, uint32_t duration, uint16_t vob_id, uint16_t cell_id)
+void DTSDemuxWriter::SetBoundary(uint32_t start_timecode, uint32_t duration, const CellListElem *cell)
{
m_TimecodeFile = GetTimecodeFile();
@@ -977,10 +985,10 @@
m_last_end_timecode = start_timecode;
m_last_start_timecode = start_timecode;
- fprintf(m_TimecodeFile, "\n# VOB %d Cell %d\n", vob_id, cell_id);
+ fprintf(m_TimecodeFile, "\n# VOB %d Cell %d\n", cell->vobid, cell->cellid);
}
-void LPCMDemuxWriter::SetBoundary(uint32_t start_timecode, uint32_t duration, uint16_t vob_id, uint16_t cell_id)
+void LPCMDemuxWriter::SetBoundary(uint32_t start_timecode, uint32_t duration, const CellListElem *cell)
{
m_TimecodeFile = GetTimecodeFile();
@@ -1002,21 +1010,21 @@
m_last_end_timecode = start_timecode;
m_last_start_timecode = start_timecode;
- fprintf(m_TimecodeFile, "\n# VOB %d Cell %d\n", vob_id, cell_id);
+ fprintf(m_TimecodeFile, "\n# VOB %d Cell %d\n", cell->vobid, cell->cellid);
}
-void MPADemuxWriter::SetBoundary(uint32_t start_timecode, uint32_t duration, uint16_t vob_id, uint16_t cell_id)
+void MPADemuxWriter::SetBoundary(uint32_t start_timecode, uint32_t duration, const CellListElem *cell)
{
}
-void SubDemuxWriter::SetBoundary(uint32_t start_timecode, uint32_t duration, uint16_t vob_id, uint16_t cell_id)
+void SubDemuxWriter::SetBoundary(uint32_t start_timecode, uint32_t duration, const CellListElem *cell)
{
if (start_timecode == 0)
m_start_timecode = m_end_timecode;
m_end_timecode += duration;
}
-void BtnDemuxWriter::SetBoundary(uint32_t start_timecode, uint32_t duration, uint16_t vob_id, uint16_t cell_id)
+void BtnDemuxWriter::SetBoundary(uint32_t start_timecode, uint32_t duration, const CellListElem *cell)
{
m_TimecodeFile = GetTimecodeFile();
@@ -1038,7 +1046,7 @@
m_last_end_timecode = start_timecode;
m_last_start_timecode = start_timecode;
- fprintf(m_TimecodeFile, "\n# VOB %d Cell %d\n", vob_id, cell_id);
+ fprintf(m_TimecodeFile, "\n# VOB %d Cell %d\n", cell->vobid, cell->cellid);
}
VideoDemuxWriter::~VideoDemuxWriter()
@@ -1046,7 +1054,13 @@
m_TimecodeFile = GetTimecodeFile();
if (m_end_timecode != 0)
- fprintf(m_TimecodeFile, "%lf\n", (m_end_timecode - m_start_timecode) / 1000.0);
+ {
+ if (m_is_still) {
+ fwrite(" (Still)\n", 1, 9, m_TimecodeFile);
+ fprintf(m_TimecodeFile, "%lf,%lf\n", (m_end_timecode - m_start_timecode) / 1000.0, 1000.0 / (m_end_timecode - m_start_timecode));
+ } else
+ fprintf(m_TimecodeFile, "\n%lf\n", (m_end_timecode - m_start_timecode) / 1000.0);
+ }
}
AC3DemuxWriter::~AC3DemuxWriter()
Modified: trunk/DvdMenuXtractor/VobParser.h
===================================================================
--- trunk/DvdMenuXtractor/VobParser.h 2005-01-01 17:37:10 UTC (rev 993)
+++ trunk/DvdMenuXtractor/VobParser.h 2005-01-02 19:15:25 UTC (rev 994)
@@ -48,6 +48,19 @@
// Type
// ============================================================================
+typedef struct
+{
+ unsigned int vobid;
+ unsigned int cellid;
+ unsigned int start_frame;
+ unsigned int end_frame;
+ unsigned int nb_frames;
+ unsigned int first_sector; // sector in vob
+ double frame_dur;
+ bool isStill;
+ //ButtonsListType btt_list;
+} CellListElem;
+
typedef struct {
uint16_t start_x; // Starting X position
uint16_t start_y; // Starting Y position
@@ -177,7 +190,7 @@
public:
virtual ~Demuxer() {}
virtual void ProcessStream(uint8_t* buff, uint32_t size, uint32_t start_time, uint32_t end_time, wxString & debug) = 0;
- virtual void SetBoundary(uint32_t start_timecode, uint32_t duration, uint16_t vob_id, uint16_t cell_id) = 0;
+ virtual void SetBoundary(uint32_t start_timecode, uint32_t duration, const CellListElem *cell) = 0;
};
// ----------------------------------------------------------------------------
@@ -257,9 +270,10 @@
,m_end_timecode(0)
,m_last_start_timecode(0)
,m_last_end_timecode(0)
+ ,m_is_still(false)
{}
void ProcessStream(uint8_t* buff, uint32_t size, uint32_t start_time, uint32_t end_time, wxString & debug) { Write(buff, size, start_time, end_time, debug); }
- void SetBoundary(uint32_t start_timecode, uint32_t duration, uint16_t vob_id, uint16_t cell_id);
+ void SetBoundary(uint32_t start_timecode, uint32_t duration, const CellListElem *cell);
~VideoDemuxWriter();
protected:
void WriteTimecodeInfo(uint32_t start_time, uint32_t end_time, uint64_t filepos, wxString & debug);
@@ -267,6 +281,7 @@
uint32_t m_end_timecode;
uint32_t m_last_start_timecode;
uint32_t m_last_end_timecode;
+ bool m_is_still;
};
// ----------------------------------------------------------------------------
@@ -286,7 +301,7 @@
{
Write(buff,size, start_time, end_time, debug);
}
- void SetBoundary(uint32_t start_timecode, uint32_t duration, uint16_t vob_id, uint16_t cell_id);
+ void SetBoundary(uint32_t start_timecode, uint32_t duration, const CellListElem *cell);
private:
uint8_t m_streamID;
protected:
@@ -314,7 +329,7 @@
{
Write(buff,size, start_time, end_time, debug);
}
- void SetBoundary(uint32_t start_timecode, uint32_t duration, uint16_t vob_id, uint16_t cell_id);
+ void SetBoundary(uint32_t start_timecode, uint32_t duration, const CellListElem *cell);
private:
uint8_t m_streamID;
protected:
@@ -359,7 +374,7 @@
{
Write(buff,size, start_time, end_time, debug);
}
- void SetBoundary(uint32_t start_timecode, uint32_t duration, uint16_t vob_id, uint16_t cell_id);
+ void SetBoundary(uint32_t start_timecode, uint32_t duration, const CellListElem *cell);
private:
uint8_t m_streamID;
protected:
@@ -381,7 +396,7 @@
{
Write(buff,size, start_time, end_time, debug);
}
- void SetBoundary(uint32_t start_timecode, uint32_t duration, uint16_t vob_id, uint16_t cell_id);
+ void SetBoundary(uint32_t start_timecode, uint32_t duration, const CellListElem *cell);
private:
uint8_t m_streamID;
protected:
@@ -407,7 +422,7 @@
{
Write(buff,size, start_time, end_time, debug);
}
- void SetBoundary(uint32_t start_timecode, uint32_t duration, uint16_t vob_id, uint16_t cell_id);
+ void SetBoundary(uint32_t start_timecode, uint32_t duration, const CellListElem *cell);
protected:
void WriteTimecodeInfo(uint32_t start_time, uint32_t end_time, uint64_t filepos, wxString & debug);
private:
@@ -454,7 +469,7 @@
}
Write(buff,size, start_time, end_time, debug);
}
- void SetBoundary(uint32_t start_timecode, uint32_t duration, uint16_t vob_id, uint16_t cell_id);
+ void SetBoundary(uint32_t start_timecode, uint32_t duration, const CellListElem *cell);
~BtnDemuxWriter();
protected:
void WriteTimecodeInfo(uint32_t start_time, uint32_t end_time, uint64_t filepos, wxString & debug);
@@ -475,7 +490,7 @@
bool AddDemuxer(uint8_t streamID, Demuxer * demuxer);
void ProcessStream(uint8_t streamID, uint8_t* buff, uint32_t size, int32_t start_time, int32_t end_time, wxString & debug);
void Reset();
- void SetBoundary(uint32_t start_timecode, uint32_t duration, uint16_t vob_id, uint16_t cell_id);
+ void SetBoundary(uint32_t start_timecode, uint32_t duration, const CellListElem *cell);
protected:
Demuxer * m_muxers[256];