You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
1777 lines
56 KiB
1777 lines
56 KiB
/***************************************************************************
|
|
* Copyright (C) 2005 by Jean-Michel Petit *
|
|
* jm_petit@laposte.net *
|
|
* *
|
|
* This program is free software; you can redistribute it and/or modify *
|
|
* it under the terms of the GNU General Public License as published by *
|
|
* the Free Software Foundation; either version 2 of the License, or *
|
|
* (at your option) any later version. *
|
|
* *
|
|
* This program is distributed in the hope that it will be useful, *
|
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of *
|
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
|
|
* GNU General Public License for more details. *
|
|
* *
|
|
* You should have received a copy of the GNU General Public License *
|
|
* along with this program; if not, write to the *
|
|
* Free Software Foundation, Inc., *
|
|
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. *
|
|
***************************************************************************/
|
|
#include "k9dvdbackup.h"
|
|
#include "k9dvd.h"
|
|
#include "bswap.h"
|
|
#include "k9ifo2.h"
|
|
#include "k9vamps.h"
|
|
#include "ac.h"
|
|
#include "k9dvdtitleset.h"
|
|
#include <kmessagebox.h>
|
|
#include <kapplication.h>
|
|
#include <tqapplication.h>
|
|
#include <tqfileinfo.h>
|
|
|
|
#include <stdio.h>
|
|
#include <stdlib.h>
|
|
#include <stdarg.h>
|
|
#include <errno.h>
|
|
#include <string.h>
|
|
#include <klocale.h>
|
|
#include <tqdir.h>
|
|
#include <kstandarddirs.h>
|
|
#include "k9backupdlg.h"
|
|
#include "dvdread.h"
|
|
#include "k9script.h"
|
|
#include "k9tools.h"
|
|
|
|
#define BUF_SECS 1024
|
|
|
|
|
|
#include "k9dvdbackup.moc"
|
|
|
|
int k9CadtList::compareItems(TQPtrCollection::Item item1,TQPtrCollection::Item item2) {
|
|
cell_adr_t * it1=(cell_adr_t*)item1;
|
|
cell_adr_t * it2=(cell_adr_t*)item2;
|
|
return it1->start_sector - it2->start_sector;
|
|
};
|
|
|
|
int k9TitleSetList::compareItems ( TQPtrCollection::Item item1, TQPtrCollection::Item item2 ) {
|
|
k9TitleSet * it1,*it2;
|
|
it1=(k9TitleSet *) item1;
|
|
it2=(k9TitleSet *)item2;
|
|
return it1->VTS - it2->VTS;
|
|
}
|
|
|
|
/*void k9TitleSet::clearCells() {
|
|
while (!cells.isEmpty()) delete cells.take();
|
|
//qDeleteAll(cells);
|
|
cells.clear();
|
|
}
|
|
*/
|
|
|
|
k9TitleSet::k9TitleSet(int _VTS):TQObject(NULL,"") {
|
|
startSector=0;
|
|
lastSector=0;
|
|
VTS=_VTS;
|
|
cells.setAutoDelete(true);
|
|
ifoTitle=NULL;
|
|
}
|
|
|
|
k9TitleSet::~k9TitleSet() {
|
|
//ifoTitle->closeIFO();
|
|
//delete ifoTitle;
|
|
}
|
|
|
|
k9Cell* k9TitleSet::addCell(int _vts,int _pgc, int _vob) {
|
|
return cells.addCell(_vts,_pgc,_vob);
|
|
|
|
}
|
|
|
|
uint32_t k9TitleSet::getSize() {
|
|
return (lastSector +1) ;
|
|
}
|
|
|
|
|
|
k9DVDBackup::k9DVDBackup(TQObject* _dvd,const char* name,const TQStringList& )
|
|
: TQObject(NULL, name) {
|
|
DVD = (k9DVD*)_dvd;
|
|
m_dvdread=DVD->getdvd();
|
|
currVTS=0;
|
|
outputFile=NULL;
|
|
currTS=NULL;
|
|
errMsg="";
|
|
error=false;
|
|
backupDlg = new k9BackupDlg(tqApp->mainWidget(),"",true);
|
|
// cells.setAutoDelete(true);
|
|
vamps=new k9vamps(this);
|
|
m_withMenu=false;
|
|
m_forcedFactor=false;
|
|
m_preserve=true;
|
|
}
|
|
|
|
|
|
k9DVDBackup::~k9DVDBackup() {
|
|
if (outputFile !=NULL) {
|
|
outputFile->close();
|
|
delete outputFile;
|
|
}
|
|
delete backupDlg;
|
|
delete vamps;
|
|
}
|
|
|
|
void k9DVDBackup::setWithMenus(bool _value) {
|
|
m_withMenu=_value;
|
|
}
|
|
|
|
bool k9DVDBackup::geterror() {
|
|
return error;
|
|
}
|
|
|
|
void k9DVDBackup::seterror(const TQString &_msg) {
|
|
error=true;
|
|
errMsg=_msg;
|
|
}
|
|
|
|
|
|
TQString k9DVDBackup::getErrMsg() {
|
|
return(errMsg);
|
|
}
|
|
|
|
void k9DVDBackup::prepareVTS(int _VTS) {
|
|
if (error)
|
|
return;
|
|
ifo_handle_t *hifo;
|
|
|
|
cellSize=0;
|
|
if (currTS==NULL) {
|
|
currVTS=0;
|
|
m_vmgSize=copyMenu2(0);
|
|
calcFactor();
|
|
if (outputFile != NULL) {
|
|
outputFile->close();
|
|
delete outputFile;
|
|
outputFile=NULL;
|
|
}
|
|
}
|
|
if (backupDlg->getAbort()) {
|
|
seterror(tr2i18n("DVD backup cancelled"));
|
|
return;
|
|
}
|
|
//creation of output file
|
|
if (currVTS != _VTS) {
|
|
if (outputFile != NULL) {
|
|
outputFile->close();
|
|
delete outputFile;
|
|
outputFile=NULL;
|
|
updateIfo();
|
|
updateVob(&currTS->cells);
|
|
}
|
|
|
|
if (backupDlg->getAbort()) {
|
|
seterror(tr2i18n("DVD backup cancelled"));
|
|
return;
|
|
}
|
|
|
|
uint32_t startSector=0;
|
|
|
|
if (currTS != NULL) {
|
|
startSector = currTS->startSector + currTS->getSize();
|
|
} else {
|
|
k9Ifo2 *kifo;
|
|
kifo=m_dvdread->getIfo(0);
|
|
hifo = kifo->getIFO();
|
|
if (!hifo) {
|
|
seterror( tr2i18n("unable to open VIDEO_TS.IFO"));
|
|
return;
|
|
}
|
|
startSector= hifo->vmgi_mat->vmg_last_sector+1 ;
|
|
}
|
|
|
|
currTS = new k9TitleSet(_VTS);
|
|
currVOB=0;
|
|
currVTS=_VTS;
|
|
|
|
calcFactor(); //menus are always shrinked
|
|
currTS->menuSize=copyMenu2(_VTS);
|
|
if (outputFile != NULL) {
|
|
outputFile->close();
|
|
delete outputFile;
|
|
}
|
|
|
|
TQString filename;
|
|
filename.sprintf("/VTS_%02d_1.VOB",_VTS);
|
|
filename=output+filename;
|
|
outputFile=new TQFile(filename);
|
|
if (! outputFile->open(IO_WriteOnly)) {
|
|
seterror(tr2i18n("Unable to open file ") + filename);
|
|
return;
|
|
}
|
|
|
|
currVOB=1;
|
|
|
|
currTS->startSector=startSector;
|
|
currTS->lastSector += currTS->menuSize ;
|
|
titleSets.append(currTS);
|
|
|
|
k9Ifo2 *kifo;
|
|
kifo=m_dvdread->getIfo(_VTS);
|
|
currTS->ifoTitle=kifo;
|
|
|
|
m_position=0;
|
|
m_copyMenu=false;
|
|
calcFactor();
|
|
}
|
|
|
|
currVTS=_VTS;
|
|
|
|
}
|
|
|
|
|
|
void k9DVDBackup::copyCell(int _VTS,k9Cell * _cell,bool _empty) {
|
|
if (error)
|
|
return;
|
|
|
|
prepareVTS(_VTS);
|
|
if (error)
|
|
return;
|
|
|
|
if (_cell->getforceFactor())
|
|
forceFactor( _cell->getFactor());
|
|
|
|
|
|
mutex.lock();
|
|
k9Cell *cell= currTS->addCell(_VTS,0,0);
|
|
//JMP cell->startSector=m_position;
|
|
cell->startSector=cell->cellList->getPosition();
|
|
currCell=cell;
|
|
//start cell copy
|
|
mutex.unlock();
|
|
if (!_empty) {
|
|
if (!vamps->running()) {
|
|
vamps->reset();
|
|
vamps->setPreserve(true);
|
|
vamps->setInputSize(argSize);
|
|
TQValueList<int>::iterator it;
|
|
for ( it = _cell->audio.begin(); it != _cell->audio.end(); ++it ) {
|
|
if (m_preserve)
|
|
vamps->addAudio(*it);
|
|
else
|
|
vamps->addAudio(*it,_cell->getTitleset()->getNewAudioStreamId(*it));
|
|
}
|
|
|
|
for ( it = _cell->subpicture.begin(); it != _cell->subpicture.end(); ++it ) {
|
|
vamps->addSubpicture(*it);
|
|
}
|
|
|
|
vamps->setVapFactor(argFactor);
|
|
vamps->start(TQThread::NormalPriority);
|
|
}
|
|
playCell(_VTS,_cell,_empty);
|
|
} else
|
|
copyEmptyPgc(_VTS,_cell);
|
|
tqApp->processEvents();
|
|
}
|
|
|
|
void k9DVDBackup::copyEmptyPgc(int _vts,k9Cell *_cell) {
|
|
if (error)
|
|
return;
|
|
|
|
ifo_handle_t *vts_handle=currTS->ifoTitle->getIFO();
|
|
;
|
|
|
|
k9DVDFile *dvdfile;
|
|
if ((dvdfile = m_dvdread->openTitle( _vts))== 0) {
|
|
TQString stmp;
|
|
stmp=i18n("Unable to open titleset %1").tqarg(_vts);
|
|
seterror(stmp);
|
|
return ;
|
|
}
|
|
backupDlg->setTotalSteps(vts_handle->vtsi_mat->vts_last_sector-vts_handle->vtsi_mat->vtstt_vobs -1);
|
|
TQString c;
|
|
c=i18n("Extracting titleset %1").tqarg(_vts);
|
|
backupDlg->setProgressLabel(c);
|
|
backupDlg->show();
|
|
|
|
|
|
uint32_t sector;
|
|
int32_t len=0;
|
|
uchar buffer[DVD_VIDEO_LB_LEN];
|
|
sector = _cell->startSector;
|
|
backupDlg->setProgress(sector);
|
|
dsi_t dsi_pack;
|
|
uint32_t nsectors;
|
|
|
|
len=dvdfile->readBlocks (sector, 1, buffer);
|
|
//JMP : D V C
|
|
if (!k9Cell::isNavPack( buffer) || len==-1)
|
|
setDummyNavPack( buffer,sector);
|
|
|
|
k9Vobu * vobu=currCell->addVobu(sector);
|
|
vobu->empty=true;
|
|
currCell->addNewVobus((char*)buffer,DVD_VIDEO_LB_LEN,currCell->cellList->getPosition(),currVOB,outputFile->at());
|
|
outputFile->writeBlock((char*)buffer,DVD_VIDEO_LB_LEN);
|
|
|
|
/* parse contained DSI pack */
|
|
navRead_DSI (&dsi_pack, buffer + DSI_START_BYTE);
|
|
currCell->vob = dsi_pack.dsi_gi.vobu_vob_idn;
|
|
|
|
//dummy video pack
|
|
setDummyPack( buffer);
|
|
currCell->addNewVobus((char*)buffer,DVD_VIDEO_LB_LEN,currCell->cellList->getPosition()+1,currVOB,outputFile->at());
|
|
outputFile->writeBlock((char*)buffer,DVD_VIDEO_LB_LEN);
|
|
|
|
nsectors=1;
|
|
len=1;
|
|
|
|
//vobu->size +=nsectors;
|
|
currCell->lastSector=currCell->startSector+ len;
|
|
currCell->cellList->setPosition(currCell->cellList->getPosition()+1+len);
|
|
currTS->lastSector+=len+1;
|
|
dvdfile->close();
|
|
backupDlg->setProgressTotal(len+1);
|
|
if (!m_forcedFactor) {
|
|
m_cellCopyList->addInbytes( DVD_VIDEO_LB_LEN *2);
|
|
m_cellCopyList->addOutbytes( DVD_VIDEO_LB_LEN *2);
|
|
} else {
|
|
m_cellCopyList->addFrcinbytes(DVD_VIDEO_LB_LEN *2);
|
|
m_cellCopyList->addFrcoutbytes( DVD_VIDEO_LB_LEN *2);
|
|
|
|
}
|
|
}
|
|
|
|
|
|
void k9DVDBackup::getOutput(uchar * buffer, uint32_t buflen) {
|
|
if (error)
|
|
return;
|
|
mutex.lock();
|
|
backupDlg->playMovie(buffer,buflen);
|
|
mutex.unlock();
|
|
|
|
if (!m_forcedFactor)
|
|
m_cellCopyList->addOutbytes( buflen);
|
|
else
|
|
m_cellCopyList->addFrcoutbytes( buflen);
|
|
|
|
uchar *temp =buffer;
|
|
TQString sName;
|
|
if ((buflen %2048) !=0)
|
|
qDebug("getOutput, buffer : %u",buflen);
|
|
uint end=0;
|
|
|
|
for (uint itemp=0;itemp<buflen;itemp+=DVD_VIDEO_LB_LEN) {
|
|
if (buflen-itemp <DVD_VIDEO_LB_LEN)
|
|
break;
|
|
|
|
|
|
mutex.lock();
|
|
long fileSize=outputFile->size();
|
|
end=itemp+DVD_VIDEO_LB_LEN;
|
|
if (k9Cell::isNavPack(temp+itemp)) {
|
|
|
|
k9Vobu * vobu = vobuQueue.dequeue();
|
|
|
|
cellOut=vobu->parent;
|
|
dsi_t dsiPack;
|
|
navRead_DSI (&dsiPack, (uchar*)(temp+itemp) + DSI_START_BYTE);
|
|
|
|
cellOut->vob = dsiPack.dsi_gi.vobu_vob_idn;
|
|
if ((dsiPack.dsi_gi.vobu_ea * DVD_VIDEO_LB_LEN) + fileSize >= (1024*1024*1024)) {
|
|
outputFile->close();
|
|
delete outputFile;
|
|
currVOB++;
|
|
if (currVTS==0)
|
|
sName = "/VIDEO_TS.VOB";
|
|
else
|
|
sName.sprintf("/VTS_%02d_%d.VOB",(int)currVTS,(int)currVOB);
|
|
sName=output+sName;
|
|
outputFile=new TQFile(sName);
|
|
if ( !outputFile->open(IO_WriteOnly)) {
|
|
seterror(tr2i18n("Unable to open file ") + sName);
|
|
mutex.unlock();
|
|
return;
|
|
}
|
|
}
|
|
}
|
|
cellOut->addNewVobus((char*)(temp+itemp),DVD_VIDEO_LB_LEN,cellOut->cellList->getPosition() ,currVOB,outputFile->at());
|
|
outputFile->writeBlock((char*)(temp+itemp),DVD_VIDEO_LB_LEN);
|
|
|
|
backupDlg->setProgressTotal(1);
|
|
cellOut->cellList->setPosition( cellOut->cellList->getPosition()+1);
|
|
if (!m_copyMenu)
|
|
currTS->lastSector++;
|
|
mutex.unlock();
|
|
}
|
|
}
|
|
|
|
|
|
/*!
|
|
\fn k9DVDBackup::setDevice(TQString _device)
|
|
*/
|
|
void k9DVDBackup::setDevice(TQString _device) {
|
|
device=_device;
|
|
}
|
|
|
|
|
|
/*!
|
|
\fn k9DVDBackup::setOutput(TQString _output)
|
|
*/
|
|
void k9DVDBackup::setOutput(TQString _output) {
|
|
output=TQDir::cleanDirPath(_output);
|
|
}
|
|
|
|
|
|
uint32_t k9DVDBackup::copyMenu2(int _vts) {
|
|
if (error || !m_withMenu )
|
|
return 0;
|
|
k9Ifo2 *kifo;
|
|
kifo=m_dvdread->getIfo( _vts);
|
|
ifo_handle_t *hifo =kifo->getIFO();
|
|
m_ifo=hifo;
|
|
uint32_t msize=0;
|
|
uint32_t menuLastSector;
|
|
if (_vts==0)
|
|
msize=hifo->vmgi_mat->vmg_last_sector -1 - 2* hifo->vmgi_mat->vmgi_last_sector;
|
|
else
|
|
msize=hifo->vtsi_mat->vtstt_vobs - hifo->vtsi_mat->vtsi_last_sector -1;
|
|
|
|
if (msize==0) {
|
|
//kifo.closeIFO();
|
|
return 0;
|
|
}
|
|
menuLastSector=msize-1;
|
|
|
|
|
|
m_position=0;
|
|
m_copyMenu=true;
|
|
TQString targetName;
|
|
if (_vts == 0) {
|
|
targetName="VIDEO_TS.VOB";
|
|
} else {
|
|
targetName.sprintf("VTS_%02i_0.VOB",_vts);
|
|
}
|
|
targetName=output+"/"+targetName;
|
|
|
|
outputFile=new TQFile(targetName);
|
|
if (! outputFile->open(IO_WriteOnly)) {
|
|
seterror(tr2i18n("Unable to open file ") + targetName);
|
|
return 0;
|
|
}
|
|
|
|
k9DVDFile *dvdfile;
|
|
if ((dvdfile = m_dvdread->openMenu( _vts))== 0) {
|
|
TQString stmp;
|
|
stmp=i18n("Unable to open menu for titleset %1").tqarg(_vts);
|
|
seterror (stmp);
|
|
return 0;
|
|
}
|
|
|
|
k9CellList *lstCell;
|
|
if (_vts==0)
|
|
lstCell = &vmgCells;
|
|
else
|
|
lstCell = &currTS->menuCells;
|
|
|
|
lstCell->setAutoDelete(true);
|
|
|
|
|
|
c_adt_t *c_adt = hifo->menu_c_adt;
|
|
// c_adt shouldn't be null. It would say that the menu doesn't contain video !?
|
|
if (c_adt==NULL)
|
|
return 0;
|
|
|
|
uint32_t length = c_adt->last_byte + 1 - C_ADT_SIZE;
|
|
cell_adr_t *ptr;
|
|
ptr= c_adt->cell_adr_table;
|
|
|
|
uint32_t sector, dsi_next_vobu = 0;
|
|
uint32_t imax=length/sizeof(cell_adr_t);
|
|
TQString c;
|
|
c=i18n("Extracting menu for titleset %1").tqarg(_vts);
|
|
backupDlg->setProgressLabel(c);
|
|
|
|
backupDlg->show();
|
|
backupDlg->setTotalSteps(ptr[imax-1].last_sector);
|
|
|
|
k9CadtList cadr;
|
|
|
|
uint32_t nbCells=0;
|
|
for (uint32_t i=0;i<imax;i++) {
|
|
if ((ptr+i)->last_sector > menuLastSector)
|
|
(ptr+i)->last_sector=menuLastSector;
|
|
|
|
if ((ptr+i)->start_sector <= menuLastSector) {
|
|
cadr.append(ptr+i);
|
|
nbCells++;
|
|
}
|
|
//else
|
|
//qDebug() << TQString("cell start sector (%1) exceed menu size (%2)").tqarg((ptr+i)->start_sector).tqarg(menuLastSector);
|
|
}
|
|
cadr.sort();
|
|
vamps->reset();
|
|
vamps->setPreserve(true);
|
|
for (uint i=1;i<=8;i++)
|
|
vamps->addAudio(i);
|
|
|
|
for (uint i=1;i<=32;i++)
|
|
vamps->addSubpicture(i);
|
|
|
|
vamps->setVapFactor(argFactor);
|
|
vamps->setInputSize(msize*2048);
|
|
|
|
vamps->start(TQThread::NormalPriority);
|
|
// while(!vamps->running() && !vamps->finished());
|
|
|
|
for(uint32_t i = 0; i < nbCells; i++) {
|
|
currCell=lstCell->addCell(_vts,1,1);
|
|
dsi_next_vobu=0;
|
|
cell_adr_t * cellAdr=cadr.at(i);
|
|
for (sector = cellAdr->start_sector;
|
|
sector <= cellAdr->last_sector; sector += dsi_next_vobu & 0x7fffffff) {
|
|
backupDlg->setProgress(sector);
|
|
if (backupDlg->getAbort()) {
|
|
seterror(tr2i18n("DVD backup cancelled"));
|
|
}
|
|
|
|
if (error) {
|
|
vamps->abort();
|
|
break;
|
|
} else if (vamps->geterror()) {
|
|
seterror( vamps->geterrMsg());
|
|
break;
|
|
}
|
|
dsi_next_vobu= copyVobu(dvdfile,sector,NULL);
|
|
}
|
|
}
|
|
vamps->setNoData();
|
|
vamps->wait();
|
|
uint32_t size=0;
|
|
|
|
//JMP size=m_position;
|
|
size =lstCell->getPosition();
|
|
|
|
dvdfile->close();
|
|
outputFile->close();
|
|
delete outputFile;
|
|
outputFile=NULL;
|
|
//kifo.closeIFO();
|
|
|
|
updateVob(lstCell);
|
|
|
|
m_copyMenu=false;
|
|
return size;
|
|
}
|
|
|
|
|
|
|
|
|
|
void k9DVDBackup::playCell (int vts_num, k9Cell *_cell,bool _empty) {
|
|
|
|
if (error)
|
|
return;
|
|
|
|
ifo_handle_t *vts_handle;
|
|
k9DVDFile *dvdfile;
|
|
uint32_t sector, dsi_next_vobu = 0;
|
|
/* open disc */
|
|
if (m_dvdread->opened()) {
|
|
/* load information for the given VTS */
|
|
// vts_handle = ifoOpen (dvd_handle, vts_num);
|
|
vts_handle=currTS->ifoTitle->getIFO();
|
|
if (!vts_handle) {
|
|
TQString stmp;
|
|
stmp=i18n("Unable to open ifo file for titleset %1").tqarg(vts_num);
|
|
seterror (stmp);
|
|
//JMP vamps->setNoData();
|
|
return;
|
|
}
|
|
|
|
backupDlg->setTotalSteps( vts_handle->vtsi_mat->vts_last_sector-vts_handle->vtsi_mat->vtstt_vobs -1);
|
|
TQString c;
|
|
c=i18n("Extracting titleset %1").tqarg(vts_num);
|
|
backupDlg->setProgressLabel(c);
|
|
backupDlg->show();
|
|
} else {
|
|
seterror(tr2i18n("Unable to open DVD"));
|
|
//JMP vamps->setNoData();
|
|
return;
|
|
}
|
|
|
|
|
|
/* open VTS data */
|
|
dvdfile = m_dvdread->openTitle (vts_num);
|
|
if (! dvdfile) {
|
|
TQString stmp;
|
|
stmp=i18n("Unable to open vobs for titleset %1").tqarg(vts_num);
|
|
seterror( stmp);
|
|
//JMP vamps->setNoData();
|
|
return;
|
|
}
|
|
|
|
|
|
/* loop until out of the cell */
|
|
//TO REMOVE currCell->oldStartSector=_cell->startSector;
|
|
for (sector = _cell->startSector;
|
|
sector <= _cell->lastSector; sector += dsi_next_vobu & 0x7fffffff) {
|
|
|
|
backupDlg->setProgress(sector);
|
|
if (backupDlg->getAbort()) {
|
|
seterror(tr2i18n("DVD backup cancelled"));
|
|
}
|
|
|
|
if (error) {
|
|
vamps->abort();
|
|
break;
|
|
} else if (vamps->geterror()) {
|
|
seterror( vamps->geterrMsg());
|
|
break;
|
|
}
|
|
dsi_next_vobu= copyVobu(dvdfile,sector,NULL,_empty);
|
|
}
|
|
dvdfile->close();
|
|
}
|
|
|
|
void k9DVDBackup::setDummyNavPack(uchar *buf,uint32_t _sector)
|
|
{
|
|
int8_t *ptr = (int8_t*)buf;
|
|
static uint8_t nav_pack1 [] =
|
|
{
|
|
/* pack header: SCR=0, mux rate=10080000bps, stuffing length=0 */
|
|
0, 0, 1, 0xba, 0x44, 0x00, 0x04, 0x00, 0x04, 0x01, 0x01, 0x89, 0xc3, 0xf8,
|
|
/* system header */
|
|
0, 0, 1, 0xbb, 0x00, 0x12,
|
|
/* contents of system header filled in at run time (18 bytes) */
|
|
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
|
/* PES header for first private stream 2 packet */
|
|
0, 0, 1, 0xbf, 0x03, 0xd4
|
|
};
|
|
static uint8_t nav_pack2 [] =
|
|
{
|
|
/* PES header for second private stream 2 packet */
|
|
0, 0, 1, 0xbf, 0x03, 0xfa
|
|
};
|
|
|
|
tc_memcpy (ptr, nav_pack1, sizeof (nav_pack1));
|
|
ptr += sizeof (nav_pack1);
|
|
memset (ptr, 0, DVD_VIDEO_LB_LEN/2 - sizeof (nav_pack1));
|
|
ptr = (int8_t*)buf + DVD_VIDEO_LB_LEN/2;
|
|
tc_memcpy (ptr, nav_pack2, sizeof (nav_pack2));
|
|
ptr += sizeof (nav_pack2);
|
|
memset (ptr, 0, DVD_VIDEO_LB_LEN/2 - sizeof (nav_pack2));
|
|
|
|
dsi_t dsiPack;
|
|
pci_t pciPack;
|
|
navRead_DSI (&dsiPack, buf + DSI_START_BYTE);
|
|
k9Ifo2::navRead_PCI (&pciPack, buf+0x2d);
|
|
dsiPack.dsi_gi.nv_pck_lbn=_sector;
|
|
dsiPack.dsi_gi.vobu_ea = 1;
|
|
|
|
navRead_DSI((dsi_t*)(buf + DSI_START_BYTE),(uchar*)&dsiPack);
|
|
pciPack.pci_gi.nv_pck_lbn =dsiPack.dsi_gi.nv_pck_lbn;
|
|
k9Ifo2::navRead_PCI((pci_t*)(buf+0x2d),(uchar*)&pciPack);
|
|
}
|
|
|
|
|
|
void k9DVDBackup::setDummyPack(uchar *_buffer) {
|
|
int8_t *ptr = (int8_t*)_buffer;
|
|
uint8_t dummy_pack [] =
|
|
{
|
|
/* pack header: SCR=0, mux rate=10080000bps, stuffing length=0 */
|
|
0, 0, 1, 0xba, 0x44, 0x00, 0x04, 0x00, 0x04, 0x01, 0x01, 0x89, 0xc3, 0xf8,
|
|
/* PES header for dummy video packet */
|
|
0, 0, 1, 0xe0, 0x07, 0xec, 0x81, 0x00, 0x00
|
|
};
|
|
|
|
tc_memcpy (ptr, dummy_pack, sizeof (dummy_pack));
|
|
ptr += sizeof (dummy_pack);
|
|
memset (ptr, 0xff, DVD_VIDEO_LB_LEN - sizeof (dummy_pack));
|
|
|
|
}
|
|
|
|
|
|
uint32_t k9DVDBackup::findNextVobu(uint32_t _sector) {
|
|
k9Ifo2 *ifo;
|
|
ifo = m_dvdread->getIfo(currVTS);
|
|
m_ifo=ifo->getIFO();
|
|
vobu_admap_t * vobu_admap;
|
|
if (m_copyMenu)
|
|
vobu_admap = m_ifo->menu_vobu_admap;
|
|
else
|
|
vobu_admap = m_ifo->vts_vobu_admap;
|
|
uint32_t length = vobu_admap->last_byte + 1 - VOBU_ADMAP_SIZE;
|
|
for(uint32_t i = 0; i < length/sizeof(uint32_t); i++) {
|
|
if (vobu_admap->vobu_start_sectors[i] >= _sector) {
|
|
uint32_t nextVobu=vobu_admap->vobu_start_sectors[i+1];
|
|
//ifo.closeIFO();
|
|
return nextVobu;
|
|
}
|
|
}
|
|
//ifo.closeIFO();
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
uint32_t k9DVDBackup::copyVobu(k9DVDFile *_fileHandle,uint32_t _startSector,k9Vobu * _vobu,bool _empty) {
|
|
dsi_t dsi_pack;
|
|
k9Vobu * currVobu;
|
|
bool badNavPack=false;
|
|
|
|
uint32_t nsectors, nextVobu=0;
|
|
int32_t len=0;
|
|
uchar *buf;
|
|
uint32_t sector=_startSector;
|
|
/* read nav pack */
|
|
buf=(uchar*) malloc(DVD_VIDEO_LB_LEN);
|
|
len = _fileHandle->readBlocks ( sector, 1, buf);
|
|
/* parse contained DSI pack */
|
|
|
|
//test if nav pack is ok
|
|
if (len !=-1) {
|
|
navRead_DSI (&dsi_pack, buf + DSI_START_BYTE);
|
|
if (dsi_pack.dsi_gi.nv_pck_lbn != sector) {
|
|
len=-1;
|
|
}
|
|
}
|
|
|
|
if (len==-1) {
|
|
setDummyNavPack(buf,sector);
|
|
nextVobu=findNextVobu(sector);
|
|
qDebug ("VOBU : %u Read Error !!!! ==> %u",sector,nextVobu);
|
|
badNavPack=true;
|
|
}
|
|
currVobu=_vobu;
|
|
|
|
mutex.lock();
|
|
if (k9Cell::isNavPack(buf)) {
|
|
//TO REMOVE currCell->oldLastSector=sector;
|
|
if (currVobu==NULL) {
|
|
currVobu =currCell->addVobu(sector);
|
|
vobuQueue.enqueue(currVobu);
|
|
}
|
|
}
|
|
mutex.unlock();
|
|
/* generate an MPEG2 program stream (including nav packs) */
|
|
wrote=false;
|
|
|
|
vamps->addData(buf,DVD_VIDEO_LB_LEN);
|
|
|
|
|
|
|
|
if (!m_forcedFactor)
|
|
m_cellCopyList->addInbytes( DVD_VIDEO_LB_LEN);
|
|
else
|
|
m_cellCopyList->addFrcinbytes(DVD_VIDEO_LB_LEN);
|
|
uint32_t end;
|
|
|
|
if (badNavPack) {
|
|
setDummyPack(buf);
|
|
nsectors=1;
|
|
if (nextVobu !=0) end=nextVobu-_startSector-1;
|
|
|
|
} else {
|
|
if (!_empty)
|
|
nsectors = dsi_pack.dsi_gi.vobu_ea;
|
|
else
|
|
nsectors = 1;
|
|
|
|
//uint32_t dsi_next_vobu = dsi_pack.vobu_sri.next_vobu;
|
|
|
|
buf=(uchar*) realloc(buf,nsectors*DVD_VIDEO_LB_LEN);
|
|
|
|
end=dsi_pack.dsi_gi.vobu_ea;
|
|
|
|
if (_empty)
|
|
setDummyPack(buf);
|
|
/* read VOBU */
|
|
else
|
|
for (uint32_t i=0;i< nsectors;i++) {
|
|
len = _fileHandle->readBlocks ( (sector + 1)+i, 1, buf +(i*DVD_VIDEO_LB_LEN));
|
|
if (len==-1) {
|
|
qDebug ("VOBU : %u Read Error !!!!",sector);
|
|
//setDummyPack(buf + (i*DVD_VIDEO_LB_LEN));
|
|
setDummyPack(buf);
|
|
nsectors=1;
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
|
|
/* write VOBU */
|
|
for (uint32_t i=0;i<nsectors ;i++) {
|
|
vamps->addData(buf + (i*DVD_VIDEO_LB_LEN), DVD_VIDEO_LB_LEN);
|
|
}
|
|
free(buf);
|
|
|
|
if (! m_forcedFactor)
|
|
m_cellCopyList->addInbytes( nsectors*DVD_VIDEO_LB_LEN);
|
|
else
|
|
m_cellCopyList->addFrcinbytes( nsectors*DVD_VIDEO_LB_LEN);
|
|
|
|
mutex.lock();
|
|
tqApp->processEvents();
|
|
mutex.unlock();
|
|
|
|
return (end+1);
|
|
}
|
|
|
|
|
|
|
|
k9Vobu * k9DVDBackup::remapVobu(uint32_t *value) {
|
|
k9Vobu *vobu=NULL;
|
|
uint32_t sector,mask;
|
|
if ( (*value & 0x80000000) == 0x80000000) {
|
|
sector = *value & 0x7FFFFFFF;
|
|
mask=0x80000000;
|
|
} else {
|
|
sector =*value;
|
|
mask=0;
|
|
}
|
|
*value=0;
|
|
k9CellList *lstCell;
|
|
if(! m_copyMenu) {
|
|
lstCell=&(currTS->cells);
|
|
} else {
|
|
if (currVTS==0)
|
|
lstCell=&vmgCells;
|
|
else
|
|
lstCell=&(currTS->menuCells);
|
|
}
|
|
vobu=lstCell->findVobu(sector);
|
|
if (vobu !=NULL) {
|
|
*value = vobu->newSector | mask;
|
|
return vobu;
|
|
}
|
|
|
|
*value=0;
|
|
return vobu;
|
|
|
|
}
|
|
|
|
|
|
k9Vobu * k9DVDBackup::remapOffset(uint32_t _sector,uint32_t *_offset,int _dir) {
|
|
k9Vobu *vobu1=NULL, *vobu2=NULL;
|
|
uint32_t offset,sector;
|
|
uint32_t maskOffset1=0,maskOffset2=0,maskSector=0;
|
|
|
|
if ((*_offset!= 0xbfffffff) && (*_offset!=0x3fffffff) && (*_offset!=0x7fffffff)) {
|
|
|
|
if ( (*_offset & 0x80000000) == 0x80000000)
|
|
maskOffset1= 0x80000000;
|
|
if ( (*_offset & 0x40000000) == 0x40000000)
|
|
maskOffset2= 0x40000000;
|
|
offset = *_offset & 0x3FFFFFFF;
|
|
|
|
if ( (_sector & 0x80000000) == 0x80000000) {
|
|
sector = _sector & 0x7FFFFFFF;
|
|
maskSector=0x80000000;
|
|
} else {
|
|
sector =_sector;
|
|
maskSector=0;
|
|
}
|
|
|
|
k9CellList *lstCell;
|
|
if(! m_copyMenu) {
|
|
lstCell=&(currTS->cells);
|
|
} else {
|
|
if (currVTS==0)
|
|
lstCell=&vmgCells;
|
|
else
|
|
lstCell=&(currTS->menuCells);
|
|
}
|
|
vobu1 = lstCell->findVobu(sector);
|
|
vobu2 = lstCell->findVobu(sector+_dir*offset);
|
|
|
|
|
|
|
|
if ((vobu1 !=NULL) && (vobu2!=NULL)) {
|
|
*_offset = abs(vobu1->newSector - vobu2->newSector) | maskOffset1 ;
|
|
*_offset |= maskOffset2;
|
|
return vobu2;
|
|
}
|
|
|
|
if (vobu1==NULL && vobu2==NULL)
|
|
qDebug ("remapOffset : sector not found");
|
|
}
|
|
return vobu2;
|
|
}
|
|
|
|
|
|
void k9DVDBackup::updateMainIfo() {
|
|
|
|
if (error)
|
|
return;
|
|
|
|
k9Ifo2 ifo(m_dvdread);
|
|
ifo.setOutput(output);
|
|
ifo.setDevice(device);
|
|
|
|
ifo.openIFO(0);
|
|
ifo_handle_t *hifo =ifo.getIFO();
|
|
|
|
hifo->vmgi_mat->vmg_last_sector= 1+ m_vmgSize+hifo->vmgi_mat->vmgi_last_sector*2;
|
|
if (m_vmgSize >0) {
|
|
if (hifo->vmgi_mat->vmgm_vobs != hifo->vmgi_mat->vmgi_last_sector +1)
|
|
qDebug ("error in ifo file : vmgm_vobs %u -> %u)",hifo->vmgi_mat->vmgm_vobs,hifo->vmgi_mat->vmgi_last_sector +1);
|
|
hifo->vmgi_mat->vmgm_vobs=hifo->vmgi_mat->vmgi_last_sector +1;
|
|
}
|
|
|
|
currVTS=0;
|
|
|
|
k9Vobu* vobu2=NULL;
|
|
uint32_t newPos=0;
|
|
//update first play PGC
|
|
if (hifo->first_play_pgc !=NULL ) {
|
|
m_copyMenu=true;
|
|
pgc_t *pgc=hifo->first_play_pgc;
|
|
if (! m_withMenu && pgc->command_tbl!=0 ) {
|
|
pgc->command_tbl->nr_of_pre=0;
|
|
pgc->command_tbl->nr_of_post=0;
|
|
pgc->command_tbl->nr_of_cell=0;
|
|
}
|
|
|
|
|
|
cell_playback_t *cell_playback =pgc->cell_playback;
|
|
uint32_t nr= pgc->nr_of_cells;
|
|
|
|
vobu2=NULL;
|
|
cell_playback_t cell;
|
|
newPos=0;
|
|
for( uint32_t j = 0; j < nr; j++) {
|
|
k9Vobu *vobu=remapVobu(&cell_playback[j].first_sector);
|
|
vobu2=vobu;
|
|
|
|
remapVobu(&cell_playback[j].first_ilvu_end_sector);
|
|
if (vobu !=NULL) {
|
|
vobu=remapVobu(&cell_playback[j].last_vobu_start_sector);
|
|
if (vobu==NULL) {
|
|
cell_playback[j].last_vobu_start_sector=cell_playback[j].first_sector;
|
|
vobu=vobu2;
|
|
pgc->playback_time.hour=0;
|
|
pgc->playback_time.minute=0;
|
|
pgc->playback_time.second=0;
|
|
|
|
cell_playback[j].playback_time.hour=0;
|
|
cell_playback[j].playback_time.minute=0;
|
|
cell_playback[j].playback_time.second=0;
|
|
}
|
|
cell_playback[j].last_sector = vobu->newSector+vobu->size;// -1 ;
|
|
cell_playback[newPos]=cell_playback[j];
|
|
cell=cell_playback[newPos];
|
|
newPos++;
|
|
} else {
|
|
cell_playback[newPos]=cell;
|
|
newPos++;
|
|
}
|
|
}
|
|
for (uint32_t j=newPos;j<nr;j++)
|
|
cell_playback[j].last_sector=0;
|
|
pgc->nr_of_cells=newPos;
|
|
m_copyMenu=false;
|
|
}
|
|
|
|
|
|
|
|
updatePgci_ut(hifo);
|
|
update4Menu(hifo);
|
|
|
|
//mise �jour des startSectors
|
|
k9TitleSet *TSp=NULL;
|
|
titleSets.sort();
|
|
for (uint iTS=0;iTS < titleSets.count();iTS++) {
|
|
k9TitleSet *TS=titleSets.at(iTS);
|
|
uint32_t startSector;
|
|
if (TSp!=NULL)
|
|
startSector = TSp->startSector + TSp->getSize();
|
|
else
|
|
startSector=hifo->vmgi_mat->vmg_last_sector+1 ;
|
|
TS->startSector=startSector;
|
|
TSp=TS;
|
|
}
|
|
|
|
hifo->vmgi_mat->vmg_category=0;
|
|
bool found=false;
|
|
for (uint32_t i=0 ; i< hifo->tt_srpt->nr_of_srpts;i++) {
|
|
for (uint iTS=0;iTS<titleSets.count() &&(!found);iTS++) {
|
|
k9TitleSet *TS=titleSets.at(iTS);
|
|
if (TS->VTS == hifo->tt_srpt->title[i].title_set_nr ) {
|
|
hifo->tt_srpt->title[i].title_set_sector = TS->startSector;
|
|
found=true;
|
|
}
|
|
}
|
|
found=false;
|
|
}
|
|
|
|
ifo.saveIFO();
|
|
ifo.closeIFO();
|
|
|
|
}
|
|
|
|
void k9DVDBackup::updatePgci_ut(ifo_handle_t *_hifo) {
|
|
pgci_ut_t *pgci_ut=_hifo->pgci_ut;
|
|
k9Vobu* vobu2=NULL;
|
|
uint newPos=0;
|
|
//update pgci_ut
|
|
|
|
if (pgci_ut !=0 && m_withMenu) {
|
|
m_copyMenu=true;
|
|
for (uint i=0; i <pgci_ut->nr_of_lus;i++) {
|
|
pgci_lu_t *pgci_lu= &pgci_ut->lu[i];
|
|
pgcit_t * pgcit= pgci_lu->pgcit;
|
|
for (uint i2=0 ; i2 <pgcit->nr_of_pgci_srp;i2++) {
|
|
pgci_srp_t * pgci_srp=&pgcit->pgci_srp[i2];
|
|
pgc_t *pgc=pgci_srp->pgc;
|
|
|
|
|
|
if (! m_withMenu && pgc->command_tbl!=0) {
|
|
pgc->command_tbl->nr_of_pre=0;
|
|
pgc->command_tbl->nr_of_post=0;
|
|
pgc->command_tbl->nr_of_cell=0;
|
|
}
|
|
|
|
cell_playback_t *cell_playback =pgc->cell_playback;
|
|
uint32_t nr= pgc->nr_of_cells;
|
|
|
|
vobu2=NULL;
|
|
cell_playback_t cell;
|
|
newPos=0;
|
|
for( uint32_t j = 0; j < nr; j++) {
|
|
k9Vobu *vobu=remapVobu(&cell_playback[j].first_sector);
|
|
vobu2=vobu;
|
|
|
|
if (cell_playback[j].first_ilvu_end_sector !=0) {
|
|
uint32_t tmp=cell_playback[j].first_ilvu_end_sector+1;
|
|
remapVobu(&tmp);
|
|
if (tmp!=0)
|
|
cell_playback[j].first_ilvu_end_sector=tmp-1;
|
|
}
|
|
if (vobu !=NULL) {
|
|
vobu=remapVobu(&cell_playback[j].last_vobu_start_sector);
|
|
if (vobu !=NULL)
|
|
cell_playback[j].last_sector = vobu->newSector+vobu->size;// -1 ;
|
|
cell_playback[newPos]=cell_playback[j];
|
|
cell=cell_playback[newPos];
|
|
newPos++;
|
|
} else {
|
|
cell_playback[newPos]=cell;
|
|
newPos++;
|
|
}
|
|
}
|
|
for (uint32_t j=newPos;j<nr;j++)
|
|
cell_playback[j].last_sector=0;
|
|
pgc->nr_of_cells=newPos;
|
|
}
|
|
}
|
|
m_copyMenu=false;
|
|
}
|
|
|
|
if (!m_withMenu ) {
|
|
k9Script *script=new k9Script(_hifo,DVD);
|
|
script->updatePGCIUT();
|
|
script->updateFPPGC();
|
|
delete script;
|
|
if (_hifo->vmgi_mat) {
|
|
_hifo->vmgi_mat->vmgm_c_adt=0;
|
|
_hifo->vmgi_mat->vmgm_vobu_admap=0;
|
|
} else {
|
|
_hifo->vtsi_mat->vtsm_c_adt=0;
|
|
_hifo->vtsi_mat->vtsm_vobu_admap=0;
|
|
}
|
|
}
|
|
|
|
|
|
}
|
|
|
|
void k9DVDBackup::update4Menu(ifo_handle_t *_hifo) {
|
|
if (!m_withMenu)
|
|
return;
|
|
// Mise �jour vtsm_c_adt pour le menu
|
|
m_copyMenu=true; //indispensable pour remapvobu
|
|
c_adt_t *c_adt = _hifo->menu_c_adt;
|
|
uint32_t length;
|
|
if (c_adt!=NULL) {
|
|
length = c_adt->last_byte + 1 - C_ADT_SIZE;
|
|
cell_adr_t *ptr= c_adt->cell_adr_table;
|
|
for(uint32_t i = 0; i < length/sizeof(cell_adr_t); i++) {
|
|
uint32_t startSect=ptr[i].start_sector;
|
|
// last sector of a vobu = start sector of next vobu -1
|
|
uint32_t lastSect= ptr[i].last_sector +1;
|
|
k9Vobu *vobu=remapVobu(&startSect);
|
|
if (vobu == NULL)
|
|
qDebug ("Error : could not find startSector");
|
|
else {
|
|
if (remapVobu(&lastSect)==NULL)
|
|
lastSect=vobu->parent->lastSector;
|
|
else
|
|
lastSect--;
|
|
ptr[i].start_sector = startSect;
|
|
ptr[i].last_sector = lastSect;
|
|
}
|
|
|
|
}
|
|
}
|
|
|
|
vobu_admap_t * vobu_admap = _hifo->menu_vobu_admap;
|
|
if (vobu_admap != NULL) {
|
|
length = vobu_admap->last_byte + 1 - VOBU_ADMAP_SIZE;
|
|
uint newPos=0;
|
|
for(uint32_t i = 0; i < length/sizeof(uint32_t); i++) {
|
|
if (remapVobu(&vobu_admap->vobu_start_sectors[i])!= NULL) {
|
|
vobu_admap->vobu_start_sectors[newPos]=vobu_admap->vobu_start_sectors[i];
|
|
newPos++;
|
|
}
|
|
}
|
|
for (uint32_t i=newPos ; i < length/sizeof(uint32_t);i++)
|
|
vobu_admap->vobu_start_sectors[i]=0;
|
|
|
|
vobu_admap->last_byte = newPos * sizeof(uint32_t) -1 +VOBU_ADMAP_SIZE;
|
|
}
|
|
m_copyMenu=false;
|
|
|
|
}
|
|
|
|
void k9DVDBackup::updateIfo() {
|
|
|
|
if (error)
|
|
return;
|
|
|
|
k9Ifo2 ifo(m_dvdread);
|
|
ifo.setOutput(output);
|
|
ifo.setDevice(device);
|
|
|
|
ifo.openIFO(currVTS);
|
|
|
|
ifo_handle_t *hifo =ifo.getIFO();
|
|
|
|
pgcit_t * pgcit = hifo->vts_pgcit;
|
|
|
|
//update total VTS size with IFO size
|
|
currTS->lastSector += 2 *(hifo->vtsi_mat->vtsi_last_sector ) +1;
|
|
|
|
hifo->vtsi_mat->vts_last_sector = currTS->lastSector ;
|
|
|
|
hifo->vtsi_mat->vtstt_vobs = hifo->vtsi_mat->vtsi_last_sector + 1 + currTS->menuSize;
|
|
//JMP
|
|
if (currTS->menuSize >0) {
|
|
if (hifo->vtsi_mat->vtsm_vobs != hifo->vtsi_mat->vtsi_last_sector +1)
|
|
qDebug ("error in ifo file %u : vtsm_vobs %u -> %u",currTS->VTS,hifo->vtsi_mat->vtsm_vobs,hifo->vtsi_mat->vtsi_last_sector +1);
|
|
hifo->vtsi_mat->vtsm_vobs= hifo->vtsi_mat->vtsi_last_sector +1 ;
|
|
|
|
}else
|
|
hifo->vtsi_mat->vtsm_vobs=0;
|
|
|
|
updatePgci_ut(hifo);
|
|
|
|
k9Vobu* vobu2=NULL;
|
|
uint32_t newPos=0;
|
|
//update first play PGC
|
|
if (hifo->first_play_pgc !=NULL ) {
|
|
pgc_t *pgc=hifo->first_play_pgc;
|
|
if (! m_withMenu && pgc->command_tbl!=0) {
|
|
pgc->command_tbl->nr_of_pre=0;
|
|
pgc->command_tbl->nr_of_post=0;
|
|
pgc->command_tbl->nr_of_cell=0;
|
|
}
|
|
cell_playback_t *cell_playback =pgc->cell_playback;
|
|
uint32_t nr= pgc->nr_of_cells;
|
|
|
|
vobu2=NULL;
|
|
cell_playback_t cell;
|
|
newPos=0;
|
|
for( uint j = 0; j < nr; j++) {
|
|
k9Vobu *vobu=remapVobu(&cell_playback[j].first_sector);
|
|
vobu2=vobu;
|
|
|
|
remapVobu(&cell_playback[j].first_ilvu_end_sector);
|
|
if (vobu !=NULL) {
|
|
vobu=remapVobu(&cell_playback[j].last_vobu_start_sector);
|
|
if (vobu==NULL) {
|
|
cell_playback[j].last_vobu_start_sector=cell_playback[j].first_sector;
|
|
vobu=vobu2;
|
|
pgc->playback_time.hour=0;
|
|
pgc->playback_time.minute=0;
|
|
pgc->playback_time.second=0;
|
|
|
|
cell_playback[j].playback_time.hour=0;
|
|
cell_playback[j].playback_time.minute=0;
|
|
cell_playback[j].playback_time.second=0;
|
|
}
|
|
cell_playback[j].last_sector = vobu->newSector+vobu->size;// -1 ;
|
|
cell_playback[newPos]=cell_playback[j];
|
|
cell=cell_playback[newPos];
|
|
newPos++;
|
|
} else {
|
|
cell_playback[newPos]=cell;
|
|
newPos++;
|
|
}
|
|
}
|
|
for (uint32_t j=newPos;j<nr;j++)
|
|
cell_playback[j].last_sector=0;
|
|
pgc->nr_of_cells=newPos;
|
|
}
|
|
|
|
newPos=0;
|
|
|
|
|
|
audio_attr_t vts_audio_attr[8];
|
|
|
|
//update each PGC
|
|
bool bUpdateAudioAttr=true;
|
|
|
|
if (!m_preserve) {
|
|
memcpy (vts_audio_attr, hifo->vtsi_mat->vts_audio_attr,sizeof(audio_attr_t)*8);
|
|
memset(hifo->vtsi_mat->vts_audio_attr,0,sizeof(audio_attr_t)*8);
|
|
}
|
|
|
|
for(uint32_t i = 0; i < pgcit->nr_of_pgci_srp; i++) {
|
|
pgc_t *pgc=pgcit->pgci_srp[i].pgc;
|
|
int numTitle=pgcit->pgci_srp[i].entry_id & 0x7F;
|
|
|
|
if (! m_withMenu) {
|
|
k9Script *script=new k9Script(hifo,DVD);
|
|
script->updatePGC(pgc,currTS->VTS,numTitle);
|
|
delete script;
|
|
}
|
|
|
|
//shift audio streams;
|
|
if (!m_preserve) {
|
|
int idx=0;
|
|
uint16_t audio_control [8];
|
|
memcpy(audio_control,pgc->audio_control,sizeof(uint16_t) *8);
|
|
memset(pgc->audio_control,0,sizeof(uint16_t) *8);
|
|
for (int istr=0; istr< 8; istr++) {
|
|
uint16_t ctrl=audio_control[istr] & 0xF8FF;
|
|
int streamId = 1+ ((audio_control[istr]>>8) & 0x7) ;
|
|
int newStreamId = DVD->gettitleset(currTS->VTS-1)->getNewAudioStreamId(streamId);
|
|
if (newStreamId !=0) {
|
|
pgc->audio_control[idx]=ctrl | ((newStreamId-1)<<8);
|
|
if (bUpdateAudioAttr) {
|
|
hifo->vtsi_mat->vts_audio_attr[idx]=vts_audio_attr[istr];
|
|
}
|
|
idx++;
|
|
}
|
|
}
|
|
if (bUpdateAudioAttr)
|
|
hifo->vtsi_mat->nr_of_vts_audio_streams=idx;
|
|
bUpdateAudioAttr=false;
|
|
}
|
|
|
|
cell_playback_t *cell_playback =pgc->cell_playback;
|
|
uint32_t nr= pgc->nr_of_cells;
|
|
|
|
vobu2=NULL;
|
|
cell_playback_t cell;
|
|
newPos=0;
|
|
for( uint32_t j = 0; j < nr; j++) {
|
|
k9Vobu *vobu=remapVobu(&cell_playback[j].first_sector);
|
|
vobu2=vobu;
|
|
|
|
if (cell_playback[j].first_ilvu_end_sector !=0) {
|
|
uint32_t tmp=cell_playback[j].first_ilvu_end_sector+1;
|
|
remapVobu(&tmp);
|
|
if (tmp!=0)
|
|
cell_playback[j].first_ilvu_end_sector=tmp-1;
|
|
}
|
|
if (vobu !=NULL) {
|
|
vobu=remapVobu(&cell_playback[j].last_vobu_start_sector);
|
|
if (vobu==NULL) {
|
|
cell_playback[j].last_vobu_start_sector=cell_playback[j].first_sector;
|
|
vobu=vobu2;
|
|
pgc->playback_time.hour=0;
|
|
pgc->playback_time.minute=0;
|
|
pgc->playback_time.second=0;
|
|
|
|
cell_playback[j].playback_time.hour=0;
|
|
cell_playback[j].playback_time.minute=0;
|
|
cell_playback[j].playback_time.second=0;
|
|
|
|
}
|
|
cell_playback[j].last_sector = vobu->newSector+vobu->size;// -1 ;
|
|
cell_playback[newPos]=cell_playback[j];
|
|
cell=cell_playback[newPos];
|
|
newPos++;
|
|
} else {
|
|
cell_playback[newPos]=cell;
|
|
newPos++;
|
|
}
|
|
}
|
|
for (uint32_t j=newPos;j<nr;j++)
|
|
cell_playback[j].last_sector=0;
|
|
pgc->nr_of_cells=newPos;
|
|
}
|
|
|
|
|
|
c_adt_t *c_adt = hifo->vts_c_adt;
|
|
uint32_t length = c_adt->last_byte + 1 - C_ADT_SIZE;
|
|
cell_adr_t *ptr= c_adt->cell_adr_table;
|
|
newPos=0;
|
|
for(uint32_t i = 0; i < length/sizeof(cell_adr_t); i++) {
|
|
uint32_t startSect=ptr[i].start_sector;
|
|
// last sector of a vobu = start sector of next vobu -1
|
|
uint32_t lastSect= ptr[i].last_sector +1;
|
|
k9Vobu *vobu=remapVobu(&startSect);
|
|
if (vobu == NULL)
|
|
qDebug ("Error : could not find startSector");
|
|
else {
|
|
if (remapVobu(&lastSect)==NULL)
|
|
lastSect= vobu->parent->lastSector;
|
|
else
|
|
lastSect--;
|
|
ptr[i].start_sector = startSect;
|
|
ptr[i].last_sector = lastSect;
|
|
}
|
|
}
|
|
|
|
|
|
vobu_admap_t * vobu_admap = hifo->vts_vobu_admap;
|
|
length = vobu_admap->last_byte + 1 - VOBU_ADMAP_SIZE;
|
|
newPos=0;
|
|
for(uint32_t i = 0; i < length/sizeof(uint32_t); i++) {
|
|
if (remapVobu(&vobu_admap->vobu_start_sectors[i])!= NULL) {
|
|
vobu_admap->vobu_start_sectors[newPos]=vobu_admap->vobu_start_sectors[i];
|
|
newPos++;
|
|
}
|
|
}
|
|
for (uint32_t i=newPos ; i < length/sizeof(uint32_t);i++)
|
|
vobu_admap->vobu_start_sectors[i]=0;
|
|
|
|
vobu_admap->last_byte = newPos * sizeof(uint32_t) -1 +VOBU_ADMAP_SIZE;
|
|
|
|
|
|
//update VTS_TMAP
|
|
vts_tmapt_t *vts_tmapt=hifo->vts_tmapt;
|
|
if (vts_tmapt) {
|
|
for(uint32_t i = 0; i < vts_tmapt->nr_of_tmaps; i++) {
|
|
if(vts_tmapt->tmap[i].nr_of_entries == 0) { // Early out if zero entries
|
|
continue;
|
|
}
|
|
map_ent_t * map_ent=vts_tmapt->tmap[i].map_ent;
|
|
newPos=0;
|
|
for(uint32_t j = 0; j < vts_tmapt->tmap[i].nr_of_entries; j++) {
|
|
//bit 31 indicates whether VOBU time codes are discontinous with previous
|
|
uint32_t mask=map_ent[j] & 0x80000000 ;
|
|
uint32_t value=map_ent[j] & 0x7FFFFFFF;
|
|
if (remapVobu(&value) !=NULL) {
|
|
map_ent[j]=value | mask;
|
|
map_ent[newPos]=map_ent[j];
|
|
newPos++;
|
|
} else
|
|
map_ent[j]=0;
|
|
}
|
|
for (int j = newPos; j < vts_tmapt->tmap[i].nr_of_entries;j++)
|
|
map_ent[j]=0;
|
|
vts_tmapt->tmap[i].nr_of_entries=newPos;
|
|
}
|
|
}
|
|
|
|
update4Menu(hifo);
|
|
|
|
ifo.saveIFO();
|
|
}
|
|
|
|
void k9DVDBackup::updateVob(k9CellList *cellLst) {
|
|
int nbVobuUpdated=0;
|
|
|
|
uchar buffer[DVD_VIDEO_LB_LEN];
|
|
TQFile *file=NULL;
|
|
TQString dbg;
|
|
int pVobNum=-1;
|
|
//for (uint iCell=0;iCell<currTS->cells.count();iCell++) {
|
|
// k9Cell *cell=currTS->cells.at(iCell);
|
|
for (uint iCell=0;iCell< cellLst->count();iCell++) {
|
|
k9Cell *cell=cellLst->at(iCell);
|
|
for (uint ivobu=0; ivobu<cell->vobus.count();ivobu++) {
|
|
tqApp->processEvents();
|
|
k9Vobu * vobu = cell->vobus.at(ivobu);
|
|
int VobNum=vobu->vobNum;
|
|
if (error)
|
|
return;
|
|
if (pVobNum !=VobNum) {
|
|
if (file !=NULL){
|
|
file->close();
|
|
delete file;
|
|
}
|
|
//fclose(file);
|
|
TQString sName;
|
|
if (currVTS==0)
|
|
sName="VIDEO_TS.VOB";
|
|
else
|
|
sName.sprintf("VTS_%02d_%d.VOB",(int)currVTS,(int)VobNum);
|
|
dbg=i18n("Updating vob %1").tqarg(sName);
|
|
sName=output+"/"+sName;
|
|
TQFileInfo finfo(sName);
|
|
long fileSize=finfo.size();
|
|
|
|
backupDlg->setTotalSteps(fileSize);
|
|
backupDlg->setProgressLabel(dbg);
|
|
file =new TQFile(sName);
|
|
file->open( IO_ReadWrite);
|
|
//file=fopen(sName,"r+b");
|
|
pVobNum=VobNum;
|
|
}
|
|
if( file !=NULL) {
|
|
uint32_t sector=0;
|
|
long pos=vobu->vobPos;
|
|
backupDlg->setProgress(pos);
|
|
if (backupDlg->getAbort()) {
|
|
seterror(tr2i18n("DVD backup canceled"));
|
|
break;
|
|
}
|
|
|
|
bool emptyPgc=false;
|
|
/* long currpos=ftell(file);
|
|
long offset=pos-currpos;
|
|
fseek(file,offset,SEEK_CUR);
|
|
*/
|
|
//fseek(file,pos,SEEK_SET);
|
|
file->at(pos);
|
|
//fread(buffer,DVD_VIDEO_LB_LEN,1,file);
|
|
file->readBlock((char*)buffer,DVD_VIDEO_LB_LEN);
|
|
if (k9Cell::isNavPack((uchar*)buffer)) {
|
|
dsi_t dsiPack;
|
|
pci_t pciPack;
|
|
nbVobuUpdated++;
|
|
navRead_DSI (&dsiPack, buffer + DSI_START_BYTE);
|
|
k9Ifo2::navRead_PCI (&pciPack, buffer+0x2d);
|
|
sector=dsiPack.dsi_gi.nv_pck_lbn; //JMP : pour debug
|
|
//vobu=remapVobu(&dsiPack.dsi_gi.nv_pck_lbn );
|
|
sector=vobu->oldSector;
|
|
dsiPack.dsi_gi.nv_pck_lbn=vobu->newSector;
|
|
if (vobu != NULL) {
|
|
dsiPack.dsi_gi.vobu_ea = vobu->size;
|
|
emptyPgc=vobu->empty;
|
|
} else {
|
|
dbg.sprintf("remapVobu failed for %d",dsiPack.dsi_gi.nv_pck_lbn);
|
|
}
|
|
|
|
if (!emptyPgc) {
|
|
remapOffset(sector, &dsiPack.vobu_sri.next_video,1 );
|
|
for (int i =0;i<19;i++) {
|
|
remapOffset(sector,&dsiPack.vobu_sri.fwda[i],1);
|
|
}
|
|
remapOffset(sector,&dsiPack.vobu_sri.next_vobu,1);
|
|
remapOffset(sector,&dsiPack.vobu_sri.prev_vobu,-1);
|
|
for (int i =0;i<19;i++) {
|
|
remapOffset(sector,&dsiPack.vobu_sri.bwda[i],-1);
|
|
}
|
|
|
|
remapOffset(sector,&dsiPack.vobu_sri.prev_video,-1);
|
|
|
|
//1st audio packet
|
|
for (int i =0 ;i <8 ;i++) {
|
|
//if (((dsiPack.synci.a_synca[i] & 0x8000) != 0x8000 ) && (dsiPack.synci.a_synca[i] !=0x3FFF) && (dsiPack.synci.a_synca[i] !=0x0)) {
|
|
if ( (dsiPack.synci.a_synca[i] !=0x3FFF) && (dsiPack.synci.a_synca[i] !=0x0)) {
|
|
if (vobu->firstAudio[i] !=-1) {
|
|
dsiPack.synci.a_synca[i]=vobu->firstAudio [i];
|
|
} else {
|
|
//JMP dsiPack.synci.a_synca[i] =0;
|
|
dsiPack.synci.a_synca[i] =0x3FFF;
|
|
}
|
|
}
|
|
}
|
|
//1st subpicture packet
|
|
for (int i =0 ;i <32 ;i++) {
|
|
// if (((dsiPack.synci.sp_synca[i] & 0x80000000) != 0x80000000) &&
|
|
// (dsiPack.synci.sp_synca[i] != 0x3FFFFFFF) && (dsiPack.synci.sp_synca[i] != 0x7FFFFFFF) && (dsiPack.synci.sp_synca[i] != 0x0)) {
|
|
if ((dsiPack.synci.sp_synca[i] != 0x3FFFFFFF) && (dsiPack.synci.sp_synca[i] != 0x0)) {
|
|
if (vobu->firstSubp[i] !=-1) {
|
|
dsiPack.synci.sp_synca[i]=vobu->firstSubp [i];
|
|
} else {
|
|
//JMP dsiPack.synci.sp_synca[i] =0;
|
|
dsiPack.synci.sp_synca[i] =0x3FFFFFFF;
|
|
}
|
|
}
|
|
}
|
|
//ILVU
|
|
|
|
for (int i=0;i<9;i++) {
|
|
if (dsiPack.sml_agli.data[i].address !=0 && dsiPack.sml_agli.data[i].address !=0x7FFFFFFF) {
|
|
uint32_t tmpAdr=dsiPack.sml_agli.data[i].address;
|
|
uint32_t tmpSize=(dsiPack.sml_agli.data[i].address & 0x7FFFFFFF) + dsiPack.sml_agli.data[i].size;
|
|
int dir;
|
|
if ((tmpAdr & 0x80000000) ==0x80000000)
|
|
dir=-1;
|
|
else
|
|
dir=1;
|
|
remapOffset(sector,&tmpAdr,dir);
|
|
remapOffset(sector,&tmpSize,1);
|
|
dsiPack.sml_agli.data[i].address=tmpAdr;
|
|
dsiPack.sml_agli.data[i].size=tmpSize-(tmpAdr &0x7FFFFFFF);
|
|
}
|
|
}
|
|
|
|
|
|
if (dsiPack.sml_pbi.ilvu_ea !=0) {
|
|
uint32_t tmp=dsiPack.sml_pbi.ilvu_ea+1;
|
|
remapOffset(sector,&tmp,1);
|
|
if (tmp!=0)
|
|
tmp--;
|
|
dsiPack.sml_pbi.ilvu_ea=tmp;
|
|
}
|
|
if (dsiPack.sml_pbi.ilvu_sa !=0) {
|
|
k9Vobu *vobu2=remapOffset(sector,&dsiPack.sml_pbi.ilvu_sa,1);
|
|
if (vobu2!= NULL) {
|
|
TQFile *file2;
|
|
if ( vobu2->vobNum != VobNum) {
|
|
TQString sName;
|
|
sName.sprintf("/VTS_%02d_%d.VOB",(int)currVTS,(int)vobu2->vobNum);
|
|
sName=output+sName;
|
|
file2=new TQFile(sName);
|
|
file2->open(IO_ReadWrite);
|
|
//file2=fopen(sName,"rb");
|
|
} else
|
|
file2=file;
|
|
//fseek(file2,vobu2->vobPos,SEEK_SET);
|
|
file2->at(vobu2->vobPos);
|
|
uchar *tmpbuff=(uchar*)malloc(2048);
|
|
//fread(tmpbuff,DVD_VIDEO_LB_LEN,1,file2);
|
|
file2->readBlock( (char*)tmpbuff,DVD_VIDEO_LB_LEN);
|
|
dsi_t dsiNext;
|
|
navRead_DSI (&dsiNext, tmpbuff + DSI_START_BYTE);
|
|
uint32_t sectmp= dsiNext.sml_pbi.ilvu_ea+1;
|
|
remapOffset(dsiNext.dsi_gi.nv_pck_lbn,§mp,1);
|
|
dsiPack.sml_pbi.size=sectmp;
|
|
free (tmpbuff);
|
|
if (vobu2->vobNum!=VobNum) {
|
|
file2->close();
|
|
delete file2;
|
|
}
|
|
|
|
}
|
|
}
|
|
// end block reference frames
|
|
dsiPack.dsi_gi.vobu_1stref_ea = vobu->firstRef;
|
|
dsiPack.dsi_gi.vobu_2ndref_ea=vobu->secondRef;
|
|
dsiPack.dsi_gi.vobu_3rdref_ea=vobu->thirdRef;
|
|
|
|
|
|
// update pci pack
|
|
for (int i=0; i<9;i++) {
|
|
if ((pciPack.nsml_agli.nsml_agl_dsta[i] & 0x80000000) != 0x80000000)
|
|
remapOffset(sector,&pciPack.nsml_agli.nsml_agl_dsta[i],1);
|
|
}
|
|
|
|
} else {
|
|
dsiPack.vobu_sri.next_video= 0xbfffffff;
|
|
for (int i =0;i<19;i++)
|
|
dsiPack.vobu_sri.fwda[i] = 0x3fffffff;
|
|
dsiPack.vobu_sri.next_vobu=0x3fffffff;
|
|
dsiPack.vobu_sri.prev_vobu=0x3fffffff;
|
|
for (int i =0;i<19;i++)
|
|
dsiPack.vobu_sri.bwda[i] = 0x3fffffff;
|
|
dsiPack.vobu_sri.prev_video=0xbfffffff;
|
|
for (int i =0 ;i <8 ;i++)
|
|
dsiPack.synci.a_synca[i]=0x3fff;
|
|
for (int i =0 ;i <32 ;i++)
|
|
dsiPack.synci.sp_synca[i] =0x3FFFFFFF;
|
|
// end block reference frames
|
|
dsiPack.dsi_gi.vobu_1stref_ea = 0;
|
|
dsiPack.dsi_gi.vobu_2ndref_ea=0;
|
|
dsiPack.dsi_gi.vobu_3rdref_ea=0;
|
|
//JMP for tests
|
|
pciPack.pci_gi.vobu_s_ptm=0;
|
|
pciPack.pci_gi.vobu_e_ptm=0;
|
|
pciPack.pci_gi.vobu_se_e_ptm=0;
|
|
pciPack.pci_gi.e_eltm.hour = pciPack.pci_gi.e_eltm.minute =pciPack.pci_gi.e_eltm.second=0;
|
|
dsiPack.dsi_gi.c_eltm.hour=dsiPack.dsi_gi.c_eltm.minute=dsiPack.dsi_gi.c_eltm.second=0;
|
|
|
|
for (int i=0;i<9;i++) {
|
|
dsiPack.sml_agli.data[i].address=0x7FFFFFFF;
|
|
dsiPack.sml_agli.data[i].size=0;
|
|
}
|
|
dsiPack.sml_pbi.ilvu_ea=0;
|
|
dsiPack.sml_pbi.ilvu_sa=0;
|
|
dsiPack.sml_pbi.size=0;
|
|
|
|
dsiPack.dsi_gi.vobu_1stref_ea = 0;
|
|
dsiPack.dsi_gi.vobu_2ndref_ea=0;
|
|
dsiPack.dsi_gi.vobu_3rdref_ea=0;
|
|
|
|
}
|
|
// mise en place des donnees modifi�s dans le buffer de sortie
|
|
navRead_DSI((dsi_t*)(buffer + DSI_START_BYTE),(uchar*)&dsiPack);
|
|
pciPack.pci_gi.nv_pck_lbn =dsiPack.dsi_gi.nv_pck_lbn;
|
|
k9Ifo2::navRead_PCI((pci_t*)(buffer+0x2d),(uchar*)&pciPack);
|
|
//mise �jour du fichier
|
|
//fseek(file,pos,SEEK_SET);
|
|
file->at(pos);
|
|
//fwrite(buffer,DVD_VIDEO_LB_LEN,1,file);
|
|
file->writeBlock((const char*)buffer,DVD_VIDEO_LB_LEN);
|
|
}
|
|
|
|
} else {
|
|
qDebug ("erreur positionning");
|
|
}
|
|
}
|
|
}
|
|
if (file!=NULL) {
|
|
file->close();
|
|
delete file;
|
|
}
|
|
}
|
|
|
|
|
|
uint k9DVDBackup::getLastCell(k9CellCopyList *_cellCopyList, uint _index) {
|
|
|
|
k9Cell *orig=(k9Cell*)_cellCopyList->at(_index);
|
|
uint result=_index;
|
|
|
|
uint64_t dsize=1+orig->lastSector-orig->startSector;
|
|
|
|
uchar audioOrig[8];
|
|
uchar subpOrig[32];
|
|
memset(audioOrig,0,sizeof(uchar)*8);
|
|
memset(subpOrig,0,sizeof(uchar)*32);
|
|
|
|
;
|
|
TQValueList<int>::iterator it;
|
|
for ( it = orig->audio.begin(); it != orig->audio.end(); ++it )
|
|
audioOrig[*it -1]=1;
|
|
|
|
for ( it = orig->subpicture.begin(); it != orig->subpicture.end(); ++it )
|
|
subpOrig[*it -1]=1;
|
|
|
|
float factor=-1;
|
|
|
|
for (uint iCell=_index+1;(iCell<_cellCopyList->count()) ;iCell++) {
|
|
k9Cell *cell=(k9Cell*)_cellCopyList->at(iCell);
|
|
if ((cell->vts== orig->vts) && ( cell->selected)) {
|
|
//if the cell factor changed, it's a new group of cells
|
|
if (factor==-1)
|
|
factor=cell->getFactor();
|
|
else {
|
|
if (cell->getFactor()!=factor)
|
|
break;
|
|
}
|
|
|
|
uchar audio[8];
|
|
uchar subp[32];
|
|
memset(audio,0,sizeof(uchar)*8);
|
|
memset(subp,0,sizeof(uchar)*32);
|
|
;
|
|
TQValueList<int>::iterator it;
|
|
for ( it = cell->audio.begin(); it != cell->audio.end(); ++it )
|
|
audio[*it -1]=1;
|
|
|
|
for ( it = cell->subpicture.begin(); it != cell->subpicture.end(); ++it )
|
|
subp[*it -1]=1;
|
|
|
|
if ( (memcmp(audioOrig,audio,sizeof(uchar)*8) ==0) && (memcmp(subpOrig,subp,sizeof(uchar)*32) ==0)) {
|
|
result=iCell;
|
|
dsize+=1+cell->lastSector-cell->startSector;
|
|
} else
|
|
break;
|
|
} else
|
|
break;
|
|
}
|
|
|
|
dsize*=DVD_BLOCK_LEN;
|
|
argSize=dsize;
|
|
return result;
|
|
}
|
|
|
|
void k9DVDBackup::calcFactor() {
|
|
double factor=m_cellCopyList->getfactor(m_withMenu,false);
|
|
TQString sFactor;
|
|
sFactor.sprintf("%.2f",factor);
|
|
backupDlg->setFactor(sFactor);
|
|
argFactor = factor;
|
|
m_forcedFactor=false;
|
|
}
|
|
|
|
void k9DVDBackup::forceFactor(double _factor) {
|
|
double factor=_factor;
|
|
double minFactor=m_cellCopyList->getMinFactor( m_withMenu);
|
|
if (factor<minFactor)
|
|
factor=minFactor;
|
|
TQString sFactor;
|
|
sFactor.sprintf("%.2f",factor);
|
|
backupDlg->setFactor(sFactor);
|
|
argFactor = factor;
|
|
m_forcedFactor=true;
|
|
qDebug("force factor : %f min:%f",factor,minFactor);
|
|
}
|
|
|
|
|
|
void k9DVDBackup::execute() {
|
|
TQString sOutput=output;
|
|
|
|
output=TQDir::cleanDirPath(output +"/dvd");
|
|
|
|
TQDir root("/");
|
|
root.mkdir(output);
|
|
k9Tools::clearOutput(output);
|
|
|
|
TQDir dir(output);
|
|
dir.mkdir("VIDEO_TS");
|
|
dir.mkdir("AUDIO_TS");
|
|
|
|
output=TQDir::cleanDirPath(output +"/VIDEO_TS");
|
|
|
|
m_dvdread->openDevice(device);
|
|
if (!m_dvdread->opened()) {
|
|
seterror(tr2i18n("Unable to open DVD"));
|
|
return;
|
|
}
|
|
|
|
k9CellCopyList *cellCopyList =new k9CellCopyList(m_dvdread,DVD);
|
|
m_cellCopyList=cellCopyList;
|
|
|
|
double totalSize=cellCopyList->gettotalSize();
|
|
if (m_withMenu)
|
|
totalSize+=DVD->getmenuSize() *2048 ;
|
|
|
|
totalSize/=(1024*1024);
|
|
totalSize = (totalSize >k9DVDSize::getMaxSize()) ? k9DVDSize::getMaxSize():totalSize;
|
|
|
|
backupDlg->setTotalMax((uint32_t)totalSize);
|
|
|
|
int lastCell;
|
|
calcFactor();
|
|
|
|
//VTSList is sorted by size, so it is easier to ajust the compression factor
|
|
for(uint iTS=0;iTS<cellCopyList->VTSList.count() &&(!error);iTS++) {
|
|
k9CellCopyVTS *VTS=cellCopyList->VTSList.at(iTS);
|
|
//loop on each cell from the titleset
|
|
lastCell=-1;
|
|
for (uint iCell=0;(iCell<cellCopyList->count()) ;iCell++) {
|
|
k9Cell *cell=(k9Cell*)cellCopyList->at(iCell);
|
|
if (cell->vts==(int) VTS->getnum() && (!cell->copied)) {
|
|
// currCopyCell=cell;
|
|
if (lastCell < (int)iCell) {
|
|
lastCell=getLastCell( cellCopyList,iCell);
|
|
//adjusting factor of compression
|
|
if ( cell->getforceFactor())
|
|
forceFactor( cell->getFactor());
|
|
else
|
|
calcFactor();
|
|
}
|
|
copyCell(cell->vts,cell,! cell->selected);
|
|
if (!error) {
|
|
cell->copied=true;
|
|
}
|
|
// }
|
|
if (lastCell==(int)iCell) {
|
|
vamps->setNoData();
|
|
vamps->wait();
|
|
}
|
|
if (error)
|
|
break;
|
|
}
|
|
}
|
|
vamps->setNoData();
|
|
vamps->wait();
|
|
}
|
|
delete cellCopyList;
|
|
|
|
if (!error) {
|
|
updateIfo();
|
|
updateVob(&currTS->cells);
|
|
updateMainIfo();
|
|
}
|
|
output=sOutput;
|
|
backupDlg->hide();
|
|
|
|
if (error)
|
|
KMessageBox::error(0,errMsg,"DVD Backup");
|
|
//m_dvdread->close();
|
|
}
|