[matroska] r1018 - trunk/DvdMenuXtractor

[email protected]
Newsgroups gmane.comp.multimedia.matroska.cvs
Message-ID <[email protected]>
Author: robux4
Date: 2005-01-07 01:28:25 +0300 (Fri, 07 Jan 2005)
New Revision: 1018

Modified:
   trunk/DvdMenuXtractor/DvdMenuXtractor.cpp
   trunk/DvdMenuXtractor/IFOFile.cpp
   trunk/DvdMenuXtractor/IFOFile.h
   trunk/DvdMenuXtractor/VobParser.h
Log:
DMX: part 1 of the cell mapping rewriting

Modified: trunk/DvdMenuXtractor/DvdMenuXtractor.cpp
===================================================================
--- trunk/DvdMenuXtractor/DvdMenuXtractor.cpp	2005-01-06 19:23:10 UTC (rev 1017)
+++ trunk/DvdMenuXtractor/DvdMenuXtractor.cpp	2005-01-06 22:28:25 UTC (rev 1018)
@@ -862,12 +862,12 @@
 		return result;
 	}
 
-	uint64_t OutputProgram(int lvl, wxTextFile & XmlFile, const pgc_t * pgc, int program_number, uint64_t start_time)
+	uint64_t OutputProgram(int lvl, wxTextFile & XmlFile, const pgc_t * pgc, int program_number, const CellsListType & cell_list)
 	{
 		static unsigned char _PrivatePG[] = {0x10, 0x00, 0x00};
 		static unsigned char _PrivateCN[] = {0x08, 0x00, 0x00, 0x00, 0x00};
 		
-		uint64_t st_time = start_time, end_time;
+		uint64_t end_time = 0;
 
 		XmlFile.AddLine(IndentString(lvl)+"<ChapterAtom>");
 		lvl++;
@@ -894,6 +894,10 @@
 			if (cell.block_mode != 0 && cell.block_mode != 3)
 				continue;
 
+			const CellListElem * cell_elt = cell_list.Get(position);
+			if (cell_elt == NULL)
+				continue;
+
 			if (cell.block_mode) // multi-angle
 				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
@@ -931,21 +935,21 @@
 				_PrivateCN[4] = cell_num - entry_cell_num + 1; // Number of angles
 				OutputCodecPrivate(lvl, XmlFile, encodebase64(_PrivateCN,5));
 
-				end_time = st_time + DvdTimecodeToNano(cell.playback_time, cell.still_time);
-				DisplayTime(lvl, XmlFile, st_time, end_time);
-				st_time = end_time;
+				DisplayTime(lvl, XmlFile, cell_elt->start_time, cell_elt->start_time + cell_elt->duration);
+				if (end_time < cell_elt->start_time + cell_elt->duration)
+					end_time = cell_elt->start_time + cell_elt->duration;
 				lvl--;
 			XmlFile.AddLine(IndentString(lvl)+"</ChapterAtom>");
 		}
 		
 		// PGC start/end times
-		DisplayTime(lvl, XmlFile, start_time, end_time);
+//		DisplayTime(lvl, XmlFile, start_time, end_time);
 		lvl--;
 		XmlFile.AddLine(IndentString(lvl)+"</ChapterAtom>");
 		return end_time;
 	}
 	
-	uint64_t OutputPGC(int lvl, wxTextFile & XmlFile, const pgc_t * pgc, uint64_t start_time, uint16_t pgc_num, unsigned char pgc_type, const ttu_t * ptts)
+	uint64_t OutputPGC(int lvl, wxTextFile & XmlFile, const pgc_t * pgc, uint64_t start_time, uint16_t pgc_num, unsigned char pgc_type, const CellsListType & cell_list, const ttu_t * ptts)
 	{
 		static unsigned char _PrivatePGC[] = {0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00};
 		static unsigned char _PrivatePTT[] = {0x18, 0x00, 0x00};
@@ -1014,11 +1018,11 @@
 			}
 
 			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, cell_list);
 		}
 	
 		// PGC start/end times
