home *** CD-ROM | disk | FTP | other *** search
/ PC Welt 2001 September / PC-WELT 9-2001.ISO / software / hw / brennen / flask_src.exe / Input / inputStream.cpp < prev    next >
Encoding:
C/C++ Source or Header  |  2000-05-25  |  10.8 KB  |  419 lines

  1. /* 
  2.  *  inputStream.cpp 
  3.  *
  4.  *    Copyright (C) Alberto Vigata - January 2000 - ultraflask@yahoo.com
  5.  *
  6.  *  This file is part of FlasKMPEG, a free MPEG to MPEG/AVI converter
  7.  *    
  8.  *  FlasKMPEG is free software; you can redistribute it and/or modify
  9.  *  it under the terms of the GNU General Public License as published by
  10.  *  the Free Software Foundation; either version 2, or (at your option)
  11.  *  any later version.
  12.  *   
  13.  *  FlasKMPEG is distributed in the hope that it will be useful,
  14.  *  but WITHOUT ANY WARRANTY; without even the implied warranty of
  15.  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  16.  *  GNU General Public License for more details.
  17.  *   
  18.  *  You should have received a copy of the GNU General Public License
  19.  *  along with GNU Make; see the file COPYING.  If not, write to
  20.  *  the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. 
  21.  *
  22.  */
  23.  
  24. #include "inputStream.h"
  25. extern HWND hMainWnd;
  26.  
  27. CinputStream::CinputStream(){
  28.     int i;
  29.  
  30.     for( i=0; i<100; i++){
  31.         iStream.file[i].handle = NULL;
  32.         iStream.file[i].position=0;
  33.         iStream.file[i].size=0;
  34.     }
  35.     iStream.actualFile=0;
  36.     iStream.globalPos=0;
  37.     iStream.nFiles=0;
  38.     iStream.totalSize=0;
  39.     workingMode = NORMAL_MODE;
  40.     ps.sp = NULL;
  41.     ps.span_count =0;
  42.     ps.spanptr = 0;
  43.     ps.total_size=0;
  44.  
  45. }
  46. CinputStream::~CinputStream(){
  47.     // free playsequence memory
  48.     if(ps.sp)
  49.         free(ps.sp);
  50. }
  51.  
  52. int CinputStream::SetOneFileMode(int n_file){
  53.     if(n_file<0)
  54.         n_file=0;
  55.     if(n_file>=iStream.nFiles)
  56.         n_file=iStream.nFiles-1;
  57.     iStream.actualFile= n_file;
  58.     iStream.multipleFileMode=false;
  59.     SetStreamPos(0);
  60.     return 1;
  61.  
  62. }
  63.  
  64. int CinputStream::SetStreamPos(i64 pos)
  65. {
  66.     int i;
  67.     i64 a=0;
  68.     i64 posbak;
  69. if(iStream.multipleFileMode){
  70.     if( (pos+1) > iStream.totalSize )
  71.         pos=iStream.totalSize;
  72.     if(pos<0)
  73.         pos=0;
  74.     posbak = pos;
  75.     //Go trough all files to find the one that owns this pos
  76.     for( i=0; i<iStream.nFiles; i++)
  77.     {
  78.         //a   += iStream.file[i].size;
  79.         if( pos<= iStream.file[i].size ){//this is the one
  80.             fsetpos(iStream.file[i].handle, &pos);
  81.             iStream.actualFile=i;
  82.             iStream.globalPos = posbak;
  83.             return 1;
  84.         }
  85.         pos -= iStream.file[i].size;
  86.     }
  87. }
  88. else{
  89.     fsetpos(iStream.file[iStream.actualFile].handle, &pos);
  90.     iStream.globalPos = pos;
  91.     return 1;
  92. }
  93. return 0;
  94.  
  95. }
  96. int CinputStream::CloseStream()
  97. {
  98.     int i;
  99.     //Closes opened input_file
  100.     for( i=0; i<iStream.nFiles ;i++)
  101.         fclose( iStream.file[i].handle );
  102.     return 1;
  103. }
  104.  
  105. int CinputStream::SetMulFileMode(){
  106.     iStream.multipleFileMode=true;
  107.     return 1;
  108. }
  109.  
  110.  
  111. i64 CinputStream::GetStreamSize()
  112. {
  113.     if(iStream.multipleFileMode==true)
  114.         return iStream.totalSize;
  115.     else
  116.         return iStream.file[iStream.actualFile].size;
  117. }
  118.  
  119. int CinputStream::SeekStream(__int64 pos)
  120. {
  121.     int val;
  122.     //FlushBuffers();
  123.     //ParseStep( true );
  124.     //Seek the file at the very beginning
  125.     val=SetStreamPos(pos);
  126.     //init
  127.     //init_getbits();
  128.     return val;
  129. }
  130.  
  131. i64 CinputStream::GetStreamPos()
  132. {
  133.     i64 iPos=0;
  134.     return iStream.globalPos;
  135. /*if(iStream.multipleFileMode){
  136.     for(i=0; i<iStream.actualFile; i++)
  137.     {
  138.         iPos += iStream.file[i].size;
  139.     }
  140.     fgetpos(iStream.file[iStream.actualFile].handle, &parPos);
  141.     return (iPos+parPos);
  142. }
  143. else
  144. {
  145.     fgetpos(iStream.file[iStream.actualFile].handle, &parPos);
  146.     return parPos;
  147. }
  148. */
  149. }
  150.  
  151.  
  152. ////////////////////////////////////////////////////////////////
  153. //            OpenStream(Inputfile, mode)
  154. //
  155. //    Opens and prepares a input file for reading.
  156. //  Rules:  if the input file is something like vts_xx_1.vob
  157. //            search for following vts_xx_y.vob files (up to y=9?)
  158. //    If success return 1, 0 otherwise
  159. //
  160. ///////////////////////////////////////////////////////////////
  161.  
  162. int CinputStream::OpenStream(char *inputFile, int mode)
  163. {
  164.     char szTemp1[1024],szTemp2[256],path[1024],*FileName,Message[10000];
  165.     int  nameSize,i,finalNamePos;
  166.     // mode=1 => DVDmode, mode=0=> NORMALmode
  167.     if(!inputFile)
  168.         return 0;
  169.  
  170.  
  171.     strcpy(Message, "DVD MODE. The following files will be used\n as just one logical file\n");
  172.     GetFullPathName( inputFile, 1024, path, &FileName);    
  173.     strlwr( FileName ); //Lowercase input file    
  174.     nameSize=strlen( FileName );
  175.     if((mode&DVD_MODE) && (nameSize>=12)){//Open file in DVDmode
  176.  
  177.         strcpy( szTemp2, FileName );
  178.         // file name to test= vts_xx_1.vob
  179.         szTemp2[4]=szTemp2[5]='x';
  180.         strcpy(szTemp1, "vts_xx_1.vob");
  181.         if( strcmp(szTemp1, szTemp2) == 0){ //The file has the format vts_xx_1.vob
  182.             //Create all the files
  183.             i=0;
  184.             iStream.globalPos=0;
  185.             iStream.actualFile=0;
  186.             iStream.totalSize=0;
  187.             do{
  188.                 strcpy( iStream.file[i].name, path);
  189.                 finalNamePos= strlen( inputFile ) - 5; // point here=> *.vob
  190.                 iStream.file[i].name[finalNamePos]= '1' + i;
  191.                 iStream.file[i].handle= fopen(iStream.file[i].name, "rb");
  192.                 if( iStream.file[i].handle != NULL ){
  193.                     //Set buffer size
  194.                     setvbuf( iStream.file[i].handle, NULL, _IOFBF, 256000);
  195.                     iStream.nFiles=i+1;
  196.                     //file size
  197.                     fseek( iStream.file[i].handle,0,SEEK_END );
  198.                     fgetpos(iStream.file[i].handle, &iStream.file[i].size);
  199.                     fseek( iStream.file[i].handle,0,SEEK_SET );
  200.                     iStream.file[i].position=0;
  201.                     iStream.totalSize+= iStream.file[i].size;
  202.                     sprintf(szTemp1, "        %s           size: %.2f  MB\n",iStream.file[i].name, BtoMB(iStream.file[i].size));
  203.                     strcat(Message, szTemp1);
  204.                 }
  205.                 
  206.             }while( iStream.file[i++].handle != NULL );
  207.             if( iStream.file[0].handle == NULL )
  208.                 return 0;
  209.             else{
  210.                 sprintf(szTemp1, "\nTotal size:     %.2f  MBytes", BtoMB(iStream.totalSize));
  211.                 strcat(Message, szTemp1);
  212.                 if(mode & VERBOSE_MODE)
  213.                     MessageBox(hMainWnd, Message, "Flask Warning", MB_OK);
  214.                 SetMulFileMode();
  215.  
  216.                 return 1; //SUCCESS!!
  217.             }
  218.         }
  219.     }
  220.     //Not in DVD mode. Either the file was not suitable for DVDmode
  221.     //DVDmode was disabled
  222.     iStream.file[0].handle= fopen(inputFile,"rb");
  223.     if( iStream.file[0].handle==NULL)
  224.         return 0;
  225.     strcpy(iStream.file[0].name, inputFile);
  226.     iStream.globalPos=0;
  227.     iStream.actualFile=0;                    
  228.     iStream.nFiles=1;
  229.     fseek( iStream.file[0].handle,0,SEEK_END );
  230.     fgetpos(iStream.file[0].handle, &iStream.file[0].size);
  231.     fseek( iStream.file[0].handle,0,SEEK_SET );
  232.     iStream.totalSize= iStream.file[0].size;
  233.     SetMulFileMode();
  234.     return 1;
  235.     
  236.  
  237. }
  238.  
  239. ///////////////////////////////////////////////////////////////
  240. //         int ReadInputStream( buffer, size )
  241. //    Reads size bytes and puts them into the buffer.
  242. //  if the funcion is successful returns bytes written = size
  243. //   if not, returns -1 for error, or last written bytes
  244. //////////////////////////////////////////////////////////////
  245. int CinputStream::Read( ui8 *buffer, int size)
  246. {
  247.     int remaining_bytes;
  248.     int partial,bytes_read;
  249.     
  250.     switch(workingMode)
  251.     {
  252.         case NORMAL_MODE:
  253.             return __read(buffer, size);
  254.         case PLAYSEQ_MODE:
  255.             // The file pointer is not inside the current vob cell.
  256.             if(iStream.globalPos < ps.sp[ps.spanptr].start  ||
  257.                iStream.globalPos > ps.sp[ps.spanptr].end)
  258.             {
  259.                 if(iStream.globalPos > ps.sp[ps.span_count-1].end)
  260.                     return 0;
  261.                 AlignStreamToSpan();
  262.             }
  263.             remaining_bytes = size;
  264.             while(1)
  265.             {
  266.                 if( (partial=(int)(ps.sp[ps.spanptr].end+1 - iStream.globalPos)) < remaining_bytes )
  267.                 {
  268.                     bytes_read = __read(buffer, partial);
  269.                     
  270.                     if(bytes_read < partial)
  271.                         return size - remaining_bytes + bytes_read;
  272.                     buffer       += bytes_read;
  273.                     remaining_bytes -= partial;
  274.                     AlignStreamToSpan();
  275.                     continue;
  276.                 }
  277.                 else
  278.                 {
  279.                     // The remaining bytes belong to this cell
  280.                     return __read(buffer, remaining_bytes);
  281.                 }
  282.             }
  283.             
  284.     }
  285.     return 0;
  286.     
  287. }
  288.  
  289. int  inline CinputStream::__read( ui8 *buffer, int size)
  290. {
  291.     if(!size)
  292.         return 0;
  293. if(iStream.multipleFileMode){
  294.     fgetpos(iStream.file[iStream.actualFile].handle, &iStream.file[iStream.actualFile].position );
  295.     remainingBytes = iStream.file[iStream.actualFile].size - (iStream.file[iStream.actualFile].position);
  296.     if( size > remainingBytes){ //Oops..
  297.         if( (iStream.actualFile+1) == iStream.nFiles ){ //return remaining bits
  298.             ret = fread(buffer, 1, remainingBytes, iStream.file[iStream.actualFile].handle);
  299.             iStream.globalPos += ret;
  300.             return ret;
  301.         }
  302.         else{
  303.             //Read data from the actual file
  304.             ret  = fread(buffer,                      1, remainingBytes,      iStream.file[iStream.actualFile].handle);
  305.                    fseek(iStream.file[++iStream.actualFile].handle, 0L, SEEK_SET);
  306.             ret += fread(&buffer[remainingBytes],     1, size-remainingBytes, iStream.file[iStream.actualFile].handle);
  307.             iStream.globalPos += ret;
  308.             
  309.             return size;
  310.         }
  311.     }
  312.     else{
  313.         //Just copy the bytes
  314.         ret = fread(buffer, 1, size, iStream.file[iStream.actualFile].handle);
  315.         iStream.globalPos += ret;
  316.         return ret;
  317.     }
  318.     return 0;
  319. }
  320. else{
  321.     ret = fread(buffer, 1, size, iStream.file[iStream.actualFile].handle);
  322.     iStream.globalPos += ret;
  323.     return ret;
  324. }
  325.  
  326.  
  327. }
  328. char *CinputStream::GetFileName(){
  329.     return iStream.file[iStream.actualFile].name;
  330. }
  331.  
  332.  
  333. int CinputStream::SetWorkingMode(int mode)
  334. {
  335.     workingMode = mode;
  336.     return 1;
  337. }
  338. //  CinputStream::ValidatePlaySequence()
  339. //
  340. //    Checks the validity of the playsequence
  341. //    that was previously set
  342. int CinputStream::ValidatePlaySequence()
  343. {
  344.     if(ps.total_size <=0)
  345.         return 0;
  346.     if(iStream.totalSize < ps.total_size)
  347.         return 0;
  348.     return 1;
  349. }
  350. // This method alings a stream to the next available span
  351. //    if the file pointer is inside a span, it moves the pointer
  352. //    to the beginning of the span.
  353. int inline CinputStream::AlignStreamToSpan()
  354. {
  355.     int i;
  356.     // First update the current cell pointer
  357.     ps.spanptr++;
  358.     if( ps.spanptr >= ps.span_count )
  359.         ps.spanptr = ps.span_count - 1;
  360.     // Look at this cellptr
  361.     if( iStream.globalPos == ps.sp[ps.spanptr].start){
  362.         // we're on it!
  363.         return 1;
  364.     }
  365.  
  366.     // Ok. Now check that the pointer is inside a span
  367.     int its_inside = 0;
  368.     for(i=0; i< ps.span_count; i++)
  369.     {
  370.         if( iStream.globalPos >= ps.sp[i].start &&
  371.             iStream.globalPos <= ps.sp[i].end  ){
  372.             // we're between it
  373.                 ps.spanptr = i;
  374.                 its_inside = 1;
  375.                 break;
  376.         }
  377.     }
  378.     if(its_inside)
  379.         //we're done
  380.         return 1;
  381.  
  382.     //Align the stream to the next available span
  383.     for(i=0; i< ps.span_count; i++)
  384.     {
  385.         if( iStream.globalPos <= ps.sp[i].start){
  386.             // pick this one
  387.             ps.spanptr = i;
  388.             SetStreamPos(ps.sp[i].start);
  389.             break;
  390.         }
  391.         if( i== ps.span_count-1 ){
  392.             //globalPos is greater than the latest cell start
  393.             ps.spanptr = i;
  394.             SetStreamPos(ps.sp[i].start);
  395.             break;
  396.         }
  397.     }
  398.  
  399.     return 1;
  400. }
  401.  
  402. int CinputStream::AddSpan(TPlaySequenceSpan *span)
  403. {
  404.     if(!span)
  405.         return 0;
  406.     // check for correct span
  407.     if(span->end <= span->start)
  408.         return 0;
  409. //    if(ps.span_count)
  410. //        if(span->start <= ps.sp[ps.span_count - 1].end)
  411. //            return 0;
  412.  
  413.     ps.sp = (TPlaySequenceSpan *) realloc( ps.sp, sizeof(TPlaySequenceSpan)*(ps.span_count+1) );
  414.     ps.span_count++;
  415.     ps.sp[ps.span_count - 1 ] = *span;
  416.     // Update ps stuff
  417.     ps.total_size += span->end - span->start + 1;
  418.     return 1; 
  419. }