ReactOS  0.4.14-dev-317-g96040ec
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 }
static MPEGSplitterImpl * impl_from_IAMStreamSelect(IAMStreamSelect *iface)
Definition: mpegsplit.c:78
#define FIXME(fmt,...)
Definition: debug.h:110
#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 }
static MPEGSplitterImpl * impl_from_IAMStreamSelect(IAMStreamSelect *iface)
Definition: mpegsplit.c:78
#define FIXME(fmt,...)
Definition: debug.h:110
GLuint index
Definition: glext.h:6031
GLbitfield flags
Definition: glext.h:7161
#define E_NOTIMPL
Definition: ddrawi.h:99

◆ 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 MPEGSplitterImpl * impl_from_IAMStreamSelect(IAMStreamSelect *iface)
Definition: mpegsplit.c:78
#define FIXME(fmt,...)
Definition: debug.h:110
GLuint index
Definition: glext.h:6031
GLboolean GLuint group
Definition: glext.h:11120
Definition: id3.c:18
GLbitfield flags
Definition: glext.h:7161
#define E_NOTIMPL
Definition: ddrawi.h:99
Definition: name.c:36

◆ 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 }
static MPEGSplitterImpl * impl_from_IAMStreamSelect(IAMStreamSelect *iface)
Definition: mpegsplit.c:78
REFIID riid
Definition: precomp.h:44
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 }
static MPEGSplitterImpl * impl_from_IAMStreamSelect(IAMStreamSelect *iface)
Definition: mpegsplit.c:78

