ReactOS 0.4.16-dev-297-gc569aee
mpegsplit.c File Reference
#include <assert.h>
#include <math.h>
#include "quartz_private.h"
#include "pin.h"
#include "uuids.h"
#include "mmreg.h"
#include "mmsystem.h"
#include "wine/winternl.h"
#include "wine/unicode.h"
#include "wine/debug.h"
#include "parser.h"
Include dependency graph for mpegsplit.c:

Go to the source code of this file.

Classes

struct  MPEGSplitterImpl
 

Macros

#define SEQUENCE_HEADER_CODE   0xB3
 
#define PACK_START_CODE   0xBA
 
#define SYSTEM_START_CODE   0xBB
 
#define AUDIO_ELEMENTARY_STREAM   0xC0
 
#define VIDEO_ELEMENTARY_STREAM   0xE0
 
#define MPEG_SYSTEM_HEADER   3
 
#define MPEG_VIDEO_HEADER   2
 
#define MPEG_AUDIO_HEADER   1
 
#define MPEG_NO_HEADER   0
 

Typedefs

typedef struct MPEGSplitterImpl MPEGSplitterImpl
 

Functions

 WINE_DEFAULT_DEBUG_CHANNEL (quartz)
 
static MPEGSplitterImplimpl_from_IBaseFilter (IBaseFilter *iface)
 
static MPEGSplitterImplimpl_from_IMediaSeeking (IMediaSeeking *iface)
 
static MPEGSplitterImplimpl_from_IAMStreamSelect (IAMStreamSelect *iface)
 
static int MPEGSplitter_head_check (const BYTE *header)
 
static HRESULT parse_header (BYTE *header, LONGLONG *plen, LONGLONG *pduration)
 
static HRESULT FillBuffer (MPEGSplitterImpl *This, IMediaSample *pCurrentSample)
 
static HRESULT MPEGSplitter_process_sample (LPVOID iface, IMediaSample *pSample, DWORD_PTR cookie)
 
static HRESULT MPEGSplitter_query_accept (LPVOID iface, const AM_MEDIA_TYPE *pmt)
 
static HRESULT MPEGSplitter_init_audio (MPEGSplitterImpl *This, const BYTE *header, PIN_INFO *ppiOutput, AM_MEDIA_TYPE *pamt)
 
static HRESULT MPEGSplitter_pre_connect (IPin *iface, IPin *pConnectPin, ALLOCATOR_PROPERTIES *props)
 
static HRESULT MPEGSplitter_cleanup (LPVOID iface)
 
static HRESULT WINAPI MPEGSplitter_seek (IMediaSeeking *iface)
 
static HRESULT MPEGSplitter_disconnect (LPVOID iface)
 
static HRESULT MPEGSplitter_first_request (LPVOID iface)
 
static HRESULT WINAPI MPEGSplitter_QueryInterface (IBaseFilter *iface, REFIID riid, void **ppv)
 
static HRESULT WINAPI AMStreamSelect_QueryInterface (IAMStreamSelect *iface, REFIID riid, void **ppv)
 
static ULONG WINAPI AMStreamSelect_AddRef (IAMStreamSelect *iface)
 
static ULONG WINAPI AMStreamSelect_Release (IAMStreamSelect *iface)
 
static HRESULT WINAPI AMStreamSelect_Count (IAMStreamSelect *iface, DWORD *streams)
 
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 HRESULT WINAPI AMStreamSelect_Enable (IAMStreamSelect *iface, LONG index, DWORD flags)
 
HRESULT MPEGSplitter_create (IUnknown *pUnkOuter, LPVOID *ppv)
 

Variables

static const WCHAR wszAudioStream [] = {'A','u','d','i','o',0}
 
static const DWORD freqs [10] = { 44100, 48000, 32000, 22050, 24000, 16000, 11025, 12000, 8000, 0 }
 
static const DWORD tabsel_123 [2][3][16]
 
static const IBaseFilterVtbl MPEGSplitter_Vtbl
 
static const IAMStreamSelectVtbl AMStreamSelectVtbl
 

Macro Definition Documentation

◆ AUDIO_ELEMENTARY_STREAM

#define AUDIO_ELEMENTARY_STREAM   0xC0

Definition at line 47 of file mpegsplit.c.

◆ MPEG_AUDIO_HEADER

#define MPEG_AUDIO_HEADER   1

Definition at line 52 of file mpegsplit.c.

◆ MPEG_NO_HEADER

#define MPEG_NO_HEADER   0

Definition at line 53 of file mpegsplit.c.

◆ MPEG_SYSTEM_HEADER

#define MPEG_SYSTEM_HEADER   3

Definition at line 50 of file mpegsplit.c.

◆ MPEG_VIDEO_HEADER

#define MPEG_VIDEO_HEADER   2

Definition at line 51 of file mpegsplit.c.

◆ PACK_START_CODE

#define PACK_START_CODE   0xBA

Definition at line 44 of file mpegsplit.c.

◆ SEQUENCE_HEADER_CODE

#define SEQUENCE_HEADER_CODE   0xB3

Definition at line 43 of file mpegsplit.c.

◆ SYSTEM_START_CODE

#define SYSTEM_START_CODE   0xBB

Definition at line 46 of file mpegsplit.c.

◆ VIDEO_ELEMENTARY_STREAM

#define VIDEO_ELEMENTARY_STREAM   0xE0

Definition at line 48 of file mpegsplit.c.

Typedef Documentation

◆ MPEGSplitterImpl

Function Documentation

◆ AMStreamSelect_AddRef()

static ULONG WINAPI AMStreamSelect_AddRef ( IAMStreamSelect iface)
static

Definition at line 820 of file mpegsplit.c.

821{
823
824 return IBaseFilter_AddRef(&This->Parser.filter.IBaseFilter_iface);
825}
static MPEGSplitterImpl * impl_from_IAMStreamSelect(IAMStreamSelect *iface)
Definition: mpegsplit.c:78

◆ AMStreamSelect_Count()

static HRESULT WINAPI AMStreamSelect_Count ( IAMStreamSelect iface,
DWORD streams 
)
static

Definition at line 834 of file mpegsplit.c.

835{
837
838 FIXME("(%p/%p)->(%p) stub!\n", This, iface, streams);
839
840 return E_NOTIMPL;
841}
#define FIXME(fmt,...)
Definition: precomp.h:53
#define E_NOTIMPL
Definition: ddrawi.h:99

◆ AMStreamSelect_Enable()

static HRESULT WINAPI AMStreamSelect_Enable ( IAMStreamSelect iface,
LONG  index,
DWORD  flags 
)
static

Definition at line 852 of file mpegsplit.c.

