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

  1. /* 
  2.  *  StreamDetector.cpp: implementation of the CStreamDetector class.
  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. #include <windows.h>
  24. #include <commctrl.h>
  25. #include "..\Misc\selectordialog.h"
  26. #include "StreamDetector.h"
  27. #include "..\flaskmpeg.h"
  28. #include "..\runstate.h"
  29. #include "..\resource.h"
  30. #include "..\error.h"
  31. #include "..\demux\demux.h"
  32.  
  33. #define BtoMB(A) ((double)A/1048576)
  34.  
  35. extern TRunState rs;
  36. //////////////////////////////////////////////////////////////////////
  37. // Construction/Destruction
  38. //////////////////////////////////////////////////////////////////////
  39.  
  40. CStreamDetector::CStreamDetector()
  41. {
  42.     inp=NULL;
  43. }
  44.  
  45. CStreamDetector::~CStreamDetector()
  46. {
  47.     if(inp)
  48.         delete inp;
  49. }
  50.  
  51.  
  52.  
  53. #define SWAP_INT32(x)  ((((ui8*)&x)[0] << 24) |  \
  54.                          (((ui8*)&x)[1] << 16) |  \
  55.                          (((ui8*)&x)[2] << 8) |   \
  56.                          ((ui8*)&x)[3])   
  57. #define INPUT_NOEXIST            1
  58. #define IS_TRANSPORTSTREAM      2
  59. #define NOT_RECOGNIZED            3
  60. #define NO_AUDIOVIDEO           4
  61. #define PACK_START_CODE          0x000001BA
  62.  
  63. int CStreamDetector::RecognizeType()
  64. {
  65.     ui32 i;
  66.  
  67.     if(!inp)
  68.         return INPUT_NOEXIST;
  69.  
  70.     inp->SetStreamPos(0);
  71.     //Recognize type
  72.     inp->Read((ui8 *)&i, 4); //Read first 32 bits
  73.  
  74.       if (SWAP_INT32(i) != PACK_START_CODE)
  75.       {
  76.         DebugPrint("File is not an MPEG Program Stream",0);
  77.         return NOT_RECOGNIZED;
  78.       }
  79.  
  80.       
  81. /*      //Rewind file
  82.       SeekFirst();
  83.       if(!GetStreams())
  84.           return NO_AUDIOVIDEO;
  85. */
  86.       return 0;    //Everything OK
  87.  
  88. }
  89.  
  90.  
  91. extern HINSTANCE hInst;
  92. extern HWND hMainWnd;
  93. HWND   hDlgParser, hSelectStream;
  94. unsigned int videoFound, audioFound;
  95. TStreamDetector *gSt;
  96. fpos_t pos;
  97.  
  98. LRESULT CALLBACK DlgParser(HWND hDlg, UINT message, WPARAM wParam, LPARAM lParam)
  99. {
  100.     switch (message)
  101.     {
  102.         case WM_INITDIALOG:
  103.                 return TRUE;
  104.  
  105.         case WM_COMMAND:
  106.             if (LOWORD(wParam) == IDOK || LOWORD(wParam) == IDCANCEL) 
  107.             {
  108.                 EndDialog(hDlg, LOWORD(wParam));
  109.                 return TRUE;
  110.             }
  111.             break;
  112.     }
  113.     return FALSE;
  114. }
  115.  
  116.  
  117.  
  118. int CStreamDetector::GetStreams(TStreamDetector *st, int lurk_size)
  119. {
  120.     int                       porciento,i;
  121.     char                      szTemp[256];
  122.     unsigned char             *dummy;
  123.     PESinfo                   PES;
  124.     bool                      stream_ids[256], substream_ids[256];
  125.     TStreamIdentifier         mySt;
  126.     
  127.     gSt = st;
  128.  
  129.     if(!st)
  130.         return 0;
  131.  
  132.     hDlgParser= CreateDialog(hInst,(LPCTSTR)(IDD_PARSER), hMainWnd ,(DLGPROC)DlgParser );
  133.     ShowWindow(hDlgParser, SW_SHOW);
  134.     
  135.     CDemux *demux=NULL;
  136.     demux=new CDemux();
  137.     if(demux){
  138.         if(!demux->SetInput(inp)){
  139.             delete demux;
  140.             return 0;
  141.         }
  142.     }
  143.     else
  144.         return 0;
  145.     
  146.  
  147.     //Initialize Tstream detector
  148.     for(i=0;i<256;i++){
  149.            stream_ids[i]=   false;
  150.         substream_ids[i]=   false;
  151.     }
  152.  
  153.     st->n_audio_streams =0;
  154.     st->n_subpic_streams=0;
  155.     st->n_video_streams =0;
  156.     st->audio           =NULL;
  157.     st->video           =NULL;
  158.     st->subpic          =NULL;
  159.     
  160.     st->video_selected=0;
  161.     for(i=0; i<MAX_AUDIO_STREAMS; i++)
  162.         st->audio_selected[i]=0;
  163.     st->subpic_selected=0;
  164.  
  165.  
  166.  
  167.     //START
  168.     inp->SetStreamPos(0);
  169.  
  170.  
  171.         pos=inp->GetStreamPos();
  172.  
  173.  
  174.         while(pos<(lurk_size*1024) && demux->ReadPES(&dummy,&PES)){
  175.             if(stream_ids[PES.streamID]==false){    //if this stream is a new one
  176.                 if(PES.streamID >= 0xE0 && PES.streamID <= 0xEF){   //if it was a video stream
  177.                     mySt.aux          =0;
  178.                     mySt.streamID     =PES.streamID;
  179.                     mySt.subStreamID  =0;
  180.                     sprintf(szTemp, "MPEG %s 0x%02X ", GS(FST_VIDEOTRACK) ,PES.streamID);
  181.                     strcpy(mySt.id,  szTemp);
  182.                     
  183.                     st->AddST(&mySt);
  184.                     
  185.  
  186.                     sprintf( szTemp, "%s %d", GS(FST_VIDEOFOUND),st->n_video_streams);
  187.                     SetDlgItemText( hDlgParser, IDC_VIDEO, szTemp);
  188.                     stream_ids[PES.streamID]=true;
  189.                 }
  190.                 if(PES.streamID >= 0xC0 && PES.streamID <= 0xDF ){//if it was an audio stream
  191.                     mySt.aux          =0;
  192.                     mySt.streamID     =PES.streamID;
  193.                     mySt.subStreamID  =0;
  194.                     sprintf(szTemp, "MPEG %s 0x%02X ", GS(FST_AUDIOTRACK),PES.streamID);
  195.                     strcpy(mySt.id,  szTemp);
  196.                     
  197.                     st->AddST(&mySt);
  198.                     
  199.  
  200.  
  201.  
  202.                     sprintf( szTemp, "%s %d", GS(FST_AUDIOFOUND),st->n_audio_streams);
  203.                     SetDlgItemText( hDlgParser, IDC_AUDIO, szTemp);
  204.                     stream_ids[PES.streamID]=true;
  205.  
  206.                 }
  207.                 if(substream_ids[PES.subStreamID]==false && PES.streamID == 0xBD && PES.subStreamID >= 0x80 && PES.subStreamID <= 0x87){//if it was an audio stream
  208.                     mySt.aux          =0;
  209.                     mySt.streamID     =PES.streamID;
  210.                     mySt.subStreamID  =PES.subStreamID;
  211.                     sprintf(szTemp, "AC3 %s 0x%02X %s 0x%02X", GS(FST_AUDIOTRACK),PES.subStreamID,GS(FST_MAINTRACK), PES.streamID);
  212.                     strcpy(mySt.id,  szTemp);
  213.                     
  214.                     st->AddST(&mySt);
  215.                     
  216.  
  217.  
  218.                     sprintf( szTemp, "%s %d", GS(FST_AUDIOFOUND),st->n_audio_streams);
  219.                     SetDlgItemText( hDlgParser, IDC_AUDIO, szTemp);
  220.                        stream_ids[PES.streamID]   =false;
  221.                     substream_ids[PES.subStreamID]=true;
  222.  
  223.                 }
  224.               
  225.             }
  226.             pos=inp->GetStreamPos();
  227.  
  228.             porciento= (int)(((double)pos/(double)(lurk_size*1024))*100.0);
  229.             SendDlgItemMessage( hDlgParser, IDC_PROGRESS, PBM_SETPOS, porciento , 0);
  230.  
  231.         }
  232.  
  233.     //    We've finished the lurking
  234.         if(st->n_video_streams<1){
  235.             delete demux;
  236.             DestroyWindow(hDlgParser);
  237.             return 0;    //No video stream found. CHUNGO
  238.         }
  239.         if(st->n_video_streams==1 && st->n_audio_streams==1){
  240.             st->video_selected      = 0;
  241.             st->audio_selected[0]        = 0;
  242.         }
  243.         else if(st->n_video_streams==1 && st->n_audio_streams==0){
  244.             st->video_selected      = 0;
  245.         }
  246.         else if(st->n_video_streams>1 || st->n_audio_streams>0){
  247.             //DialogBox(hInst,(LPCTSTR)(IDD_STRSELECTOR), hMainWnd ,(DLGPROC)DlgSelector);
  248.             TSelectorDialog *sd= (TSelectorDialog *) new TSelectorDialog;
  249.  
  250.             sd->lateral_text = GS(FST_LATERAL);
  251.             sd->tittle       = GS(FST_TITLE);
  252.             sd->button_text  = GS(FST_BUTTON);
  253.             sd->sections_titles[0]=GS(FST_VIDEOFOUND);
  254.             sd->section_mode[0]   =SINGLE_SELECT | MUST_SELECT;
  255.             sd->section_mode[1]   =SINGLE_SELECT | MUST_SELECT ;
  256.             sd->sections_titles[1]=GS(FST_AUDIOFOUND);
  257.             sd->section_count = 2;
  258.  
  259.  
  260.             sd->strings[0].SetArraySize(st->n_video_streams);
  261.             for(i=0; i<st->n_video_streams; i++)
  262.                 sd->strings[0][i] = st->video[i].id;
  263.  
  264.             sd->strings[1].SetArraySize(st->n_audio_streams);            
  265.             for(i=0; i<st->n_audio_streams; i++)
  266.                 sd->strings[1][i] = st->audio[i].id;
  267.             
  268.             // ResetSelections MUST be called before OpenSelectorDialog or setting default selections
  269.             //      in order to initialize selections.
  270.             ResetSelections(sd);
  271.             // Now set default selections
  272.             sd->selected[0][0] = 1;  //First section first video
  273.             sd->selected[1][0] = 1;  //Second section First audio
  274.  
  275.             OpenSelectorDialog(hMainWnd, hInst, sd);
  276.  
  277.             // FIXME: Video is mandatory but that is likely to change in future versions
  278.             st->video_selected    = 0;  // Select the first stream
  279.             // FIXME: When multiaudio is available check this one
  280.             i=0;
  281.             while( i < sd->selected[1].GetCount() ){
  282.                 if(sd->selected[1][i]==1)
  283.                     break;
  284.                 i++;
  285.             }
  286.  
  287.             st->audio_selected[0] = i;
  288.  
  289.             delete sd;
  290.  
  291.  
  292.         }
  293.     
  294.  
  295.     delete demux;
  296.     DestroyWindow(hDlgParser);
  297.     return 1;
  298.  
  299. }
  300.  
  301. int CStreamDetector::SetFile(char *inputfile)
  302. {
  303.     inp=new CinputStream;
  304.     if(inp)
  305.         return inp->OpenStream(inputfile, DVD_MODE|VERBOSE_MODE);
  306.     else
  307.         return 0;
  308. }
  309.  
  310. TStreamDetector::TStreamDetector(){
  311.     video= NULL;
  312.     audio= NULL;
  313.     subpic=NULL;
  314. }
  315.  
  316. TStreamDetector::~TStreamDetector(){
  317.     if(video)
  318.         free(video);
  319.     if(audio)
  320.         free(audio);
  321.     if(subpic)
  322.         free(subpic);
  323. }
  324.  
  325. int TStreamDetector::AddST(TStreamIdentifier *si)
  326. {
  327.     if(si->streamID >= 0xE0 && si->streamID <= 0xEF){
  328.         n_video_streams++;
  329.         //resize the SIs buffer
  330.         video=(TStreamIdentifier *) realloc(video, n_video_streams*sizeof(TStreamIdentifier));
  331.         memcpy((void *)&video[n_video_streams-1], (void *)si, sizeof(TStreamIdentifier));
  332.     }
  333.     else if((si->streamID >= 0xC0 && si->streamID <= 0xDF) || \
  334.             (si->streamID == 0xBD && si->subStreamID >= 0x80 && si->subStreamID <= 0x87)){
  335.         n_audio_streams++;
  336.         //resize the SIs buffer
  337.         audio=(TStreamIdentifier *) realloc(audio, n_audio_streams*sizeof(TStreamIdentifier));
  338.         memcpy((void *)&audio[n_audio_streams-1], (void *)si, sizeof(TStreamIdentifier));
  339.     }
  340.     return 1;
  341. }
  342.