
#include "AviWrite.h"
//#include "AviAudioWriteStream.h"

using namespace Creators;

AviAudioWriteStream::AviAudioWriteStream(AviWriteFile* file, int ckid, fourcc_t fourcc,
					 WAVEFORMATEX* fmt, int bitrate, int flags=0)
    :AviWriteStream(file, ckid, AviStream::Audio, fourcc, bitrate, flags),
    m_pIEnc(0), _status(0), _bitrate(bitrate)
//    AviWriteStream(AviWriteFile* file, int ckid,
//	enum AviStream::StreamType type,
//	const char* format, Unsigned format_size,
//	int handler, int frame_rate,
//	int samplesize=0, int quality=0, int flags=0);
{
    if(fmt)srcfmt=*fmt;
}

AviAudioWriteStream::~AviAudioWriteStream()
{
    FreeAudioEncoder(m_pIEnc);
}

HRESULT AviAudioWriteStream::AviAudioWriteStream::Start()
{
    if (_status)
	return 0;

    m_pIEnc = CreateAudioEncoder(AviWriteStream::m_header.fccHandler, &srcfmt);
    m_pIEnc->SetBitrate(_bitrate);
    WAVEFORMATEX* fmt;
    m_forsize = m_pIEnc->GetFormatSize();
    m_format = new uint8_t[m_forsize];
    m_pIEnc->GetFormat(m_format, m_forsize);
    fmt = (WAVEFORMATEX*)m_format;
    AviWriteStream::m_header.dwSampleSize=fmt->nBlockAlign;
    AviWriteStream::m_header.dwRate=_bitrate;
    AviWriteStream::m_header.dwScale=fmt->nBlockAlign;

    m_pIEnc->Start();
    _status=1;
    return 0;
}

HRESULT AviAudioWriteStream::AddData(void* data, size_t size)
{
    if (!_status)
	return -1;

    size_t outsize=2*size/srcfmt.nBlockAlign+7200;
    uint8_t* buf = new uint8_t[outsize];
    size_t written = 0;
    HRESULT hr;
    if (data)
    {
	hr = m_pIEnc->Convert((uint8_t*)data, size/srcfmt.nBlockAlign, buf,
			      outsize, (size_t*)0, &written);
	//	    cerr<<"Converted "<<size<<" bytes to "<<written<<" bytes"<<endl;
	if (hr == 0)
	    hr=AviWriteStream::AddChunk(buf, written, 16);
    }
    else
	hr=AviWriteStream::AddChunk(NULL, 0);

    delete buf;
    return hr;
}

HRESULT AviAudioWriteStream::Stop()
{
    if (!_status)
	return -1;
    uint8_t buf[7200];
    size_t written = 0;
    m_pIEnc->Close(buf, sizeof(buf), &written);
    if (written)
	AviWriteStream::AddChunk(buf, written);
    FreeAudioEncoder(m_pIEnc);
    m_pIEnc = 0;
    _status = 0;
    return 0;
}

//0..10
HRESULT AviAudioWriteStream::SetQuality(int quality)
{
    if (m_pIEnc)
	return m_pIEnc->SetQuality(quality);
    return -1;
}

unsigned int AviAudioWriteStream::GetLength() const
{
    return AviWriteStream::GetLength();
}
