#pragma once

#include <streams.h>
#include <shlwapi.h>
#include "../CSimpleFilter/CSimpleFilter.h"

#define FLAC__NO_DLL
#include "stream_decoder.h"



#pragma comment(lib, "winmm.lib")
#pragma comment(lib, "shlwapi.lib")
#pragma comment(lib, "../lib/strmbase.lib")
#pragma comment(lib, "../lib/CSimpleFilter.lib")
#pragma comment(lib, "ogg_static.lib")
#pragma comment(lib, "libFLAC_static.lib")


static const GUID CLSID_SourceFlac = 
{ 0x11971e60, 0xf06, 0x4c4f, { 0xb8, 0xf8, 0x48, 0x7f, 0x60, 0x4c, 0x16, 0x75 } };

class CSourceFlac : public CSimplePushSource , public IFileSourceFilter
{
public:
   DECLARE_IUNKNOWN

   
   CSourceFlac(LPUNKNOWN, HRESULT *);
   ~CSourceFlac();

   
   static CUnknown * WINAPI CreateInstance(LPUNKNOWN, HRESULT *);

   
   HRESULT OnConnectOutPin(CMediaType *, int *, REFERENCE_TIME *);
   HRESULT FillBuffer(IMediaSample *);

   
   STDMETHODIMP OnQueryInterface(REFIID riid, void ** ppv);
   HRESULT OnSeek(LONGLONG, LONGLONG);

   
   STDMETHODIMP Load(LPCOLESTR, const AM_MEDIA_TYPE *);
   STDMETHODIMP GetCurFile(LPOLESTR *, AM_MEDIA_TYPE *);

private:

   
   static FLAC__StreamDecoderReadStatus read_callback(const FLAC__StreamDecoder *, FLAC__byte [], size_t *, void *);
   static void metadata_callback(const FLAC__StreamDecoder *, const FLAC__StreamMetadata *, void *);
   static FLAC__StreamDecoderWriteStatus write_callback(const FLAC__StreamDecoder *, const FLAC__Frame *, const FLAC__int32 * const [], void *);
   static void error_callback(const FLAC__StreamDecoder *, FLAC__StreamDecoderErrorStatus, void *);

   
   FLAC__StreamDecoder *m_pDecoder;
   int m_nMaxBlockSize;
   LONGLONG m_llDuration;

   BYTE *m_pOutBufferPointer;
   int m_nOutBufferLength;

   WAVEFORMATEX m_outFormat;
   WCHAR m_awInputFileName[MAX_PATH];

   REFERENCE_TIME m_rtStop, m_rtCurrent;

};

