[matroska] r994 - trunk/DvdMenuXtractor

[email protected]
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];
lmpx.com only provides a reader for public news (NNTP) servers. It is not affiliated with the servers or forums shown here and is not responsible for the content of articles, which is written by their respective authors.