◆ 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 memmove(s1, s2, n)
Definition: mkisofs.h:881
#define TRUE
Definition: types.h:120
HRESULT hr
Definition: shlfolder.c:183
BaseOutputPin pin
Definition: parser.h:46
IPin IPin_iface
Definition: strmbase.h:35
#define assert(x)
Definition: debug.h:53
__u16 time
Definition: mkdosfs.c:366
void WINAPI EnterCriticalSection(LPCRITICAL_SECTION)
Definition: regsvr.c:103
Definition: pin.h:70
#define FIXME(fmt,...)
Definition: debug.h:110
#define S_FALSE
Definition: winerror.h:2357
static const char mbstate_t *static wchar_t const char mbstate_t *static const wchar_t int *static double
Definition: string.c:80
smooth NULL
Definition: ftsmooth.c:416
#define ALIGNUP(value, boundary)
Definition: pin.c:33
int64_t LONGLONG
Definition: typedefs.h:66
#define TRACE(s)
Definition: solgame.cpp:4
LONG HRESULT
Definition: typedefs.h:77
GLenum GLuint GLenum GLsizei length
Definition: glext.h:5579
BasePin pin
Definition: strmbase.h:66
REFERENCE_TIME tStart
Definition: strmbase.h:41
unsigned long DWORD
Definition: ntddk_ex.h:95
#define BYTES_FROM_MEDIATIME(time)
double dRate
Definition: strmbase.h:43
#define memcpy(s1, s2, n)
Definition: mkisofs.h:878
GLenum GLsizei len
Definition: glext.h:6722
unsigned char BYTE
Definition: mem.h:68
#define S_OK
Definition: intsafe.h:59
static Parser_OutputPin * unsafe_impl_Parser_OutputPin_from_IPin(IPin *iface)
Definition: parser.h:81
Definition: axcore.idl:91
HRESULT WINAPI BaseOutputPinImpl_Deliver(BaseOutputPin *This, IMediaSample *pSample)
Definition: pin.c:574
static HRESULT parse_header(BYTE *header, LONGLONG *plen, LONGLONG *pduration)
Definition: mpegsplit.c:123
#define MEDIATIME_FROM_BYTES(x)
void WINAPI LeaveCriticalSection(LPCRITICAL_SECTION)
#define SUCCEEDED(hr)
Definition: intsafe.h:57

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 }
PFLT_MESSAGE_WAITER_QUEUE CONTAINING_RECORD(Csq, DEVICE_EXTENSION, IrpQueue)) -> WaiterQ.mLock) _IRQL_raises_(DISPATCH_LEVEL) VOID NTAPI FltpAcquireMessageWaiterLock(_In_ PIO_CSQ Csq, _Out_ PKIRQL Irql)
Definition: Messaging.c:560

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 }
PFLT_MESSAGE_WAITER_QUEUE CONTAINING_RECORD(Csq, DEVICE_EXTENSION, IrpQueue)) -> WaiterQ.mLock) _IRQL_raises_(DISPATCH_LEVEL) VOID NTAPI FltpAcquireMessageWaiterLock(_In_ PIO_CSQ Csq, _Out_ PKIRQL Irql)
Definition: Messaging.c:560

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 }
PFLT_MESSAGE_WAITER_QUEUE CONTAINING_RECORD(Csq, DEVICE_EXTENSION, IrpQueue)) -> WaiterQ.mLock) _IRQL_raises_(DISPATCH_LEVEL) VOID NTAPI FltpAcquireMessageWaiterLock(_In_ PIO_CSQ Csq, _Out_ PKIRQL Irql)
Definition: Messaging.c:560

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 }
#define TRACE(s)
Definition: solgame.cpp:4
#define S_OK
Definition: intsafe.h:59

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)
881  return CLASS_E_NOAGGREGATION;
882 
884  if (!This)
885  return E_OUTOFMEMORY;
886 
887  ZeroMemory(This, sizeof(MPEGSplitterImpl));
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 TRUE
Definition: types.h:120
VOID WINAPI CoTaskMemFree(LPVOID ptr)
Definition: ifs.c:420
HRESULT hr
Definition: shlfolder.c:183
REFIID LPVOID * ppv
Definition: atlbase.h:39
#define ZeroMemory
Definition: winbase.h:1642
#define E_FAIL
Definition: ddrawi.h:102
static const IBaseFilterVtbl MPEGSplitter_Vtbl
Definition: mpegsplit.c:794
static HRESULT MPEGSplitter_disconnect(LPVOID iface)
Definition: mpegsplit.c:708
#define E_OUTOFMEMORY
Definition: ddrawi.h:100
smooth NULL
Definition: ftsmooth.c:416
static const IAMStreamSelectVtbl AMStreamSelectVtbl
Definition: mpegsplit.c:861
#define TRACE(s)
Definition: solgame.cpp:4
static HRESULT MPEGSplitter_cleanup(LPVOID iface)
Definition: mpegsplit.c:633
LONG HRESULT
Definition: typedefs.h:77
#define CLASS_E_NOAGGREGATION
Definition: winerror.h:2662
static HRESULT WINAPI MPEGSplitter_seek(IMediaSeeking *iface)
Definition: mpegsplit.c:642
static HRESULT MPEGSplitter_first_request(LPVOID iface)
Definition: mpegsplit.c:714
static HRESULT MPEGSplitter_query_accept(LPVOID iface, const AM_MEDIA_TYPE *pmt)
Definition: mpegsplit.c:343
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
static HRESULT MPEGSplitter_process_sample(LPVOID iface, IMediaSample *pSample, DWORD_PTR cookie)
Definition: mpegsplit.c:275
LPVOID WINAPI CoTaskMemAlloc(SIZE_T size)
Definition: ifs.c:404
static HRESULT MPEGSplitter_pre_connect(IPin *iface, IPin *pConnectPin, ALLOCATOR_PROPERTIES *props)
Definition: mpegsplit.c:485

