home *** CD-ROM | disk | FTP | other *** search
- /*
- * inputStream.cpp
- *
- * Copyright (C) Alberto Vigata - January 2000 - ultraflask@yahoo.com
- *
- * This file is part of FlasKMPEG, a free MPEG to MPEG/AVI converter
- *
- * FlasKMPEG 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, or (at your option)
- * any later version.
- *
- * FlasKMPEG 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 GNU Make; see the file COPYING. If not, write to
- * the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
- *
- */
-
- #include "inputStream.h"
- extern HWND hMainWnd;
-
- CinputStream::CinputStream(){
- int i;
-
- for( i=0; i<100; i++){
- iStream.file[i].handle = NULL;
- iStream.file[i].position=0;
- iStream.file[i].size=0;
- }
- iStream.actualFile=0;
- iStream.globalPos=0;
- iStream.nFiles=0;
- iStream.totalSize=0;
- workingMode = NORMAL_MODE;
- ps.sp = NULL;
- ps.span_count =0;
- ps.spanptr = 0;
- ps.total_size=0;
-
- }
- CinputStream::~CinputStream(){
- // free playsequence memory
- if(ps.sp)
- free(ps.sp);
- }
-
- int CinputStream::SetOneFileMode(int n_file){
- if(n_file<0)
- n_file=0;
- if(n_file>=iStream.nFiles)
- n_file=iStream.nFiles-1;
- iStream.actualFile= n_file;
- iStream.multipleFileMode=false;
- SetStreamPos(0);
- return 1;
-
- }
-
- int CinputStream::SetStreamPos(i64 pos)
- {
- int i;
- i64 a=0;
- i64 posbak;
- if(iStream.multipleFileMode){
- if( (pos+1) > iStream.totalSize )
- pos=iStream.totalSize;
- if(pos<0)
- pos=0;
- posbak = pos;
- //Go trough all files to find the one that owns this pos
- for( i=0; i<iStream.nFiles; i++)
- {
- //a += iStream.file[i].size;
- if( pos<= iStream.file[i].size ){//this is the one
- fsetpos(iStream.file[i].handle, &pos);
- iStream.actualFile=i;
- iStream.globalPos = posbak;
- return 1;
- }
- pos -= iStream.file[i].size;
- }
- }
- else{
- fsetpos(iStream.file[iStream.actualFile].handle, &pos);
- iStream.globalPos = pos;
- return 1;
- }
- return 0;
-
- }
- int CinputStream::CloseStream()
- {
- int i;
- //Closes opened input_file
- for( i=0; i<iStream.nFiles ;i++)
- fclose( iStream.file[i].handle );
- return 1;
- }
-
- int CinputStream::SetMulFileMode(){
- iStream.multipleFileMode=true;
- return 1;
- }
-
-
- i64 CinputStream::GetStreamSize()
- {
- if(iStream.multipleFileMode==true)
- return iStream.totalSize;
- else
- return iStream.file[iStream.actualFile].size;
- }
-
- int CinputStream::SeekStream(__int64 pos)
- {
- int val;
- //FlushBuffers();
- //ParseStep( true );
- //Seek the file at the very beginning
- val=SetStreamPos(pos);
- //init
- //init_getbits();
- return val;
- }
-
- i64 CinputStream::GetStreamPos()
- {
- i64 iPos=0;
- return iStream.globalPos;
- /*if(iStream.multipleFileMode){
- for(i=0; i<iStream.actualFile; i++)
- {
- iPos += iStream.file[i].size;
- }
- fgetpos(iStream.file[iStream.actualFile].handle, &parPos);
- return (iPos+parPos);
- }
- else
- {
- fgetpos(iStream.file[iStream.actualFile].handle, &parPos);
- return parPos;
- }
- */
- }
-
-
- ////////////////////////////////////////////////////////////////
- // OpenStream(Inputfile, mode)
- //
- // Opens and prepares a input file for reading.
- // Rules: if the input file is something like vts_xx_1.vob
- // search for following vts_xx_y.vob files (up to y=9?)
- // If success return 1, 0 otherwise
- //
- ///////////////////////////////////////////////////////////////
-
- int CinputStream::OpenStream(char *inputFile, int mode)
- {
- char szTemp1[1024],szTemp2[256],path[1024],*FileName,Message[10000];
- int nameSize,i,finalNamePos;
- // mode=1 => DVDmode, mode=0=> NORMALmode
- if(!inputFile)
- return 0;
-
-
- strcpy(Message, "DVD MODE. The following files will be used\n as just one logical file\n");
- GetFullPathName( inputFile, 1024, path, &FileName);
- strlwr( FileName ); //Lowercase input file
- nameSize=strlen( FileName );
- if((mode&DVD_MODE) && (nameSize>=12)){//Open file in DVDmode
-
- strcpy( szTemp2, FileName );
- // file name to test= vts_xx_1.vob
- szTemp2[4]=szTemp2[5]='x';
- strcpy(szTemp1, "vts_xx_1.vob");
- if( strcmp(szTemp1, szTemp2) == 0){ //The file has the format vts_xx_1.vob
- //Create all the files
- i=0;
- iStream.globalPos=0;
- iStream.actualFile=0;
- iStream.totalSize=0;
- do{
- strcpy( iStream.file[i].name, path);
- finalNamePos= strlen( inputFile ) - 5; // point here=> *.vob
- iStream.file[i].name[finalNamePos]= '1' + i;
- iStream.file[i].handle= fopen(iStream.file[i].name, "rb");
- if( iStream.file[i].handle != NULL ){
- //Set buffer size
- setvbuf( iStream.file[i].handle, NULL, _IOFBF, 256000);
- iStream.nFiles=i+1;
- //file size
- fseek( iStream.file[i].handle,0,SEEK_END );
- fgetpos(iStream.file[i].handle, &iStream.file[i].size);
- fseek( iStream.file[i].handle,0,SEEK_SET );
- iStream.file[i].position=0;
- iStream.totalSize+= iStream.file[i].size;
- sprintf(szTemp1, " %s size: %.2f MB\n",iStream.file[i].name, BtoMB(iStream.file[i].size));
- strcat(Message, szTemp1);
- }
-
- }while( iStream.file[i++].handle != NULL );
- if( iStream.file[0].handle == NULL )
- return 0;
- else{
- sprintf(szTemp1, "\nTotal size: %.2f MBytes", BtoMB(iStream.totalSize));
- strcat(Message, szTemp1);
- if(mode & VERBOSE_MODE)
- MessageBox(hMainWnd, Message, "Flask Warning", MB_OK);
- SetMulFileMode();
-
- return 1; //SUCCESS!!
- }
- }
- }
- //Not in DVD mode. Either the file was not suitable for DVDmode
- //DVDmode was disabled
- iStream.file[0].handle= fopen(inputFile,"rb");
- if( iStream.file[0].handle==NULL)
- return 0;
- strcpy(iStream.file[0].name, inputFile);
- iStream.globalPos=0;
- iStream.actualFile=0;
- iStream.nFiles=1;
- fseek( iStream.file[0].handle,0,SEEK_END );
- fgetpos(iStream.file[0].handle, &iStream.file[0].size);
- fseek( iStream.file[0].handle,0,SEEK_SET );
- iStream.totalSize= iStream.file[0].size;
- SetMulFileMode();
- return 1;
-
-
- }
-
- ///////////////////////////////////////////////////////////////
- // int ReadInputStream( buffer, size )
- // Reads size bytes and puts them into the buffer.
- // if the funcion is successful returns bytes written = size
- // if not, returns -1 for error, or last written bytes
- //////////////////////////////////////////////////////////////
- int CinputStream::Read( ui8 *buffer, int size)
- {
- int remaining_bytes;
- int partial,bytes_read;
-
- switch(workingMode)
- {
- case NORMAL_MODE:
- return __read(buffer, size);
- case PLAYSEQ_MODE:
- // The file pointer is not inside the current vob cell.
- if(iStream.globalPos < ps.sp[ps.spanptr].start ||
- iStream.globalPos > ps.sp[ps.spanptr].end)
- {
- if(iStream.globalPos > ps.sp[ps.span_count-1].end)
- return 0;
- AlignStreamToSpan();
- }
- remaining_bytes = size;
- while(1)
- {
- if( (partial=(int)(ps.sp[ps.spanptr].end+1 - iStream.globalPos)) < remaining_bytes )
- {
- bytes_read = __read(buffer, partial);
-
- if(bytes_read < partial)
- return size - remaining_bytes + bytes_read;
- buffer += bytes_read;
- remaining_bytes -= partial;
- AlignStreamToSpan();
- continue;
- }
- else
- {
- // The remaining bytes belong to this cell
- return __read(buffer, remaining_bytes);
- }
- }
-
- }
- return 0;
-
- }
-
- int inline CinputStream::__read( ui8 *buffer, int size)
- {
- if(!size)
- return 0;
- if(iStream.multipleFileMode){
- fgetpos(iStream.file[iStream.actualFile].handle, &iStream.file[iStream.actualFile].position );
- remainingBytes = iStream.file[iStream.actualFile].size - (iStream.file[iStream.actualFile].position);
- if( size > remainingBytes){ //Oops..
- if( (iStream.actualFile+1) == iStream.nFiles ){ //return remaining bits
- ret = fread(buffer, 1, remainingBytes, iStream.file[iStream.actualFile].handle);
- iStream.globalPos += ret;
- return ret;
- }
- else{
- //Read data from the actual file
- ret = fread(buffer, 1, remainingBytes, iStream.file[iStream.actualFile].handle);
- fseek(iStream.file[++iStream.actualFile].handle, 0L, SEEK_SET);
- ret += fread(&buffer[remainingBytes], 1, size-remainingBytes, iStream.file[iStream.actualFile].handle);
- iStream.globalPos += ret;
-
- return size;
- }
- }
- else{
- //Just copy the bytes
- ret = fread(buffer, 1, size, iStream.file[iStream.actualFile].handle);
- iStream.globalPos += ret;
- return ret;
- }
- return 0;
- }
- else{
- ret = fread(buffer, 1, size, iStream.file[iStream.actualFile].handle);
- iStream.globalPos += ret;
- return ret;
- }
-
-
- }
- char *CinputStream::GetFileName(){
- return iStream.file[iStream.actualFile].name;
- }
-
-
- int CinputStream::SetWorkingMode(int mode)
- {
- workingMode = mode;
- return 1;
- }
- // CinputStream::ValidatePlaySequence()
- //
- // Checks the validity of the playsequence
- // that was previously set
- int CinputStream::ValidatePlaySequence()
- {
- if(ps.total_size <=0)
- return 0;
- if(iStream.totalSize < ps.total_size)
- return 0;
- return 1;
- }
- // This method alings a stream to the next available span
- // if the file pointer is inside a span, it moves the pointer
- // to the beginning of the span.
- int inline CinputStream::AlignStreamToSpan()
- {
- int i;
- // First update the current cell pointer
- ps.spanptr++;
- if( ps.spanptr >= ps.span_count )
- ps.spanptr = ps.span_count - 1;
- // Look at this cellptr
- if( iStream.globalPos == ps.sp[ps.spanptr].start){
- // we're on it!
- return 1;
- }
-
- // Ok. Now check that the pointer is inside a span
- int its_inside = 0;
- for(i=0; i< ps.span_count; i++)
- {
- if( iStream.globalPos >= ps.sp[i].start &&
- iStream.globalPos <= ps.sp[i].end ){
- // we're between it
- ps.spanptr = i;
- its_inside = 1;
- break;
- }
- }
- if(its_inside)
- //we're done
- return 1;
-
- //Align the stream to the next available span
- for(i=0; i< ps.span_count; i++)
- {
- if( iStream.globalPos <= ps.sp[i].start){
- // pick this one
- ps.spanptr = i;
- SetStreamPos(ps.sp[i].start);
- break;
- }
- if( i== ps.span_count-1 ){
- //globalPos is greater than the latest cell start
- ps.spanptr = i;
- SetStreamPos(ps.sp[i].start);
- break;
- }
- }
-
- return 1;
- }
-
- int CinputStream::AddSpan(TPlaySequenceSpan *span)
- {
- if(!span)
- return 0;
- // check for correct span
- if(span->end <= span->start)
- return 0;
- // if(ps.span_count)
- // if(span->start <= ps.sp[ps.span_count - 1].end)
- // return 0;
-
- ps.sp = (TPlaySequenceSpan *) realloc( ps.sp, sizeof(TPlaySequenceSpan)*(ps.span_count+1) );
- ps.span_count++;
- ps.sp[ps.span_count - 1 ] = *span;
- // Update ps stuff
- ps.total_size += span->end - span->start + 1;
- return 1;
- }