summaryrefslogtreecommitdiffstats
path: root/libk9copy/k9cell.cpp
diff options
context:
space:
mode:
authortpearson <tpearson@283d02a7-25f6-0310-bc7c-ecb5cbfe19da>2010-02-17 00:32:19 +0000
committertpearson <tpearson@283d02a7-25f6-0310-bc7c-ecb5cbfe19da>2010-02-17 00:32:19 +0000
commit0d382a262c0638d0f572fc37193ccc5ed3dc895f (patch)
tree8578dcddfce4191f3f7a142a37769df7add48475 /libk9copy/k9cell.cpp
downloadk9copy-0d382a262c0638d0f572fc37193ccc5ed3dc895f.tar.gz
k9copy-0d382a262c0638d0f572fc37193ccc5ed3dc895f.zip
Added old abandoned version of k9copy
git-svn-id: svn://anonsvn.kde.org/home/kde/branches/trinity/applications/k9copy@1091546 283d02a7-25f6-0310-bc7c-ecb5cbfe19da
Diffstat (limited to 'libk9copy/k9cell.cpp')
-rwxr-xr-xlibk9copy/k9cell.cpp443
1 files changed, 443 insertions, 0 deletions
diff --git a/libk9copy/k9cell.cpp b/libk9copy/k9cell.cpp
new file mode 100755
index 0000000..d757e26
--- /dev/null
+++ b/libk9copy/k9cell.cpp
@@ -0,0 +1,443 @@
+/**************************************************************************
+* Copyright (C) 2005 by Jean-Michel Petit *
+* *
+* 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 "k9cell.h"
+#include "k9dvdtitleset.h"
+
+int k9VobuList::compareItems ( QPtrCollection::Item item1, QPtrCollection::Item item2 ) {
+ return(((k9Vobu*)item1)->oldSector- ((k9Vobu*)item2)->oldSector);
+}
+
+k9Vobu * k9VobuList::findVobu(uint32_t sector) {
+ //int c=count();
+ //if (c >0) {
+ k9Vobu *v1,*v2;
+ v1=first();
+ v2=last();
+ if (v1==NULL)
+ return NULL;
+
+ if (sector >= v1->oldSector && sector <= v2->oldSector)
+ return findVobu(sector,0,count()-1);
+ else
+ return NULL;
+ //}
+}
+
+k9Vobu * k9VobuList::findVobu(uint32_t sector, uint32_t start, uint32_t end) {
+
+ long lstart=start;
+ long lend=end;
+
+
+ while (lstart <=lend) {
+ long m =(lstart+lend)/2;
+ k9Vobu *v = (k9Vobu *)at(m);
+ if ( v->oldSector == sector) {
+ return v;
+ } else if ( v->oldSector >sector) {
+ lend = m-1;
+ } else {
+ lstart=m+1;
+ }
+ }
+ return NULL;
+}
+
+uint32_t k9Cell::getnewSize() {
+ uint32_t size=0;
+ //for (k9Vobu * vobu=vobus.first();vobu;vobu=vobus.next())
+ for (uint i=0; i<vobus.count();i++) {
+ k9Vobu *vobu=vobus.at(i);
+ size+=vobu->size;
+ }
+ return size;
+}
+
+int k9Cell::getStreamID(int type) {
+ int abase=0;
+ if (type >= 0x80 && type <= 0x87) {
+ // AC3 audio
+ abase = 0x80;
+ } else if (type >= 0x88 && type <= 0x8f) {
+ // DTS audio
+ abase = 0x88;
+ } else if (type >= 0xa0 && type <= 0xbf) {
+ // LPCM audio
+ abase = 0xa0;
+ } else if (type >= 0xc0 && type <= 0xdf) {
+ // MPEG audio
+ abase = 0xc0;
+ } else if (type >=0x20 && type <=0x3f) {
+ //subpicture;
+ abase =0x20;
+ }
+ return (type-abase );
+
+}
+
+
+streamType_t k9Cell::identifyStream( uchar *buffer,int *packetType ) {
+ *packetType = buffer[17];
+
+ if( (*packetType >= 0xE0) && (*packetType <= 0xEF) ) { // video streams
+ return stVideo;
+ } else if( *packetType == 0xBB ) { // system header
+ return stOther;
+ } else if( *packetType == 0xBE ) { // padding
+ return stOther;
+ } else if( *packetType == 0xBF ) { // nav pack
+ return stOther;
+ } else if( (*packetType >= 0xC0) && (*packetType <= 0xDF) ) { // mpeg audio
+ return stAudio;
+ } else if( *packetType == 0xBD ) { // private stream, check content
+ *packetType = buffer[23+buffer[22]];
+ if (( (*packetType >=0x80) && (*packetType <=0x8f)) || ((*packetType >=0xa0) && (*packetType <=0xa7)) || ((*packetType >=0xc0) && (*packetType <=0xdf)))
+ return stAudio;
+ if ( (*packetType >=0x20) && (*packetType <=0x3f))
+ return stSubpicture;
+ return stOther;
+ } else
+ return stOther;
+
+}
+
+
+
+int k9Cell::isNavPack (uchar *_ptr) {
+ uint32_t start_code;
+ uchar *ptr=_ptr;
+ if ((ptr [0]!=0) || (ptr [1] !=0) || (ptr [2] != 0x01) || (ptr [3] != 0xba))
+ return 0;
+
+ if ((ptr [4] & 0xc0) != 0x40)
+ return 0;
+
+ // ptr += 14;
+
+ start_code = (uint32_t) (ptr [14]) << 24;
+ start_code |= (uint32_t) (ptr [15]) << 16;
+ start_code |= (uint32_t) (ptr [16]) << 8;
+ start_code |= (uint32_t) (ptr [17]);
+
+ if (start_code != 0x000001bb)
+ return 0;
+
+ // ptr += 24;
+
+ start_code = (uint32_t) (ptr [0x26]) << 24;
+ start_code |= (uint32_t) (ptr [0x27]) << 16;
+ start_code |= (uint32_t) (ptr [0x28]) << 8;
+ start_code |= (uint32_t) (ptr [0x29]);
+
+ if (start_code != 0x000001bf)
+ return 0;
+
+ // ptr += 986;
+
+ start_code = (uint32_t) (ptr [0x400]) << 24;
+ start_code |= (uint32_t) (ptr [0x401]) << 16;
+ start_code |= (uint32_t) (ptr [0x402]) << 8;
+ start_code |= (uint32_t) (ptr [0x403]);
+
+ if (start_code != 0x000001bf)
+ return 0;
+
+ return 1;
+}
+
+
+
+k9Cell::k9Cell(QObject *parent, const char *name)
+ : QObject(parent, name) {
+ vobus.setAutoDelete(true);
+ numVobu=0;
+
+ vts=0;
+ pgc=0;
+ vob=0;
+ startSector=0;
+ lastSector=0;
+ //TO REMOVE oldStartSector=0;
+ //TO REMOVE oldLastSector=0;
+ //TO REMOVE newSize=0;
+ id=0;
+ selected=false;
+ copied=false;
+ //TO REMOVE nbVideoNew=0;
+ //TO REMOVE nbVideoOld=0;
+ angleBlock=angleNone;
+}
+
+
+k9Cell::~k9Cell() {}
+
+//add a title in the title list (titles using this cell)
+void k9Cell::addTitle( k9DVDTitle *_title) {
+ m_titles.append( _title);
+}
+
+bool k9Cell::getforceFactor() {
+ bool m_forced=false;
+ for (uint i=0; i< m_titles.count() && !m_forced ;i++) {
+ k9DVDTitle *title=m_titles.at(i);
+ if (title->getforceFactor())
+ m_forced=true;
+ }
+ return m_forced;
+}
+
+// returns the shrink factor.
+float k9Cell::getFactor() {
+ float factor=0;
+ for (uint i=0; i< m_titles.count() ;i++) {
+ k9DVDTitle *title=m_titles.at(i);
+ if ((title->getfactor()< factor || factor==0 ) && title->getforceFactor() )
+ factor=title->getfactor();
+ }
+ return factor;
+}
+
+
+//looking for the end reference frame adress block
+void k9Cell::addRefStream(k9Vobu *_vobu,uchar *_buffer,uint32_t _position) {
+ if (_vobu->firstRefOk && _vobu->secondRefOk && _vobu->thirdRefOk)
+ return;
+ //offset of frame
+ uint start=0x16+_buffer[0x16]+1;
+ //PES Length
+ uint length=_buffer[0x12];
+ length=(length <<8 ) + _buffer[0x13];
+
+ //end of PES
+ uint end=0x14+length;
+
+ if ( _vobu->frameType!=0x18) {
+ if (!_vobu->firstRefOk)
+ _vobu->firstRef=_position;
+ else if (!_vobu->secondRefOk)
+ _vobu->secondRef=_position;
+ else if (!_vobu->thirdRefOk)
+ _vobu->thirdRef=_position;
+ }
+
+ for (uint i=start;i <end-7;i++) {
+ //if last picture is not a B-Frame, keep offset of last video
+
+ //looking for start code picture
+ if ((_buffer[i-5] ==0) &&( _buffer[i-4] ==0) &&( _buffer[i-3] ==1)&&( _buffer[i-2] ==0)) {
+ uchar frameType=_buffer[i] &0x38;
+ // if frameType != B-Frame and a reference picture was found
+ if ((_vobu->frameType!=0x18) && (_vobu->frameType!=0)) {
+ if (!_vobu->firstRefOk) {
+ _vobu->firstRefOk=true;
+ _vobu->firstRef=_position;
+ } else if (!_vobu->secondRefOk) {
+ _vobu->secondRefOk=true;
+ _vobu->secondRef=_position;
+ } else if (!_vobu->thirdRefOk) {
+ _vobu->thirdRefOk=true;
+ _vobu->thirdRef=_position;
+ }
+ }
+ //keep the current frame type
+ _vobu->frameType=frameType;
+ }
+ }
+
+}
+
+k9Vobu * k9Cell::addVobu(uint32_t _sector) {
+ k9Vobu * vobu = new k9Vobu(this,_sector);
+ vobus.append(vobu);
+ return vobu;
+}
+
+
+void k9Cell::addNewVobus(char *_buffer,uint32_t _len,uint32_t _position,int _vobNum,long _vobPos) {
+ uint32_t start= _position ;//lastSector - _len ;
+ k9Vobu *vobu;
+ for (uint32_t i= 0 ; i<_len ;i+=DVD_BLOCK_LEN) {
+ if (isNavPack((uchar*)_buffer+i)) {
+ vobu=(k9Vobu*)vobus.at(numVobu);
+ vobu->newSector=i/DVD_BLOCK_LEN +start;
+ numVobu++;
+ vobu->vobNum=_vobNum;
+ vobu->vobPos=_vobPos;
+ //QString c;
+ //c.sprintf("vobu : %d old: %d new :%d",numVobu-1,vobu->oldSector,vobu->newSector);
+ //qDebug (c.latin1());
+
+ } else {
+ streamType_t st;
+ int packetType,id;
+ st=k9Cell::identifyStream((uchar*)_buffer+i,&packetType);
+ vobu=(k9Vobu*)vobus.at(numVobu-1);
+ switch (st) {
+ case stAudio:
+ id=k9Cell::getStreamID(packetType);
+ if (vobu->firstAudio[id]==-1) {
+ vobu->firstAudio[id]= ((i/ DVD_BLOCK_LEN) + start) - vobu->newSector;
+ }
+ break;
+ case stSubpicture:
+ id=k9Cell::getStreamID(packetType);
+ if ((id >=0) && (id<32)) {
+ if (vobu->firstSubp[id]==-1) {
+ vobu->firstSubp[id]= ((i / DVD_BLOCK_LEN)+start) - vobu->newSector;
+ }
+ }
+ break;
+ case stVideo:
+ addRefStream(vobu,(uchar*)_buffer+i,(i/DVD_BLOCK_LEN +start) - vobu->newSector);
+ if (vobu->firstVideo==-1) {
+ vobu->firstVideo = ((i / DVD_BLOCK_LEN)+start) - vobu->newSector;
+ }
+ //TO REMOVE nbVideoNew++;
+ break;
+ }
+
+ }
+ vobu->size= _position-vobu->newSector;
+ // �v�ifier
+ lastSector=_position;
+ }
+
+}
+
+k9Vobu::k9Vobu(k9Cell *_parent,uint32_t _oldSector)
+ : QObject(_parent,"") {
+ parent=_parent;
+ oldSector = _oldSector;
+ newSector = 0;
+ size=0;
+ for (int i=0;i<8;i++)
+ firstAudio[i]=-1;
+ for (int i=0;i<32;i++)
+ firstSubp[i]=-1;
+ firstVideo=-1;
+ empty=false;
+ vobPos=0;
+ vobNum=0;
+ frameType=0;
+ firstRef=0;
+ secondRef=0;
+ thirdRef=0;
+ firstRefOk=false;
+ secondRefOk=false;
+ thirdRefOk=false;
+}
+
+
+/*!
+\fn k9Cell::findVobu(int _oldSector)
+*/
+k9Vobu * k9Cell::findVobu(uint32_t _oldSector) {
+ return vobus.findVobu(_oldSector) ;
+}
+
+
+k9Vobu::~k9Vobu() {}
+
+
+k9Cell* k9CellList::addCell(int _vts,int _pgc, int _vob) {
+ k9Cell* cell=new k9Cell;
+ cell->cellList=this;
+ cell->vts=_vts;
+ cell->vob=_vob;
+ cell->pgc=_pgc;
+
+ if (count()!=0) {
+ k9Cell *prev=(k9Cell*)getLast();
+ if (prev->vts==_vts) {
+ cell->startSector= prev->lastSector +1;
+ if (_pgc!=prev->pgc)
+ cell->id=1;
+ else
+ cell->id=prev->id+1;
+ }
+ } else {
+ cell->startSector = 0;
+ cell->id=1;
+ }
+ append (cell);
+ return(cell);
+
+}
+
+k9Vobu *k9CellList::findVobu(uint32_t sector) {
+ k9Vobu *vobu=NULL;
+ k9Cell *cell=findCell(sector);
+ if (cell==NULL)
+ return NULL;
+ else
+ return cell->findVobu(sector);
+
+ int nbCells=count();
+ for (int i=0;i <nbCells;i++) {
+ k9Cell * cell = (k9Cell*)at(i);
+ vobu = cell->findVobu(sector);
+ if (vobu !=NULL) {
+ return vobu;
+ }
+ cell = (k9Cell*)at(nbCells-1-i);
+ vobu = cell->findVobu(sector);
+ if (vobu !=NULL) {
+ return vobu;
+ }
+
+
+ }
+ return vobu;
+}
+
+k9Cell * k9CellList::findCell(uint32_t sector) {
+ return findCell(sector,0,count()-1);
+}
+
+k9Cell * k9CellList::findCell(uint32_t sector, uint32_t start, uint32_t end) {
+
+ long lstart=start;
+ long lend=end;
+
+ while (lstart <=lend) {
+ long m =(lstart+lend)/2;
+ k9Cell *cell = (k9Cell *)at(m);
+ k9Vobu *fv=cell->vobus.first();
+ k9Vobu *lv=cell->vobus.last();
+
+
+ if ( sector >=fv->oldSector && sector<= lv->oldSector) {
+ return cell;
+ } else if ( fv->oldSector >sector) {
+ lend = m-1;
+ } else {
+ lstart=m+1;
+ }
+ }
+ return NULL;
+}
+
+k9DVDTitleset * k9Cell::getTitleset() {
+ k9DVDTitle *title=m_titles.at(0);
+ return title->gettitleset();
+}
+
+
+#include "k9cell.moc"