34#include "wine/winternl.h"
36#include "wine/unicode.h"
43#define SEQUENCE_HEADER_CODE 0xB3
44#define PACK_START_CODE 0xBA
46#define SYSTEM_START_CODE 0xBB
47#define AUDIO_ELEMENTARY_STREAM 0xC0
48#define VIDEO_ELEMENTARY_STREAM 0xE0
50#define MPEG_SYSTEM_HEADER 3
51#define MPEG_VIDEO_HEADER 2
52#define MPEG_AUDIO_HEADER 1
53#define MPEG_NO_HEADER 0
101 ((
header[1]>>1)&0x3) != 0 && ((
header[2]>>4)&0xf) != 0xf &&
102 ((
header[2]>>2)&0x3) != 0x3)
111static const DWORD freqs[10] = { 44100, 48000, 32000, 22050, 24000, 16000, 11025, 12000, 8000, 0 };
114 { {0,32,64,96,128,160,192,224,256,288,320,352,384,416,448,},
115 {0,32,48,56, 64, 80, 96,112,128,160,192,224,256,320,384,},
116 {0,32,40,48, 56, 64, 80, 96,112,128,160,192,224,256,320,} },
118 { {0,32,48,56,64,80,96,112,128,144,160,176,192,224,256,},
119 {0,8,16,24,32,40,48,56,64,80,96,112,128,144,160,},
120 {0,8,16,24,32,40,48,56,64,80,96,112,128,144,160,} }
134 mpeg1 = (
header[1]>>4)&0x1;
136 lsf = ((
header[1]>>3)&0x1)^1;
139 bitrate_index = ((
header[2]>>4)&0xf);
140 freq_index = ((
header[2]>>2)&0x3) + (mpeg1?(lsf*3):6);
158 ERR(
"Impossible layer %d\n",
layer);
165 *pduration += duration;
177 DWORD len = IMediaSample_GetActualDataLength(pCurrentSample);
180 IMediaSample_GetPointer(pCurrentSample, &fbuf);
185 IMediaSample_SetActualDataLength(pCurrentSample,
length);
200 IAsyncReader_SyncRead(
pin->pReader, ++
pos, 1,
This->header + 3);
211 if (rtSampleStop >
pin->rtStop)
214 hr = IMemAllocator_GetBuffer(
pin->pAlloc, &sample,
NULL,
NULL, 0);
217 IMediaSample_SetTime(sample, &rtSampleStart, &rtSampleStop);
218 IMediaSample_SetPreroll(sample,
FALSE);
219 IMediaSample_SetDiscontinuity(sample,
FALSE);
220 IMediaSample_SetSyncPoint(sample,
TRUE);
221 hr = IAsyncReader_Request(
pin->pReader, sample, 0);
224 pin->rtCurrent = rtSampleStart;
225 pin->rtNext = rtSampleStop;
228 IMediaSample_Release(sample);
238 if (IMediaSample_IsDiscontinuity(pCurrentSample) ==
S_OK) {
246 hr = IPin_NewSegment(victim,
time,
This->Parser.sourceSeeking.llStop,
247 This->Parser.sourceSeeking.dRate);
249 FIXME(
"NewSegment returns %08x\n",
hr);
250 IPin_Release(victim);
258 IMediaSample_SetTime(pCurrentSample, &rtstart, &rtstop);
259 IMediaSample_SetMediaTime(pCurrentSample, &
time, &
This->position);
266 TRACE(
"Error sending sample (%x)\n",
hr);
268 TRACE(
"S_FALSE (%d), holding\n", IMediaSample_GetActualDataLength(pCurrentSample));
279 DWORD cbSrcStream = 0;
283 hr = IMediaSample_GetTime(pSample, &tStart, &tStop);
286 cbSrcStream = IMediaSample_GetActualDataLength(pSample);
287 hr = IMediaSample_GetPointer(pSample, &pbSrcStream);
291 if (cbSrcStream == 0)
293 FIXME(
".. Why do I need you?\n");
304 WARN(
"Failed with hres: %08x!\n",
hr);
310 This->Parser.pInputPin->rtCurrent = tStart;
311 This->position = tAviStart;
319 TRACE(
"End of file reached\n");
321 for (
i = 0;
i <
This->Parser.cStreams;
i++)
325 hr = IPin_ConnectedTo(
This->Parser.ppPins[
i+1], &ppin);
328 hr = IPin_EndOfStream(ppin);
332 WARN(
"Error sending EndOfStream to pin %u (%x)\n",
i,
hr);
345 if (!
IsEqualIID(&pmt->majortype, &MEDIATYPE_Stream))
348 if (
IsEqualIID(&pmt->subtype, &MEDIASUBTYPE_MPEG1Audio))
351 if (
IsEqualIID(&pmt->subtype, &MEDIASUBTYPE_MPEG1Video))
352 FIXME(
"MPEG-1 video streams not yet supported.\n");
353 else if (
IsEqualIID(&pmt->subtype, &MEDIASUBTYPE_MPEG1System))
354 FIXME(
"MPEG-1 system streams not yet supported.\n");
355 else if (
IsEqualIID(&pmt->subtype, &MEDIASUBTYPE_MPEG1VideoCD))
356 FIXME(
"MPEG-1 VideoCD streams not yet supported.\n");
378 ppiOutput->pFilter = &
This->Parser.filter.IBaseFilter_iface;
381 pamt->formattype = FORMAT_WaveFormatEx;
382 pamt->majortype = MEDIATYPE_Audio;
383 pamt->subtype = MEDIASUBTYPE_MPEG1AudioPayload;
385 pamt->lSampleSize = 0;
386 pamt->bFixedSizeSamples =
FALSE;
387 pamt->bTemporalCompression = 0;
389 mpeg1 = (
header[1]>>4)&0x1;
391 lsf = ((
header[1]>>3)&0x1)^1;
394 bitrate_index = ((
header[2]>>4)&0xf);
396 freq_index = ((
header[2]>>2)&0x3) + (mpeg1?(lsf*3):6);
398 mode_ext = ((
header[3]>>4)&0x3);
399 emphasis = ((
header[3]>>0)&0x3);
404 FIXME(
"Variable-bitrate audio not fully supported.\n");
423 format->nBlockAlign =
format->nAvgBytesPerSec * 8 * 144 /
426 format->nBlockAlign =
format->nAvgBytesPerSec * 8 * 144 /
431 format->wBitsPerSample = 0;
469 pamt->subtype.Data1 =
format->wFormatTag;
471 TRACE(
"MPEG audio stream detected:\n"
474 "\tChannels: %d (%d)\n"
475 "\tBytesPerSec: %d\n",
554 TRACE(
"%x:%x:%x:%x is a fake audio header, looking for next...\n",
595 ERR(
"Could not create pin for MPEG audio stream (%x)\n",
hr);
604 This->EndOfFile -= 128;
608 duration = (
This->EndOfFile-
This->begin_offset) * 10000000 /
format->nAvgBytesPerSec;
609 TRACE(
"Duration: %d seconds\n", (
DWORD)(duration / 10000000));
611 This->Parser.sourceSeeking.llCurrent = 0;
612 This->Parser.sourceSeeking.llDuration = duration;
613 This->Parser.sourceSeeking.llStop = duration;
617 FIXME(
"MPEG video processing not yet supported!\n");
621 FIXME(
"MPEG system streams not yet supported!\n");
650 newpos =
This->Parser.sourceSeeking.llCurrent;
651 if (
This->position/1000000 == newpos/1000000)
657 bytepos =
This->begin_offset;
660 while (bytepos + 3 <
This->EndOfFile)
668 bytepos + 4 <
This->EndOfFile)
672 hr = IAsyncReader_SyncRead(pPin->
pReader, ++bytepos + 3, 1,
header + 3);
676 if (
hr !=
S_OK || duration > newpos)
686 TRACE(
"Moving sound to %08u bytes!\n", (
DWORD)bytepos);
689 IPin_BeginFlush(&
pin->pin.IPin_iface);
698 This->position = newpos;
701 TRACE(
"Done flushing\n");
702 IPin_EndFlush(&
pin->pin.IPin_iface);
727 if (
pin->rtCurrent >=
pin->rtStop)
734 hr = IMemAllocator_GetBuffer(
pin->pAlloc, &sample,
NULL,
NULL, 0);
736 pin->rtNext =
pin->rtCurrent;
743 if (rtSampleStop >
pin->rtStop)
746 IMediaSample_SetTime(sample, &rtSampleStart, &rtSampleStop);
747 IMediaSample_SetPreroll(sample,
FALSE);
748 IMediaSample_SetDiscontinuity(sample,
TRUE);
749 IMediaSample_SetSyncPoint(sample, 1);
752 hr = IAsyncReader_Request(
pin->pReader, sample, 0);
755 pin->rtCurrent =
pin->rtNext;
756 pin->rtNext = rtSampleStop;
759 IMediaSample_Release(sample);
762 ERR(
"Horsemen of the apocalypse came to bring error 0x%08x\n",
hr);
780 *
ppv = &
This->IAMStreamSelect_iface;
784 IBaseFilter_AddRef(iface);
817 return IBaseFilter_QueryInterface(&
This->Parser.filter.IBaseFilter_iface,
riid,
ppv);
824 return IBaseFilter_AddRef(&
This->Parser.filter.IBaseFilter_iface);
831 return IBaseFilter_Release(&
This->Parser.filter.IBaseFilter_iface);
838 FIXME(
"(%p/%p)->(%p) stub!\n",
This, iface, streams);
847 FIXME(
"(%p/%p)->(%d,%p,%p,%p,%p,%p,%p,%p) stub!\n",
This, iface,
index, media_type,
flags, lcid,
group,
name,
object,
unknown);
876 TRACE(
"(%p, %p)\n", pUnkOuter,
ppv);
888 hr =
Parser_Create(&(
This->Parser), &
MPEGSplitter_Vtbl, &CLSID_MPEG1Splitter,
MPEGSplitter_process_sample,
MPEGSplitter_query_accept,
MPEGSplitter_pre_connect,
MPEGSplitter_cleanup,
MPEGSplitter_disconnect,
MPEGSplitter_first_request,
NULL,
NULL,
MPEGSplitter_seek,
NULL);
898 *
ppv = &
This->Parser.filter.IBaseFilter_iface;
int memcmp(void *Buffer1, void *Buffer2, ACPI_SIZE Count)
int strncmp(const char *String1, const char *String2, ACPI_SIZE Count)
#define WINE_DEFAULT_DEBUG_CHANNEL(t)
const GUID IID_IBaseFilter
const char * qzdebugstr_guid(const GUID *id)
static const WCHAR wszAudioStream[]
static const DWORD tabsel_123[2][3][16]
static MPEGSplitterImpl * impl_from_IAMStreamSelect(IAMStreamSelect *iface)
static HRESULT MPEGSplitter_process_sample(LPVOID iface, IMediaSample *pSample, DWORD_PTR cookie)
static HRESULT parse_header(BYTE *header, LONGLONG *plen, LONGLONG *pduration)
static HRESULT WINAPI AMStreamSelect_Info(IAMStreamSelect *iface, LONG index, AM_MEDIA_TYPE **media_type, DWORD *flags, LCID *lcid, DWORD *group, WCHAR **name, IUnknown **object, IUnknown **unknown)
static const IBaseFilterVtbl MPEGSplitter_Vtbl
static HRESULT MPEGSplitter_init_audio(MPEGSplitterImpl *This, const BYTE *header, PIN_INFO *ppiOutput, AM_MEDIA_TYPE *pamt)
#define MPEG_VIDEO_HEADER
static HRESULT MPEGSplitter_query_accept(LPVOID iface, const AM_MEDIA_TYPE *pmt)
static const DWORD freqs[10]
static HRESULT WINAPI AMStreamSelect_Count(IAMStreamSelect *iface, DWORD *streams)
static ULONG WINAPI AMStreamSelect_AddRef(IAMStreamSelect *iface)
static MPEGSplitterImpl * impl_from_IBaseFilter(IBaseFilter *iface)
HRESULT MPEGSplitter_create(IUnknown *pUnkOuter, LPVOID *ppv)
static ULONG WINAPI AMStreamSelect_Release(IAMStreamSelect *iface)
static HRESULT MPEGSplitter_pre_connect(IPin *iface, IPin *pConnectPin, ALLOCATOR_PROPERTIES *props)
#define AUDIO_ELEMENTARY_STREAM
static HRESULT WINAPI AMStreamSelect_QueryInterface(IAMStreamSelect *iface, REFIID riid, void **ppv)
static HRESULT WINAPI MPEGSplitter_seek(IMediaSeeking *iface)
#define SEQUENCE_HEADER_CODE
static HRESULT MPEGSplitter_cleanup(LPVOID iface)
static MPEGSplitterImpl * impl_from_IMediaSeeking(IMediaSeeking *iface)
#define MPEG_SYSTEM_HEADER
static const IAMStreamSelectVtbl AMStreamSelectVtbl
static HRESULT MPEGSplitter_first_request(LPVOID iface)
static HRESULT WINAPI MPEGSplitter_QueryInterface(IBaseFilter *iface, REFIID riid, void **ppv)
static HRESULT WINAPI AMStreamSelect_Enable(IAMStreamSelect *iface, LONG index, DWORD flags)
static int MPEGSplitter_head_check(const BYTE *header)
#define MPEG_AUDIO_HEADER
static HRESULT FillBuffer(MPEGSplitterImpl *This, IMediaSample *pCurrentSample)
#define VIDEO_ELEMENTARY_STREAM
static HRESULT MPEGSplitter_disconnect(LPVOID iface)
HRESULT WINAPI Parser_QueryFilterInfo(IBaseFilter *iface, FILTER_INFO *pInfo)
HRESULT WINAPI Parser_GetClassID(IBaseFilter *iface, CLSID *pClsid)
HRESULT WINAPI Parser_Run(IBaseFilter *iface, REFERENCE_TIME tStart)
HRESULT WINAPI Parser_Pause(IBaseFilter *iface)
HRESULT WINAPI Parser_Stop(IBaseFilter *iface)
ULONG WINAPI Parser_AddRef(IBaseFilter *iface)
HRESULT WINAPI Parser_QueryVendorInfo(IBaseFilter *iface, LPWSTR *pVendorInfo)
HRESULT Parser_AddPin(ParserImpl *This, const PIN_INFO *piOutput, ALLOCATOR_PROPERTIES *props, const AM_MEDIA_TYPE *amt)
HRESULT WINAPI Parser_GetState(IBaseFilter *iface, DWORD dwMilliSecsTimeout, FILTER_STATE *pState)
HRESULT Parser_Create(ParserImpl *pParser, const IBaseFilterVtbl *Parser_Vtbl, const CLSID *pClsid, PFN_PROCESS_SAMPLE fnProcessSample, PFN_QUERY_ACCEPT fnQueryAccept, PFN_PRE_CONNECT fnPreConnect, PFN_CLEANUP fnCleanup, PFN_DISCONNECT fnDisconnect, REQUESTPROC fnRequest, STOPPROCESSPROC fnDone, SourceSeeking_ChangeStop stop, SourceSeeking_ChangeStart start, SourceSeeking_ChangeRate rate)
HRESULT WINAPI Parser_GetSyncSource(IBaseFilter *iface, IReferenceClock **ppClock)
ULONG WINAPI Parser_Release(IBaseFilter *iface)
HRESULT WINAPI Parser_EnumPins(IBaseFilter *iface, IEnumPins **ppEnum)
HRESULT WINAPI Parser_SetSyncSource(IBaseFilter *iface, IReferenceClock *pClock)
HRESULT WINAPI Parser_FindPin(IBaseFilter *iface, LPCWSTR Id, IPin **ppPin)
HRESULT WINAPI Parser_JoinFilterGraph(IBaseFilter *iface, IFilterGraph *pGraph, LPCWSTR pName)
static Parser_OutputPin * unsafe_impl_Parser_OutputPin_from_IPin(IPin *iface)
#define ALIGNUP(value, boundary)
static WCHAR unknown[MAX_STRING_RESOURCE_LEN]
GLint GLint GLsizei GLsizei GLsizei GLint GLenum format
GLuint GLsizei GLsizei * length
GLenum GLuint GLint GLint layer
GLsizei GLenum const GLvoid GLsizei GLenum GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLint GLint GLint GLshort GLshort GLshort GLubyte GLubyte GLubyte GLuint GLuint GLuint GLushort GLushort GLushort GLbyte GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLfloat GLint GLint GLint GLint GLshort GLshort GLshort GLshort GLubyte GLubyte GLubyte GLubyte GLuint GLuint GLuint GLuint GLushort GLushort GLushort GLushort GLboolean const GLdouble const GLfloat const GLint const GLshort const GLbyte const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLdouble const GLfloat const GLfloat const GLint const GLint const GLshort const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort GLenum GLenum GLenum GLfloat GLenum GLint GLenum GLenum GLenum GLfloat GLenum GLenum GLint GLenum GLfloat GLenum GLint GLint GLushort GLenum GLenum GLfloat GLenum GLenum GLint GLfloat const GLubyte GLenum GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLint GLint GLsizei GLsizei GLint GLenum GLenum const GLvoid GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLenum const GLdouble GLenum GLenum const GLfloat GLenum GLenum const GLint GLsizei GLuint GLfloat GLuint GLbitfield GLfloat GLint GLuint GLboolean GLenum GLfloat GLenum GLbitfield GLenum GLfloat GLfloat GLint GLint const GLfloat GLenum GLfloat GLfloat GLint GLint GLfloat GLfloat GLint GLint const GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat const GLdouble const GLfloat const GLdouble const GLfloat GLint i
VOID WINAPI CoTaskMemFree(LPVOID ptr)
LPVOID WINAPI CoTaskMemAlloc(SIZE_T size)
#define memcpy(s1, s2, n)
#define memmove(s1, s2, n)
#define ACM_MPEG_DUALCHANNEL
#define MPEGLAYER3_FLAG_PADDING_ON
#define ACM_MPEG_JOINTSTEREO
#define MPEGLAYER3_ID_MPEG
#define MPEGLAYER3_WFX_EXTRA_BYTES
#define WAVE_FORMAT_MPEGLAYER3
#define ACM_MPEG_SINGLECHANNEL
struct mpeg1waveformat_tag MPEG1WAVEFORMAT
#define ACM_MPEG_ID_MPEG1
static const char mbstate_t *static wchar_t const char mbstate_t *static const wchar_t int *static double
static const DWORD padding[]
static PullPin * impl_PullPin_from_IPin(IPin *iface)
#define IsEqualIID(riid1, riid2)
#define MEDIATIME_FROM_BYTES(x)
#define BYTES_FROM_MEDIATIME(time)
HRESULT WINAPI BaseOutputPinImpl_Deliver(BaseOutputPin *This, IMediaSample *pSample)
IAMStreamSelect IAMStreamSelect_iface
#define CONTAINING_RECORD(address, type, field)
#define VFW_E_WRONG_STATE
static const WCHAR props[]
void WINAPI LeaveCriticalSection(LPCRITICAL_SECTION)
void WINAPI EnterCriticalSection(LPCRITICAL_SECTION)
#define CLASS_E_NOAGGREGATION
int WINAPIV wsprintfW(_Out_ LPWSTR, _In_ _Printf_format_string_ LPCWSTR,...)