-		DisplayTime(lvl, XmlFile, start_time, st_time);
+//		DisplayTime(lvl, XmlFile, start_time, st_time);
 		lvl--;
 		XmlFile.AddLine(IndentString(lvl)+"</ChapterAtom>");
 		return st_time;
@@ -1116,7 +1120,7 @@
 					for (int j=0; j<_LU.pgcit->nr_of_pgci_srp; j++)
 					{
 						const pgci_srp_t &_PGC_SRP = _LU.pgcit->pgci_srp[j];
-						timecode_endB = OutputPGC(lvl, XmlFile, _PGC_SRP.pgc, timecode_endB, j, _PGC_SRP.entry_id, NULL);
+						timecode_endB = OutputPGC(lvl, XmlFile, _PGC_SRP.pgc, timecode_endB, j, _PGC_SRP.entry_id, _ifo.CellsList(title, true), NULL);
 					}
 				}
 				DisplayTime(lvl, XmlFile, timecode_startB, timecode_endB);
@@ -1318,7 +1322,7 @@
 									if ((IfoFile->VtsPGCs(title)->pgci_srp[k].entry_id & 0x7F) == i+1)
 									{
 											timecode_startC = OutputPGC(lvl, XmlFile, 
-												IfoFile->VtsPGCs(title)->pgci_srp[k].pgc, timecode_startC, k, 0, &IfoFile->VtsTitles(title)->title[i]);
+												IfoFile->VtsPGCs(title)->pgci_srp[k].pgc, timecode_startC, k, 0, IfoFile->CellsList(title, false), &IfoFile->VtsTitles(title)->title[i]);
 									}
 								}
 								timecode_endB = timecode_startC;

Modified: trunk/DvdMenuXtractor/IFOFile.cpp
===================================================================
--- trunk/DvdMenuXtractor/IFOFile.cpp	2005-01-06 19:23:10 UTC (rev 1017)
+++ trunk/DvdMenuXtractor/IFOFile.cpp	2005-01-06 22:28:25 UTC (rev 1018)
@@ -9,7 +9,7 @@
 #include "wx/listimpl.cpp"
 #include <wx/arrimpl.cpp>
 
-WX_DEFINE_LIST(CellsListType);
+WX_DEFINE_LIST(_CellsListType);
 WX_DEFINE_LIST(IfoHandles);
 WX_DEFINE_OBJARRAY(IdArray);
 
@@ -89,7 +89,6 @@
 	{
 		DVDClose(m_dvd);
 	}
-	m_cellsList.DeleteContents(true);
 }
 
 // ----------------------------------------------------------------------------
@@ -211,7 +210,7 @@
 }
 
 // ----------------------------------------------------------------------------
