home *** CD-ROM | disk | FTP | other *** search
/ PC Welt 2004 March / PCWELT_3_2004.ISO / pcwsoft / flaskmpeg_078_39_src.z.exe / mism_null / flaskmpegmism.cpp < prev    next >
Encoding:
C/C++ Source or Header  |  2002-10-28  |  13.0 KB  |  459 lines

  1. /* 
  2.  *  FlasKMPEG Null Mpeg Input Stream Module 1.0
  3.  *  
  4.  *  This module is a null MISM to support program streams inside FlasKMPEG.
  5.  *
  6.  *    Copyright (C) Alberto Vigata - December 2000  ultraflask@yahoo.com
  7.  *    
  8.  *  This file is part of FlasKMPEG, a free MPEG to MPEG/AVI converter
  9.  *    
  10.  *  FlasKMPEG is free software; you can redistribute it and/or modify
  11.  *  it under the terms of the GNU General Public License as published by
  12.  *  the Free Software Foundation; either version 2, or (at your option)
  13.  *  any later version.
  14.  *   
  15.  *  FlasKMPEG is distributed in the hope that it will be useful,
  16.  *  but WITHOUT ANY WARRANTY; without even the implied warranty of
  17.  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  18.  *  GNU General Public License for more details.
  19.  *   
  20.  *  You should have received a copy of the GNU General Public License
  21.  *  along with GNU Make; see the file COPYING.  If not, write to
  22.  *  the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. 
  23.  *
  24.  */
  25.  
  26. #include "stdafx.h"
  27.  
  28. #include <windows.h>
  29. #include <commctrl.h>
  30. #include <stdio.h>
  31. #include "selectordialog.h"
  32. #include "flaskmpegmism.h"
  33. #include "resource.h"
  34. #include "..\include\mismapi.h"
  35.  
  36.  
  37. #define BtoMB(A) ((double)A/1048576)
  38.  
  39.  
  40. #define SWAP_INT32(x)  ((((ui8*)&x)[0] << 24) |  \
  41.                          (((ui8*)&x)[1] << 16) |  \
  42.                          (((ui8*)&x)[2] << 8) |   \
  43.                          ((ui8*)&x)[3])   
  44. #define INPUT_NOEXIST                 1
  45. #define IS_TRANSPORTSTREAM     2
  46. #define NOT_RECOGNIZED               3
  47. #define NO_AUDIOVIDEO          4
  48. #define PACK_START_CODE        0x000001BA
  49.  
  50. // This points to the last error that ocurred
  51. static char *lastError;
  52.  
  53. // Global params from initialization
  54. static FMMismProperties properties;
  55. static FMMismStdParms params;
  56. static FILE   *openedFile=NULL;
  57. static char fileName[MAX_PATH];
  58. static ui64 streamSize;
  59.  
  60. HWND   hDlgParser, hSelectStream;
  61. unsigned int videoFound, audioFound;
  62. fpos_t pos;
  63.  
  64. LRESULT CALLBACK DlgParser(HWND hDlg, UINT message, WPARAM wParam, LPARAM lParam)
  65. {
  66.     switch (message)
  67.     {
  68.         case WM_INITDIALOG:
  69.                 return TRUE;
  70.  
  71.         case WM_COMMAND:
  72.             if (LOWORD(wParam) == IDOK || LOWORD(wParam) == IDCANCEL) 
  73.             {
  74.                 EndDialog(hDlg, LOWORD(wParam));
  75.                 return TRUE;
  76.             }
  77.             break;
  78.     }
  79.     return FALSE;
  80. }
  81.  
  82. #define GS(x) (params.GetString(x))
  83.  
  84.  
  85. static bool AlignStartCodePrefix(FILE *file){
  86.   bool val = true;
  87.   BYTE inbuf[3];
  88.  
  89.   memset( inbuf, 0xFF, sizeof 3 );
  90.  
  91.   while( (inbuf[0]!=0x00 || inbuf[1]!=0x00 || inbuf[2]!=0x01)  && val){
  92.     inbuf[0]=inbuf[1];
  93.     inbuf[1]=inbuf[2];
  94.     val = fread( &inbuf[2],1,1, file ) == 1;
  95.   }
  96.   return val;
  97. }
  98.  
  99. static bool GetPESID(FILE *file, fmStreamId &strId)
  100. {
  101.   long remainingBytes=0;
  102.   bool bSuccess=true;
  103.   BYTE inbuf[65536];
  104.  
  105.   // Look for a PES and return the Id.
  106.   if( AlignStartCodePrefix(file) )
  107.   {
  108.     // Get the ID and the size of the PES
  109.     bSuccess = fread( inbuf, 3, 1, file ) == 1;
  110.     if( bSuccess )
  111.     {
  112.       strId.streamId    = inbuf[0];
  113.       strId.subStreamId = 0;
  114.       remainingBytes = inbuf[1] << 8 | inbuf[2];
  115.  
  116.       if( inbuf[0] == 0xBD ) // if private stream, handle substream id
  117.       {
  118.         // Substream ID is the first byte of the payload of a private_stream_1
  119.         // Read fixed PES header. 3 bytes
  120.         bSuccess = fread( inbuf, 3, 1, file ) == 1;
  121.         if( bSuccess )
  122.         {
  123.           remainingBytes -= 3;
  124.           // Work out the optional PES header size
  125.           char optPESHeaderSize = inbuf[2];
  126.           // Read the optional header plus the id of the substream
  127.           bSuccess = fread( inbuf, optPESHeaderSize + 1, 1, file ) == 1;
  128.           if( bSuccess )
  129.           {
  130.             remainingBytes -= optPESHeaderSize + 1;
  131.             strId.streamId    = 0xBD;
  132.             strId.subStreamId = inbuf[optPESHeaderSize];
  133.           }
  134.  
  135.         }
  136.       }
  137.       // Read remaining bytes in pes if this is really a PES 
  138.       if( strId.streamId!=0xBA && strId.streamId!=0xBB )
  139.         fread( inbuf, remainingBytes, 1, file);
  140.       return true;
  141.     }
  142.   }
  143.   return false;
  144. }
  145.  
  146. typedef CArr<char> myString;
  147.  
  148. int FindStreams(fmStreamIds *ids, char *file)
  149. {
  150.     int                       porciento,i;
  151.   myString                  tempString;
  152.   tempString.SetArraySize( 256 );
  153.  
  154.     bool                      stream_ids[256], substream_ids[256];
  155.   CArr<fmStreamId>          audioStreams;
  156.   CArr<fmStreamId>          videoStreams;
  157.  
  158.   //CArr<myString>           audioStreamsDesc;
  159.   //CArr<myString>           videoStreamsDesc;
  160.   FILE *infile;
  161.   
  162.   // Opening file
  163.   if( !(infile = fopen( file, "rb" )) )
  164.   {
  165.     lastError = "NullMISM :: Couldn't open file";
  166.     return false;
  167.   }
  168.  
  169.   fmStreamId strId;
  170.  
  171.   hDlgParser = CreateDialog( params.hInst ,(LPCTSTR)(IDD_PARSER), params.hWnd ,(DLGPROC)DlgParser );
  172.   ShowWindow(hDlgParser, SW_SHOW);
  173.     
  174.     //Initialize Tstream detector
  175.     for(i=0;i<256;i++){
  176.            stream_ids[i]=   false;
  177.         substream_ids[i]=   false;
  178.     }
  179.  
  180.   audioStreams.EmptyArray();
  181.   videoStreams.EmptyArray();
  182.  
  183.   ids->idCount = 0;
  184.  
  185.     //START
  186.     fseek( infile, 0, SEEK_SET );
  187.  
  188.   fgetpos( infile, &pos );
  189.  
  190.         while( pos<(params.lurkSize*1024) && GetPESID(infile, strId) ){
  191.             if(stream_ids[strId.streamId]==false){    //if this stream is a new one
  192.                 if(strId.streamId >= 0xE0 && strId.streamId <= 0xEF){   //if it was a video stream
  193.  
  194.           sprintf( strId.streamName , "MPEG %s 0x%02X ", GS(FST_VIDEOTRACK) ,strId.streamId);        
  195.           videoStreams.AddItem(&strId);
  196.                     
  197.  
  198.                     sprintf( tempString.GetData(), "%s %d", GS(FST_VIDEOFOUND),videoStreams.GetCount() );
  199.                     SetDlgItemText( hDlgParser, IDC_VIDEO, tempString.GetData());
  200.                     stream_ids[strId.streamId]=true;
  201.                 }
  202.                 if(strId.streamId >= 0xC0 && strId.streamId <= 0xDF ){//if it was an audio stream
  203.  
  204.           sprintf(strId.streamName, "MPEG %s 0x%02X ", GS(FST_AUDIOTRACK),strId.streamId);
  205.           audioStreams.AddItem( &strId );
  206.                 
  207.                     sprintf( tempString.GetData(), "%s %d", GS(FST_AUDIOFOUND),audioStreams.GetCount() );
  208.                     SetDlgItemText( hDlgParser, IDC_AUDIO, tempString.GetData());
  209.                     stream_ids[strId.streamId]=true;
  210.  
  211.                 }
  212.                 if(substream_ids[strId.subStreamId]==false && strId.streamId == 0xBD && strId.subStreamId >= 0x80 && strId.subStreamId <= 0x87){//if it was an audio stream
  213.  
  214.                     sprintf(strId.streamName, "AC3 %s 0x%02X %s 0x%02X", GS(FST_AUDIOTRACK),strId.subStreamId,GS(FST_MAINTRACK), strId.streamId);
  215.           audioStreams.AddItem( &strId );
  216.  
  217.  
  218.                     sprintf( tempString.GetData(), "%s %d", GS(FST_AUDIOFOUND),audioStreams.GetCount());
  219.                     SetDlgItemText( hDlgParser, IDC_AUDIO, tempString.GetData());
  220.                        stream_ids[strId.streamId]   =false;
  221.                     substream_ids[strId.subStreamId]=true;
  222.  
  223.                 }
  224.               
  225.             }
  226.             fgetpos( infile, &pos );
  227.  
  228.             porciento= (int)(((double)pos/(double)(params.lurkSize*1024))*100.0);
  229.             SendDlgItemMessage( hDlgParser, IDC_PROGRESS, PBM_SETPOS, porciento , 0);
  230.  
  231.         }
  232.  
  233.     //    We've finished the lurking
  234.         if(videoStreams.GetCount()<1){
  235.             DestroyWindow(hDlgParser);
  236.             return 0;    //No video stream found. CHUNGO
  237.         }
  238.         if(videoStreams.GetCount()==1 && audioStreams.GetCount()==1){
  239.       // We found one audio and one video stream
  240.       ids->vIds[0] = videoStreams[0];
  241.             ids->vIds[1] = audioStreams[0];
  242.       ids->idAudioDef = 1;
  243.       ids->idCount = 2;
  244.         }
  245.         else if(videoStreams.GetCount()==1 && audioStreams.GetCount()==0){
  246.             ids->vIds[0] = videoStreams[0];
  247.       ids->idAudioDef = 0;
  248.       ids->idCount = 1;
  249.         }
  250.         else if(videoStreams.GetCount()>1 || audioStreams.GetCount()>0){
  251.  
  252.             TSelectorDialog *sd= (TSelectorDialog *) new TSelectorDialog;
  253.  
  254.             sd->lateral_text = GS(FST_LATERAL);
  255.             sd->tittle       = GS(FST_TITLE);
  256.             sd->button_text  = GS(FST_BUTTON);
  257.             sd->sections_titles[0]=GS(FST_VIDEOFOUND);
  258.             sd->section_mode[0]   =SINGLE_SELECT | MUST_SELECT;
  259.             sd->section_mode[1]   =SINGLE_SELECT | MUST_SELECT ;
  260.             sd->sections_titles[1]=GS(FST_AUDIOFOUND);
  261.             sd->section_count = 2;
  262.  
  263.  
  264.             sd->strings[0].SetArraySize( videoStreams.GetCount() );
  265.             for(i=0; i<videoStreams.GetCount(); i++)
  266.                 sd->strings[0][i] = videoStreams[i].streamName;
  267.  
  268.             sd->strings[1].SetArraySize( audioStreams.GetCount() );            
  269.             for(i=0; i<audioStreams.GetCount(); i++)
  270.                 sd->strings[1][i] = audioStreams[i].streamName;
  271.             
  272.             // ResetSelections MUST be called before OpenSelectorDialog or setting default selections
  273.             //      in order to initialize selections.
  274.             ResetSelections(sd);
  275.             // Now set default selections
  276.             sd->selected[0][0] = 1;  //First section first video
  277.             sd->selected[1][0] = 1;  //Second section First audio
  278.  
  279.             OpenSelectorDialog(params.hWnd, params.hInst, sd);
  280.  
  281.             // FIXME: Video is mandatory but that is likely to change in future versions
  282.       ids->vIds[0] = videoStreams[0];
  283.       ids->idCount = 1;
  284.             // FIXME: When multiaudio is available check this one
  285.       // Copy all the availabe audio streams
  286.       ids->idAudioDef = ids->idCount + GetFirstSelected( sd, 1 );
  287.       for(i=0; i<audioStreams.GetCount(); i++)
  288.       {
  289.         ids->vIds[i+1] = audioStreams[i];
  290.         ids->idCount++;
  291.       }
  292.  
  293.  
  294.             delete sd;
  295.         }
  296.  
  297.     fclose( infile );
  298.     DestroyWindow(hDlgParser);
  299.     return true;
  300. }
  301.  
  302.  
  303.  
  304.  
  305.   // File IO ptrs
  306. bool CanOpenFile(char *fileName, DWORD *merit)
  307. {
  308.   FILE *file;
  309.   int startcode;
  310.  
  311.   // Opening file
  312.   if( !(file = fopen( fileName, "rb" )) )
  313.   {
  314.     lastError = "NullMISM :: Couldn't open file";
  315.     return false;
  316.   }
  317.  
  318.  
  319.   fseek(file, 0, SEEK_SET);
  320.  
  321.   fread( (ui8 *)&startcode, 4, 1, file ); //Read first 32 bits
  322.  
  323.   fclose( file );  
  324.  
  325.   bool bSupported = (SWAP_INT32(startcode) == PACK_START_CODE);
  326.   if(bSupported) *merit = FM_MISM_MERIT_NORMAL;
  327.   return  bSupported;
  328. }
  329.  
  330. ui64 InternalGetStreamSize(fmHandle file);
  331.  
  332. fmHandle OpenStream(char *file)
  333. {
  334.   // Opening file and return it
  335.   if( !(openedFile = fopen( file, "rb" )) )
  336.   {
  337.     lastError = "NullMISM :: Couldn't open file";
  338.     return NULL;
  339.   }
  340.   // save file name
  341.   strcpy( fileName, file );
  342.   // update streamSize
  343.   streamSize = InternalGetStreamSize( (fmHandle)openedFile );
  344.  
  345.   return (fmHandle)openedFile;
  346. }
  347.  
  348. int ReadStream(fmHandle file, ui8 *buf, unsigned int size)
  349. {
  350.   return fread( buf, 1, size, (FILE *)file );
  351. }
  352.  
  353. int SetStreamPos(fmHandle file, ui64 pos)
  354. {
  355.   fpos_t my_pos = pos;
  356.   return fsetpos( (FILE *)file, &my_pos )==0 ? FM_MISM_OK : FM_MISM_ERROR;
  357. }
  358.   // Set the position of the stream if the module supports FM_MISM_READFILES feature
  359.   // Return FM_MISM_ERROR otherwise.
  360.  
  361. int GetStreamPos(fmHandle file, ui64 *pos)
  362. {
  363.   fpos_t my_pos;
  364.   int ret = fgetpos( (FILE *)file, &my_pos )==0 ? FM_MISM_OK : FM_MISM_ERROR;
  365.   *pos = my_pos;
  366.   return ret;
  367. }
  368.  
  369. ui64 InternalGetStreamSize(fmHandle file)
  370. {
  371.   ui64 currentPos, fileSize;
  372.   // Save current position
  373.   GetStreamPos( file, ¤tPos );
  374.   // Move to the end
  375.   fseek( (FILE *)file, 0, SEEK_END );
  376.   // Get position
  377.   GetStreamPos( file, &fileSize );
  378.   // Restore position
  379.   SetStreamPos( file, currentPos );
  380.  
  381.   return fileSize;
  382. }
  383. // FIXME different handles could yield different streamSizes.
  384. ui64 GetStreamSize( fmHandle strHandle )
  385. {
  386.   return streamSize;
  387. }
  388.  
  389. int CloseStream(fmHandle file)
  390. {
  391.   return fclose( (FILE *)file )==0 ? FM_MISM_OK : FM_MISM_ERROR;
  392. }
  393.  
  394. // Windows already defines GetLastError
  395. char* GetLastErrorInt(void)
  396. {
  397.   return lastError;
  398. }
  399.  
  400. int GetStreams(fmStreamIds *ids, char* fileName)
  401. {
  402.   // Open the stream and look for stream Ids.
  403.   if(!FindStreams( ids, fileName ))
  404.      return FM_MISM_ERROR;
  405.   return FM_MISM_OK;
  406. }
  407.  
  408. char* GetStreamStatus(fmHandle file)
  409. {
  410.   return openedFile ? "Normal" : "Idle";
  411. }
  412. char *GetFileName(fmHandle file)
  413. {
  414.   return fileName;
  415. }
  416.  
  417. bool initDone = false;
  418. void Init(LPFMMismStdParms parms)
  419. {
  420.   memcpy( ¶ms, parms, sizeof FMMismStdParms );
  421.   properties.dwSize   = sizeof properties;
  422.   properties.dwMismId = MISM_NULLID;
  423.   initDone = true;
  424. }
  425.  
  426. void DeInit(void)
  427. {
  428.   return;
  429. }
  430.  
  431.  
  432. extern "C"
  433. {
  434.   __declspec(dllexport) void __cdecl fmGetMism(LPFMMismInfo pMismInfo)
  435.   {
  436.     pMismInfo->dwSize         =  sizeof FMMismInfo;
  437.     pMismInfo->dwVersion      =  FM_MISM_VERSION;
  438.     pMismInfo->dwOutputTypes  =  FM_MISM_PROGRAMSTREAM;
  439.     pMismInfo->pProperties    = &properties;
  440.     strcpy( pMismInfo->sDescription, "MPEG Program Stream NULL MISM" );
  441.     strcpy( pMismInfo->sExtensions, "*.m2v;*.mpg;*.vob;*.m1v;*.m2v;*.mpe;*.mpeg;*.mv2;*.mpv;" );
  442.     pMismInfo->CanOpenFile      =   CanOpenFile;
  443.     pMismInfo->OpenStream       =   OpenStream;
  444.     pMismInfo->ReadStream       =   ReadStream;
  445.     pMismInfo->SetStreamPos     =   SetStreamPos;
  446.     pMismInfo->GetStreamPos     =   GetStreamPos;
  447.     pMismInfo->CloseStream      =   CloseStream;
  448.     pMismInfo->GetStreams       =   GetStreams;
  449.     pMismInfo->GetLastError     =   GetLastErrorInt;
  450.     pMismInfo->GetStreamStatus  =   GetStreamStatus;
  451.     pMismInfo->GetStreamSize    =   GetStreamSize;
  452.     pMismInfo->Init             =   Init;
  453.     pMismInfo->DeInit           =   DeInit;
  454.     pMismInfo->GetFileName      =   GetFileName;
  455.     pMismInfo->dwReserved       =   0;
  456.   }
  457. }
  458.  
  459.