853{
855
856 FIXME("(%p/%p)->(%d,%x) stub!\n", This, iface, index, flags);
857
858 return E_NOTIMPL;
859}
GLuint index
Definition: glext.h:6031
GLbitfield flags
Definition: glext.h:7161

◆ AMStreamSelect_Info()

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

Definition at line 843 of file mpegsplit.c.

844{
846
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);
848
849 return E_NOTIMPL;
850}
static WCHAR unknown[MAX_STRING_RESOURCE_LEN]
Definition: object.c:1605
GLboolean GLuint group
Definition: glext.h:11120
Definition: name.c:39

◆ AMStreamSelect_QueryInterface()

static HRESULT WINAPI AMStreamSelect_QueryInterface ( IAMStreamSelect iface,
REFIID  riid,
void **  ppv 
)
static

Definition at line 813 of file mpegsplit.c.

814{
816
817 return IBaseFilter_QueryInterface(&This->Parser.filter.IBaseFilter_iface, riid, ppv);
818}
REFIID riid
Definition: atlbase.h:39
REFIID LPVOID * ppv
Definition: atlbase.h:39

◆ AMStreamSelect_Release()

static ULONG WINAPI AMStreamSelect_Release ( IAMStreamSelect iface)
static

Definition at line 827 of file mpegsplit.c.

828{
830
831 return IBaseFilter_Release(&This->Parser.filter.IBaseFilter_iface);
832}

◆ FillBuffer()

static HRESULT FillBuffer ( MPEGSplitterImpl This,
IMediaSample pCurrentSample 
)
static

Definition at line 169 of file mpegsplit.c.

170{
171 Parser_OutputPin * pOutputPin = unsafe_impl_Parser_OutputPin_from_IPin(This->Parser.ppPins[1]);
172 LONGLONG length = 0;
173 LONGLONG pos = BYTES_FROM_MEDIATIME(This->Parser.pInputPin->rtNext);
174 LONGLONG time = This->position, rtstop, rtstart;
175 HRESULT hr;
176 BYTE *fbuf = NULL;
177 DWORD len = IMediaSample_GetActualDataLength(pCurrentSample);
178
179 TRACE("Source length: %u\n", len);
180 IMediaSample_GetPointer(pCurrentSample, &fbuf);
181
182 /* Find the next valid header.. it <SHOULD> be right here */
183 hr = parse_header(fbuf, &length, &This->position);
184 assert(hr == S_OK);
185 IMediaSample_SetActualDataLength(pCurrentSample, length);
186
187 /* Queue the next sample */
188 if (length + 4 == len)
189 {
190 PullPin *pin = This->Parser.pInputPin;
191 LONGLONG stop = BYTES_FROM_MEDIATIME(pin->rtStop);
192
193 hr = S_OK;
194 memcpy(This->header, fbuf + length, 4);
195 while (FAILED(hr = parse_header(This->header, &length, NULL)))
196 {
197 memmove(This->header, This->header+1, 3);
198 if (pos + 4 >= stop)
199 break;
200 IAsyncReader_SyncRead(pin->pReader, ++pos, 1, This->header + 3);
201 }
202 pin->rtNext = MEDIATIME_FROM_BYTES(pos);
203
204 if (SUCCEEDED(hr))
205 {
206 /* Remove 4 for the last header, which should hopefully work */
207 IMediaSample *sample = NULL;
208 LONGLONG rtSampleStart = pin->rtNext - MEDIATIME_FROM_BYTES(4);
209 LONGLONG rtSampleStop = rtSampleStart + MEDIATIME_FROM_BYTES(length + 4);
210
211 if (rtSampleStop > pin->rtStop)
212 rtSampleStop = MEDIATIME_FROM_BYTES(ALIGNUP(BYTES_FROM_MEDIATIME(pin->rtStop), pin->cbAlign));
213
214 hr = IMemAllocator_GetBuffer(pin->pAlloc, &sample, NULL, NULL, 0);
215 if (SUCCEEDED(hr))
216 {
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);
222 if (SUCCEEDED(hr))
223 {
224 pin->rtCurrent = rtSampleStart;
225 pin->rtNext = rtSampleStop;
226 }
227 else
228 IMediaSample_Release(sample);
229 }
230 if (FAILED(hr))
231 FIXME("o_Ox%08x\n", hr);
232 }
233 }
234 /* If not, we're presumably at the end of file */
235
236 TRACE("Media time : %u.%03u\n", (DWORD)(This->position/10000000), (DWORD)((This->position/10000)%1000));
237
238 if (IMediaSample_IsDiscontinuity(pCurrentSample) == S_OK) {
239 IPin *victim;
240 EnterCriticalSection(&This->Parser.filter.csFilter);
241 pOutputPin->pin.pin.tStart = time;
242 pOutputPin->pin.pin.dRate = This->Parser.sourceSeeking.dRate;
243 hr = IPin_ConnectedTo(&pOutputPin->pin.pin.IPin_iface, &victim);
244 if (hr == S_OK)
245 {
246 hr = IPin_NewSegment(victim, time, This->Parser.sourceSeeking.llStop,
247 This->Parser.sourceSeeking.dRate);
248 if (hr != S_OK)
249 FIXME("NewSegment returns %08x\n", hr);
250 IPin_Release(victim);
251 }
252 LeaveCriticalSection(&This->Parser.filter.csFilter);
253 if (hr != S_OK)
254 return hr;
255 }
256 rtstart = (double)(time - pOutputPin->pin.pin.tStart) / pOutputPin->pin.pin.dRate;
257 rtstop = (double)(This->position - pOutputPin->pin.pin.tStart) / pOutputPin->pin.pin.dRate;
258 IMediaSample_SetTime(pCurrentSample, &rtstart, &rtstop);
259 IMediaSample_SetMediaTime(pCurrentSample, &time, &This->position);
260
261 hr = BaseOutputPinImpl_Deliver(&pOutputPin->pin, pCurrentSample);
262
263 if (hr != S_OK)
264 {
265 if (hr != S_FALSE)
266 TRACE("Error sending sample (%x)\n", hr);
267 else
268 TRACE("S_FALSE (%d), holding\n", IMediaSample_GetActualDataLength(pCurrentSample));
269 }
270
271 return hr;
272}
#define NULL
Definition: types.h:112
#define TRUE
Definition: types.h:120
#define FALSE
Definition: types.h:117
static HRESULT parse_header(BYTE *header, LONGLONG *plen, LONGLONG *pduration)
Definition: mpegsplit.c:123
static Parser_OutputPin * unsafe_impl_Parser_OutputPin_from_IPin(IPin *iface)
Definition: parser.h:81
#define ALIGNUP(value, boundary)
Definition: pin.c:33
#define assert(x)
Definition: debug.h:53
unsigned long DWORD
Definition: ntddk_ex.h:95
GLuint GLsizei GLsizei * length
Definition: glext.h:6040
GLenum GLsizei len
Definition: glext.h:6722
Definition: axcore.idl:92
#define S_OK
Definition: intsafe.h:52
#define SUCCEEDED(hr)
Definition: intsafe.h:50
#define FAILED(hr)
Definition: intsafe.h:51
__u16 time
Definition: mkdosfs.c:8
#define memcpy(s1, s2, n)
Definition: mkisofs.h:878
#define memmove(s1, s2, n)
Definition: mkisofs.h:881
static const char mbstate_t *static wchar_t const char mbstate_t *static const wchar_t int *static double
Definition: string.c:80
#define MEDIATIME_FROM_BYTES(x)
#define BYTES_FROM_MEDIATIME(time)
HRESULT hr
Definition: shlfolder.c:183
#define TRACE(s)
Definition: solgame.cpp:4
HRESULT WINAPI BaseOutputPinImpl_Deliver(BaseOutputPin *This, IMediaSample *pSample)
Definition: pin.c:574
BasePin pin
Definition: strmbase.h:66
double dRate
Definition: strmbase.h:43
IPin IPin_iface
Definition: strmbase.h:35
REFERENCE_TIME tStart
Definition: strmbase.h:41
BaseOutputPin pin
Definition: parser.h:46
Definition: pin.h:71
Definition: regsvr.c:104
int64_t LONGLONG
Definition: typedefs.h:68
void WINAPI LeaveCriticalSection(LPCRITICAL_SECTION)
void WINAPI EnterCriticalSection(LPCRITICAL_SECTION)
#define S_FALSE
Definition: winerror.h:2357
unsigned char BYTE
Definition: xxhash.c:193