-void IFOFile::GetPGCCells(const pgcit_t & pgcit, CellsHashType * CellsHash)
+void IfoContent::GetPGCCells(const pgcit_t & pgcit, const c_adt_t & adt, CellsHashType * CellsHash)
 {
 	CellListElem* cle;
 
@@ -225,25 +224,38 @@
 
 			if (CellsHash->find(MAKE_CELLS_KEY(vob_id, cell_id)) == CellsHash->end())
 			{
-				cle = new CellListElem();
-				(*CellsHash)[MAKE_CELLS_KEY(vob_id, cell_id)] = cle;
+				size_t cell_nr = adt.last_byte;
+				cell_nr -= 7;
+				cell_nr /= sizeof(cell_adr_t);
+				for (size_t l=0; l < cell_nr; l++)
+				{
+					if (adt.cell_adr_table[l].vob_id == vob_id && adt.cell_adr_table[l].cell_id == cell_id)
+					{
+						cle = new CellListElem();
+						(*CellsHash)[MAKE_CELLS_KEY(vob_id, cell_id)] = cle;
 
-				cle->vobid = vob_id;
-				cle->cellid = cell_id;
+						cle->vobid = vob_id;
+						cle->cellid = cell_id;
 
-				cle->nb_frames = dvdtime2frame(&srp.pgc->cell_playback[k].playback_time, cle->frame_dur);
-				cle->isStill = (srp.pgc->cell_playback[k].still_time > 0);
-				if (cle->isStill)
-				{
-					wxLogWarning("Still cell (%d.%d) detected. Assuming there is just one frame.", vob_id, cell_id);
-					if (srp.pgc->cell_playback[k].still_time == 0xFF) {
-						wxLogWarning("Cell %d.%d with still infinite duration !", vob_id, cell_id);
-					} else {
-						cle->nb_frames = 1; // maybe not true ?
-						cle->frame_dur = srp.pgc->cell_playback[k].still_time * 1000.0 / cle->nb_frames;
+						cle->start_sector = adt.cell_adr_table[l].start_sector;
+						cle->last_sector = adt.cell_adr_table[l].last_sector;
+						cle->selected = true; // all cells selected for the moment
+
+						cle->nb_frames = dvdtime2frame(&srp.pgc->cell_playback[k].playback_time, cle->frame_dur);
+						cle->isStill = (srp.pgc->cell_playback[k].still_time > 0);
+						if (cle->isStill)
+						{
+							wxLogWarning("Still cell (%d.%d) detected. Assuming there is just one frame.", vob_id, cell_id);
+							if (srp.pgc->cell_playback[k].still_time == 0xFF) {
+								wxLogWarning("Cell %d.%d with still infinite duration !", vob_id, cell_id);
+							} else {
+								cle->nb_frames = 1; // maybe not true ?
+								cle->frame_dur = srp.pgc->cell_playback[k].still_time * 1000.0 / cle->nb_frames;
+							}
+						}
+						break;
 					}
 				}
-				cle->first_sector = srp.pgc->cell_playback[k].first_sector;
 			}
 		}
 	}
@@ -260,40 +272,16 @@
 		return NULL;
 
 	ifo_handle_t &_ifo = ifoc->Handle(); 
+	// _todo_
 	
 	if (language)
 	{
-		if (_ifo.pgci_ut)
-		{
-			for(int i = 0; i < _ifo.pgci_ut->nr_of_lus; i++)
-			{
-				pgci_lu_t& lu = _ifo.pgci_ut->lu[i];
-				GetPGCCells(*lu.pgcit, &CellsHash);
-			}
-		}
+		return NULL;
 	}
 	else
 	{
-		// handle non-language unit cells
-		if (_ifo.vts_pgcit)
-		{
-			GetPGCCells(*_ifo.vts_pgcit, &CellsHash);
-		}
+		return NULL;
 	}
-
-	// Transfer hash map to the list to be sorted
-	m_cellsList.DeleteContents(TRUE);
-	m_cellsList.Clear();
-    CellsHashType::iterator it;
-    for( it = CellsHash.begin(); it != CellsHash.end(); ++it )
-    {
-		m_cellsList.Append(it->second);
-    }
-	CellsHash.clear();
-
-	m_cellsList.Sort(CellListElemCompare);
-	
-	return &m_cellsList;
 }
 
 // ----------------------------------------------------------------------------
@@ -303,7 +291,9 @@
 	CellsListType::Node *node;
 	CellListElem* cle;
 
-	node = m_cellsList.GetFirst();
+	return NULL; // _todo_
+#if 0
+	node = m_CellsList.GetFirst();
 
 	while(node)
 	{
@@ -315,6 +305,7 @@
 		node = node->GetNext();
 	}
 	return NULL;
+#endif
 }
 
 // ----------------------------------------------------------------------------
@@ -343,6 +334,18 @@
 		return _ifo->m_Subs;
 }
 
