 /***************************************************************************************
 *This program 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 of the License, or					*
 * (at your option) any later version.													*
 *																						*
 * The GPL can be found at: http://www.gnu.org/copyleft/gpl.html						*
 *																						*
 *																						*	
 ****************************************************************************************
 * Authors:																			  *
 *          Marc Dukette                                                              *
 **************************************************************************************/

#include "stdafx.h"
#include "MP3Reader.h"

BOOL APIENTRY DllMain( HANDLE hModule, 
                       DWORD  ul_reason_for_call, 
                       LPVOID lpReserved
					 )
{
    switch (ul_reason_for_call)
	{
		case DLL_PROCESS_ATTACH:
		case DLL_THREAD_ATTACH:
		case DLL_THREAD_DETACH:
		case DLL_PROCESS_DETACH:
			break;
    }
    return TRUE;
}
videoinfo vidinfo;

typedef int (CALLBACK* pInputMediaRead)(char *data, unsigned int size);
typedef int (CALLBACK* pInputMediaSeek)(int   size, unsigned int method);
typedef int (CALLBACK* pInputMediaOpen)(LPTSTR lpFilename, int mode, int type, int reserve, int maxsize);
typedef void (CALLBACK* pInputMediaClose)();

pInputMediaRead InputMediaRead;
pInputMediaSeek InputMediaSeek;
pInputMediaOpen InputMediaOpen;
pInputMediaClose InputMediaClose;
HMODULE hDLL;
//#include "inputmedia.h"
/*
 * Some useful functions
 */

/*
 * copy n into dst as a 4 byte, 
 * little endian number.
 * should also work on 
 * big endian machines 
 *
 */


/*
 * Reads the first 12 bytes of
 * the file, and returns TRUE
 * if the file is an AVI.
 *
 */

int MP3Reader_IsAVI()
{
	
	return 0;
}

/*
 * Returns the sample size of
 * the first audio stream...
 *
 */

int MP3Reader_SampleSize()
{
	
	return 0;
}


/*
 * Fill the class with info from headers
 * and reconstruct an index if wanted.
 *
 */

int MP3Reader_FillHeader(int getIndex)
{
	InputMediaSeek(0,INPUT_SEEK_SET);
	vidinfo.width=0;
	vidinfo.height=0;
	vidinfo.video_frames=0;
	vidinfo.video_pos = 0;
	strcpy(vidinfo.compressor,"");
	vidinfo.a_fmt=85;
	return 1;
}


/*
 * Reading Functions
 *
 */


 /*
 * Tries to open an AVI
 * with and without an index
 */

MP3READER_API int MP3Reader_Open(LPTSTR lpFilename, int type, int maxsize,videoinfo** vid)
{

	if (wcsstr(lpFilename,_T("://")))
		hDLL=LoadLibrary(_T("InputMediaHTTP.dll"));
	else if (type)
		hDLL=LoadLibrary(_T("InputMediaCache.dll"));
	else
		hDLL=LoadLibrary(_T("InputMedia.dll"));
	InputMediaRead=(pInputMediaRead)GetProcAddress(hDLL,_T("InputMediaRead"));
	InputMediaSeek=(pInputMediaSeek)GetProcAddress(hDLL,_T("InputMediaSeek"));
	InputMediaOpen=(pInputMediaOpen)GetProcAddress(hDLL,_T("InputMediaOpen"));
	InputMediaClose=(pInputMediaClose)GetProcAddress(hDLL,_T("InputMediaClose"));
	vidinfo.audio_bytes=InputMediaOpen(lpFilename, 0, type,1000000, maxsize);
	if (!vidinfo.audio_bytes) 
	{
		FreeLibrary(hDLL);
		hDLL=NULL;
		return 0;
	}
	vidinfo.hIOMutex = CreateMutex (NULL, FALSE, NULL);

	vidinfo.video_pos  = 0;
	vidinfo.audio_posc = 0;
	vidinfo.audio_posb = 0;

	vidinfo.idx         = NULL;
	vidinfo.video_index = NULL;
	vidinfo.audio_index = NULL;
	*vid=&::vidinfo;
	if(MP3Reader_FillHeader(1)) {
	
		return 1;
	}
	return 0;
}


/*
 * Returns the wavefromatex
 * associated with the first audio 
 * stream.
 */
	
/*
 * Reads the next video Frame into
 * buffer, return the actual size of
 * the frame.
 *
 */

MP3READER_API int MP3Reader_NextVideoFrame(char *buffer, int drop)
{
   return 0;
}

/*
 * Reads any amount of audio
 * data. FIXME : should return
 * the actual number read.
 */

MP3READER_API int MP3Reader_ReadAudio(char *audbuf, int bytes)
{
	int nr;


   nr = 0; 

   /*
    * Request the read Mutex 
    */

   WaitForSingleObject(vidinfo.hIOMutex, INFINITE);


   nr=InputMediaRead(audbuf, bytes);


   ReleaseMutex(vidinfo.hIOMutex);

   return nr;
}

/*
 * Return the actual framerate
 * FIXME : should be a double...
 *
 */

double MP3Reader_FrameRate()
{

	return (double) vidinfo.fps;
}


/*
 * Seek to a particular 
 * video frame.
 */

int MP3Reader_VideoSeek(long frame)
{
   return 1;
}

int MP3Reader_AudioSeek(long bytes)
{
	InputMediaSeek(bytes,INPUT_SEEK_SET);
   return 0;
}

BOOL MP3Reader_isKeyframe(long frame)
{
      return 1; 
}

int MP3Reader_NextKeyFrame()
{
	return 0;
}

int	MP3Reader_PreviousKeyFrame()
{
	return 1;
}


MP3READER_API int MP3Reader_Seek(int percent, int isFrame)
{
	__int64 audio_bytes;

	  WaitForSingleObject(vidinfo.hIOMutex, INFINITE);

      audio_bytes  = (__int64) (percent * vidinfo.audio_bytes)/100;
      audio_bytes  += audio_bytes % 4;

      MP3Reader_AudioSeek(audio_bytes);

      ReleaseMutex(vidinfo.hIOMutex);

      return vidinfo.audio_bytes-audio_bytes;

}

MP3READER_API int MP3Reader_ReSeekAudio()
{

    return vidinfo.audio_bytes;
}

MP3READER_API double MP3Reader_GetProgress()
{
	
	return (double) ((double)(InputMediaSeek(0,INPUT_SEEK_CUR)))*100.0/((double)vidinfo.audio_bytes);
}


MP3READER_API int MP3Reader_Close()
{
	if (hDLL)
	{
		InputMediaClose();
		if (vidinfo.video_index) free(vidinfo.video_index);
		if (vidinfo.audio_index) free(vidinfo.audio_index);
		if (vidinfo.idx) free(vidinfo.idx);
		FreeLibrary(hDLL);
		hDLL=NULL;
	}

	return 1;
}

MP3READER_API void InitializeReader(reader* rd)
{
	rd->READER_Open=MP3Reader_Open;
	rd->READER_ReadAudio=MP3Reader_ReadAudio;
	rd->READER_NextVideoFrame=MP3Reader_NextVideoFrame;
	rd->READER_Seek=MP3Reader_Seek;
	rd->READER_ReSeekAudio=MP3Reader_ReSeekAudio;
	rd->READER_GetProgress=MP3Reader_GetProgress;
	rd->READER_Close=MP3Reader_Close;

}

// This is the constructor of a class that has been exported.
// see MP3Reader.h for the class definition
CMP3Reader::CMP3Reader()
{ 
	return; 
}

