#include <winsock2.h>
/* YUNTAI KYONG
Advanced Internet Service
term project
*/
#include "rtpMPEGLib.h"
#include "elementaryStream.h"
#include "fileStream.h"

#define LARGE_BUFFER_SIZE 300000
#define MAX_PAYLOAD_SIZE 5000
#define INITIAL_TIME_STAMP 1000
#define INITIAL_SEQ_NUM 50

typedef struct
{
	fileStream *fs; 
	elementaryStream *e; 
} argument;

static argument arg;
static unsigned char buffer[LARGE_BUFFER_SIZE];
unsigned char payloadBuffer[MAX_PAYLOAD_SIZE];
HANDLE hThread;

CSocket *pCsocket;
fileStream *fs; 
elementaryStream *e; 

DWORD WINAPI ThreadProc(  LPVOID lpParameter )
{
	fileStream *fs = ((argument*)lpParameter)->fs;
	elementaryStream *e = ((argument*)lpParameter)->e;
	int headerSize = 8;
	int payloadSize;
	
	/* searching starting code */
	int ret;
	int remainSize;
	int seqHeader = 0;
	int newPic = 0;

	do  {
		payloadSize = headerSize;
		
		if( (ret = e->get_sequence_header(buffer,LARGE_BUFFER_SIZE)) == -2 )
		{
			break;
		}
		seqHeader = 1;
		
		printf("sequence_header size: %d\n", ret );
		memcpy( payloadBuffer+payloadSize, buffer, ret );
		payloadSize += ret;
		int wRet = 0;
		int increment =0;
		do  {
			if( (ret = e->get_gop_header(buffer,LARGE_BUFFER_SIZE)) == -2 )
			{
				break;	
			}
			printf("gop_header size: %d\n", ret );
			
			memcpy( payloadBuffer+payloadSize, buffer, ret );
			payloadSize += ret;		
			
			do {
				if( (ret = e->get_picture_header(buffer,LARGE_BUFFER_SIZE)) == -2 )
				{
					printf("last bits: %d\n", fs->get_bits(4));
					//error("fatal: get_picture_header()");
					break;
				}
				newPic = 1;
				printf("picture_header size: %d\n", ret );
				memcpy( payloadBuffer+payloadSize, buffer, ret );
				payloadSize += ret;		
				
				if( (ret = e->get_extension(buffer,LARGE_BUFFER_SIZE)) == -2 )
				{
					//error("fatal: get_extension()");
					break;
				}
				
				printf("extension_header size: %d\n", ret );
				memcpy( payloadBuffer+payloadSize, buffer, ret );
				payloadSize += ret;		
				
				if( (ret = e->get_slices(buffer,LARGE_BUFFER_SIZE)) == -2 )
				{
					printf("end of file");
					//error("fatal: get_extension()");
					break;
				}
				printf("slices size: %d\n", ret );
				
				remainSize = MAX_PAYLOAD_SIZE - payloadSize;
				printf("payloadSize: %d, remainSize: %d\n", payloadSize, remainSize );			
				
				while( ret > remainSize )
				{
					memcpy( payloadBuffer+payloadSize, buffer, remainSize );
					if( e->m_pic_type == I_FRAME || e->m_pic_type == P_FRAME )
					{
						increment = 1;
					}
					else
					{
						increment = 0;
						e->hold ++;
					}
					
					e->getVideoSpecficeHeader( payloadBuffer,0,1,seqHeader,newPic,1 );
					
					e->getMPEG2ExtensionHeader( payloadBuffer+4 );
					e->sendRTPpacket(payloadBuffer, increment, 0, MAX_PAYLOAD_SIZE);
					
					ret -= remainSize;
					payloadSize = 8;
					remainSize = MAX_PAYLOAD_SIZE - payloadSize;
				}
				
				if( ret + payloadSize > 0 )
				{
					memcpy( payloadBuffer+payloadSize, buffer, ret + payloadSize );
					e->getVideoSpecficeHeader( payloadBuffer,1,0,seqHeader,newPic,1 );
					e->getMPEG2ExtensionHeader( payloadBuffer+4 );
					wRet  = e->sendRTPpacket(payloadBuffer, 0, 1,  ret + payloadSize);
					printf("wRet: %d\n", wRet );
				}
				seqHeader = 0;
				newPic = 0;
				printf("end-of-slices...\n");
			} while(fs->next_bits(32, PICTURE_START_CODE )!=-2);
		} while(fs->next_bits(32, GROUP_START_CODE)!=-2);
	} while(fs->next_bits(32, SEQUENCE_HEADER_CODE)!=-2);
	return 1;
}

int play( FILE *f, unsigned long starting_time, SOCKET sock )
{
	DWORD threadID;
	CSocket *socket;
	fileStream *fs; 
	elementaryStream *e; 
	
	pCsocket	= new CSocket(sock);
	fs		= new fileStream(f);
	e		= new elementaryStream(fs, pCsocket,INITIAL_TIME_STAMP, INITIAL_SEQ_NUM);
	
	arg.fs	= fs;
	arg.e	= e;
	
	if( !socket || !fs || !e )
		return -1;
	Sleep( starting_time );	
	hThread = CreateThread(NULL, 0, ThreadProc, (LPVOID)&arg, 0, &threadID);
	
	return 1;
}


int stop()
{
	CloseHandle( hThread );
	if( pCsocket )
		delete pCsocket;
	if( fs )
		delete fs;
	if( e )
		delete e;
	return 1;
}