Referenced by MPEGSplitter_process_sample().

◆ impl_from_IAMStreamSelect()

static MPEGSplitterImpl * impl_from_IAMStreamSelect ( IAMStreamSelect iface)
inlinestatic

Definition at line 78 of file mpegsplit.c.

79{
80 return CONTAINING_RECORD(iface, MPEGSplitterImpl, IAMStreamSelect_iface);
81}
#define CONTAINING_RECORD(address, type, field)
Definition: typedefs.h:260

Referenced by AMStreamSelect_AddRef(), AMStreamSelect_Count(), AMStreamSelect_Enable(), AMStreamSelect_Info(), AMStreamSelect_QueryInterface(), and AMStreamSelect_Release().

◆ impl_from_IBaseFilter()

static MPEGSplitterImpl * impl_from_IBaseFilter ( IBaseFilter iface)
inlinestatic

Definition at line 68 of file mpegsplit.c.

69{
70 return CONTAINING_RECORD(iface, MPEGSplitterImpl, Parser.filter.IBaseFilter_iface);
71}

Referenced by MPEGSplitter_QueryInterface().

◆ impl_from_IMediaSeeking()

static MPEGSplitterImpl * impl_from_IMediaSeeking ( IMediaSeeking iface)
inlinestatic

Definition at line 73 of file mpegsplit.c.

74{
75 return CONTAINING_RECORD(iface, MPEGSplitterImpl, Parser.sourceSeeking.IMediaSeeking_iface);
76}

Referenced by MPEGSplitter_seek().

◆ MPEGSplitter_cleanup()

static HRESULT MPEGSplitter_cleanup ( LPVOID  iface)
static

Definition at line 633 of file mpegsplit.c.

634{
635 MPEGSplitterImpl *This = iface;
636
637 TRACE("(%p)\n", This);
638
639 return S_OK;
640}

Referenced by MPEGSplitter_create().

◆ MPEGSplitter_create()

HRESULT MPEGSplitter_create ( IUnknown pUnkOuter,
LPVOID ppv 
)

Definition at line 871 of file mpegsplit.c.

872{
874 HRESULT hr = E_FAIL;
875
876 TRACE("(%p, %p)\n", pUnkOuter, ppv);
877
878 *ppv = NULL;
879
880 if (pUnkOuter)
882
884 if (!This)
885 return E_OUTOFMEMORY;
886
889 if (FAILED(hr))
890 {
892 return hr;
893 }
894 This->IAMStreamSelect_iface.lpVtbl = &AMStreamSelectVtbl;
895 This->seek = TRUE;
896
897 /* Note: This memory is managed by the parser filter once created */
898 *ppv = &This->Parser.filter.IBaseFilter_iface;
899
900 return hr;
901}
#define E_OUTOFMEMORY
Definition: ddrawi.h:100
#define E_FAIL
Definition: ddrawi.h:102
static HRESULT MPEGSplitter_process_sample(LPVOID iface, IMediaSample *pSample, DWORD_PTR cookie)
Definition: mpegsplit.c:275
static const IBaseFilterVtbl MPEGSplitter_Vtbl
Definition: mpegsplit.c:794
static HRESULT MPEGSplitter_query_accept(LPVOID iface, const AM_MEDIA_TYPE *pmt)
Definition: mpegsplit.c:343
static HRESULT MPEGSplitter_pre_connect(IPin *iface, IPin *pConnectPin, ALLOCATOR_PROPERTIES *props)
Definition: mpegsplit.c:485
static HRESULT WINAPI MPEGSplitter_seek(IMediaSeeking *iface)
Definition: mpegsplit.c:642
static HRESULT MPEGSplitter_cleanup(LPVOID iface)
Definition: mpegsplit.c:633
static const IAMStreamSelectVtbl AMStreamSelectVtbl
Definition: mpegsplit.c:861
static HRESULT MPEGSplitter_first_request(LPVOID iface)
Definition: mpegsplit.c:714
static HRESULT MPEGSplitter_disconnect(LPVOID iface)
Definition: mpegsplit.c:708
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)
Definition: parser.c:96
VOID WINAPI CoTaskMemFree(LPVOID ptr)
Definition: ifs.c:442
LPVOID WINAPI CoTaskMemAlloc(SIZE_T size)
Definition: ifs.c:426
#define ZeroMemory
Definition: winbase.h:1737
#define CLASS_E_NOAGGREGATION
Definition: winerror.h:2662

◆ MPEGSplitter_disconnect()

static HRESULT MPEGSplitter_disconnect ( LPVOID  iface)
static

Definition at line 708 of file mpegsplit.c.

709{
710 /* TODO: Find memory leaks etc */
711 return S_OK;
712}

Referenced by MPEGSplitter_create().

◆ MPEGSplitter_first_request()

static HRESULT MPEGSplitter_first_request ( LPVOID  iface)
static

Definition at line 714 of file mpegsplit.c.