+const CellsListType & IFOFile::CellsList(unsigned int title, bool language) const
+{
+	IfoContent *_ifo = m_ifos.GetIfoTitle(title);
+	if (!_ifo)
+		throw;
+
+	if (language)
+		return _ifo->m_langCellsList;
+	else
+		return _ifo->m_CellsList;
+}
+
 bool IFOFile::VideoSize(unsigned int title, bool language, uint16_t & width, uint16_t & height, double & fps) const
 {
 	IfoContent *_ifo = m_ifos.GetIfoTitle(title);
@@ -445,6 +448,8 @@
 	if (!m_handle)
 		throw IFOInvalidFileFormatException();
 
+	CellsHashType CellsHash;
+
 	if (title == 0)
 	{
 		if (m_handle->vmgi_mat)
@@ -457,11 +462,27 @@
 		}
 
 		// _todo_ handle the list of menu cells with their ID and sectors
-		if (m_handle->menu_c_adt)
+		CellsHash.clear();
+		if (m_handle->pgci_ut && m_handle->menu_c_adt)
 		{
 			// add each cell in a list
 			// order this list according to vob ID, cell ID
 			// for each cell, find the duration (and start time) from all menu PGCs
+			for(int i = 0; i < m_handle->pgci_ut->nr_of_lus; i++)
+			{
+				pgci_lu_t& lu = m_handle->pgci_ut->lu[i];
+				GetPGCCells(*lu.pgcit, *m_handle->menu_c_adt, &CellsHash);
+			}
+
+			// Transfer hash map to the list to be sorted
+			m_langCellsList.Clear();
+			CellsHashType::iterator it;
+			for( it = CellsHash.begin(); it != CellsHash.end(); ++it )
+			{
+				m_langCellsList.Append(it->second);
+			}
+
+			m_langCellsList.Arrange();
 		}
 	}
 	else
@@ -481,20 +502,48 @@
 				m_Subs.push_back(&vtsi_mat.vts_subp_attr[_stream]);
 		}
 
-		// _todo_ handle the list of menu cells with their ID and sectors
-		if (m_handle->menu_c_adt)
+		// handle the list of menu cells with their ID and sectors
+		CellsHash.clear();
+		if (m_handle->pgci_ut && m_handle->menu_c_adt)
 		{
 			// add each cell in a list
 			// order this list according to vob ID, cell ID
 			// for each cell, find the duration (and start time) from all menu PGCs
+			for(int i = 0; i < m_handle->pgci_ut->nr_of_lus; i++)
+			{
+				pgci_lu_t& lu = m_handle->pgci_ut->lu[i];
+				GetPGCCells(*lu.pgcit, *m_handle->menu_c_adt, &CellsHash);
+			}
+
+			// Transfer hash map to the list to be sorted
+			m_langCellsList.Clear();
+			CellsHashType::iterator it;
+			for( it = CellsHash.begin(); it != CellsHash.end(); ++it )
+			{
+				m_langCellsList.Append(it->second);
+			}
+
+			m_langCellsList.Arrange();
 		}
 
-		// _todo_ handle the list of cells with their ID and sectors
-		if (m_handle->vts_c_adt)
+		// handle the list of cells with their ID and sectors
+		CellsHash.clear();
+		if (m_handle->vts_pgcit && m_handle->vts_c_adt)
 		{
 			// add each cell in a list
 			// order this list according to vob ID, cell ID
 			// for each cell, find the duration (and start time) from all PGCs
+			GetPGCCells(*m_handle->vts_pgcit, *m_handle->vts_c_adt, &CellsHash);
+
+			// Transfer hash map to the list to be sorted
+			m_CellsList.Clear();
+			CellsHashType::iterator it;
+			for( it = CellsHash.begin(); it != CellsHash.end(); ++it )
+			{
+				m_CellsList.Append(it->second);
+			}
+
+			m_CellsList.Arrange();
 		}
 	}
 }
@@ -596,3 +645,32 @@
 	return NULL;
 }
 
+const CellListElem * CellsListType::Get(const cell_position_t & position) const
+{
+	CellsListType::Node *node = GetFirst();
+	while (node)
+	{
+		CellListElem *cell = node->GetData();
+		if (cell->cellid == position.cell_nr && cell->vobid == position.vob_id_nr)
+			return cell;
+		node = node->GetNext();
+	}
+	return NULL;
+}
+
+void CellsListType::Arrange()
+{
+	Sort(CellListElemCompare);
+
+	// make the timecodes continuous
+	int64_t timecode = 0;
+	CellsListType::Node *node = GetFirst();
+	while (node)
+	{
+		CellListElem *cell = node->GetData();
+		cell->start_time = timecode;
+		cell->duration = int64_t(cell->frame_dur * cell->nb_frames * 1000000.0);
+		timecode += cell->duration;
+		node = node->GetNext();
+	}
+}
\ No newline at end of file

