summaryrefslogtreecommitdiff
path: root/src/libw32dll/DirectShow/DS_AudioDecoder.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/libw32dll/DirectShow/DS_AudioDecoder.c')
-rw-r--r--src/libw32dll/DirectShow/DS_AudioDecoder.c172
1 files changed, 172 insertions, 0 deletions
diff --git a/src/libw32dll/DirectShow/DS_AudioDecoder.c b/src/libw32dll/DirectShow/DS_AudioDecoder.c
new file mode 100644
index 000000000..c86da0675
--- /dev/null
+++ b/src/libw32dll/DirectShow/DS_AudioDecoder.c
@@ -0,0 +1,172 @@
+/********************************************************
+
+ DirectShow audio decoder
+ Copyright 2001 Eugene Kuznetsov (divx@euro.ru)
+
+*********************************************************/
+#define NOAVIFILE_HEADERS
+
+#include "DS_AudioDecoder.h"
+#include <string.h>
+#include <stdio.h>
+#include <stdlib.h>
+
+#define __MODULE__ "DirectShow audio decoder"
+const GUID FORMAT_WaveFormatEx = {
+ 0x05589f81, 0xc356, 0x11CE,
+ { 0xBF, 0x01, 0x00, 0xAA, 0x00, 0x55, 0x59, 0x5A }
+};
+const GUID MEDIATYPE_Audio = {
+ 0x73647561, 0x0000, 0x0010,
+ { 0x80, 0x00, 0x00, 0xAA, 0x00, 0x38, 0x9B, 0x71 }
+};
+const GUID MEDIASUBTYPE_PCM = {
+ 0x00000001, 0x0000, 0x0010,
+ { 0x80, 0x00, 0x00, 0xAA, 0x00, 0x38, 0x9B, 0x71 }
+};
+
+typedef long STDCALL (*GETCLASS) (GUID*, GUID*, void**);
+
+DS_AudioDecoder * DS_AudioDecoder_Create(const CodecInfo * info, const WAVEFORMATEX* wf)
+{
+ DS_AudioDecoder *this;
+ int sz;
+ WAVEFORMATEX* pWF;
+
+ this = malloc(sizeof(DS_AudioDecoder));
+
+ sz = 18 + wf->cbSize;
+ this->m_sVhdr = malloc(sz);
+ memcpy(this->m_sVhdr, wf, sz);
+ this->m_sVhdr2 = malloc(sz);
+ memcpy(this->m_sVhdr2, this->m_sVhdr, sz);
+
+ pWF = (WAVEFORMATEX*)this->m_sVhdr2;
+ pWF->wFormatTag = 1;
+ pWF->wBitsPerSample = 16;
+ pWF->nBlockAlign = 2*pWF->nChannels;
+ pWF->cbSize = 0;
+
+ memcpy(&this->in_fmt,wf,sizeof(WAVEFORMATEX));
+
+ memset(&this->m_sOurType, 0, sizeof(this->m_sOurType));
+ this->m_sOurType.majortype=MEDIATYPE_Audio;
+ this->m_sOurType.subtype=MEDIASUBTYPE_PCM;
+ this->m_sOurType.subtype.f1=wf->wFormatTag;
+ this->m_sOurType.formattype=FORMAT_WaveFormatEx;
+ this->m_sOurType.lSampleSize=wf->nBlockAlign;
+ this->m_sOurType.bFixedSizeSamples=1;
+ this->m_sOurType.bTemporalCompression=0;
+ this->m_sOurType.pUnk=0;
+ this->m_sOurType.cbFormat=sz;
+ this->m_sOurType.pbFormat=this->m_sVhdr;
+
+ memset(&this->m_sDestType, 0, sizeof(this->m_sDestType));
+ this->m_sDestType.majortype=MEDIATYPE_Audio;
+ this->m_sDestType.subtype=MEDIASUBTYPE_PCM;
+ this->m_sDestType.formattype=FORMAT_WaveFormatEx;
+ this->m_sDestType.bFixedSizeSamples=1;
+ this->m_sDestType.bTemporalCompression=0;
+ this->m_sDestType.lSampleSize=2*wf->nChannels;
+ this->m_sDestType.pUnk=0;
+ this->m_sDestType.cbFormat=pWF->cbSize;
+ this->m_sDestType.pbFormat=this->m_sVhdr2;
+
+ /*try*/
+ {
+ ALLOCATOR_PROPERTIES props, props1;
+ this->m_pDS_Filter = DS_Filter_Create((const char*)info->dll, &info->guid, &this->m_sOurType, &this->m_sDestType);
+ DS_Filter_Start(this->m_pDS_Filter);
+
+ props.cBuffers=1;
+ props.cbBuffer=this->m_sOurType.lSampleSize;
+ props.cbAlign=props.cbPrefix=0;
+ this->m_pDS_Filter->m_pAll->vt->SetProperties(this->m_pDS_Filter->m_pAll, &props, &props1);
+ this->m_pDS_Filter->m_pAll->vt->Commit(this->m_pDS_Filter->m_pAll);
+ }
+ /*
+ catch (FatalError& e)
+ {
+ e.PrintAll();
+ delete[] m_sVhdr;
+ delete[] m_sVhdr2;
+ delete m_pDS_Filter;
+ throw;
+ }
+ */
+ return this;
+}
+
+void DS_AudioDecoder_Destroy(DS_AudioDecoder *this)
+{
+ free(this->m_sVhdr);
+ free(this->m_sVhdr2);
+ DS_Filter_Destroy(this->m_pDS_Filter);
+ free(this);
+}
+
+int DS_AudioDecoder_Convert(DS_AudioDecoder *this, const void* in_data, uint_t in_size,
+ void* out_data, uint_t out_size,
+ uint_t* size_read, uint_t* size_written)
+{
+ uint_t written = 0;
+ uint_t read = 0;
+
+ if (!in_data || !out_data)
+ return -1;
+
+ in_size -= in_size%this->in_fmt.nBlockAlign;
+ while (in_size>0)
+ {
+ uint_t frame_size = 0;
+ char* frame_pointer;
+ IMediaSample* sample=0;
+ char* ptr;
+ int result;
+
+// this->m_pOurOutput->SetFramePointer(out_data+written);
+ COutputPin_SetFramePointer(this->m_pDS_Filter->m_pOurOutput,&frame_pointer);
+ COutputPin_SetFrameSizePointer(this->m_pDS_Filter->m_pOurOutput,(long*)&frame_size);
+ this->m_pDS_Filter->m_pAll->vt->GetBuffer(this->m_pDS_Filter->m_pAll, &sample, 0, 0, 0);
+ if (!sample)
+ {
+ Debug printf("DS_AudioDecoder::Convert() Error: null sample\n");
+ break;
+ }
+ sample->vt->GetPointer(sample, (BYTE **)&ptr);
+ memcpy(ptr, (const uint8_t*)in_data + read, this->in_fmt.nBlockAlign);
+ sample->vt->SetActualDataLength(sample, this->in_fmt.nBlockAlign);
+ sample->vt->SetSyncPoint(sample, 1);
+ sample->vt->SetPreroll(sample, 0);
+ result = this->m_pDS_Filter->m_pImp->vt->Receive(this->m_pDS_Filter->m_pImp, sample);
+ if (result)
+ Debug printf("DS_AudioDecoder::Convert() Error: putting data into input pin %x\n", result);
+ if ((written + frame_size) > out_size)
+ {
+ sample->vt->Release((IUnknown*)sample);
+ break;
+ }
+ memcpy((uint8_t*)out_data + written, frame_pointer, frame_size);
+ sample->vt->Release((IUnknown*)sample);
+ read+=this->in_fmt.nBlockAlign;
+ written+=frame_size;
+ }
+ if (size_read)
+ *size_read = read;
+ if (size_written)
+ *size_written = written;
+ return 0;
+}
+
+int DS_AudioDecoder_GetSrcSize(DS_AudioDecoder *this, int dest_size)
+{
+ double efficiency;
+ int frames;
+
+ efficiency = (double) this->in_fmt.nAvgBytesPerSec
+ / (this->in_fmt.nSamplesPerSec*this->in_fmt.nBlockAlign);
+ frames = (int)(dest_size*efficiency);
+ if (frames < 1)
+ frames = 1;
+ return frames * this->in_fmt.nBlockAlign;
+}