715{
716 MPEGSplitterImpl *This = iface;
717 PullPin *pin = This->Parser.pInputPin;
718 HRESULT hr;
720 IMediaSample *sample;
721
722 TRACE("Seeking? %d\n", This->seek);
723
724 hr = parse_header(This->header, &length, NULL);
725 assert(hr == S_OK);
726
727 if (pin->rtCurrent >= pin->rtStop)
728 {
729 /* Last sample has already been queued, request nothing more */
730 FIXME("Done!\n");
731 return S_OK;
732 }
733
734 hr = IMemAllocator_GetBuffer(pin->pAlloc, &sample, NULL, NULL, 0);
735
736 pin->rtNext = pin->rtCurrent;
737 if (SUCCEEDED(hr))
738 {
739 LONGLONG rtSampleStart = pin->rtNext;
740 /* Add 4 for the next header, which should hopefully work */
741 LONGLONG rtSampleStop = rtSampleStart + MEDIATIME_FROM_BYTES(length + 4);
742
743 if (rtSampleStop > pin->rtStop)
744 rtSampleStop = MEDIATIME_FROM_BYTES(ALIGNUP(BYTES_FROM_MEDIATIME(pin->rtStop), pin->cbAlign));
745
746 IMediaSample_SetTime(sample, &rtSampleStart, &rtSampleStop);
747 IMediaSample_SetPreroll(sample, FALSE);
748 IMediaSample_SetDiscontinuity(sample, TRUE);
749 IMediaSample_SetSyncPoint(sample, 1);
750 This->seek = FALSE;
751
752 hr = IAsyncReader_Request(pin->pReader, sample, 0);
753 if (SUCCEEDED(hr))
754 {
755 pin->rtCurrent = pin->rtNext;
756 pin->rtNext = rtSampleStop;
757 }
758 else
759 IMediaSample_Release(sample);
760 }
761 if (FAILED(hr))
762 ERR("Horsemen of the apocalypse came to bring error 0x%08x\n", hr);
763
764 return hr;
765}
#define ERR(fmt,...)
Definition: precomp.h:57

Referenced by MPEGSplitter_create().

◆ MPEGSplitter_head_check()

static int MPEGSplitter_head_check ( const BYTE header)
static

Definition at line 83 of file mpegsplit.c.