◆ 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 }
#define S_OK
Definition: intsafe.h:59

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 TRUE
Definition: types.h:120
HRESULT hr
Definition: shlfolder.c:183
#define assert(x)
Definition: debug.h:53
Definition: regsvr.c:103
Definition: pin.h:70
#define FIXME(fmt,...)
Definition: debug.h:110
smooth NULL
Definition: ftsmooth.c:416
#define ALIGNUP(value, boundary)
Definition: pin.c:33
int64_t LONGLONG
Definition: typedefs.h:66
#define TRACE(s)
Definition: solgame.cpp:4
LONG HRESULT
Definition: typedefs.h:77
GLenum GLuint GLenum GLsizei length
Definition: glext.h:5579
#define BYTES_FROM_MEDIATIME(time)
#define ERR(fmt,...)
Definition: debug.h:109
#define S_OK
Definition: intsafe.h:59
static HRESULT parse_header(BYTE *header, LONGLONG *plen, LONGLONG *pduration)
Definition: mpegsplit.c:123
#define MEDIATIME_FROM_BYTES(x)
#define SUCCEEDED(hr)
Definition: intsafe.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 */
95  if (header[3] == SEQUENCE_HEADER_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_NO_HEADER
Definition: mpegsplit.c:53
#define SEQUENCE_HEADER_CODE
Definition: mpegsplit.c:43
#define MPEG_SYSTEM_HEADER
Definition: mpegsplit.c:50
#define MPEG_VIDEO_HEADER
Definition: mpegsplit.c:51
#define VIDEO_ELEMENTARY_STREAM
Definition: mpegsplit.c:48
#define MPEG_AUDIO_HEADER
Definition: mpegsplit.c:52
#define AUDIO_ELEMENTARY_STREAM
Definition: mpegsplit.c:47
#define PACK_START_CODE
Definition: mpegsplit.c:44
struct CFHEADER header
Definition: fdi.c:101

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  {
453  MPEG1WAVEFORMAT *mpgformat = (MPEG1WAVEFORMAT*)format;
454 
455  format->cbSize = 22;
456 
457  mpgformat->fwHeadLayer = ((layer == 1) ? ACM_MPEG_LAYER1 :
458  ((layer == 2) ? ACM_MPEG_LAYER2 :
459  ACM_MPEG_LAYER3));
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 :
464  ACM_MPEG_STEREO)));
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 }
int WINAPIV wsprintfW(_Out_ LPWSTR, _In_ _Printf_format_string_ LPCWSTR,...)
void dump_AM_MEDIA_TYPE(const AM_MEDIA_TYPE *pmt)
Definition: enummedia.c:27
#define ACM_MPEG_SINGLECHANNEL
Definition: mmreg.h:423
#define MPEGLAYER3_WFX_EXTRA_BYTES
Definition: mmreg.h:439
#define ACM_MPEG_LAYER1
Definition: mmreg.h:416
_In_ CLIPOBJ _In_ BRUSHOBJ _In_ LONG x1
Definition: winddi.h:3706
#define MPEGLAYER3_FLAG_PADDING_ON
Definition: mmreg.h:446
#define ZeroMemory
Definition: winbase.h:1642
#define ACM_MPEG_LAYER2
Definition: mmreg.h:417
GLint GLint GLsizei GLsizei GLsizei GLint GLenum format
Definition: gl.h:1546
#define WAVE_FORMAT_MPEG
Definition: mmreg.h:126
static const DWORD tabsel_123[2][3][16]
Definition: mpegsplit.c:113
#define ACM_MPEG_JOINTSTEREO
Definition: mmreg.h:421
#define E_OUTOFMEMORY
Definition: ddrawi.h:100
#define FIXME(fmt,...)
Definition: debug.h:110
struct mpeg1waveformat_tag MPEG1WAVEFORMAT
#define ACM_MPEG_ID_MPEG1
Definition: mmreg.h:428
#define MPEGLAYER3_ID_MPEG
Definition: mmreg.h:442
GLenum GLuint GLint GLint layer
Definition: glext.h:7007
#define TRACE(s)
Definition: solgame.cpp:4
static const WCHAR wszAudioStream[]
Definition: mpegsplit.c:109
unsigned int padding
Definition: isohybrid.c:50
WORD fwHeadModeExt
Definition: mmreg.h:409
static const DWORD freqs[10]
Definition: mpegsplit.c:111
WORD wHeadEmphasis
Definition: mmreg.h:410
#define WAVE_FORMAT_MPEGLAYER3
Definition: mmreg.h:127
GLenum mode
Definition: glext.h:6217
#define ACM_MPEG_LAYER3
Definition: mmreg.h:418
#define ACM_MPEG_STEREO
Definition: mmreg.h:420
#define S_OK
Definition: intsafe.h:59
#define ACM_MPEG_DUALCHANNEL
Definition: mmreg.h:422
DWORD dwHeadBitrate
Definition: mmreg.h:407
LPVOID WINAPI CoTaskMemAlloc(SIZE_T size)
Definition: ifs.c:404
struct CFHEADER header
Definition: fdi.c:101

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);
488  MPEGSplitterImpl *This = (MPEGSplitterImpl*)pPin->pin.pinInfo.pFilter;
489  HRESULT hr;
490  LONGLONG pos = 0; /* in bytes */
491  BYTE header[10];
492  int streamtype;
493  LONGLONG total, avail;
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  {
540  if (parse_header(header, &length, NULL) == S_OK)
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  {
573  case MPEG_AUDIO_HEADER:
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  }
616  case MPEG_VIDEO_HEADER:
617  FIXME("MPEG video processing not yet supported!\n");
618  hr = E_FAIL;
619  break;
620  case MPEG_SYSTEM_HEADER:
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 }
#define memmove(s1, s2, n)
Definition: mkisofs.h:881
IAsyncReader * pReader
Definition: pin.h:77
int memcmp(void *Buffer1, void *Buffer2, ACPI_SIZE Count)
Definition: utclib.c:112
VOID WINAPI CoTaskMemFree(LPVOID ptr)
Definition: ifs.c:420
HRESULT hr
Definition: shlfolder.c:183
#define E_FAIL
Definition: ddrawi.h:102
static PullPin * impl_PullPin_from_IPin(IPin *iface)
Definition: pin.h:132
static int avail
Definition: adh-main.c:39
GLint GLint GLsizei GLsizei GLsizei GLint GLenum format
Definition: gl.h:1546
static HRESULT MPEGSplitter_init_audio(MPEGSplitterImpl *This, const BYTE *header, PIN_INFO *ppiOutput, AM_MEDIA_TYPE *pamt)
Definition: mpegsplit.c:363
Definition: pin.h:70
#define FIXME(fmt,...)
Definition: debug.h:110
smooth NULL
Definition: ftsmooth.c:416
int64_t LONGLONG
Definition: typedefs.h:66
#define TRACE(s)
Definition: solgame.cpp:4
LONG HRESULT
Definition: typedefs.h:77
GLenum GLuint GLenum GLsizei length
Definition: glext.h:5579
#define MPEG_SYSTEM_HEADER
Definition: mpegsplit.c:50
int strncmp(const char *String1, const char *String2, ACPI_SIZE Count)
Definition: utclib.c:534
unsigned long DWORD
Definition: ntddk_ex.h:95
BasePin pin
Definition: pin.h:73
HRESULT Parser_AddPin(ParserImpl *This, const PIN_INFO *piOutput, ALLOCATOR_PROPERTIES *props, const AM_MEDIA_TYPE *amt)
Definition: parser.c:446
#define memcpy(s1, s2, n)
Definition: mkisofs.h:878
unsigned char BYTE
Definition: mem.h:68
#define MPEG_VIDEO_HEADER
Definition: mpegsplit.c:51
#define ERR(fmt,...)
Definition: debug.h:109
#define S_OK
Definition: intsafe.h:59
unsigned int UINT
Definition: ndis.h:50
#define MPEG_AUDIO_HEADER
Definition: mpegsplit.c:52
PIN_INFO pinInfo
Definition: strmbase.h:38
static HRESULT parse_header(BYTE *header, LONGLONG *plen, LONGLONG *pduration)
Definition: mpegsplit.c:123
static const WCHAR props[]
Definition: wbemdisp.c:288
static int MPEGSplitter_head_check(const BYTE *header)
Definition: mpegsplit.c:83
#define MEDIATIME_FROM_BYTES(x)
struct CFHEADER header
Definition: fdi.c:101
#define SUCCEEDED(hr)
Definition: intsafe.h:57

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 }
HRESULT hr
Definition: shlfolder.c:183
#define WARN(fmt,...)
Definition: debug.h:111
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 FIXME(fmt,...)
Definition: debug.h:110
#define S_FALSE
Definition: winerror.h:2357
#define TRACE(s)
Definition: solgame.cpp:4
LONGLONG REFERENCE_TIME
Definition: dmusicks.h:9
LONG HRESULT
Definition: typedefs.h:77
unsigned long DWORD
Definition: ntddk_ex.h:95
#define BYTES_FROM_MEDIATIME(time)
#define memcpy(s1, s2, n)
Definition: mkisofs.h:878
unsigned char BYTE
Definition: mem.h:68
#define S_OK
Definition: intsafe.h:59
static HRESULT FillBuffer(MPEGSplitterImpl *This, IMediaSample *pCurrentSample)
Definition: mpegsplit.c:169
Definition: axcore.idl:91
#define VFW_E_WRONG_STATE
Definition: vfwmsgs.h:78
#define SUCCEEDED(hr)
Definition: intsafe.h:57

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 FIXME(fmt,...)
Definition: debug.h:110
#define S_FALSE
Definition: winerror.h:2357
#define debugstr_guid
Definition: kernel32.h:35
#define S_OK
Definition: intsafe.h:59
#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_IBaseFilter
static MPEGSplitterImpl * impl_from_IBaseFilter(IBaseFilter *iface)
Definition: mpegsplit.c:68
#define E_NOINTERFACE
Definition: winerror.h:2364
REFIID riid
Definition: precomp.h:44
const char * qzdebugstr_guid(const GUID *id)
Definition: main.c:279
const GUID IID_IPersist
Definition: proxy.cpp:14
REFIID LPVOID * ppv
Definition: atlbase.h:39
#define FIXME(fmt,...)
Definition: debug.h:110
smooth NULL
Definition: ftsmooth.c:416
#define TRACE(s)
Definition: solgame.cpp:4
const GUID IID_IUnknown
#define S_OK
Definition: intsafe.h:59
const GUID IID_IPin
Definition: pincontrol.cpp:15
#define IsEqualIID(riid1, riid2)
Definition: guiddef.h:95