Modified: trunk/DvdMenuXtractor/IFOFile.h
===================================================================
--- trunk/DvdMenuXtractor/IFOFile.h	2005-01-06 19:23:10 UTC (rev 1017)
+++ trunk/DvdMenuXtractor/IFOFile.h	2005-01-06 22:28:25 UTC (rev 1018)
@@ -18,8 +18,17 @@
 
 // ----------------------------------------------------------------------------
 
-WX_DECLARE_LIST(CellListElem, CellsListType);
+class CellsHashType;
 
+WX_DECLARE_LIST(CellListElem, _CellsListType);
+
+class CellsListType : public _CellsListType
+{
+public:
+	const CellListElem * Get(const cell_position_t & position) const;
+	void Arrange();
+};
+
 typedef std::vector<const audio_attr_t*> AudioTrackList;
 typedef std::vector<const subp_attr_t*> SubtitleTrackList;
 WX_DECLARE_OBJARRAY(uint8_t, IdArray);
@@ -32,6 +41,8 @@
 	~IfoContent()
 	{
 		ifoClose(m_handle);
+		m_CellsList.DeleteContents(true);
+		m_langCellsList.DeleteContents(true);
 	}
 
 	ifo_handle_t & Handle()
@@ -42,12 +53,15 @@
 
 	uint8_t FindAudioStream(uint8_t streamID, bool language) const;
 	IdArray FindSubStream(uint8_t streamID, bool language) const;
+	void GetPGCCells(const pgcit_t & pgcit, const c_adt_t & adt, CellsHashType * CellsHash);
 
 	int16_t m_title;
 	AudioTrackList m_langAudio;
 	AudioTrackList m_Audio;
 	SubtitleTrackList m_langSubs;
 	SubtitleTrackList m_Subs;
+	CellsListType m_CellsList;
+	CellsListType m_langCellsList;
 
 protected:
 	ifo_handle_t *m_handle;
@@ -62,8 +76,6 @@
 	IfoContent * GetIfoTitle(int16_t title) const;
 };
 
-class CellsHashType;
-
 // ----------------------------------------------------------------------------
 
 class IFOFile  
@@ -83,20 +95,17 @@
 	const int16_t NumberOfTitles() const;
 	const AudioTrackList & AudioTracks(unsigned int title, bool language) const;
 	const SubtitleTrackList & SubsTracks(unsigned int title, bool language) const;
+	const CellsListType & CellsList(unsigned int title, bool language) const;
 	bool VideoSize(unsigned int title, bool language, uint16_t & width, uint16_t & height, double & fps) const;
 	const uint32_t * GetPalette(unsigned int title, bool language) const;
 
 	uint8_t GetAudioId(uint8_t streamID, uint8_t title, bool language) const;
 	IdArray GetSubsId(uint8_t streamID, uint8_t title, bool language) const;
 
-protected:
-	void GetPGCCells(const pgcit_t & pgc, CellsHashType * CellsHash);
-
 private:
 	IfoHandleList m_ifos;
 	dvd_reader_t* m_dvd;
 	wxArrayString m_languageList;
-	CellsListType m_cellsList;
 	char m_SelectionTab[8];
 };
 

Modified: trunk/DvdMenuXtractor/VobParser.h
===================================================================
--- trunk/DvdMenuXtractor/VobParser.h	2005-01-06 19:23:10 UTC (rev 1017)
+++ trunk/DvdMenuXtractor/VobParser.h	2005-01-06 22:28:25 UTC (rev 1018)
@@ -54,9 +54,13 @@
 	unsigned int start_frame;
 	unsigned int end_frame;
 	unsigned int nb_frames;
-	unsigned int first_sector; // sector in vob
+	uint32_t start_sector;
+	uint32_t last_sector;
 	double frame_dur;
+	int64_t start_time;
+	int64_t duration;
 	bool isStill;
+	bool selected;
 	//ButtonsListType btt_list;
 } CellListElem;
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.