84{
85 /* If this is a possible start code, check for a system or video header */
86 if (header[0] == 0 && header[1] == 0 && header[2] == 1)
87 {
88 /* Check if we got a system or elementary stream start code */
89 if (header[3] == PACK_START_CODE ||
92 return MPEG_SYSTEM_HEADER;
93
94 /* Check for a MPEG video sequence start code */
96 return MPEG_VIDEO_HEADER;
97 }
98
99 /* This should give a good guess if we have an MPEG audio header */
100 if(header[0] == 0xff && ((header[1]>>5)&0x7) == 0x7 &&
101 ((header[1]>>1)&0x3) != 0 && ((header[2]>>4)&0xf) != 0xf &&
102 ((header[2]>>2)&0x3) != 0x3)
103 return MPEG_AUDIO_HEADER;
104
105 /* Nothing yet.. */
106 return MPEG_NO_HEADER;
107}
#define MPEG_VIDEO_HEADER
Definition: mpegsplit.c:51
#define MPEG_NO_HEADER
Definition: mpegsplit.c:53
#define AUDIO_ELEMENTARY_STREAM
Definition: mpegsplit.c:47
#define SEQUENCE_HEADER_CODE
Definition: mpegsplit.c:43
#define MPEG_SYSTEM_HEADER
Definition: mpegsplit.c:50
#define MPEG_AUDIO_HEADER
Definition: mpegsplit.c:52
#define VIDEO_ELEMENTARY_STREAM
Definition: mpegsplit.c:48
#define PACK_START_CODE
Definition: mpegsplit.c:44

Referenced by MPEGSplitter_pre_connect(), and parse_header().

◆ MPEGSplitter_init_audio()

static HRESULT MPEGSplitter_init_audio ( MPEGSplitterImpl This,
const BYTE header,
PIN_INFO ppiOutput,
AM_MEDIA_TYPE pamt 
)
static

Definition at line 363 of file mpegsplit.c.

364{
366 int bitrate_index;
367 int freq_index;
368 int mode_ext;
369 int emphasis;
370 int padding;
371 int lsf = 1;
372 int mpeg1;
373 int layer;
374 int mode;
375
376 ZeroMemory(pamt, sizeof(*pamt));
377 ppiOutput->dir = PINDIR_OUTPUT;
378 ppiOutput->pFilter = &This->Parser.filter.IBaseFilter_iface;
379 wsprintfW(ppiOutput->achName, wszAudioStream);
380
381 pamt->formattype = FORMAT_WaveFormatEx;
382 pamt->majortype = MEDIATYPE_Audio;
383 pamt->subtype = MEDIASUBTYPE_MPEG1AudioPayload;
384
385 pamt->lSampleSize = 0;
386 pamt->bFixedSizeSamples = FALSE;
387 pamt->bTemporalCompression = 0;
388
389 mpeg1 = (header[1]>>4)&0x1;
390 if (mpeg1)
391 lsf = ((header[1]>>3)&0x1)^1;
392
393 layer = 4-((header[1]>>1)&0x3);
394 bitrate_index = ((header[2]>>4)&0xf);
395 padding = ((header[2]>>1)&0x1);
396 freq_index = ((header[2]>>2)&0x3) + (mpeg1?(lsf*3):6);
397 mode = ((header[3]>>6)&0x3);
398 mode_ext = ((header[3]>>4)&0x3);
399 emphasis = ((header[3]>>0)&0x3);
400
401 if (!bitrate_index)
402 {
403 /* Set to highest bitrate so samples will fit in for sure */
404 FIXME("Variable-bitrate audio not fully supported.\n");
405 bitrate_index = 15;
406 }
407
408 pamt->cbFormat = ((layer==3)? sizeof(MPEGLAYER3WAVEFORMAT) :
409 sizeof(MPEG1WAVEFORMAT));
410 pamt->pbFormat = CoTaskMemAlloc(pamt->cbFormat);
411 if (!pamt->pbFormat)
412 return E_OUTOFMEMORY;
413 ZeroMemory(pamt->pbFormat, pamt->cbFormat);
414 format = (WAVEFORMATEX*)pamt->pbFormat;
415
416 format->wFormatTag = ((layer == 3) ? WAVE_FORMAT_MPEGLAYER3 :
418 format->nChannels = ((mode == 3) ? 1 : 2);
419 format->nSamplesPerSec = freqs[freq_index];
420 format->nAvgBytesPerSec = tabsel_123[lsf][layer-1][bitrate_index] * 1000 / 8;
421
422 if (layer == 3)
423 format->nBlockAlign = format->nAvgBytesPerSec * 8 * 144 /
424 (format->nSamplesPerSec<<lsf) + padding;
425 else if (layer == 2)
426 format->nBlockAlign = format->nAvgBytesPerSec * 8 * 144 /
427 format->nSamplesPerSec + padding;
428 else
429 format->nBlockAlign = 4 * (format->nAvgBytesPerSec * 8 * 12 / format->nSamplesPerSec + padding);
430
431 format->wBitsPerSample = 0;
432
433 if (layer == 3)
434 {
436
438
439 mp3format->wID = MPEGLAYER3_ID_MPEG;
441 mp3format->nBlockSize = format->nBlockAlign;
442 mp3format->nFramesPerBlock = 1;
443
444 /* Beware the evil magic numbers. This struct is apparently horribly
445 * under-documented, and the only references I could find had it being
446 * set to this with no real explanation. It works fine though, so I'm
447 * not complaining (yet).
448 */
449 mp3format->nCodecDelay = 1393;
450 }
451 else
452 {
454
455 format->cbSize = 22;
456
457 mpgformat->fwHeadLayer = ((layer == 1) ? ACM_MPEG_LAYER1 :
458 ((layer == 2) ? ACM_MPEG_LAYER2 :
460 mpgformat->dwHeadBitrate = format->nAvgBytesPerSec * 8;
461 mpgformat->fwHeadMode = ((mode == 3) ? ACM_MPEG_SINGLECHANNEL :
462 ((mode == 2) ? ACM_MPEG_DUALCHANNEL :
463 ((mode == 1) ? ACM_MPEG_JOINTSTEREO :
465 mpgformat->fwHeadModeExt = ((mode == 1) ? 0x0F : (1<<mode_ext));
466 mpgformat->wHeadEmphasis = emphasis + 1;
467 mpgformat->fwHeadFlags = ACM_MPEG_ID_MPEG1;
468 }
469 pamt->subtype.Data1 = format->wFormatTag;
470
471 TRACE("MPEG audio stream detected:\n"
472 "\tLayer %d (%#x)\n"
473 "\tFrequency: %d\n"
474 "\tChannels: %d (%d)\n"
475 "\tBytesPerSec: %d\n",
476 layer, format->wFormatTag, format->nSamplesPerSec,
477 format->nChannels, mode, format->nAvgBytesPerSec);
478
479 dump_AM_MEDIA_TYPE(pamt);
480
481 return S_OK;
482}
@ PINDIR_OUTPUT
Definition: axcore.idl:42
static const WCHAR wszAudioStream[]
Definition: mpegsplit.c:109
static const DWORD tabsel_123[2][3][16]
Definition: mpegsplit.c:113
static const DWORD freqs[10]
Definition: mpegsplit.c:111
GLenum mode
Definition: glext.h:6217
GLenum GLuint GLint GLint layer
Definition: glext.h:7007
#define ACM_MPEG_DUALCHANNEL
Definition: mmreg.h:422
#define ACM_MPEG_STEREO
Definition: mmreg.h:420
#define MPEGLAYER3_FLAG_PADDING_ON
Definition: mmreg.h:446
#define ACM_MPEG_JOINTSTEREO
Definition: mmreg.h:421
#define MPEGLAYER3_ID_MPEG
Definition: mmreg.h:442
#define WAVE_FORMAT_MPEG
Definition: mmreg.h:126
#define MPEGLAYER3_WFX_EXTRA_BYTES
Definition: mmreg.h:439
#define WAVE_FORMAT_MPEGLAYER3
Definition: mmreg.h:127
#define ACM_MPEG_SINGLECHANNEL
Definition: mmreg.h:423
#define ACM_MPEG_LAYER3
Definition: mmreg.h:418
#define ACM_MPEG_LAYER1
Definition: mmreg.h:416
#define ACM_MPEG_LAYER2
Definition: mmreg.h:417
struct mpeg1waveformat_tag MPEG1WAVEFORMAT
#define ACM_MPEG_ID_MPEG1
Definition: mmreg.h:428
static const DWORD padding[]
Definition: mciwnd.c:89
void dump_AM_MEDIA_TYPE(const AM_MEDIA_TYPE *pmt)
Definition: enummedia.c:38
Definition: format.c:58
DWORD dwHeadBitrate
Definition: mmreg.h:407
WORD fwHeadModeExt
Definition: mmreg.h:409
WORD wHeadEmphasis
Definition: mmreg.h:410
int WINAPIV wsprintfW(_Out_ LPWSTR, _In_ _Printf_format_string_ LPCWSTR,...)

Referenced by MPEGSplitter_pre_connect().

◆ MPEGSplitter_pre_connect()

static HRESULT MPEGSplitter_pre_connect ( IPin iface,
IPin pConnectPin,
ALLOCATOR_PROPERTIES props 
)
static

Definition at line 485 of file mpegsplit.c.

486{
487 PullPin *pPin = impl_PullPin_from_IPin(iface);
489 HRESULT hr;
490 LONGLONG pos = 0; /* in bytes */
491 BYTE header[10];
492 int streamtype;
494 AM_MEDIA_TYPE amt;
495 PIN_INFO piOutput;
496
497 IAsyncReader_Length(pPin->pReader, &total, &avail);
498 This->EndOfFile = total;
499
500 hr = IAsyncReader_SyncRead(pPin->pReader, pos, 4, header);
501 if (SUCCEEDED(hr))
502 pos += 4;
503
504 /* Skip ID3 v2 tag, if any */
505 if (SUCCEEDED(hr) && !memcmp("ID3", header, 3))
506 do {
507 UINT length = 0;
508 hr = IAsyncReader_SyncRead(pPin->pReader, pos, 6, header + 4);
509 if (FAILED(hr))
510 break;
511 pos += 6;
512 TRACE("Found ID3 v2.%d.%d\n", header[3], header[4]);
513 if(header[3] <= 4 && header[4] != 0xff &&
514 (header[5]&0x0f) == 0 && (header[6]&0x80) == 0 &&
515 (header[7]&0x80) == 0 && (header[8]&0x80) == 0 &&
516 (header[9]&0x80) == 0)
517 {
518 length = (header[6]<<21) | (header[7]<<14) |
519 (header[8]<< 7) | (header[9] );
520 if((header[5]&0x10))
521 length += 10;
522 TRACE("Length: %u\n", length);
523 }
524 pos += length;
525
526 /* Read the real header for the mpeg splitter */
527 hr = IAsyncReader_SyncRead(pPin->pReader, pos, 4, header);
528 if (SUCCEEDED(hr))
529 pos += 4;
530 } while (0);
531
532 while(SUCCEEDED(hr))
533 {
534 TRACE("Testing header %x:%x:%x:%x\n", header[0], header[1], header[2], header[3]);
535
536 streamtype = MPEGSplitter_head_check(header);
537 if (streamtype == MPEG_AUDIO_HEADER)
538 {
541 {
542 BYTE next_header[4];
543 /* Ensure we have a valid header by seeking for the next frame, some bad
544 * encoded ID3v2 may have an incorrect length and we end up finding bytes
545 * like FF FE 00 28 which are nothing more than a Unicode BOM followed by
546 * ')' character from inside a ID3v2 tag. Unfortunately that sequence
547 * matches like a valid mpeg audio header.
548 */
549 hr = IAsyncReader_SyncRead(pPin->pReader, pos + length - 4, 4, next_header);
550 if (FAILED(hr))
551 break;
552 if (parse_header(next_header, &length, NULL) == S_OK)
553 break;
554 TRACE("%x:%x:%x:%x is a fake audio header, looking for next...\n",
555 header[0], header[1], header[2], header[3]);
556 }
557 }
558 else if (streamtype) /* Video or System stream */
559 break;
560
561 /* No valid header yet; shift by a byte and check again */
562 memmove(header, header+1, 3);
563 hr = IAsyncReader_SyncRead(pPin->pReader, pos++, 1, header + 3);
564 }
565 if (FAILED(hr))
566 return hr;
567 pos -= 4;
568 This->begin_offset = pos;
569 memcpy(This->header, header, 4);
570
571 switch(streamtype)
572 {
574 {
575 LONGLONG duration = 0;
577
578 hr = MPEGSplitter_init_audio(This, header, &piOutput, &amt);
579 if (SUCCEEDED(hr))
580 {
581 format = (WAVEFORMATEX*)amt.pbFormat;
582
583 props->cbAlign = 1;
584 props->cbPrefix = 0;
585 /* Make the output buffer a multiple of the frame size */
586 props->cbBuffer = 0x4000 / format->nBlockAlign *
587 format->nBlockAlign;
588 props->cBuffers = 3;
589 hr = Parser_AddPin(&(This->Parser), &piOutput, props, &amt);
590 }
591
592 if (FAILED(hr))
593 {
594 CoTaskMemFree(amt.pbFormat);
595 ERR("Could not create pin for MPEG audio stream (%x)\n", hr);
596 break;
597 }
598
599 /* Check for idv1 tag, and remove it from stream if found */
600 hr = IAsyncReader_SyncRead(pPin->pReader, This->EndOfFile-128, 3, header);
601 if (FAILED(hr))
602 break;
603 if (!strncmp((char*)header, "TAG", 3))
604 This->EndOfFile -= 128;
605 This->Parser.pInputPin->rtStop = MEDIATIME_FROM_BYTES(This->EndOfFile);
606 This->Parser.pInputPin->rtStart = This->Parser.pInputPin->rtCurrent = MEDIATIME_FROM_BYTES(This->begin_offset);
607
608 duration = (This->EndOfFile-This->begin_offset) * 10000000 / format->nAvgBytesPerSec;
609 TRACE("Duration: %d seconds\n", (DWORD)(duration / 10000000));
610
611 This->Parser.sourceSeeking.llCurrent = 0;
612 This->Parser.sourceSeeking.llDuration = duration;
613 This->Parser.sourceSeeking.llStop = duration;
614 break;
615 }
617 FIXME("MPEG video processing not yet supported!\n");
618 hr = E_FAIL;
619 break;
621 FIXME("MPEG system streams not yet supported!\n");
622 hr = E_FAIL;
623 break;
624
625 default:
626 break;
627 }
628 This->position = 0;
629
630 return hr;
631}
int memcmp(void *Buffer1, void *Buffer2, ACPI_SIZE Count)
Definition: utclib.c:112
int strncmp(const char *String1, const char *String2, ACPI_SIZE Count)
Definition: utclib.c:534
static int avail
Definition: adh-main.c:39
static HRESULT MPEGSplitter_init_audio(MPEGSplitterImpl *This, const BYTE *header, PIN_INFO *ppiOutput, AM_MEDIA_TYPE *pamt)
Definition: mpegsplit.c:363
static int MPEGSplitter_head_check(const BYTE *header)
Definition: mpegsplit.c:83
HRESULT Parser_AddPin(ParserImpl *This, const PIN_INFO *piOutput, ALLOCATOR_PROPERTIES *props, const AM_MEDIA_TYPE *amt)
Definition: parser.c:446
size_t total
unsigned int UINT
Definition: ndis.h:50
static PullPin * impl_PullPin_from_IPin(IPin *iface)
Definition: pin.h:132
PIN_INFO pinInfo
Definition: strmbase.h:38
BasePin pin
Definition: pin.h:73
IAsyncReader * pReader
Definition: pin.h:77
static const WCHAR props[]
Definition: wbemdisp.c:288

Referenced by MPEGSplitter_create().

◆ MPEGSplitter_process_sample()

static HRESULT MPEGSplitter_process_sample ( LPVOID  iface,
IMediaSample pSample,
DWORD_PTR  cookie 
)
static

Definition at line 275 of file mpegsplit.c.

276{
277 MPEGSplitterImpl *This = iface;
278 BYTE *pbSrcStream;
279 DWORD cbSrcStream = 0;
280 REFERENCE_TIME tStart, tStop, tAviStart = This->position;
281 HRESULT hr;
282
283 hr = IMediaSample_GetTime(pSample, &tStart, &tStop);
284 if (SUCCEEDED(hr))
285 {
286 cbSrcStream = IMediaSample_GetActualDataLength(pSample);
287 hr = IMediaSample_GetPointer(pSample, &pbSrcStream);
288 }
289
290 /* Flush occurring */
291 if (cbSrcStream == 0)
292 {
293 FIXME(".. Why do I need you?\n");
294 return S_OK;
295 }
296
297 /* trace removed for performance reasons */
298 /* TRACE("(%p), %llu -> %llu\n", pSample, tStart, tStop); */
299
300 /* Now, try to find a new header */
301 hr = FillBuffer(This, pSample);
302 if (hr != S_OK)
303 {
304 WARN("Failed with hres: %08x!\n", hr);
305
306 /* Unset progression if denied! */
307 if (hr == VFW_E_WRONG_STATE || hr == S_FALSE)
308 {
309 memcpy(This->header, pbSrcStream, 4);
310 This->Parser.pInputPin->rtCurrent = tStart;
311 This->position = tAviStart;
312 }
313 }
314
315 if (BYTES_FROM_MEDIATIME(tStop) >= This->EndOfFile || This->position >= This->Parser.sourceSeeking.llStop)
316 {
317 unsigned int i;
318
319 TRACE("End of file reached\n");
320
321 for (i = 0; i < This->Parser.cStreams; i++)
322 {
323 IPin* ppin;
324
325 hr = IPin_ConnectedTo(This->Parser.ppPins[i+1], &ppin);
326 if (SUCCEEDED(hr))
327 {
328 hr = IPin_EndOfStream(ppin);
329 IPin_Release(ppin);
330 }
331 if (FAILED(hr))
332 WARN("Error sending EndOfStream to pin %u (%x)\n", i, hr);
333 }
334
335 /* Force the pullpin thread to stop */
336 hr = S_FALSE;
337 }
338
339 return hr;
340}
#define WARN(fmt,...)
Definition: precomp.h:61
static HRESULT FillBuffer(MPEGSplitterImpl *This, IMediaSample *pCurrentSample)
Definition: mpegsplit.c:169
LONGLONG REFERENCE_TIME
Definition: dmusicks.h:9
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
Definition: glfuncs.h:248
#define VFW_E_WRONG_STATE
Definition: vfwmsgs.h:78

Referenced by MPEGSplitter_create().

◆ MPEGSplitter_query_accept()

static HRESULT MPEGSplitter_query_accept ( LPVOID  iface,
const AM_MEDIA_TYPE pmt 
)
static

Definition at line 343 of file mpegsplit.c.

344{
345 if (!IsEqualIID(&pmt->majortype, &MEDIATYPE_Stream))
346 return S_FALSE;
347
348 if (IsEqualIID(&pmt->subtype, &MEDIASUBTYPE_MPEG1Audio))
349 return S_OK;
350
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");
357 else FIXME("%s\n", debugstr_guid(&pmt->subtype));
358
359 return S_FALSE;
360}
#define debugstr_guid
Definition: kernel32.h:35
#define IsEqualIID(riid1, riid2)
Definition: guiddef.h:95

Referenced by MPEGSplitter_create().

◆ MPEGSplitter_QueryInterface()

static HRESULT WINAPI MPEGSplitter_QueryInterface ( IBaseFilter iface,
REFIID  riid,
void **  ppv 
)
static

Definition at line 767 of file mpegsplit.c.

768{
770 TRACE("(%s, %p)\n", qzdebugstr_guid(riid), ppv);
771
772 *ppv = NULL;
773
776 || IsEqualIID(riid, &IID_IMediaFilter)
778 *ppv = iface;
779 else if ( IsEqualIID(riid, &IID_IAMStreamSelect) )
780 *ppv = &This->IAMStreamSelect_iface;
781
782 if (*ppv)
783 {
784 IBaseFilter_AddRef(iface);
785 return S_OK;
786 }
787
788 if (!IsEqualIID(riid, &IID_IPin) && !IsEqualIID(riid, &IID_IVideoWindow))
789 FIXME("No interface for %s!\n", qzdebugstr_guid(riid));
790
791 return E_NOINTERFACE;
792}
const GUID IID_IUnknown
const GUID IID_IBaseFilter
const char * qzdebugstr_guid(const GUID *id)
Definition: main.c:279
static MPEGSplitterImpl * impl_from_IBaseFilter(IBaseFilter *iface)
Definition: mpegsplit.c:68
const GUID IID_IPin
Definition: pincontrol.cpp:15
const GUID IID_IPersist
Definition: proxy.cpp:14
#define E_NOINTERFACE
Definition: winerror.h:2364

◆ MPEGSplitter_seek()

static HRESULT WINAPI MPEGSplitter_seek ( IMediaSeeking iface)
static

Definition at line 642 of file mpegsplit.c.

643{
645 PullPin *pPin = This->Parser.pInputPin;
646 LONGLONG newpos, timepos, bytepos;
648 BYTE header[4];
649
650 newpos = This->Parser.sourceSeeking.llCurrent;
651 if (This->position/1000000 == newpos/1000000)
652 {
653 TRACE("Requesting position %x%08x same as current position %x%08x\n", (DWORD)(newpos>>32), (DWORD)newpos, (DWORD)(This->position>>32), (DWORD)This->position);
654 return S_OK;
655 }
656
657 bytepos = This->begin_offset;
658 timepos = 0;
659 /* http://mpgedit.org/mpgedit/mpeg_format/mpeghdr.htm has a whole read up on audio headers */
660 while (bytepos + 3 < This->EndOfFile)
661 {
662 LONGLONG duration = timepos;
663 LONGLONG length = 0;
664 hr = IAsyncReader_SyncRead(pPin->pReader, bytepos, 4, header);
665 if (hr != S_OK)
666 break;
667 while ((hr=parse_header(header, &length, &duration)) != S_OK &&
668 bytepos + 4 < This->EndOfFile)
669 {
670 /* No valid header yet; shift by a byte and check again */
671 memmove(header, header+1, 3);
672 hr = IAsyncReader_SyncRead(pPin->pReader, ++bytepos + 3, 1, header + 3);
673 if (hr != S_OK)
674 break;
675 }
676 if (hr != S_OK || duration > newpos)
677 break;
678 bytepos += length;
679 timepos = duration;
680 }
681
682 if (SUCCEEDED(hr))
683 {
684 PullPin *pin = This->Parser.pInputPin;
685
686 TRACE("Moving sound to %08u bytes!\n", (DWORD)bytepos);
687
688 EnterCriticalSection(&pin->thread_lock);
689 IPin_BeginFlush(&pin->pin.IPin_iface);
690
691 /* Make sure this is done while stopped, BeginFlush takes care of this */
692 EnterCriticalSection(&This->Parser.filter.csFilter);
693 memcpy(This->header, header, 4);
694
695 pin->rtStart = pin->rtCurrent = MEDIATIME_FROM_BYTES(bytepos);
696 pin->rtStop = MEDIATIME_FROM_BYTES((REFERENCE_TIME)This->EndOfFile);
697 This->seek = TRUE;
698 This->position = newpos;
699 LeaveCriticalSection(&This->Parser.filter.csFilter);
700
701 TRACE("Done flushing\n");
702 IPin_EndFlush(&pin->pin.IPin_iface);
703 LeaveCriticalSection(&pin->thread_lock);
704 }
705 return hr;
706}
#define E_INVALIDARG
Definition: ddrawi.h:101
static MPEGSplitterImpl * impl_from_IMediaSeeking(IMediaSeeking *iface)
Definition: mpegsplit.c:73

Referenced by MPEGSplitter_create().

◆ parse_header()

static HRESULT parse_header ( BYTE header,
LONGLONG plen,
LONGLONG pduration 
)
static

Definition at line 123 of file mpegsplit.c.

124{
125 int bitrate_index, freq_index, lsf = 1, mpeg1, layer, padding, bitrate, length;
126 LONGLONG duration;
127
129 {
130 FIXME("Not a valid header: %02x:%02x:%02x:%02x\n", header[0], header[1], header[2], header[3]);
131 return E_INVALIDARG;
132 }
133
134 mpeg1 = (header[1]>>4)&0x1;
135 if (mpeg1)
136 lsf = ((header[1]>>3)&0x1)^1;
137
138 layer = 4-((header[1]>>1)&0x3);
139 bitrate_index = ((header[2]>>4)&0xf);
140 freq_index = ((header[2]>>2)&0x3) + (mpeg1?(lsf*3):6);
141 padding = ((header[2]>>1)&0x1);
142
143 bitrate = tabsel_123[lsf][layer-1][bitrate_index] * 1000;
144 if (!bitrate)
145 {
146 FIXME("Not a valid header: %02x:%02x:%02x:%02x\n", header[0], header[1], header[2], header[3]);
147 return E_INVALIDARG;
148 }
149
150 if (layer == 1)
151 length = 4 * (12 * bitrate / freqs[freq_index] + padding);
152 else if (layer == 2)
153 length = 144 * bitrate / freqs[freq_index] + padding;
154 else if (layer == 3)
155 length = 144 * bitrate / (freqs[freq_index]<<lsf) + padding;
156 else
157 {
158 ERR("Impossible layer %d\n", layer);
159 return E_INVALIDARG;
160 }
161
162 duration = (ULONGLONG)10000000 * (ULONGLONG)(length) / (ULONGLONG)(bitrate/8);
163 *plen = length;
164 if (pduration)
165 *pduration += duration;
166 return S_OK;
167}
uint64_t ULONGLONG
Definition: typedefs.h:67

Referenced by FillBuffer(), MPEGSplitter_first_request(), MPEGSplitter_pre_connect(), and MPEGSplitter_seek().

◆ WINE_DEFAULT_DEBUG_CHANNEL()

WINE_DEFAULT_DEBUG_CHANNEL ( quartz  )

Variable Documentation

◆ AMStreamSelectVtbl

const IAMStreamSelectVtbl AMStreamSelectVtbl
static
Initial value:
=
{
}
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)
Definition: mpegsplit.c:843
static HRESULT WINAPI AMStreamSelect_Count(IAMStreamSelect *iface, DWORD *streams)
Definition: mpegsplit.c:834
static ULONG WINAPI AMStreamSelect_AddRef(IAMStreamSelect *iface)
Definition: mpegsplit.c:820
static ULONG WINAPI AMStreamSelect_Release(IAMStreamSelect *iface)
Definition: mpegsplit.c:827
static HRESULT WINAPI AMStreamSelect_QueryInterface(IAMStreamSelect *iface, REFIID riid, void **ppv)
Definition: mpegsplit.c:813
static HRESULT WINAPI AMStreamSelect_Enable(IAMStreamSelect *iface, LONG index, DWORD flags)
Definition: mpegsplit.c:852

Definition at line 861 of file mpegsplit.c.

Referenced by MPEGSplitter_create().

◆ freqs

const DWORD freqs[10] = { 44100, 48000, 32000, 22050, 24000, 16000, 11025, 12000, 8000, 0 }
static

Definition at line 111 of file mpegsplit.c.

Referenced by lzx_write_compressed_tree(), MPEGSplitter_init_audio(), and parse_header().

◆ MPEGSplitter_Vtbl

const IBaseFilterVtbl MPEGSplitter_Vtbl
static
Initial value:
=
{
}
static HRESULT WINAPI MPEGSplitter_QueryInterface(IBaseFilter *iface, REFIID riid, void **ppv)
Definition: mpegsplit.c:767
HRESULT WINAPI Parser_QueryFilterInfo(IBaseFilter *iface, FILTER_INFO *pInfo)
Definition: parser.c:419
HRESULT WINAPI Parser_GetClassID(IBaseFilter *iface, CLSID *pClsid)
Definition: parser.c:228
HRESULT WINAPI Parser_Run(IBaseFilter *iface, REFERENCE_TIME tStart)
Definition: parser.c:313
HRESULT WINAPI Parser_Pause(IBaseFilter *iface)
Definition: parser.c:279
HRESULT WINAPI Parser_Stop(IBaseFilter *iface)
Definition: parser.c:241
ULONG WINAPI Parser_AddRef(IBaseFilter *iface)
Definition: parser.c:171
HRESULT WINAPI Parser_QueryVendorInfo(IBaseFilter *iface, LPWSTR *pVendorInfo)
Definition: parser.c:429
HRESULT WINAPI Parser_GetState(IBaseFilter *iface, DWORD dwMilliSecsTimeout, FILTER_STATE *pState)
Definition: parser.c:361
HRESULT WINAPI Parser_GetSyncSource(IBaseFilter *iface, IReferenceClock **ppClock)
Definition: parser.c:397
ULONG WINAPI Parser_Release(IBaseFilter *iface)
Definition: parser.c:213
HRESULT WINAPI Parser_EnumPins(IBaseFilter *iface, IEnumPins **ppEnum)
Definition: parser.c:404
HRESULT WINAPI Parser_SetSyncSource(IBaseFilter *iface, IReferenceClock *pClock)
Definition: parser.c:383
HRESULT WINAPI Parser_FindPin(IBaseFilter *iface, LPCWSTR Id, IPin **ppPin)
Definition: parser.c:409
HRESULT WINAPI Parser_JoinFilterGraph(IBaseFilter *iface, IFilterGraph *pGraph, LPCWSTR pName)
Definition: parser.c:424

Definition at line 794 of file mpegsplit.c.

Referenced by MPEGSplitter_create().

◆ tabsel_123

const DWORD tabsel_123[2][3][16]
static
Initial value:
= {
{ {0,32,64,96,128,160,192,224,256,288,320,352,384,416,448,},
{0,32,48,56, 64, 80, 96,112,128,160,192,224,256,320,384,},
{0,32,40,48, 56, 64, 80, 96,112,128,160,192,224,256,320,} },
{ {0,32,48,56,64,80,96,112,128,144,160,176,192,224,256,},
{0,8,16,24,32,40,48,56,64,80,96,112,128,144,160,},
{0,8,16,24,32,40,48,56,64,80,96,112,128,144,160,} }
}

Definition at line 113 of file mpegsplit.c.

Referenced by MPEGSplitter_init_audio(), and parse_header().

◆ wszAudioStream

const WCHAR wszAudioStream[] = {'A','u','d','i','o',0}
static

Definition at line 109 of file mpegsplit.c.

Referenced by MPEGSplitter_init_audio().