◆ 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 memmove(s1, s2, n)
Definition: mkisofs.h:881
IAsyncReader * pReader
Definition: pin.h:77
#define TRUE
Definition: types.h:120
HRESULT hr
Definition: shlfolder.c:183
void WINAPI EnterCriticalSection(LPCRITICAL_SECTION)
Definition: regsvr.c:103
Definition: pin.h:70
#define E_INVALIDARG
Definition: ddrawi.h:101
int64_t LONGLONG
Definition: typedefs.h:66
#define TRACE(s)
Definition: solgame.cpp:4
LONGLONG REFERENCE_TIME
Definition: dmusicks.h:9
LONG HRESULT
Definition: typedefs.h:77
GLenum GLuint GLenum GLsizei length
Definition: glext.h:5579
static MPEGSplitterImpl * impl_from_IMediaSeeking(IMediaSeeking *iface)
Definition: mpegsplit.c:73
unsigned long DWORD
Definition: ntddk_ex.h:95
#define memcpy(s1, s2, n)
Definition: mkisofs.h:878
unsigned char BYTE
Definition: mem.h:68
#define S_OK
Definition: intsafe.h:59
static HRESULT parse_header(BYTE *header, LONGLONG *plen, LONGLONG *pduration)
Definition: mpegsplit.c:123
#define MEDIATIME_FROM_BYTES(x)
void WINAPI LeaveCriticalSection(LPCRITICAL_SECTION)
struct CFHEADER header
Definition: fdi.c:101
#define SUCCEEDED(hr)
Definition: intsafe.h:57

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 }
_In_ CLIPOBJ _In_ BRUSHOBJ _In_ LONG x1
Definition: winddi.h:3706
static const DWORD tabsel_123[2][3][16]
Definition: mpegsplit.c:113
#define FIXME(fmt,...)
Definition: debug.h:110
#define E_INVALIDARG
Definition: ddrawi.h:101
GLenum GLuint GLint GLint layer
Definition: glext.h:7007
int64_t LONGLONG
Definition: typedefs.h:66
unsigned int padding
Definition: isohybrid.c:50
GLenum GLuint GLenum GLsizei length
Definition: glext.h:5579
uint64_t ULONGLONG
Definition: typedefs.h:65
static const DWORD freqs[10]
Definition: mpegsplit.c:111
#define ERR(fmt,...)
Definition: debug.h:109
#define S_OK
Definition: intsafe.h:59
#define MPEG_AUDIO_HEADER
Definition: mpegsplit.c:52
static int MPEGSplitter_head_check(const BYTE *header)
Definition: mpegsplit.c:83
struct CFHEADER header
Definition: fdi.c:101

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_Enable(IAMStreamSelect *iface, LONG index, DWORD flags)
Definition: mpegsplit.c:852
static HRESULT WINAPI AMStreamSelect_QueryInterface(IAMStreamSelect *iface, REFIID riid, void **ppv)
Definition: mpegsplit.c:813
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_Release(IAMStreamSelect *iface)
Definition: mpegsplit.c:827
static ULONG WINAPI AMStreamSelect_AddRef(IAMStreamSelect *iface)
Definition: mpegsplit.c:820

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:
=
{
}
HRESULT WINAPI Parser_Pause(IBaseFilter *iface)
Definition: parser.c:279
HRESULT WINAPI Parser_Run(IBaseFilter *iface, REFERENCE_TIME tStart)
Definition: parser.c:313
HRESULT WINAPI Parser_JoinFilterGraph(IBaseFilter *iface, IFilterGraph *pGraph, LPCWSTR pName)
Definition: parser.c:424
HRESULT WINAPI Parser_GetSyncSource(IBaseFilter *iface, IReferenceClock **ppClock)
Definition: parser.c:397
HRESULT WINAPI Parser_FindPin(IBaseFilter *iface, LPCWSTR Id, IPin **ppPin)
Definition: parser.c:409
HRESULT WINAPI Parser_EnumPins(IBaseFilter *iface, IEnumPins **ppEnum)
Definition: parser.c:404
ULONG WINAPI Parser_Release(IBaseFilter *iface)
Definition: parser.c:213
HRESULT WINAPI Parser_Stop(IBaseFilter *iface)
Definition: parser.c:241
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_SetSyncSource(IBaseFilter *iface, IReferenceClock *pClock)
Definition: parser.c:383
HRESULT WINAPI Parser_GetClassID(IBaseFilter *iface, CLSID *pClsid)
Definition: parser.c:228
ULONG WINAPI Parser_AddRef(IBaseFilter *iface)
Definition: parser.c:171
HRESULT WINAPI Parser_QueryFilterInfo(IBaseFilter *iface, FILTER_INFO *pInfo)
Definition: parser.c:419
static HRESULT WINAPI MPEGSplitter_QueryInterface(IBaseFilter *iface, REFIID riid, void **ppv)
Definition: mpegsplit.c:767

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().