/* vim:set ft=cpp ts=4 sw=4 sts=4 sta ai bs=2: */
// Decoder.cpp : implementation file
//

#include "stdafx.h"
#include "Decoder.h"
#include "H264SeqHdr.h"

///////////////////////////////////////////
#ifdef _DEBUG
#define new DEBUG_NEW
#undef THIS_FILE
static char THIS_FILE[] = __FILE__;
#endif

/////////////////////////////////////////////////////////////////////////////
// CDecoder

CDecoder::CDecoder()
{
	for(UINT i=0; i<MAX_CHANNEL; i++)
	{
		m_render[i] = new CDDRender;
		m_pbyYUY2[i] = NULL;
	}
	m_bDDrawInit = FALSE;
	m_bMemInit = FALSE;
}

CDecoder::~CDecoder()
{
	for(UINT i=0; i<MAX_CHANNEL; i++)
	{
		delete m_render[i];
	}
}

/////////////////////////////////////////////////////////////////////////////
// CDecoder message handlers
void CDecoder::Deinitialize()
{
	for(UINT i = 0; i < MAX_CHANNEL; i++)
	{
		if(m_pbyYUY2[i])
		{
			free(m_pbyYUY2[i]);
			m_pbyYUY2[i] = NULL;
		}
	}

	// Free Direct Draw interface...
	for(UINT i=0; i<MAX_CHANNEL; i++)
	{
		Sleep(30);
		m_render[i]->DestroyDDraw();  
	}

	m_avCodec.Deinit();
}

void CDecoder::RedrawVideo(UINT nCh)
{
	if(m_render[nCh]->Render(nCh, m_pbyYUY2[nCh]) == 0)
		m_render[nCh]->Render(nCh, m_pbyYUY2[nCh]);
}

BOOL CDecoder::DecodePicture(UINT nch, int ntype, BYTE* pbybuf, DWORD dwLength)
{
	// rendering
	if(dwLength == 0){
		return FALSE;
	}

	if(ntype == I_PICTURE){
		DWORD dwMergeSize = MakeDecodeFrame(pbybuf, dwLength, m_nImageWidth, m_nImageHeight);
		m_avCodec.DecodeFrame(nch, pbybuf, dwMergeSize);
	} else {
		m_avCodec.DecodeFrame(nch, pbybuf, dwLength);
	}


	if(m_render[nch]->Render(nch, m_pbyYUY2[nch]) == 0)
		m_render[nch]->Render(nch, m_pbyYUY2[nch]);

	return TRUE;
}

void CDecoder::setDisplaySize(UINT nCh, int nwidth, int nheight)
{
	m_render[nCh]->SetDisplaySize( nwidth, nheight);
}

BOOL CDecoder::SettingResolution(UINT nch)
{
	m_render[nch]->DestroyDDraw();
	m_bDDrawInit = m_render[nch]->Init(m_pControlImageDraw->m_hWnd, m_nImageWidth, m_nImageHeight);
	m_render[nch]->SettingResolution(m_nImageWidth, m_nImageHeight);

	return m_bDDrawInit;
}

void CDecoder::SetImageSize(UINT nResolution)
{
	switch(nResolution)
	{
	case NTSC_RESOLUTION_720240:
		m_nImageWidth = 704;
		m_nImageHeight = 240;
		break;
	case NTSC_RESOLUTION_360240:
		m_nImageWidth = 352;
		m_nImageHeight = 240;
		break;
	case NTSC_RESOLUTION_720480:
		m_nImageWidth = 704;
		m_nImageHeight = 480;
		break;

	case PAL_RESOLUTION_720240:
		m_nImageWidth = 704;
		m_nImageHeight = 288;
		break;
	case PAL_RESOLUTION_360240:
		m_nImageWidth = 352;
		m_nImageHeight = 288;
		break;
	case PAL_RESOLUTION_720480:
		m_nImageWidth = 704;
		m_nImageHeight = 576;
		break;

	default:
		AfxMessageBox( "Unknown image size. We will assume the maximum size.", MB_ICONINFORMATION | MB_OK);
		m_nImageWidth = 704;
		m_nImageHeight = 576;
		break;
	}
}

void CDecoder::MemInit()
{
	if(m_bMemInit)
	{
		for(UINT i = 0; i < MAX_CHANNEL; i++)
		{
			if(m_pbyYUY2[i])
			{
				free(m_pbyYUY2[i]);
				m_pbyYUY2[i] = NULL;
			}
		}
	}

	m_bMemInit = TRUE;
	for(UINT i = 0; i < MAX_CHANNEL; i++)
	{
		if(m_pbyYUY2[i])
		{
			free(m_pbyYUY2[i]);
			m_pbyYUY2[i] = NULL;
		}
		m_pbyYUY2[i] = (unsigned char *)malloc(m_nImageWidth*m_nImageHeight*3*sizeof(char));
	}

	m_avCodec.Init();
	for(UINT i=0; i<MAX_CHANNEL; i++){
		m_avCodec.SetDecoder(i, m_nImageWidth, m_nImageHeight, m_pbyYUY2[i]);
	}
}

