[matroska] r959 - trunk/DvdMenuXtractor
[email protected] Sat, 11 Dec 2004 14:08:51 +0300 (MSK)
Newsgroups
gmane.comp.multimedia.matroska.cvs
Message-ID
<[email protected] >
Author: robux4
Date: 2004-12-11 14:08:50 +0300 (Sat, 11 Dec 2004)
New Revision: 959
Modified:
trunk/DvdMenuXtractor/DvdMenuXtractor.cpp
trunk/DvdMenuXtractor/VobParser.cpp
trunk/DvdMenuXtractor/VobParser.h
Log:
added support for extracting PCI packets containing buttons
preliminary support for general timecode files for each output
Modified: trunk/DvdMenuXtractor/DvdMenuXtractor.cpp
===================================================================
--- trunk/DvdMenuXtractor/DvdMenuXtractor.cpp 2004-11-30 15:45:16 UTC (rev 958)
+++ trunk/DvdMenuXtractor/DvdMenuXtractor.cpp 2004-12-11 11:08:50 UTC (rev 959)
@@ -5,7 +5,7 @@
#endif
#include "MyWizard.h"
-#include <time.h>
+#include <time.h>
#ifdef __BORLANDC__
#pragma hdrstop
@@ -21,10 +21,10 @@
#include <inttypes.h>
#include "IFOFile.h"
#include "VOBParser.h"
-#include "MPEG2Decoder.h"
-#include "A52Decoder.h"
-#include "SUBDecoder.h"
-#include "base64.h"
+#include "MPEG2Decoder.h"
+#include "A52Decoder.h"
+#include "SUBDecoder.h"
+#include "base64.h"
#include "iso/iso_lang.h"
// TODO : settings
@@ -62,14 +62,15 @@
// GLOBAL
// ----------------------------------------------------------------------------
-IFOFile* IfoFile = NULL;
+IFOFile* IfoFile = NULL;
wxLogWindow* wxLogWin;
wxString m2vDirectory;
wxString audioDirectory;
wxString subDirectory;
+wxString btnDirectory;
wxString bmpDirectory;
-//wxString wavDirectory;
-//wxString maskDirectory;
+//wxString wavDirectory;
+//wxString maskDirectory;
const wxString APPLICATION_NAME = "DVDMenu-X-tractor";
// ----------------------------------------------------------------------------
@@ -97,7 +98,7 @@
this->m_pageTitle = "Data menu extraction";
this->m_pageDesc = "Source files selection";
- srand( (unsigned)time( NULL ) );
+ srand( (unsigned)time( NULL ) );
wxFileConfig *pConfig = (wxFileConfig *)wxConfigBase::Get();
wxFlexGridSizer *fgs = new wxFlexGridSizer(4,3,0,0);
@@ -105,10 +106,10 @@
pConfig->SetPath("/Input");
// Input directory
- m_lbInDir = new wxStaticText(this,-1,"Input directory :",
+ m_lbInDir = new wxStaticText(this,-1,"Input directory :",
wxDefaultPosition,wxDefaultSize, DEFAULT_COMMON_STYLE);
- m_edInDir = new wxTextCtrl(this,-1,
- pConfig->Read("InDirectory",""), wxDefaultPosition,
+ m_edInDir = new wxTextCtrl(this,-1,
+ pConfig->Read("InDirectory",""), wxDefaultPosition,
wxDefaultSize, DEFAULT_COMMON_STYLE);
m_bttBrowseInDir = new wxButton(this, wxID_P1_BROWSE_IN_DIR, "...",
wxDefaultPosition, wxSize(24,24),DEFAULT_COMMON_STYLE);
@@ -117,10 +118,10 @@
fgs->Add(m_bttBrowseInDir,0,wxALL,5);
// Output directory
- m_lbOutDir = new wxStaticText(this,-1,"Output directory :",
+ m_lbOutDir = new wxStaticText(this,-1,"Output directory :",
wxDefaultPosition,wxDefaultSize, DEFAULT_COMMON_STYLE);
- m_edOutDir = new wxTextCtrl(this,-1,
- pConfig->Read("OutputDirectory",""), wxDefaultPosition,
+ m_edOutDir = new wxTextCtrl(this,-1,
+ pConfig->Read("OutputDirectory",""), wxDefaultPosition,
wxDefaultSize, DEFAULT_COMMON_STYLE);
m_bttBrowseOutDir = new wxButton(this, wxID_P1_BROWSE_OUT_DIR, "...",
wxDefaultPosition, wxSize(24,24),DEFAULT_COMMON_STYLE);
@@ -141,14 +142,14 @@
{
SaveSettings();
}
-
+
void OnBrowseOutputDirectory(wxCommandEvent& WXUNUSED(event))
{
- wxString defaultDir = m_edOutDir->GetValue();
- if (defaultDir.IsEmpty())
- {
- defaultDir = m_edInDir->GetValue();
- }
+ wxString defaultDir = m_edOutDir->GetValue();
+ if (defaultDir.IsEmpty())
+ {
+ defaultDir = m_edInDir->GetValue();
+ }
wxDirDialog dialog(this, "Select the output directory :", defaultDir,
wxDD_NEW_DIR_BUTTON);
if (dialog.ShowModal() == wxID_OK)
@@ -167,7 +168,7 @@
void OnBrowseInputDirectory(wxCommandEvent& WXUNUSED(event))
{
- wxString defaultDir = m_edInDir->GetValue();
+ wxString defaultDir = m_edInDir->GetValue();
wxDirDialog dialog(this, "Select the DVD input directory :", defaultDir,
wxDD_NEW_DIR_BUTTON);
if (dialog.ShowModal() == wxID_OK)
@@ -233,12 +234,12 @@
if(IfoFile != NULL)
{
delete IfoFile;
- }
+ }
try
- {
+ {
wxFileName _FileName(m_edInDir->GetValue());
- IfoFile = new IFOFile(_FileName.GetPath(wxPATH_GET_VOLUME));
+ IfoFile = new IFOFile(_FileName.GetPath(wxPATH_GET_VOLUME));
}
catch(IFOException&)
{
@@ -252,7 +253,7 @@
{
wxFileConfig *pConfig = (wxFileConfig *)wxConfigBase::Get();
pConfig->SetPath("/Input");
-
+
pConfig->Write("InDirectory", m_edInDir->GetValue());
pConfig->Write("OutputDirectory",m_edOutDir->GetValue());
}
@@ -510,36 +511,36 @@
this->SetAutoLayout(TRUE);
this->SetSizer(fgs);
fgs->Fit(this);
- fgs->SetSizeHints(this);
-
+ fgs->SetSizeHints(this);
+
m_OperationInProgress = FALSE;
- }
-
- ~wxMyWizardPage4()
- {}
-
-
- VobParser * BuildVobMap(int16_t title, bool language)
- {
- wxFileConfig *pConfig = (wxFileConfig *)wxConfigBase::Get();
-
- m_gaDemuxProgress->SetValue(0);
-
- VobParser * _VobParser = NULL;
- try {
+ }
+
+ ~wxMyWizardPage4()
+ {}
+
+
+ VobParser * BuildVobMap(int16_t title, bool language)
+ {
+ wxFileConfig *pConfig = (wxFileConfig *)wxConfigBase::Get();
+
+ m_gaDemuxProgress->SetValue(0);
+
+ VobParser * _VobParser = NULL;
+ try {
_VobParser = new VobParser(pConfig->Read("InDirectory","").c_str(), title, language);
} catch (...)
{
m_txtDemuxLog->AppendText(wxString::Format("no VOB files found in %s for Title %02d\n",pConfig->Read("InDirectory","").c_str(),title));
}
- return _VobParser;
+ return _VobParser;
}
- wxString CellName(int16_t title, int16_t vobid, int16_t cellid, bool language) const
- {
- return wxString::Format("cell_%sT%02d_V%03d_C%02d", language?"L_":"", title, vobid, cellid);
- }
-
+ wxString CellName(int16_t title, int16_t vobid, int16_t cellid, bool language) const
+ {
+ return wxString::Format("cell_%sT%02d_V%03d_C%02d", language?"L_":"", title, vobid, cellid);
+ }
+
void SplitAndDemux(VobParser & aVobParser, int16_t title, bool language)
{
wxString newFilename;
@@ -549,8 +550,8 @@
if (!CellsList)
return;
- aVobParser.Reset();
-
+ aVobParser.Reset();
+
try
{
m_gaDemuxProgress->SetRange(CellsList->GetCount());
@@ -571,8 +572,8 @@
if(IfoFile->IsACandidateCell(aVobParser.GetVobID(),aVobParser.GetCellID()))
{
demuxer.Reset();
- newFilename = CellName(title, aVobParser.GetVobID(), aVobParser.GetCellID(), language);
-
+ newFilename = CellName(title, aVobParser.GetVobID(), aVobParser.GetCellID(), language);
+
m_txtDemuxLog->AppendText("Processing " + newFilename + "\n");
Demuxer * _muxer = new VideoDemuxWriter(m2vDirectory+newFilename);
@@ -625,10 +626,10 @@
default:
myfprintf(stderr, "Unknown audio format %d", _attr->audio_format);
break;
- }
- }
- }
-
+ }
+ }
+ }
+
if (_subTracks.GetCount())
{
for (_stream=0; _stream<_subTracks.GetCount();_stream++)
@@ -644,14 +645,15 @@
_langName = wxString::Format("_%d_un", _IDs.Item(_IDidx));
else
_langName = wxString::Format("_%d_%c%c", _IDs.Item(_IDidx), _attr->lang_code >> 8, _attr->lang_code & 0xFF);
-// if(aVobParser.m_pci.btn_ns > 0)
- {
- _muxer = new SubDemuxWriter(subDirectory+newFilename+_langName, 0x20 + _IDs.Item(_IDidx), _width, _height, _palette, _attr->lang_code, _attr->lang_extension == 9);
- if (!demuxer.AddDemuxer(0x20 + _IDs.Item(_IDidx), _muxer))
- delete _muxer;
- }
+ _muxer = new SubDemuxWriter(subDirectory+newFilename+_langName, 0x20 + _IDs.Item(_IDidx), _width, _height, _palette, _attr->lang_code, _attr->lang_extension == 9);
+ if (!demuxer.AddDemuxer(0x20 + _IDs.Item(_IDidx), _muxer))
+ delete _muxer;
}
}
+ // create a possible button demuxer too
+ _muxer = new BtnDemuxWriter(btnDirectory+newFilename);
+ if (!demuxer.AddDemuxer(0x00, _muxer))
+ delete _muxer;
}
}
}
@@ -687,7 +689,7 @@
{
cle = node->GetData();
if(cle->isStill)
- {
+ {
FilenameBase = CellName(title, cle->vobid, cle->cellid, language);
m_txtDemuxLog->AppendText("Converting " + FilenameBase + ".m2v to "+FilenameBase+".bmp ...\n");
BMPWriter->SetFilename(bmpDirectory+FilenameBase+".bmp");
@@ -703,146 +705,146 @@
#if 0
void ConvertAudioToWAV(int16_t title, bool language)
- {
- wxString FilenameBase;
- CellListElem* cle;
- CellsListType::Node *node;
- const CellsListType *CellsList = IfoFile->GetCellsList(title, language);
- int i;
- wxFileConfig *pConfig = (wxFileConfig *)wxConfigBase::Get();
-
- if (!CellsList)
- return;
-
- m_gaDemuxProgress->SetValue(0);
- m_gaDemuxProgress->SetRange(CellsList->GetCount());
-
- WavfileA52DecWriter* WAVWriter = new WavfileA52DecWriter();
- A52Decoder* a52decoder = new A52Decoder(WAVWriter);
-
- for (i = 0, node = CellsList->GetFirst(); node != NULL; i++, node = node->GetNext() )
- {
- // TODO : check if audio exist
- cle = node->GetData();
- if(!cle->isStill)
- {
- FilenameBase = CellName(title, cle->vobid, cle->cellid, language);
- m_txtDemuxLog->AppendText("Converting " + FilenameBase + ".ac3 to "+FilenameBase+".wav ...\n");
- WAVWriter->SetFilename(wavDirectory+FilenameBase+".wav");
- a52decoder->ProcessFile(audioDirectory+FilenameBase+".ac3");
- wxYield();
- }
- m_gaDemuxProgress->SetValue(i);
- }
-
- delete WAVWriter;
+ {
+ wxString FilenameBase;
+ CellListElem* cle;
+ CellsListType::Node *node;
+ const CellsListType *CellsList = IfoFile->GetCellsList(title, language);
+ int i;
+ wxFileConfig *pConfig = (wxFileConfig *)wxConfigBase::Get();
+
+ if (!CellsList)
+ return;
+
+ m_gaDemuxProgress->SetValue(0);
+ m_gaDemuxProgress->SetRange(CellsList->GetCount());
+
+ WavfileA52DecWriter* WAVWriter = new WavfileA52DecWriter();
+ A52Decoder* a52decoder = new A52Decoder(WAVWriter);
+
+ for (i = 0, node = CellsList->GetFirst(); node != NULL; i++, node = node->GetNext() )
+ {
+ // TODO : check if audio exist
+ cle = node->GetData();
+ if(!cle->isStill)
+ {
+ FilenameBase = CellName(title, cle->vobid, cle->cellid, language);
+ m_txtDemuxLog->AppendText("Converting " + FilenameBase + ".ac3 to "+FilenameBase+".wav ...\n");
+ WAVWriter->SetFilename(wavDirectory+FilenameBase+".wav");
+ a52decoder->ProcessFile(audioDirectory+FilenameBase+".ac3");
+ wxYield();
+ }
+ m_gaDemuxProgress->SetValue(i);
+ }
+
+ delete WAVWriter;
delete a52decoder;
}
void ConvertButtonMaskToBMP(int16_t title, bool language)
{
- wxString FilenameBase;
- CellListElem* cle;
- CellsListType::Node *node;
- const CellsListType *CellsList = IfoFile->GetCellsList(title, language);
- int i;
- wxFileConfig *pConfig = (wxFileConfig *)wxConfigBase::Get();
-
- if (!CellsList)
- return;
-
- m_gaDemuxProgress->SetValue(0);
- m_gaDemuxProgress->SetRange(CellsList->GetCount());
-
- SUBDecOutput* BMPWriter = NULL;
- SUBDecoder* subdecoder = new SUBDecoder(NULL);
-
- for (i = 0, node = CellsList->GetFirst(); node != NULL; i++, node = node->GetNext() )
- {
- cle = node->GetData();
- // TODO : Select only cell with button
- FilenameBase = CellName(title, cle->vobid, cle->cellid, language);
- m_txtDemuxLog->AppendText("Converting " + FilenameBase + ".sub to "+FilenameBase+".bmp ...\n");
- //WAVWriter->SetFilename(wavDirectory+FilenameBase+".wav");
-
- subdecoder->ProcessFile(subDirectory+FilenameBase+".sub", maskDirectory+FilenameBase);
- wxYield();
- m_gaDemuxProgress->SetValue(i);
- }
-
- //delete BMPWriter;
+ wxString FilenameBase;
+ CellListElem* cle;
+ CellsListType::Node *node;
+ const CellsListType *CellsList = IfoFile->GetCellsList(title, language);
+ int i;
+ wxFileConfig *pConfig = (wxFileConfig *)wxConfigBase::Get();
+
+ if (!CellsList)
+ return;
+
+ m_gaDemuxProgress->SetValue(0);
+ m_gaDemuxProgress->SetRange(CellsList->GetCount());
+
+ SUBDecOutput* BMPWriter = NULL;
+ SUBDecoder* subdecoder = new SUBDecoder(NULL);
+
+ for (i = 0, node = CellsList->GetFirst(); node != NULL; i++, node = node->GetNext() )
+ {
+ cle = node->GetData();
+ // TODO : Select only cell with button
+ FilenameBase = CellName(title, cle->vobid, cle->cellid, language);
+ m_txtDemuxLog->AppendText("Converting " + FilenameBase + ".sub to "+FilenameBase+".bmp ...\n");
+ //WAVWriter->SetFilename(wavDirectory+FilenameBase+".wav");
+
+ subdecoder->ProcessFile(subDirectory+FilenameBase+".sub", maskDirectory+FilenameBase);
+ wxYield();
+ m_gaDemuxProgress->SetValue(i);
+ }
+
+ //delete BMPWriter;
delete subdecoder;
- }
+ }
#endif
-
- static wxString IndentString(int lvl)
- {
- wxString result = "";
-
- for(int i=0; i < lvl; i++)
- result += "\t";
-
- return result;
- }
-
- inline wxString CreateUID() const
- {
- return wxString::Format("%u", uint32_t(rand() | (rand() << 16)) );
- }
-
- void AddCommands(int lvl, wxTextFile & XmlFile, const pgc_command_tbl_t * command_tbl)
- {
- if (command_tbl)
- {
- unsigned char *_buf = (unsigned char*) malloc(1+command_tbl->nr_of_pre * 8);
-
- // Pre commands
- if (command_tbl->nr_of_pre)
- {
+
+ static wxString IndentString(int lvl)
+ {
+ wxString result = "";
+
+ for(int i=0; i < lvl; i++)
+ result += "\t";
+
+ return result;
+ }
+
+ inline wxString CreateUID() const
+ {
+ return wxString::Format("%u", uint32_t(rand() | (rand() << 16)) );
+ }
+
+ void AddCommands(int lvl, wxTextFile & XmlFile, const pgc_command_tbl_t * command_tbl)
+ {
+ if (command_tbl)
+ {
+ unsigned char *_buf = (unsigned char*) malloc(1+command_tbl->nr_of_pre * 8);
+
+ // Pre commands
+ if (command_tbl->nr_of_pre)
+ {
XmlFile.AddLine(IndentString(lvl)+"<!-- Pre commands -->");
- XmlFile.AddLine(IndentString(lvl)+"<ChapterProcess>");
- lvl++;
- XmlFile.AddLine(IndentString(lvl)+"<ChapterProcessTime>1</ChapterProcessTime>");
- _buf[0] = command_tbl->nr_of_pre;
- memcpy(&_buf[1], command_tbl->pre_cmds, command_tbl->nr_of_pre * 8);
- XmlFile.AddLine(IndentString(lvl)+"<ChapterProcessCommand>"+encodebase64(_buf,1+command_tbl->nr_of_pre * 8)+"</ChapterProcessCommand>");
- lvl--;
- XmlFile.AddLine(IndentString(lvl)+"</ChapterProcess>");
- }
-
- // Cell commands
- if (command_tbl->nr_of_cell)
- {
+ XmlFile.AddLine(IndentString(lvl)+"<ChapterProcess>");
+ lvl++;
+ XmlFile.AddLine(IndentString(lvl)+"<ChapterProcessTime>1</ChapterProcessTime>");
+ _buf[0] = command_tbl->nr_of_pre;
+ memcpy(&_buf[1], command_tbl->pre_cmds, command_tbl->nr_of_pre * 8);
+ XmlFile.AddLine(IndentString(lvl)+"<ChapterProcessCommand>"+encodebase64(_buf,1+command_tbl->nr_of_pre * 8)+"</ChapterProcessCommand>");
+ lvl--;
+ XmlFile.AddLine(IndentString(lvl)+"</ChapterProcess>");
+ }
+
+ // Cell commands
+ if (command_tbl->nr_of_cell)
+ {
XmlFile.AddLine(IndentString(lvl)+"<!-- Cell commands -->");
- XmlFile.AddLine(IndentString(lvl)+"<ChapterProcess>");
- lvl++;
- XmlFile.AddLine(IndentString(lvl)+"<ChapterProcessTime>0</ChapterProcessTime>");
- _buf = (unsigned char*) realloc(_buf, 1+command_tbl->nr_of_cell * 8);
- _buf[0] = command_tbl->nr_of_cell;
- memcpy(&_buf[1], command_tbl->cell_cmds, command_tbl->nr_of_cell * 8);
- XmlFile.AddLine(IndentString(lvl)+"<ChapterProcessCommand>"+encodebase64(_buf,1+command_tbl->nr_of_cell * 8)+"</ChapterProcessCommand>");
- lvl--;
- XmlFile.AddLine(IndentString(lvl)+"</ChapterProcess>");
- }
-
- // Post commands
- if (command_tbl->nr_of_post)
- {
+ XmlFile.AddLine(IndentString(lvl)+"<ChapterProcess>");
+ lvl++;
+ XmlFile.AddLine(IndentString(lvl)+"<ChapterProcessTime>0</ChapterProcessTime>");
+ _buf = (unsigned char*) realloc(_buf, 1+command_tbl->nr_of_cell * 8);
+ _buf[0] = command_tbl->nr_of_cell;
+ memcpy(&_buf[1], command_tbl->cell_cmds, command_tbl->nr_of_cell * 8);
+ XmlFile.AddLine(IndentString(lvl)+"<ChapterProcessCommand>"+encodebase64(_buf,1+command_tbl->nr_of_cell * 8)+"</ChapterProcessCommand>");
+ lvl--;
+ XmlFile.AddLine(IndentString(lvl)+"</ChapterProcess>");
+ }
+
+ // Post commands
+ if (command_tbl->nr_of_post)
+ {
XmlFile.AddLine(IndentString(lvl)+"<!-- Post commands -->");
- XmlFile.AddLine(IndentString(lvl)+"<ChapterProcess>");
- lvl++;
- XmlFile.AddLine(IndentString(lvl)+"<ChapterProcessTime>2</ChapterProcessTime>");
- _buf = (unsigned char*) realloc(_buf, 1+command_tbl->nr_of_post * 8);
- _buf[0] = command_tbl->nr_of_post;
- memcpy(&_buf[1], command_tbl->post_cmds, command_tbl->nr_of_post * 8);
- XmlFile.AddLine(IndentString(lvl)+"<ChapterProcessCommand>"+encodebase64(_buf,1+command_tbl->nr_of_post * 8)+"</ChapterProcessCommand>");
- lvl--;
- XmlFile.AddLine(IndentString(lvl)+"</ChapterProcess>");
- }
- free(_buf);
- }
- }
-
+ XmlFile.AddLine(IndentString(lvl)+"<ChapterProcess>");
+ lvl++;
+ XmlFile.AddLine(IndentString(lvl)+"<ChapterProcessTime>2</ChapterProcessTime>");
+ _buf = (unsigned char*) realloc(_buf, 1+command_tbl->nr_of_post * 8);
+ _buf[0] = command_tbl->nr_of_post;
+ memcpy(&_buf[1], command_tbl->post_cmds, command_tbl->nr_of_post * 8);
+ XmlFile.AddLine(IndentString(lvl)+"<ChapterProcessCommand>"+encodebase64(_buf,1+command_tbl->nr_of_post * 8)+"</ChapterProcessCommand>");
+ lvl--;
+ XmlFile.AddLine(IndentString(lvl)+"</ChapterProcess>");
+ }
+ free(_buf);
+ }
+ }
+
static wxString GetPGCType(unsigned char entry_id)
{
wxString result;
@@ -901,14 +903,14 @@
next_program_entry_cell_num = pgc->program_map[program_number+1];
for (int cell_num = entry_cell_num; cell_num<next_program_entry_cell_num; cell_num++)
{
- // Output cells
+ // Output cells
const cell_position_t & position = pgc->cell_position[cell_num-1];
const cell_playback_t & cell = pgc->cell_playback[cell_num-1];
-
- if (cell.block_mode != 0 && cell.block_mode != 3)
- continue;
-
- if (cell.block_mode) // multi-angle
+
+ if (cell.block_mode != 0 && cell.block_mode != 3)
+ 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
XmlFile.AddLine(IndentString(lvl)+wxString::Format("<!-- Program %sCell CN#%d -->",(cell_num==entry_cell_num)?"Entry ":"", cell_num));
@@ -923,8 +925,8 @@
_PrivateCN[4] = cell_num - entry_cell_num + 1; // Number of angles
XmlFile.AddLine(IndentString(lvl)+"<ChapterProcessedPrivate>"+encodebase64(_PrivateCN,5)+"</ChapterProcessedPrivate>");
- //_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
+ //_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);
DisplayTime(lvl, XmlFile, st_time, end_time);
@@ -948,12 +950,12 @@
XmlFile.AddLine(IndentString(lvl)+wxString::Format("<!-- PGC PGC_%d type %s -->",pgc_num+1,GetPGCType(pgc_type).c_str()));
XmlFile.AddLine(IndentString(lvl)+"<ChapterAtom>");
- lvl++;
+ lvl++;
wxString _myUID = CreateUID();
XmlFile.AddLine(IndentString(lvl)+"<ChapterUID>"+_myUID+"</ChapterUID>");
_PrivatePGC[1] = (pgc_num+1) >> 8;
_PrivatePGC[2] = (pgc_num+1) & 0xFF;
- _PrivatePGC[3] = pgc_type;
+ _PrivatePGC[3] = pgc_type;
_PrivatePGC[4] = ((uint8_t*) &pgc->prohibited_ops)[0];
_PrivatePGC[5] = ((uint8_t*) &pgc->prohibited_ops)[1];
_PrivatePGC[6] = ((uint8_t*) &pgc->prohibited_ops)[2];
@@ -968,18 +970,18 @@
// PGC commands
AddCommands(lvl, XmlFile, pgc->command_tbl);
-
+
// Handle the Programs/Cells in the PGC
for (int i=0; i< pgc->nr_of_programs; i++)
{
- // handle the PTT/Chapter
- if (ptts != NULL)
- {
- // find if the PGCN/PGN is in the list
- for (int ptt_num=0; ptt_num<ptts->nr_of_ptts; ptt_num++)
- {
- if (ptts->ptt[ptt_num].pgcn == pgc_num+1 && ptts->ptt[ptt_num].pgn == i+1)
- {
+ // handle the PTT/Chapter
+ if (ptts != NULL)
+ {
+ // find if the PGCN/PGN is in the list
+ for (int ptt_num=0; ptt_num<ptts->nr_of_ptts; ptt_num++)
+ {
+ if (ptts->ptt[ptt_num].pgcn == pgc_num+1 && ptts->ptt[ptt_num].pgn == i+1)
+ {
XmlFile.AddLine(IndentString(lvl)+wxString::Format("<!-- Chapter PTT_%d -->", ptt_num+1));
XmlFile.AddLine(IndentString(lvl)+"<ChapterAtom>");
lvl++;
@@ -994,15 +996,15 @@
XmlFile.AddLine(IndentString(lvl)+wxString::Format("<ChapterString>Your Name Here For Chapter #%d</ChapterString>", ptt_num+1));
lvl--;
XmlFile.AddLine(IndentString(lvl)+"</ChapterDisplay>");
-
+
// PTT start times (no end time, it's only a reference used to seek)
XmlFile.AddLine(IndentString(lvl)+"<ChapterTimeStart>"+TimeFormat(st_time)+"</ChapterTimeStart>");
- lvl--;
- XmlFile.AddLine(IndentString(lvl)+"</ChapterAtom>");
- break;
- }
+ lvl--;
+ XmlFile.AddLine(IndentString(lvl)+"</ChapterAtom>");
+ break;
+ }
}
- }
+ }
XmlFile.AddLine(IndentString(lvl)+"<!-- Program PGN#"+wxString::Format("%d",i+1)+" in this PGC -->");
st_time = OutputProgram(lvl, XmlFile, pgc, i, st_time);
@@ -1044,9 +1046,9 @@
return nano_duration;
}
-
- static wxString TimeFormat(uint64_t a_time)
- {
+
+ static wxString TimeFormat(uint64_t a_time)
+ {
int hour, min, sec;
uint32_t nano;
@@ -1055,10 +1057,10 @@
sec = a_time % 60;
a_time /= 60;
min = a_time % 60;
- hour = a_time / 60;
+ hour = a_time / 60;
return wxString::Format("%02d:%02d:%02d.%09d", hour, min, sec, nano);
- }
+ }
/// times in nanoseconds
static void DisplayTime(int lvl, wxTextFile & XmlFile, uint64_t start_time, uint64_t end_time)
@@ -1110,63 +1112,63 @@
return timecode_endB;
}
- void GenerateXMLScript()
- {
- if (!IfoFile)
- {
- myfprintf(stderr, "No IFO file loaded !");
- return;
- }
-
- static unsigned char _PrivateFP[] = {0x30, 0x00, 0x00, 0x00};
+ void GenerateXMLScript()
+ {
+ if (!IfoFile)
+ {
+ myfprintf(stderr, "No IFO file loaded !");
+ return;
+ }
+
+ static unsigned char _PrivateFP[] = {0x30, 0x00, 0x00, 0x00};
static unsigned char _PrivateVM[] = {0x30, 0xC0, 0x00, 0x00};
static unsigned char _PrivateVTS[] = {0x30, 0x80, 0x00, 0x00};
static unsigned char _PrivateTT[] = {0x28, 0x00, 0x00};
-
- wxString line, editionUID = CreateUID();
- wxFileConfig *pConfig = (wxFileConfig *)wxConfigBase::Get();
- // Get sub directory
- wxString Filename = pConfig->Read("OutputDirectory","") + "menuVMG.xml";
- wxTextFile XmlFile(Filename);
- XmlFile.Create();
- XmlFile.AddLine("<?xml version=\"1.0\" encoding=\"UTF-8\" standalone=\"no\"?>");
- XmlFile.AddLine("<!DOCTYPE Chapters SYSTEM \"matroskachapters.dtd\">");
- XmlFile.AddLine("");
-
- int lvl = 0;
+
+ wxString line, editionUID = CreateUID();
+ wxFileConfig *pConfig = (wxFileConfig *)wxConfigBase::Get();
+ // Get sub directory
+ wxString Filename = pConfig->Read("OutputDirectory","") + "menuVMG.xml";
+ wxTextFile XmlFile(Filename);
+ XmlFile.Create();
+ XmlFile.AddLine("<?xml version=\"1.0\" encoding=\"UTF-8\" standalone=\"no\"?>");
+ XmlFile.AddLine("<!DOCTYPE Chapters SYSTEM \"matroskachapters.dtd\">");
+ XmlFile.AddLine("");
+
+ int lvl = 0;
uint64_t timecode_startA = 0, timecode_endA = 0;
-
- XmlFile.AddLine("<Chapters>");
- lvl++;
- XmlFile.AddLine(IndentString(lvl)+"<EditionEntry>");
- lvl++;
- XmlFile.AddLine(IndentString(lvl)+"<EditionUID>"+editionUID+"</EditionUID>");
- XmlFile.AddLine(IndentString(lvl)+"<EditionProcessed>1</EditionProcessed>"); // DVD style menu
-
- // Write the first play PGC
- if (IfoFile->FirstPlayPGC())
- {
- XmlFile.AddLine(IndentString(lvl)+"<!-- First Play PGC -->");
- XmlFile.AddLine(IndentString(lvl)+"<ChapterAtom>");
- lvl++;
- wxString _myUID = CreateUID();
- XmlFile.AddLine(IndentString(lvl)+"<ChapterUID>"+_myUID+"</ChapterUID>");
- // the First Play PGC has no cell and no time
- DisplayTime(lvl, XmlFile, timecode_startA, timecode_endA);
- // display the UID for the lazy rippers
- XmlFile.AddLine(IndentString(lvl)+"<ChapterDisplay>");
- lvl++;
- XmlFile.AddLine(IndentString(lvl)+"<ChapterString>First Play PGC "+_myUID+"</ChapterString>");
- lvl--;
- XmlFile.AddLine(IndentString(lvl)+"</ChapterDisplay>");
-
- XmlFile.AddLine(IndentString(lvl)+"<ChapterProcessedPrivate>"+encodebase64(_PrivateFP,4)+"</ChapterProcessedPrivate>");
- // PGC commands
- AddCommands(lvl, XmlFile, IfoFile->FirstPlayPGC()->command_tbl);
- lvl--;
- XmlFile.AddLine(IndentString(lvl)+"</ChapterAtom>");
- }
-
+
+ XmlFile.AddLine("<Chapters>");
+ lvl++;
+ XmlFile.AddLine(IndentString(lvl)+"<EditionEntry>");
+ lvl++;
+ XmlFile.AddLine(IndentString(lvl)+"<EditionUID>"+editionUID+"</EditionUID>");
+ XmlFile.AddLine(IndentString(lvl)+"<EditionProcessed>1</EditionProcessed>"); // DVD style menu
+
+ // Write the first play PGC
+ if (IfoFile->FirstPlayPGC())
+ {
+ XmlFile.AddLine(IndentString(lvl)+"<!-- First Play PGC -->");
+ XmlFile.AddLine(IndentString(lvl)+"<ChapterAtom>");
+ lvl++;
+ wxString _myUID = CreateUID();
+ XmlFile.AddLine(IndentString(lvl)+"<ChapterUID>"+_myUID+"</ChapterUID>");
+ // the First Play PGC has no cell and no time
+ DisplayTime(lvl, XmlFile, timecode_startA, timecode_endA);
+ // display the UID for the lazy rippers
+ XmlFile.AddLine(IndentString(lvl)+"<ChapterDisplay>");
+ lvl++;
+ XmlFile.AddLine(IndentString(lvl)+"<ChapterString>First Play PGC "+_myUID+"</ChapterString>");
+ lvl--;
+ XmlFile.AddLine(IndentString(lvl)+"</ChapterDisplay>");
+
+ XmlFile.AddLine(IndentString(lvl)+"<ChapterProcessedPrivate>"+encodebase64(_PrivateFP,4)+"</ChapterProcessedPrivate>");
+ // PGC commands
+ AddCommands(lvl, XmlFile, IfoFile->FirstPlayPGC()->command_tbl);
+ lvl--;
+ XmlFile.AddLine(IndentString(lvl)+"</ChapterAtom>");
+ }
+
timecode_startA = timecode_endA;
// Language Units
@@ -1185,31 +1187,31 @@
lvl--;
XmlFile.AddLine(IndentString(lvl)+"</ChapterAtom>");
}
- lvl--;
- XmlFile.AddLine(IndentString(lvl)+"</EditionEntry>");
- lvl--;
- XmlFile.AddLine("</Chapters>");
- XmlFile.Write();
+ lvl--;
+ XmlFile.AddLine(IndentString(lvl)+"</EditionEntry>");
+ lvl--;
+ XmlFile.AddLine("</Chapters>");
+ XmlFile.Write();
// Write the Video Title Set
for (int title=1; title <= IfoFile->NumberOfTitles(); title++)
{
timecode_startA = timecode_endA;
- wxString Filename = pConfig->Read("OutputDirectory","") + wxString::Format("menuVTS%02d.xml", title);
- wxTextFile XmlFile(Filename);
- XmlFile.Create();
- XmlFile.AddLine("<?xml version=\"1.0\" encoding=\"UTF-8\" standalone=\"no\"?>");
- XmlFile.AddLine("<!DOCTYPE Chapters SYSTEM \"matroskachapters.dtd\">");
- XmlFile.AddLine("");
-
- XmlFile.AddLine("<Chapters>");
- lvl++;
- XmlFile.AddLine(IndentString(lvl)+"<EditionEntry>");
- lvl++;
- XmlFile.AddLine(IndentString(lvl)+"<EditionUID>"+editionUID+"</EditionUID>");
- XmlFile.AddLine(IndentString(lvl)+"<EditionProcessed>1</EditionProcessed>"); // DVD style menu
-
+ wxString Filename = pConfig->Read("OutputDirectory","") + wxString::Format("menuVTS%02d.xml", title);
+ wxTextFile XmlFile(Filename);
+ XmlFile.Create();
+ XmlFile.AddLine("<?xml version=\"1.0\" encoding=\"UTF-8\" standalone=\"no\"?>");
+ XmlFile.AddLine("<!DOCTYPE Chapters SYSTEM \"matroskachapters.dtd\">");
+ XmlFile.AddLine("");
+
+ XmlFile.AddLine("<Chapters>");
+ lvl++;
+ XmlFile.AddLine(IndentString(lvl)+"<EditionEntry>");
+ lvl++;
+ XmlFile.AddLine(IndentString(lvl)+"<EditionUID>"+editionUID+"</EditionUID>");
+ XmlFile.AddLine(IndentString(lvl)+"<EditionProcessed>1</EditionProcessed>"); // DVD style menu
+
XmlFile.AddLine(IndentString(lvl)+"<!-- Video Title Set -->");
XmlFile.AddLine(IndentString(lvl)+"<ChapterAtom>");
lvl++;
@@ -1225,7 +1227,7 @@
timecode_endA = HandleLanguageUnit(lvl, XmlFile, timecode_startA, *IfoFile, title);
}
- // VTS content
+ // VTS content
if (IfoFile->VtsTitles(title) && IfoFile->VtsPGCs(title))
{
uint64_t timecode_startB = timecode_endA, timecode_endB = timecode_endA;
@@ -1233,7 +1235,7 @@
{
XmlFile.AddLine(IndentString(lvl)+wxString::Format("<!-- Title TTU_%d -->",i+1));
XmlFile.AddLine(IndentString(lvl)+"<ChapterAtom>");
- lvl++;
+ lvl++;
wxString _myUIDa = CreateUID();
XmlFile.AddLine(IndentString(lvl)+"<ChapterUID>"+_myUIDa+"</ChapterUID>");
@@ -1241,7 +1243,7 @@
_PrivateTT[2] = (i+1) & 0xFF;
XmlFile.AddLine(IndentString(lvl)+"<ChapterProcessedPrivate>"+encodebase64(_PrivateTT,3)+"</ChapterProcessedPrivate>");
- // add the PGC that match this PTT
+ // add the PGC that match this PTT
uint64_t timecode_startC = timecode_startB, timecode_endC = timecode_startB;
for (int k=0; k<IfoFile->VtsPGCs(title)->nr_of_pgci_srp; k++)
{
@@ -1260,16 +1262,16 @@
}
timecode_endA = timecode_startB;
}
-
+
DisplayTime(lvl, XmlFile, timecode_startA, timecode_endA);
- lvl--;
+ lvl--;
XmlFile.AddLine(IndentString(lvl)+"</ChapterAtom>");
-
- lvl--;
- XmlFile.AddLine(IndentString(lvl)+"</EditionEntry>");
- lvl--;
- XmlFile.AddLine("</Chapters>");
- XmlFile.Write();
+
+ lvl--;
+ XmlFile.AddLine(IndentString(lvl)+"</EditionEntry>");
+ lvl--;
+ XmlFile.AddLine("</Chapters>");
+ XmlFile.Write();
}
}
@@ -1286,29 +1288,32 @@
// Create sub directory
subDirectory = pConfig->Read("OutputDirectory","")+ "sub" + wxFILE_SEP_PATH;
wxMkdir(subDirectory);
+ // Create sub directory
+ btnDirectory = pConfig->Read("OutputDirectory","")+ "buttons" + wxFILE_SEP_PATH;
+ wxMkdir(btnDirectory);
// Create bmp directory
bmpDirectory = pConfig->Read("OutputDirectory","")+ "bmp" + wxFILE_SEP_PATH;
- wxMkdir(bmpDirectory);
- // Create wav directory
-// wavDirectory = pConfig->Read("OutputDirectory","")+ "wav" + wxFILE_SEP_PATH;
-// wxMkdir(wavDirectory);
- // Create mask directory
-// maskDirectory = pConfig->Read("OutputDirectory","") + "mask" + wxFILE_SEP_PATH;
-// wxMkdir(maskDirectory);
+ wxMkdir(bmpDirectory);
+ // Create wav directory
+// wavDirectory = pConfig->Read("OutputDirectory","")+ "wav" + wxFILE_SEP_PATH;
+// wxMkdir(wavDirectory);
+ // Create mask directory
+// maskDirectory = pConfig->Read("OutputDirectory","") + "mask" + wxFILE_SEP_PATH;
+// wxMkdir(maskDirectory);
}
virtual void AfterShow(void)
- {
- const int NbsStep = 3;
- wxString StepString, StepStringFormat = "Step %d/%d : %s...";
+ {
+ const int NbsStep = 3;
+ wxString StepString, StepStringFormat = "Step %d/%d : %s...";
- m_OperationInProgress = TRUE;
-
- m_txtDemuxLog->AppendText("Creating output directories\n");
-
- CreatDirectories();
+ m_OperationInProgress = TRUE;
- bool language = true;
+ m_txtDemuxLog->AppendText("Creating output directories\n");
+
+ CreatDirectories();
+
+ bool language = true;
for (int16_t title = 0; title <= IfoFile->NumberOfTitles(); title++)
{
do {
@@ -1317,40 +1322,40 @@
language = true;
break;
}
-
- m_txtDemuxLog->AppendText(wxString::Format(" Treating Title %d %sVOB file(s)\n", title, language?"LU ":""));
-
- int Step = 1;
-
- StepString = StepString.Format(StepStringFormat, Step++, NbsStep, "Building vob map");
- m_lbStep->SetLabel(StepString);
- m_txtDemuxLog->AppendText(StepString+"\n");
+
+ m_txtDemuxLog->AppendText(wxString::Format(" Treating Title %d %sVOB file(s)\n", title, language?"LU ":""));
+
+ int Step = 1;
+
+ StepString = StepString.Format(StepStringFormat, Step++, NbsStep, "Building vob map");
+ m_lbStep->SetLabel(StepString);
+ m_txtDemuxLog->AppendText(StepString+"\n");
m_lbStep->Update();
VobParser *aVobParser = BuildVobMap(title, language);
if (aVobParser != NULL)
- {
- StepString = StepString.Format(StepStringFormat, Step++, NbsStep, "Splitting and demuxing");
- m_lbStep->SetLabel(StepString);
+ {
+ StepString = StepString.Format(StepStringFormat, Step++, NbsStep, "Splitting and demuxing");
+ m_lbStep->SetLabel(StepString);
m_txtDemuxLog->AppendText(StepString+"\n");
m_lbStep->Update();
- SplitAndDemux(*aVobParser, title, language);
-
- StepString = StepString.Format(StepStringFormat, Step++, NbsStep, "Converting still to bitmap");
- m_lbStep->SetLabel(StepString);
- m_txtDemuxLog->AppendText(StepString+"\n");
+ SplitAndDemux(*aVobParser, title, language);
+
+ StepString = StepString.Format(StepStringFormat, Step++, NbsStep, "Converting still to bitmap");
+ m_lbStep->SetLabel(StepString);
+ m_txtDemuxLog->AppendText(StepString+"\n");
m_lbStep->Update();
- ConvertStillToBMP(title, language);
-/*
- StepString = StepString.Format(StepStringFormat, Step++, NbsStep, "Converting audio to wav");
- m_lbStep->SetLabel(StepString);
- m_txtDemuxLog->AppendText(StepString+"\n");
+ ConvertStillToBMP(title, language);
+/*
+ StepString = StepString.Format(StepStringFormat, Step++, NbsStep, "Converting audio to wav");
+ m_lbStep->SetLabel(StepString);
+ m_txtDemuxLog->AppendText(StepString+"\n");
m_lbStep->Update();
- ConvertAudioToWAV(title, language);
-* /
- StepString = StepString.Format(StepStringFormat, Step++, NbsStep, "Converting button mask to bitmap");
- m_lbStep->SetLabel(StepString);
- m_txtDemuxLog->AppendText(StepString+"\n");
+ ConvertAudioToWAV(title, language);
+* /
+ StepString = StepString.Format(StepStringFormat, Step++, NbsStep, "Converting button mask to bitmap");
+ m_lbStep->SetLabel(StepString);
+ m_txtDemuxLog->AppendText(StepString+"\n");
m_lbStep->Update();
ConvertButtonMaskToBMP(title, language);
*/
@@ -1359,9 +1364,9 @@
language = !language;
} while (!language);
}
-
- GenerateXMLScript();
+ GenerateXMLScript();
+
m_OperationInProgress = FALSE;
}
@@ -1382,7 +1387,7 @@
wxStaticText* m_lbStep;
wxGauge* m_gaDemuxProgress;
wxTextCtrl* m_txtDemuxLog;
- bool m_OperationInProgress;
+ bool m_OperationInProgress;
};
// ----------------------------------------------------------------------------
@@ -1433,12 +1438,12 @@
bool DvdMenuXtractorApp::OnInit()
{
- // Create config object
- wxFileName configFilename;
- configFilename.AssignCwd();
- configFilename.SetFullName(GetAppName()+".cfg");
- wxFileConfig *pConfig = new wxFileConfig("DvdMenuXtractor","ToffSoftware",
- configFilename.GetFullPath(),"",wxCONFIG_USE_LOCAL_FILE);
+ // Create config object
+ wxFileName configFilename;
+ configFilename.AssignCwd();
+ configFilename.SetFullName(GetAppName()+".cfg");
+ wxFileConfig *pConfig = new wxFileConfig("DvdMenuXtractor","ToffSoftware",
+ configFilename.GetFullPath(),"",wxCONFIG_USE_LOCAL_FILE);
wxConfigBase::Set(pConfig);
wizard = new DvdMenuXtractorWizard();
@@ -1497,8 +1502,8 @@
{
delete IfoFile;
}
- wxFileConfig *pConfig = (wxFileConfig *)wxConfigBase::Get();
- delete pConfig;
+ wxFileConfig *pConfig = (wxFileConfig *)wxConfigBase::Get();
+ delete pConfig;
pConfig = NULL;
return 0;
Modified: trunk/DvdMenuXtractor/VobParser.cpp
===================================================================
--- trunk/DvdMenuXtractor/VobParser.cpp 2004-11-30 15:45:16 UTC (rev 958)
+++ trunk/DvdMenuXtractor/VobParser.cpp 2004-12-11 11:08:50 UTC (rev 959)
@@ -433,6 +433,8 @@
DebugLog("PCI {\n");
inc_lvl();
ParsePCI();
+ if (m_pci.btn_ns != 0) // there are some buttons
+ m_demuxer.ProcessStream(SUBSTREAM_PCI, &m_buff[0x2C], length, (int32_t)pktinfo.pts/90, wxString::Format("DTS %d PTS %d - %d %d\n", (int32_t)m_startdts/90, (int32_t)m_startpts/90, (int32_t)pktinfo.dts/90, (int32_t)pktinfo.pts/90));
dec_lvl();
DebugLog("}\n");
break;
@@ -659,7 +661,7 @@
ParsePESHeaderDataContentFlag();
ParsePESHeaderData();
- m_demuxer.ProcessStream(0xE0, &m_buff[m_index],
+ m_demuxer.ProcessStream(VIDEO_STREAM, &m_buff[m_index],
length - 3 - pes_header_data_content.PES_header_data_len, (int32_t)pktinfo.pts/90, wxString::Format("DTS %d PTS %d - %d %d\n", (int32_t)m_startdts/90, (int32_t)m_startpts/90, (int32_t)pktinfo.dts/90, (int32_t)pktinfo.pts/90));
}
@@ -870,5 +872,131 @@
fprintf(m_TimecodeFile, "timestamp: %s%02d:%02d:%02d:%03d, filepos: %09x\n", sign?"-":"", delay,minute,second,millisecond,filepos);
}
+void BtnDemuxWriter::WriteTimecodeInfo(int32_t delay, uint64_t filepos, wxString & debug)
+{
+ if (!m_TimecodeFile)
+ {
+ wxString m_filename = m_Filename;
+ m_filename += "_btn.tmc";
+ m_TimecodeFile = fopen(m_filename.c_str(),"w");
+ fwrite("# timecode format v3\n", 1, 21, m_TimecodeFile);
+ fprintf(m_TimecodeFile, "assume %lf\n", 0.0);
+ }
+ bool sign = delay < 0;
+ delay = sign?-delay:delay;
+ int millisecond = delay % 1000;
+ delay /= 1000;
+ int second = delay % 60;
+ delay /= 60;
+ int minute = delay % 60;
+ delay /= 60;
+ fprintf(m_TimecodeFile, "timestamp: %s%02d:%02d:%02d:%03d, filepos: %09x\n", sign?"-":"", delay,minute,second,millisecond,filepos);
+}
+
+void DTSDemuxWriter::WriteTimecodeInfo(int32_t delay, uint64_t filepos, wxString & debug)
+{
+ if (!m_TimecodeFile)
+ {
+ wxString m_filename = m_Filename;
+ m_filename += "_dts.tmc";
+ m_TimecodeFile = fopen(m_filename.c_str(),"w");
+ fwrite("# timecode format v3\n", 1, 21, m_TimecodeFile);
+ fprintf(m_TimecodeFile, "assume %lf\n", 0.0);
+ }
+ bool sign = delay < 0;
+ delay = sign?-delay:delay;
+ int millisecond = delay % 1000;
+ delay /= 1000;
+ int second = delay % 60;
+ delay /= 60;
+ int minute = delay % 60;
+ delay /= 60;
+ fprintf(m_TimecodeFile, "timestamp: %s%02d:%02d:%02d:%03d, filepos: %09x\n", sign?"-":"", delay,minute,second,millisecond,filepos);
+}
+
+void LPCMDemuxWriter::WriteTimecodeInfo(int32_t delay, uint64_t filepos, wxString & debug)
+{
+ if (!m_TimecodeFile)
+ {
+ wxString m_filename = m_Filename;
+ m_filename += "_lpmc.tmc";
+ m_TimecodeFile = fopen(m_filename.c_str(),"w");
+ fwrite("# timecode format v3\n", 1, 21, m_TimecodeFile);
+ fprintf(m_TimecodeFile, "assume %lf\n", 0.0);
+ }
+ bool sign = delay < 0;
+ delay = sign?-delay:delay;
+ int millisecond = delay % 1000;
+ delay /= 1000;
+ int second = delay % 60;
+ delay /= 60;
+ int minute = delay % 60;
+ delay /= 60;
+ fprintf(m_TimecodeFile, "timestamp: %s%02d:%02d:%02d:%03d, filepos: %09x\n", sign?"-":"", delay,minute,second,millisecond,filepos);
+}
+
+void MPADemuxWriter::WriteTimecodeInfo(int32_t delay, uint64_t filepos, wxString & debug)
+{
+ if (!m_TimecodeFile)
+ {
+ wxString m_filename = m_Filename;
+ m_filename += "_mpa.tmc";
+ m_TimecodeFile = fopen(m_filename.c_str(),"w");
+ fwrite("# timecode format v3\n", 1, 21, m_TimecodeFile);
+ fprintf(m_TimecodeFile, "assume %lf\n", 0.0);
+ }
+ bool sign = delay < 0;
+ delay = sign?-delay:delay;
+ int millisecond = delay % 1000;
+ delay /= 1000;
+ int second = delay % 60;
+ delay /= 60;
+ int minute = delay % 60;
+ delay /= 60;
+ fprintf(m_TimecodeFile, "timestamp: %s%02d:%02d:%02d:%03d, filepos: %09x\n", sign?"-":"", delay,minute,second,millisecond,filepos);
+}
+
+void AC3DemuxWriter::WriteTimecodeInfo(int32_t delay, uint64_t filepos, wxString & debug)
+{
+ if (!m_TimecodeFile)
+ {
+ wxString m_filename = m_Filename;
+ m_filename += "_ac3.tmc";
+ m_TimecodeFile = fopen(m_filename.c_str(),"w");
+ fwrite("# timecode format v3\n", 1, 21, m_TimecodeFile);
+ fprintf(m_TimecodeFile, "assume %lf\n", 0.0);
+ }
+ bool sign = delay < 0;
+ delay = sign?-delay:delay;
+ int millisecond = delay % 1000;
+ delay /= 1000;
+ int second = delay % 60;
+ delay /= 60;
+ int minute = delay % 60;
+ delay /= 60;
+ fprintf(m_TimecodeFile, "timestamp: %s%02d:%02d:%02d:%03d, filepos: %09x\n", sign?"-":"", delay,minute,second,millisecond,filepos);
+}
+
+void VideoDemuxWriter::WriteTimecodeInfo(int32_t delay, uint64_t filepos, wxString & debug)
+{
+ if (!m_TimecodeFile)
+ {
+ wxString m_filename = m_Filename;
+ m_filename += "_vid.tmc";
+ m_TimecodeFile = fopen(m_filename.c_str(),"w");
+ fwrite("# timecode format v3\n", 1, 21, m_TimecodeFile);
+ fprintf(m_TimecodeFile, "assume %lf\n", 0.0);
+ }
+ bool sign = delay < 0;
+ delay = sign?-delay:delay;
+ int millisecond = delay % 1000;
+ delay /= 1000;
+ int second = delay % 60;
+ delay /= 60;
+ int minute = delay % 60;
+ delay /= 60;
+ fprintf(m_TimecodeFile, "timestamp: %s%02d:%02d:%02d:%03d, filepos: %09x\n", sign?"-":"", delay,minute,second,millisecond,filepos);
+}
+
// ============================================================================
Modified: trunk/DvdMenuXtractor/VobParser.h
===================================================================
--- trunk/DvdMenuXtractor/VobParser.h 2004-11-30 15:45:16 UTC (rev 958)
+++ trunk/DvdMenuXtractor/VobParser.h 2004-12-11 11:08:50 UTC (rev 959)
@@ -224,6 +224,8 @@
public:
VideoDemuxWriter(const char* filenamePrefix) : Writer(filenamePrefix,"m2v") {}
void ProcessStream(uint8_t* buff, uint32_t size, int32_t delay, wxString & debug) { Write(buff, size, delay, debug); }
+protected:
+ void WriteTimecodeInfo(int32_t delay, uint64_t filepos, wxString & debug);
};
// ----------------------------------------------------------------------------
@@ -239,6 +241,8 @@
}
private:
uint8_t m_streamID;
+protected:
+ void WriteTimecodeInfo(int32_t delay, uint64_t filepos, wxString & debug);
};
// ----------------------------------------------------------------------------
@@ -254,6 +258,8 @@
}
private:
uint8_t m_streamID;
+protected:
+ void WriteTimecodeInfo(int32_t delay, uint64_t filepos, wxString & debug);
};
// ----------------------------------------------------------------------------
@@ -269,6 +275,8 @@
}
private:
uint8_t m_streamID;
+protected:
+ void WriteTimecodeInfo(int32_t delay, uint64_t filepos, wxString & debug);
};
// ----------------------------------------------------------------------------
@@ -284,6 +292,8 @@
}
private:
uint8_t m_streamID;
+protected:
+ void WriteTimecodeInfo(int32_t delay, uint64_t filepos, wxString & debug);
};
// ----------------------------------------------------------------------------
@@ -315,6 +325,22 @@
// ----------------------------------------------------------------------------
+class BtnDemuxWriter : public Demuxer, public Writer
+{
+public:
+ BtnDemuxWriter(const char* filenamePrefix)
+ :Writer(filenamePrefix, "btn")
+ {}
+ void ProcessStream(uint8_t* buff, uint32_t size, int32_t delay, wxString & debug)
+ {
+ Write(buff,size, delay, debug);
+ }
+protected:
+ void WriteTimecodeInfo(int32_t delay, uint64_t filepos, wxString & debug);
+};
+
+// ----------------------------------------------------------------------------
+
class CompositeDemuxWriter
{
public: