home *** CD-ROM | disk | FTP | other *** search
- /*
- * FlasKMPEG Null Mpeg Input Stream Module 1.0
- *
- * This module is a null MISM to support program streams inside FlasKMPEG.
- *
- * Copyright (C) Alberto Vigata - December 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 "stdafx.h"
-
- #include <windows.h>
- #include <commctrl.h>
- #include <stdio.h>
- #include "selectordialog.h"
- #include "flaskmpegmism.h"
- #include "resource.h"
- #include "..\include\mismapi.h"
-
-
- #define BtoMB(A) ((double)A/1048576)
-
-
- #define SWAP_INT32(x) ((((ui8*)&x)[0] << 24) | \
- (((ui8*)&x)[1] << 16) | \
- (((ui8*)&x)[2] << 8) | \
- ((ui8*)&x)[3])
- #define INPUT_NOEXIST 1
- #define IS_TRANSPORTSTREAM 2
- #define NOT_RECOGNIZED 3
- #define NO_AUDIOVIDEO 4
- #define PACK_START_CODE 0x000001BA
-
- // This points to the last error that ocurred
- static char *lastError;
-
- // Global params from initialization
- static FMMismProperties properties;
- static FMMismStdParms params;
- static FILE *openedFile=NULL;
- static char fileName[MAX_PATH];
- static ui64 streamSize;
-
- HWND hDlgParser, hSelectStream;
- unsigned int videoFound, audioFound;
- fpos_t pos;
-
- LRESULT CALLBACK DlgParser(HWND hDlg, UINT message, WPARAM wParam, LPARAM lParam)
- {
- switch (message)
- {
- case WM_INITDIALOG:
- return TRUE;
-
- case WM_COMMAND:
- if (LOWORD(wParam) == IDOK || LOWORD(wParam) == IDCANCEL)
- {
- EndDialog(hDlg, LOWORD(wParam));
- return TRUE;
- }
- break;
- }
- return FALSE;
- }
-
- #define GS(x) (params.GetString(x))
-
-
- static bool AlignStartCodePrefix(FILE *file){
- bool val = true;
- BYTE inbuf[3];
-
- memset( inbuf, 0xFF, sizeof 3 );
-
- while( (inbuf[0]!=0x00 || inbuf[1]!=0x00 || inbuf[2]!=0x01) && val){
- inbuf[0]=inbuf[1];
- inbuf[1]=inbuf[2];
- val = fread( &inbuf[2],1,1, file ) == 1;
- }
- return val;
- }
-
- static bool GetPESID(FILE *file, fmStreamId &strId)
- {
- long remainingBytes=0;
- bool bSuccess=true;
- BYTE inbuf[65536];
-
- // Look for a PES and return the Id.
- if( AlignStartCodePrefix(file) )
- {
- // Get the ID and the size of the PES
- bSuccess = fread( inbuf, 3, 1, file ) == 1;
- if( bSuccess )
- {
- strId.streamId = inbuf[0];
- strId.subStreamId = 0;
- remainingBytes = inbuf[1] << 8 | inbuf[2];
-
- if( inbuf[0] == 0xBD ) // if private stream, handle substream id
- {
- // Substream ID is the first byte of the payload of a private_stream_1
- // Read fixed PES header. 3 bytes
- bSuccess = fread( inbuf, 3, 1, file ) == 1;
- if( bSuccess )
- {
- remainingBytes -= 3;
- // Work out the optional PES header size
- char optPESHeaderSize = inbuf[2];
- // Read the optional header plus the id of the substream
- bSuccess = fread( inbuf, optPESHeaderSize + 1, 1, file ) == 1;
- if( bSuccess )
- {
- remainingBytes -= optPESHeaderSize + 1;
- strId.streamId = 0xBD;
- strId.subStreamId = inbuf[optPESHeaderSize];
- }
-
- }
- }
- // Read remaining bytes in pes if this is really a PES
- if( strId.streamId!=0xBA && strId.streamId!=0xBB )
- fread( inbuf, remainingBytes, 1, file);
- return true;
- }
- }
- return false;
- }
-
- typedef CArr<char> myString;
-
- int FindStreams(fmStreamIds *ids, char *file)
- {
- int porciento,i;
- myString tempString;
- tempString.SetArraySize( 256 );
-
- bool stream_ids[256], substream_ids[256];
- CArr<fmStreamId> audioStreams;
- CArr<fmStreamId> videoStreams;
-
- //CArr<myString> audioStreamsDesc;
- //CArr<myString> videoStreamsDesc;
- FILE *infile;
-
- // Opening file
- if( !(infile = fopen( file, "rb" )) )
- {
- lastError = "NullMISM :: Couldn't open file";
- return false;
- }
-
- fmStreamId strId;
-
- hDlgParser = CreateDialog( params.hInst ,(LPCTSTR)(IDD_PARSER), params.hWnd ,(DLGPROC)DlgParser );
- ShowWindow(hDlgParser, SW_SHOW);
-
- //Initialize Tstream detector
- for(i=0;i<256;i++){
- stream_ids[i]= false;
- substream_ids[i]= false;
- }
-
- audioStreams.EmptyArray();
- videoStreams.EmptyArray();
-
- ids->idCount = 0;
-
- //START
- fseek( infile, 0, SEEK_SET );
-
- fgetpos( infile, &pos );
-
- while( pos<(params.lurkSize*1024) && GetPESID(infile, strId) ){
- if(stream_ids[strId.streamId]==false){ //if this stream is a new one
- if(strId.streamId >= 0xE0 && strId.streamId <= 0xEF){ //if it was a video stream
-
- sprintf( strId.streamName , "MPEG %s 0x%02X ", GS(FST_VIDEOTRACK) ,strId.streamId);
- videoStreams.AddItem(&strId);
-
-
- sprintf( tempString.GetData(), "%s %d", GS(FST_VIDEOFOUND),videoStreams.GetCount() );
- SetDlgItemText( hDlgParser, IDC_VIDEO, tempString.GetData());
- stream_ids[strId.streamId]=true;
- }
- if(strId.streamId >= 0xC0 && strId.streamId <= 0xDF ){//if it was an audio stream
-
- sprintf(strId.streamName, "MPEG %s 0x%02X ", GS(FST_AUDIOTRACK),strId.streamId);
- audioStreams.AddItem( &strId );
-
- sprintf( tempString.GetData(), "%s %d", GS(FST_AUDIOFOUND),audioStreams.GetCount() );
- SetDlgItemText( hDlgParser, IDC_AUDIO, tempString.GetData());
- stream_ids[strId.streamId]=true;
-
- }
- if(substream_ids[strId.subStreamId]==false && strId.streamId == 0xBD && strId.subStreamId >= 0x80 && strId.subStreamId <= 0x87){//if it was an audio stream
-
- sprintf(strId.streamName, "AC3 %s 0x%02X %s 0x%02X", GS(FST_AUDIOTRACK),strId.subStreamId,GS(FST_MAINTRACK), strId.streamId);
- audioStreams.AddItem( &strId );
-
-
- sprintf( tempString.GetData(), "%s %d", GS(FST_AUDIOFOUND),audioStreams.GetCount());
- SetDlgItemText( hDlgParser, IDC_AUDIO, tempString.GetData());
- stream_ids[strId.streamId] =false;
- substream_ids[strId.subStreamId]=true;
-
- }
-
- }
- fgetpos( infile, &pos );
-
- porciento= (int)(((double)pos/(double)(params.lurkSize*1024))*100.0);
- SendDlgItemMessage( hDlgParser, IDC_PROGRESS, PBM_SETPOS, porciento , 0);
-
- }
-
- // We've finished the lurking
- if(videoStreams.GetCount()<1){
- DestroyWindow(hDlgParser);
- return 0; //No video stream found. CHUNGO
- }
- if(videoStreams.GetCount()==1 && audioStreams.GetCount()==1){
- // We found one audio and one video stream
- ids->vIds[0] = videoStreams[0];
- ids->vIds[1] = audioStreams[0];
- ids->idAudioDef = 1;
- ids->idCount = 2;
- }
- else if(videoStreams.GetCount()==1 && audioStreams.GetCount()==0){
- ids->vIds[0] = videoStreams[0];
- ids->idAudioDef = 0;
- ids->idCount = 1;
- }
- else if(videoStreams.GetCount()>1 || audioStreams.GetCount()>0){
-
- TSelectorDialog *sd= (TSelectorDialog *) new TSelectorDialog;
-
- sd->lateral_text = GS(FST_LATERAL);
- sd->tittle = GS(FST_TITLE);
- sd->button_text = GS(FST_BUTTON);
- sd->sections_titles[0]=GS(FST_VIDEOFOUND);
- sd->section_mode[0] =SINGLE_SELECT | MUST_SELECT;
- sd->section_mode[1] =SINGLE_SELECT | MUST_SELECT ;
- sd->sections_titles[1]=GS(FST_AUDIOFOUND);
- sd->section_count = 2;
-
-
- sd->strings[0].SetArraySize( videoStreams.GetCount() );
- for(i=0; i<videoStreams.GetCount(); i++)
- sd->strings[0][i] = videoStreams[i].streamName;
-
- sd->strings[1].SetArraySize( audioStreams.GetCount() );
- for(i=0; i<audioStreams.GetCount(); i++)
- sd->strings[1][i] = audioStreams[i].streamName;
-
- // ResetSelections MUST be called before OpenSelectorDialog or setting default selections
- // in order to initialize selections.
- ResetSelections(sd);
- // Now set default selections
- sd->selected[0][0] = 1; //First section first video
- sd->selected[1][0] = 1; //Second section First audio
-
- OpenSelectorDialog(params.hWnd, params.hInst, sd);
-
- // FIXME: Video is mandatory but that is likely to change in future versions
- ids->vIds[0] = videoStreams[0];
- ids->idCount = 1;
- // FIXME: When multiaudio is available check this one
- // Copy all the availabe audio streams
- ids->idAudioDef = ids->idCount + GetFirstSelected( sd, 1 );
- for(i=0; i<audioStreams.GetCount(); i++)
- {
- ids->vIds[i+1] = audioStreams[i];
- ids->idCount++;
- }
-
-
- delete sd;
- }
-
- fclose( infile );
- DestroyWindow(hDlgParser);
- return true;
- }
-
-
-
-
- // File IO ptrs
- bool CanOpenFile(char *fileName, DWORD *merit)
- {
- FILE *file;
- int startcode;
-
- // Opening file
- if( !(file = fopen( fileName, "rb" )) )
- {
- lastError = "NullMISM :: Couldn't open file";
- return false;
- }
-
-
- fseek(file, 0, SEEK_SET);
-
- fread( (ui8 *)&startcode, 4, 1, file ); //Read first 32 bits
-
- fclose( file );
-
- bool bSupported = (SWAP_INT32(startcode) == PACK_START_CODE);
- if(bSupported) *merit = FM_MISM_MERIT_NORMAL;
- return bSupported;
- }
-
- ui64 InternalGetStreamSize(fmHandle file);
-
- fmHandle OpenStream(char *file)
- {
- // Opening file and return it
- if( !(openedFile = fopen( file, "rb" )) )
- {
- lastError = "NullMISM :: Couldn't open file";
- return NULL;
- }
- // save file name
- strcpy( fileName, file );
- // update streamSize
- streamSize = InternalGetStreamSize( (fmHandle)openedFile );
-
- return (fmHandle)openedFile;
- }
-
- int ReadStream(fmHandle file, ui8 *buf, unsigned int size)
- {
- return fread( buf, 1, size, (FILE *)file );
- }
-
- int SetStreamPos(fmHandle file, ui64 pos)
- {
- fpos_t my_pos = pos;
- return fsetpos( (FILE *)file, &my_pos )==0 ? FM_MISM_OK : FM_MISM_ERROR;
- }
- // Set the position of the stream if the module supports FM_MISM_READFILES feature
- // Return FM_MISM_ERROR otherwise.
-
- int GetStreamPos(fmHandle file, ui64 *pos)
- {
- fpos_t my_pos;
- int ret = fgetpos( (FILE *)file, &my_pos )==0 ? FM_MISM_OK : FM_MISM_ERROR;
- *pos = my_pos;
- return ret;
- }
-
- ui64 InternalGetStreamSize(fmHandle file)
- {
- ui64 currentPos, fileSize;
- // Save current position
- GetStreamPos( file, ¤tPos );
- // Move to the end
- fseek( (FILE *)file, 0, SEEK_END );
- // Get position
- GetStreamPos( file, &fileSize );
- // Restore position
- SetStreamPos( file, currentPos );
-
- return fileSize;
- }
- // FIXME different handles could yield different streamSizes.
- ui64 GetStreamSize( fmHandle strHandle )
- {
- return streamSize;
- }
-
- int CloseStream(fmHandle file)
- {
- return fclose( (FILE *)file )==0 ? FM_MISM_OK : FM_MISM_ERROR;
- }
-
- // Windows already defines GetLastError
- char* GetLastErrorInt(void)
- {
- return lastError;
- }
-
- int GetStreams(fmStreamIds *ids, char* fileName)
- {
- // Open the stream and look for stream Ids.
- if(!FindStreams( ids, fileName ))
- return FM_MISM_ERROR;
- return FM_MISM_OK;
- }
-
- char* GetStreamStatus(fmHandle file)
- {
- return openedFile ? "Normal" : "Idle";
- }
- char *GetFileName(fmHandle file)
- {
- return fileName;
- }
-
- bool initDone = false;
- void Init(LPFMMismStdParms parms)
- {
- memcpy( ¶ms, parms, sizeof FMMismStdParms );
- properties.dwSize = sizeof properties;
- properties.dwMismId = MISM_NULLID;
- initDone = true;
- }
-
- void DeInit(void)
- {
- return;
- }
-
-
- extern "C"
- {
- __declspec(dllexport) void __cdecl fmGetMism(LPFMMismInfo pMismInfo)
- {
- pMismInfo->dwSize = sizeof FMMismInfo;
- pMismInfo->dwVersion = FM_MISM_VERSION;
- pMismInfo->dwOutputTypes = FM_MISM_PROGRAMSTREAM;
- pMismInfo->pProperties = &properties;
- strcpy( pMismInfo->sDescription, "MPEG Program Stream NULL MISM" );
- strcpy( pMismInfo->sExtensions, "*.m2v;*.mpg;*.vob;*.m1v;*.m2v;*.mpe;*.mpeg;*.mv2;*.mpv;" );
- pMismInfo->CanOpenFile = CanOpenFile;
- pMismInfo->OpenStream = OpenStream;
- pMismInfo->ReadStream = ReadStream;
- pMismInfo->SetStreamPos = SetStreamPos;
- pMismInfo->GetStreamPos = GetStreamPos;
- pMismInfo->CloseStream = CloseStream;
- pMismInfo->GetStreams = GetStreams;
- pMismInfo->GetLastError = GetLastErrorInt;
- pMismInfo->GetStreamStatus = GetStreamStatus;
- pMismInfo->GetStreamSize = GetStreamSize;
- pMismInfo->Init = Init;
- pMismInfo->DeInit = DeInit;
- pMismInfo->GetFileName = GetFileName;
- pMismInfo->dwReserved = 0;
- }
- }
-
-