virtual int setVolume(int volume)=0;
virtual int mute()=0;
virtual int unMute()=0;
+ virtual bool supportsAc3()=0;
int volumeUp();
int volumeDown();
int setVolume(int volume);
int mute();
int unMute();
+ bool supportsAc3() { return false; }
//Writing Data to Audiodevice
virtual void PrepareMediaSample(const MediaPacketList&, UINT samplepos);
-
AudioWin::AudioWin()
{
initted = 0;
AudioWin::~AudioWin()
{
-
}
int AudioWin::init(UCHAR tstreamType)
int AudioWin::reset()
{
-
+
if (!initted){return 0;}
return ((VideoWin*)Video::getInstance())->dsreset();
}
/*First Check, if we have an audio sample*/
VideoWin *vw=(VideoWin*)Video::getInstance();
- if (!vw->isdsinited()) return 0;
+ if (!vw->isdsinited()) return 0;
if (vw->InIframemode()) {
- samplepos=0;
- MILLISLEEP(10);
- return 0; //Not in iframe mode!
+ samplepos=0;
+ MILLISLEEP(10);
+ return 0; //Not in iframe mode!
}
IMediaSample* ms=NULL;
REFERENCE_TIME reftime1=0;
UINT headerstrip=0;
if (packet.disconti) {
firstsynched=false;
- vw->DeliverVideoMediaSample();
+ vw->DeliverAudioMediaSample();
+ }
+
+ if (packet.type!=vw->lastAType()){//Format Change //Push data out !
+ firstsynched=false;
+ vw->DeliverAudioMediaSample();
}
*/
if (*samplepos==0) {//stripheader
headerstrip=buffer[packet.pos_buffer+8]+9/*is this right*/;
+ if (packet.type == MPTYPE_AC3) headerstrip+=4; //skip ac3 bytes
*samplepos+=headerstrip;
if ( packet.synched ) {
vw->DeliverAudioMediaSample();//write out old data
} else {
if (!firstsynched) {//
*samplepos=packet.length;//if we have not processed at least one
-
+
return packet.length;//synched packet ignore it!
}
}
}
ms->GetPointer(&ms_buf);
+
if (ms_pos==0) {//will only be changed on first packet
if (packet.disconti) {
ms->SetDiscontinuity(TRUE);
// ms->SetSyncPoint(TRUE);
}
}
+ if (packet.type!=vw->lastAType()) {
+ vw->changeAType(packet.type,ms);
+ ms->SetDiscontinuity(TRUE);
+ }
memcpy(ms_buf+ms_pos,buffer+packet.pos_buffer+*samplepos,haveToCopy);
+
ms->SetActualDataLength(haveToCopy+ms_pos);
*samplepos+=haveToCopy;
return vw->ResetTimeOffsets();
}
+bool AudioWin::supportsAc3(){
+ VideoWin *vw=(VideoWin*)Video::getInstance();
+ return vw->supportsAc3();
+}
+
#ifdef DEV
int AudioWin::test()
{
#endif
-
arcnt = 0;
vid_seeking = aud_seeking = false;
video_pts = audio_pts = 0;
+ ispre_1_3_19 = false;
}
Demuxer::~Demuxer()
horizontal_size = vertical_size = 0;
aspect_ratio = (enum AspectRatio) 0;
frame_rate = bit_rate = 0;
+ ispre_1_3_19 = false;
for (int i = 0; i <= (PESTYPE_AUDMAX - PESTYPE_AUD0); i++)
{
avail_mpaudchan[i] = false;
}
+ for (int i = 0; i <= (PESTYPE_SUBSTREAM_AC3MAX - PESTYPE_SUBSTREAM_AC30); i++)
+ {
+ avail_ac3audchan[i] = false;
+ }
}
int Demuxer::shutdown()
{
if (dx->video_current == -1) dx->video_current = packetType;
if (dx->video_current == packetType && !dx->vid_seeking)
- sent = dx->videostream.put(data+submitted, size-submitted);
+ sent = dx->videostream.put(data+submitted, size-submitted, MPTYPE_VIDEO);
else
sent = size-submitted;
}
//Log::getInstance()->log("PESPacket", Log::DEBUG, "%i", dx->audio_current);
if (dx->audio_current == packetType && !dx->aud_seeking)
- sent = dx->audiostream.put(data+submitted, size-submitted);
+ sent = dx->audiostream.put(data+submitted, size-submitted, MPTYPE_MPEG_AUDIO);
else
sent = size-submitted;
}
+ else if (packetType == PESTYPE_PRIVATE_1)
+ {
+ if (substream >= PESTYPE_SUBSTREAM_AC30 && substream <= PESTYPE_SUBSTREAM_AC3MAX)
+ {
+ dx->avail_ac3audchan[substream-PESTYPE_SUBSTREAM_AC30]=true;
+ if (substream == dx->audio_current)
+ {
+ sent = dx->audiostream.put(data+submitted,size-submitted,(dx->ispre_1_3_19)?MPTYPE_AC3_PRE13:MPTYPE_AC3);
+ }
+ else
+ {
+ sent = size-submitted;
+ }
+ }
+ }
else
{
sent = size-submitted;
}
}
}
+ else if (packetType == PESTYPE_PRIVATE_1) //Private Stream
+ {
+ //Inspired by vdr's device.c
+ int payload_begin = data[8]+9;
+ unsigned char substream_id = data[payload_begin];
+ unsigned char substream_type = substream_id & 0xF0;
+ unsigned char substream_index = substream_id & 0x1F;
+pre_1_3_19_Recording: //This is for old recordings stuff
+ if (dx->ispre_1_3_19)
+ {
+ substream_id = PESTYPE_PRIVATE_1;
+ substream_type = 0x80;
+ substream_index = 0;
+ }
+ switch (substream_type)
+ {
+ case 0x20://SPU
+ case 0x30://SPU
+ break;
+ case 0xA0: //LPCM //not supported yet, is there any LPCM transmissio out there?
+ break;
+ case 0x80: //ac3, currently only one ac3 track per recording supported
+ substream=substream_type+substream_index;
+
+ // Extract audio PTS if it exists
+ if ( size >= 14 && (data[7] & 0x80) ) // PTS_DTS_flags indicate PTS
+ {
+ dx->audio_pts = pts = ( (ULLONG)(data[9] & 0x0E) << 29 ) |
+ ( (ULLONG)(data[10]) << 22 ) |
+ ( (ULLONG)(data[11] & 0xFE) << 14 ) |
+ ( (ULLONG)(data[12]) << 7 ) |
+ ( (ULLONG)(data[13] & 0xFE) >> 1 );
+ // We continue to seek on the audio if the video PTS that we
+ // are trying to match is ahead of the audio PTS by at most
+ // SEEK_THRESHOLD. We consider the possibility of PTS wrap.
+ if (dx->aud_seeking && !dx->vid_seeking &&
+ !( (dx->video_pts_seek > dx->audio_pts &&
+ dx->video_pts_seek - dx->audio_pts < SEEK_THRESHOLD)
+ ||
+ (dx->video_pts_seek < dx->audio_pts &&
+ dx->video_pts_seek + (1LL<<33) -
+ dx->audio_pts < SEEK_THRESHOLD) ))
+ {
+ dx->aud_seeking = 0;
+ Log::getInstance()->log("Demuxer", Log::DEBUG, "Leaving audio sync: Audio PTS = %llu", dx->audio_pts);
+ }
+ }
+ break;
+ default:
+ if (!dx->ispre_1_3_19)
+ {
+ dx->ispre_1_3_19=true; //switching to compat mode
+ goto pre_1_3_19_Recording;
+ }
+ else
+ {
+ substream=0;
+ }
+ break;
+ }
+ }
else if (packetType >= PESTYPE_VID0 && packetType <= PESTYPE_VIDMAX)
{
// Extract video PTS if it exists
return avail_mpaudchan;
}
+bool* Demuxer::getac3AudioChannels()
+{
+ return avail_ac3audchan;
+}
+
int Demuxer::getselAudioChannel()
{
return audio_current;
}
-void Demuxer::setmpAudioChannel(int aud_channel)
+void Demuxer::setAudioChannel(int aud_channel)
{
audio_current = aud_channel;
}
UINT length, size;
bool closed;
UCHAR packetType;
+ UCHAR substream; //for ac3
ULLONG pts;
bool seq_header;
UINT submitted;
virtual void parseDetails();
UINT findPictureHeader();
+
static const ULLONG PTS_INVALID;
};
friend class PESPacket;
virtual ULONG getPacketNum() {return 0;}
bool* getmpAudioChannels(); //Maybe virtual ?
+ bool* getac3AudioChannels(); //Maybe virtual ?
int getselAudioChannel();
- void setmpAudioChannel(int aud_channel);
+ void setAudioChannel(int aud_channel);
int getHorizontalSize() { return horizontal_size; }
int getVerticalSize() { return vertical_size; }
PESTYPE_VID13, PESTYPE_VID14, PESTYPE_VID15,
PESTYPE_VIDMAX = PESTYPE_VID15
};
+ enum PESTYPE_SUBSTREAM
+ {
+ PESTYPE_SUBSTREAM_AC30 = 0x80,
+ PESTYPE_SUBSTREAM_AC31,PESTYPE_SUBSTREAM_AC32, PESTYPE_SUBSTREAM_AC33,
+ PESTYPE_SUBSTREAM_AC34,PESTYPE_SUBSTREAM_AC35,PESTYPE_SUBSTREAM_AC36,
+ PESTYPE_SUBSTREAM_AC37,
+ PESTYPE_SUBSTREAM_AC3MAX = PESTYPE_SUBSTREAM_AC37
+ };
+ bool ispre_1_3_19;
bool avail_mpaudchan[PESTYPE_AUDMAX-PESTYPE_AUD0+1];
+ bool avail_ac3audchan[PESTYPE_SUBSTREAM_AC3MAX-PESTYPE_SUBSTREAM_AC30+1];
};
#endif
#include "defines.h"
#include <list>
+#define MPTYPE_VIDEO 0x00
+#define MPTYPE_MPEG_AUDIO 0x01
+#define MPTYPE_AC3 0x02
+#define MPTYPE_AC3_PRE13 0x03 //old vdr recording compatmode
+
struct MediaPacket
{
ULONG pos_buffer; //position in stream buffer
ULONG length; //length of the packet
// The fields below are not needed by the MVP
+ UCHAR type;
#ifdef WIN32
ULLONG recording_byte_pos; //position in recording
ULLONG pts;
class DsSFEnumPins: public IEnumPins {
public:
- DsSFEnumPins(DsSourcePin* audio,DsSourcePin* video,DsSourceFilter *filt,ULONG pos=0);
- virtual ~DsSFEnumPins();
- virtual HRESULT STDMETHODCALLTYPE Next(ULONG numpin,IPin **pins,ULONG *fetched);
- virtual HRESULT STDMETHODCALLTYPE Skip(ULONG numpin);
- virtual HRESULT STDMETHODCALLTYPE Reset();
- virtual HRESULT STDMETHODCALLTYPE Clone(IEnumPins **enuma);
- virtual HRESULT STDMETHODCALLTYPE QueryInterface(REFIID id,void ** object);
- virtual ULONG STDMETHODCALLTYPE AddRef();
+ DsSFEnumPins(DsSourcePin* audio,DsSourcePin* video,DsSourceFilter *filt,ULONG pos=0);
+ virtual ~DsSFEnumPins();
+ virtual HRESULT STDMETHODCALLTYPE Next(ULONG numpin,IPin **pins,ULONG *fetched);
+ virtual HRESULT STDMETHODCALLTYPE Skip(ULONG numpin);
+ virtual HRESULT STDMETHODCALLTYPE Reset();
+ virtual HRESULT STDMETHODCALLTYPE Clone(IEnumPins **enuma);
+ virtual HRESULT STDMETHODCALLTYPE QueryInterface(REFIID id,void ** object);
+ virtual ULONG STDMETHODCALLTYPE AddRef();
virtual ULONG STDMETHODCALLTYPE Release();
protected:
- DsSourcePin* audiopin;
- DsSourcePin* videopin;
- DsSourceFilter *filter;
- ULONG curpos;
- volatile long refs;
+ DsSourcePin* audiopin;
+ DsSourcePin* videopin;
+ DsSourceFilter *filter;
+ ULONG curpos;
+ volatile long refs;
};
DsSFEnumPins::DsSFEnumPins(DsSourcePin* audio,DsSourcePin* video,DsSourceFilter *filt,ULONG pos){
- audiopin=audio;
- videopin=video;
- curpos=pos;
- filter=filt;
- filt->AddRef();
- refs=0;
-
+ audiopin=audio;
+ videopin=video;
+ curpos=pos;
+ filter=filt;
+ filt->AddRef();
+ refs=0;
+
}
DsSFEnumPins::~DsSFEnumPins(){
- filter->Release();
-
+ filter->Release();
+
}
HRESULT STDMETHODCALLTYPE DsSFEnumPins::Next(ULONG numpin,IPin **pins,ULONG *fetched) {
- int i;
- if (fetched==NULL) return E_POINTER;
- if (pins==NULL) return E_POINTER;
- *fetched=0;
-
- for (i=0;(i<numpin)&& (curpos<2);i++) {
- switch (curpos) {
- case 0: audiopin->AddRef(); pins[i]=(IPin*)audiopin;break;
- case 1: videopin->AddRef(); pins[i]=(IPin*)videopin;break;
- };
- (*fetched)++;
- curpos++;
- }
- if ((*fetched)!=numpin) return S_FALSE;
- return S_OK;
+ int i;
+ if (fetched==NULL) return E_POINTER;
+ if (pins==NULL) return E_POINTER;
+ *fetched=0;
+
+ for (i=0;(i<numpin)&& (curpos<2);i++) {
+ switch (curpos) {
+ case 0: audiopin->AddRef(); pins[i]=(IPin*)audiopin;break;
+ case 1: videopin->AddRef(); pins[i]=(IPin*)videopin;break;
+ };
+ (*fetched)++;
+ curpos++;
+ }
+ if ((*fetched)!=numpin) return S_FALSE;
+ return S_OK;
}
HRESULT STDMETHODCALLTYPE DsSFEnumPins::Skip(ULONG numpin){
- curpos+=numpin;
- if (curpos>2) return S_FALSE;
- return S_OK;
+ curpos+=numpin;
+ if (curpos>2) return S_FALSE;
+ return S_OK;
}
HRESULT STDMETHODCALLTYPE DsSFEnumPins::Reset(){
- curpos=0;
- return S_OK;
+ curpos=0;
+ return S_OK;
}
HRESULT STDMETHODCALLTYPE DsSFEnumPins::Clone(IEnumPins **enuma){
- if (enuma==NULL) return E_POINTER;
- *enuma=new DsSFEnumPins(audiopin,videopin,filter,curpos);
- (*enuma)->AddRef();
- return S_OK;
+ if (enuma==NULL) return E_POINTER;
+ *enuma=new DsSFEnumPins(audiopin,videopin,filter,curpos);
+ (*enuma)->AddRef();
+ return S_OK;
}
HRESULT STDMETHODCALLTYPE DsSFEnumPins::QueryInterface(REFIID id,void ** object){
- if (object==NULL) return E_POINTER;
- if (id==IID_IUnknown ||id == IID_IEnumPins) {
- *object=(IUnknown*)this;
- ((IUnknown*)object)->AddRef();
- return NOERROR;
- } else {
- *object=NULL;
- return E_NOINTERFACE;
- }
+ if (object==NULL) return E_POINTER;
+
+ if (id==IID_IUnknown ||id == IID_IEnumPins) {
+ *object=(IUnknown*)this;
+ ((IUnknown*)object)->AddRef();
+ return NOERROR;
+ } else {
+ *object=NULL;
+ return E_NOINTERFACE;
+ }
}
ULONG STDMETHODCALLTYPE DsSFEnumPins::AddRef(){
- InterlockedIncrement(&refs);
- long tempref=refs;
- if (tempref>1) return tempref;
- else return 1;
+ InterlockedIncrement(&refs);
+ long tempref=refs;
+ if (tempref>1) return tempref;
+ else return 1;
}
ULONG STDMETHODCALLTYPE DsSFEnumPins::Release(){
- long tempref=InterlockedDecrement(&refs);
-
- if (tempref==0) {
- refs++;
- delete this;
- return NULL;
- } else {
- if (tempref>1) return tempref;
- else return 1;
- }
+ long tempref=InterlockedDecrement(&refs);
+
+ if (tempref==0) {
+ refs++;
+ delete this;
+ return NULL;
+ } else {
+ if (tempref>1) return tempref;
+ else return 1;
+ }
}
DsSourceFilter::DsSourceFilter()
{
- //add audio pin
- HRESULT res;
- audiopin=new DsSourcePin(this,&res,L"Vomp Audio Out",true);
- videopin=new DsSourcePin(this,&res,L"Vomp Video Out",false);
- filtergraph=NULL;
- clock=NULL;
- mystate=State_Stopped;
- laststart=0;
- refs=0;
- InitializeCriticalSection(&filterlock);
+ //add audio pin
+ HRESULT res;
+ audiopin=new DsSourcePin(this,&res,L"Vomp Audio Out",true);
+ videopin=new DsSourcePin(this,&res,L"Vomp Video Out",false);
+ filtergraph=NULL;
+ clock=NULL;
+ mystate=State_Stopped;
+ laststart=0;
+ refs=0;
+ InitializeCriticalSection(&filterlock);
}
DsSourceFilter::~DsSourceFilter()
{
- if (audiopin) delete audiopin;
- if (videopin) delete videopin;
- if (clock) {
- clock->Release();
- clock=NULL;
- }
- DeleteCriticalSection(&filterlock);
-
+ if (audiopin) delete audiopin;
+ if (videopin) delete videopin;
+ if (clock) {
+ clock->Release();
+ clock=NULL;
+ }
+ DeleteCriticalSection(&filterlock);
+
}
HRESULT STDMETHODCALLTYPE DsSourceFilter::GetClassID(CLSID *clsid){
- if (clsid==NULL) return E_POINTER;
- *clsid=_uuidof(this);
- return S_OK;
+ if (clsid==NULL) return E_POINTER;
+ *clsid=_uuidof(this);
+ return S_OK;
}
HRESULT STDMETHODCALLTYPE DsSourceFilter::QueryInterface(REFIID id,void ** object){
- if (object==NULL) return E_POINTER;
- if (id==IID_IUnknown) {
- *object=(IUnknown*)this;
- AddRef();
- return NOERROR;
- } else if (id==IID_IBaseFilter) {
- *object=(IBaseFilter*)this;
- AddRef();
- return NOERROR;
- } else if (id==IID_IMediaFilter) {
- *object=(IMediaFilter*)this;
- AddRef();
- return NOERROR;
- }else {
- *object=NULL;
- return E_NOINTERFACE;
- }
+ if (object==NULL) return E_POINTER;
+ if (id==IID_IUnknown) {
+ *object=(IUnknown*)this;
+ AddRef();
+ return NOERROR;
+ } else if (id==IID_IBaseFilter) {
+ *object=(IBaseFilter*)this;
+ AddRef();
+ return NOERROR;
+ } else if (id==IID_IMediaFilter) {
+ *object=(IMediaFilter*)this;
+ AddRef();
+ return NOERROR;
+ }else {
+ *object=NULL;
+ return E_NOINTERFACE;
+ }
}
ULONG STDMETHODCALLTYPE DsSourceFilter::AddRef(){
- InterlockedIncrement(&refs);
- long tempref=refs;
- if (tempref>1) return tempref;
- else return 1;
+ InterlockedIncrement(&refs);
+ long tempref=refs;
+ if (tempref>1) return tempref;
+ else return 1;
}
ULONG STDMETHODCALLTYPE DsSourceFilter::Release(){
- long tempref=InterlockedDecrement(&refs);
-
- if (tempref==0) {
- refs++;
- delete this;
- return NULL;
- } else {
- if (tempref>1) return tempref;
- else return 1;
- }
+ long tempref=InterlockedDecrement(&refs);
+
+ if (tempref==0) {
+ refs++;
+ delete this;
+ return NULL;
+ } else {
+ if (tempref>1) return tempref;
+ else return 1;
+ }
}
/*IBaseFilter*/
HRESULT STDMETHODCALLTYPE DsSourceFilter::EnumPins(IEnumPins **enumar){
- if (enumar==NULL) return E_POINTER;
- *enumar=new DsSFEnumPins(audiopin,videopin, this);
- (*enumar)->AddRef();
- return S_OK;
+ if (enumar==NULL) return E_POINTER;
+ *enumar=new DsSFEnumPins(audiopin,videopin, this);
+ (*enumar)->AddRef();
+ return S_OK;
}
HRESULT STDMETHODCALLTYPE DsSourceFilter::FindPin(LPCWSTR iden,IPin **pin){
- if (pin==NULL) return E_POINTER;
- EnterCriticalSection(&filterlock);
-
- if (wcscmp(AUDIOPIN_NAME,iden)==NULL) {
- *pin=(IPin*)audiopin;
- (*pin)->AddRef();
- LeaveCriticalSection(&filterlock);
- return S_OK;
- }
- if (wcscmp(VIDEOPIN_NAME,iden)==NULL) {
- *pin=(IPin*)videopin;
- (*pin)->AddRef();
- LeaveCriticalSection(&filterlock);
- return S_OK;
- }
-
- *pin=NULL;
- LeaveCriticalSection(&filterlock);
+ if (pin==NULL) return E_POINTER;
+ EnterCriticalSection(&filterlock);
+
+ if (wcscmp(AUDIOPIN_NAME,iden)==NULL) {
+ *pin=(IPin*)audiopin;
+ (*pin)->AddRef();
+ LeaveCriticalSection(&filterlock);
+ return S_OK;
+ }
+ if (wcscmp(VIDEOPIN_NAME,iden)==NULL) {
+ *pin=(IPin*)videopin;
+ (*pin)->AddRef();
+ LeaveCriticalSection(&filterlock);
+ return S_OK;
+ }
+
+ *pin=NULL;
+ LeaveCriticalSection(&filterlock);
return VFW_E_NOT_FOUND;
}
HRESULT STDMETHODCALLTYPE DsSourceFilter::QueryFilterInfo(FILTER_INFO *info){
- if (info==NULL) return E_POINTER;
- wcsncpy(info->achName,L"VompWinFilter", sizeof(info->achName)/sizeof(WCHAR));
- info->pGraph=filtergraph;
- if (info->pGraph!=NULL) info->pGraph->AddRef();
- return NOERROR;
+ if (info==NULL) return E_POINTER;
+ wcsncpy(info->achName,L"VompWinFilter", sizeof(info->achName)/sizeof(WCHAR));
+ info->pGraph=filtergraph;
+ if (info->pGraph!=NULL) info->pGraph->AddRef();
+ return NOERROR;
}
HRESULT STDMETHODCALLTYPE DsSourceFilter::JoinFilterGraph(IFilterGraph *graph,LPCWSTR name){
- //Should we lock
- EnterCriticalSection(&filterlock);
- filtergraph=graph;
- //filtergraph->AddRef();
- //We ignore the name
- LeaveCriticalSection(&filterlock);
-
- return S_OK;
+ //Should we lock
+ EnterCriticalSection(&filterlock);
+ filtergraph=graph;
+ //filtergraph->AddRef();
+ //We ignore the name
+ LeaveCriticalSection(&filterlock);
+
+ return S_OK;
}
HRESULT STDMETHODCALLTYPE DsSourceFilter::QueryVendorInfo(LPWSTR *vendinf) {
- return E_NOTIMPL;
+ return E_NOTIMPL;
}
/*IMediaFilter*/
HRESULT STDMETHODCALLTYPE DsSourceFilter::GetState(DWORD timeout,FILTER_STATE *state){
- if (state==NULL) return E_POINTER;
- EnterCriticalSection(&filterlock);
- *state=mystate;
- LeaveCriticalSection(&filterlock);
- return S_OK;
+ if (state==NULL) return E_POINTER;
+ EnterCriticalSection(&filterlock);
+ *state=mystate;
+ LeaveCriticalSection(&filterlock);
+ return S_OK;
}
HRESULT STDMETHODCALLTYPE DsSourceFilter::SetSyncSource(IReferenceClock *uhr){
- EnterCriticalSection(&filterlock);
- //MessageBox(0,"Sets ync","",0);
- if (clock!=NULL) {
- clock->Release();
- }
- if (uhr!=NULL) {
- uhr->AddRef();
- }
- clock=uhr;
- LeaveCriticalSection(&filterlock);
-
- return S_OK;
+ EnterCriticalSection(&filterlock);
+ if (clock!=NULL) {
+ clock->Release();
+ }
+ if (uhr!=NULL) {
+ uhr->AddRef();
+ }
+ clock=uhr;
+ LeaveCriticalSection(&filterlock);
+
+ return S_OK;
}
HRESULT STDMETHODCALLTYPE DsSourceFilter::GetSyncSource(IReferenceClock **uhr){
- if (uhr==NULL) return E_POINTER;
- EnterCriticalSection(&filterlock);
- if (clock!=NULL) clock->AddRef();
- *uhr=clock;
- LeaveCriticalSection(&filterlock);
-
- return S_OK;
+ if (uhr==NULL) return E_POINTER;
+ EnterCriticalSection(&filterlock);
+ if (clock!=NULL) clock->AddRef();
+ *uhr=clock;
+ LeaveCriticalSection(&filterlock);
+
+ return S_OK;
}
HRESULT STDMETHODCALLTYPE DsSourceFilter::Stop(){
- EnterCriticalSection(&filterlock);
- HRESULT aphres=S_OK;
- HRESULT vphres=S_OK;
-
- if (audiopin->IsConnected()){
- aphres=audiopin->Inactive();
- }
- if (videopin->IsConnected()){
- vphres=videopin->Inactive();
- }
-
- mystate=State_Stopped;
- LeaveCriticalSection(&filterlock);
- if (aphres!=S_OK) return aphres;
- if (vphres!=S_OK) return vphres;
- return S_OK;
+ EnterCriticalSection(&filterlock);
+ HRESULT aphres=S_OK;
+ HRESULT vphres=S_OK;
+
+ if (audiopin->IsConnected()){
+ aphres=audiopin->Inactive();
+ }
+ if (videopin->IsConnected()){
+ vphres=videopin->Inactive();
+ }
+
+ mystate=State_Stopped;
+ LeaveCriticalSection(&filterlock);
+ if (aphres!=S_OK) return aphres;
+ if (vphres!=S_OK) return vphres;
+ return S_OK;
}
HRESULT STDMETHODCALLTYPE DsSourceFilter::Pause(){
- EnterCriticalSection(&filterlock);
- HRESULT aphres;
- HRESULT vphres;
-
- if (audiopin->IsConnected()){
- aphres=audiopin->Active();
- if (aphres!=S_OK) {
- LeaveCriticalSection(&filterlock);
- return aphres;
- }
- }
- if (videopin->IsConnected()){
- vphres=videopin->Active();
- if (vphres!=S_OK) {
- LeaveCriticalSection(&filterlock);
- return vphres;
- }
- }
-
- mystate=State_Paused;
- LeaveCriticalSection(&filterlock);
-
-
- return S_OK;
+ EnterCriticalSection(&filterlock);
+ HRESULT aphres;
+ HRESULT vphres;
+
+ if (audiopin->IsConnected()){
+ aphres=audiopin->Active();
+ if (aphres!=S_OK) {
+ LeaveCriticalSection(&filterlock);
+ return aphres;
+ }
+ }
+ if (videopin->IsConnected()){
+ vphres=videopin->Active();
+ if (vphres!=S_OK) {
+ LeaveCriticalSection(&filterlock);
+ return vphres;
+ }
+ }
+
+ mystate=State_Paused;
+ LeaveCriticalSection(&filterlock);
+
+
+ return S_OK;
}
HRESULT STDMETHODCALLTYPE DsSourceFilter::Run(REFERENCE_TIME start){
-
- HRESULT aphres;
- HRESULT vphres;
- EnterCriticalSection(&filterlock);
-
- if (mystate==State_Stopped) {
- HRESULT phres=Pause();
- if (phres!=S_OK){
- LeaveCriticalSection(&filterlock);
- return phres;
- }
- }
-
- laststart=start;
-
-
- if (audiopin->IsConnected()){
- aphres=audiopin->Run(start);
- if (aphres!=S_OK) {
- LeaveCriticalSection(&filterlock);
- return aphres;
- }
- }
-
- if (videopin->IsConnected()){
- vphres=videopin->Run(start);
- if (vphres!=S_OK) {
- LeaveCriticalSection(&filterlock);
- return vphres;
- }
- }
-
- mystate=State_Running;
- LeaveCriticalSection(&filterlock);
-
-
- return S_OK;
+
+ HRESULT aphres;
+ HRESULT vphres;
+ EnterCriticalSection(&filterlock);
+
+ if (mystate==State_Stopped) {
+ HRESULT phres=Pause();
+ if (phres!=S_OK){
+ LeaveCriticalSection(&filterlock);
+ return phres;
+ }
+ }
+
+ laststart=start;
+
+
+ if (audiopin->IsConnected()){
+ aphres=audiopin->Run(start);
+ if (aphres!=S_OK) {
+ LeaveCriticalSection(&filterlock);
+ return aphres;
+ }
+ }
+
+ if (videopin->IsConnected()){
+ vphres=videopin->Run(start);
+ if (vphres!=S_OK) {
+ LeaveCriticalSection(&filterlock);
+ return vphres;
+ }
+ }
+
+ mystate=State_Running;
+ LeaveCriticalSection(&filterlock);
+
+
+ return S_OK;
}
int DsSourceFilter::GetPinCount()
{
- return 2; //audio and video
+ return 2; //audio and video
}
int DsSourceFilter::getCurrentAudioMediaSample(IMediaSample** ms)
{
- if (!audiopin || !IsActive()) {
- return 0;
- }
- if (audiopin->getCurrentMediaSample(ms)!=S_OK) {
- return 0;
- }
- return 1;
+ if (!audiopin || !IsActive()) {
+ return 0;
+ }
+ if (audiopin->getCurrentMediaSample(ms)!=S_OK) {
+ return 0;
+ }
+ return 1;
}
int DsSourceFilter::getCurrentVideoMediaSample(IMediaSample** ms)
{
- if (!videopin || !IsActive()) {
- return 0;
- }
- if (videopin->getCurrentMediaSample(ms)!=S_OK) {
- return 0;
- }
- return 1;
+ if (!videopin || !IsActive()) {
+ return 0;
+ }
+ if (videopin->getCurrentMediaSample(ms)!=S_OK) {
+ return 0;
+ }
+ return 1;
}
int DsSourceFilter::DeliverAudioMediaSample(IMediaSample* ms)
{
- if (!audiopin || !IsActive()) {
- ms->Release();
- return 0;
- }
- if (audiopin->deliver(ms)!=S_OK) {
- ms->Release();
- return 0;
- }
- ms->Release();
- return 1;
+ if (!audiopin || !IsActive()) {
+ ms->Release();
+ return 0;
+ }
+ if (audiopin->deliver(ms)!=S_OK) {
+ ms->Release();
+ return 0;
+ }
+ ms->Release();
+ return 1;
}
+bool DsSourceFilter::supportsAc3()
+{
+ if (!audiopin || !IsActive()) {
+ return false;
+ }
+ return audiopin->supportsAc3();
+}
+
int DsSourceFilter::DeliverVideoMediaSample(IMediaSample* ms)
{
- if (!videopin || !IsActive()) {
- ms->Release();
- return 0;
- }
- if (videopin->deliver(ms)!=S_OK) {
- ms->Release();
- return 0;
- }
- ms->Release();
- return 1;
+ if (!videopin || !IsActive()) {
+ ms->Release();
+ return 0;
+ }
+ if (videopin->deliver(ms)!=S_OK) {
+ ms->Release();
+ return 0;
+ }
+ ms->Release();
+ return 1;
}
+bool DsSourceFilter::changeAType(int type,IMediaSample* ms)
+{
+ if (!audiopin ) {
+ return false;
+ }
+ audiopin->SetPinMode(type);
+ audiopin->SetMsToMt(ms);
+
+ return true;
+}
[uuid("EB87AB22-7A95-49c3-8CCE-2F6D61A87009")]
class DsSourceFilter: public IBaseFilter {
-friend class DsSourcePin;
+friend class DsSourcePin;
public:
- DsSourceFilter();
- ~DsSourceFilter();
- virtual int GetPinCount();
- int getCurrentAudioMediaSample(IMediaSample** ms);
- int DeliverAudioMediaSample(IMediaSample* ms);
- int getCurrentVideoMediaSample(IMediaSample** ms);
- int DeliverVideoMediaSample(IMediaSample* ms);
- REFERENCE_TIME getStartOffset(){return laststart;};
- BOOL IsActive() {EnterCriticalSection(&filterlock);
- FILTER_STATE tempstate=mystate;LeaveCriticalSection(&filterlock);
- return (tempstate==State_Running) || (tempstate==State_Paused);};
+ DsSourceFilter();
+ ~DsSourceFilter();
+ virtual int GetPinCount();
+ int getCurrentAudioMediaSample(IMediaSample** ms);
+ int DeliverAudioMediaSample(IMediaSample* ms);
+ int getCurrentVideoMediaSample(IMediaSample** ms);
+ int DeliverVideoMediaSample(IMediaSample* ms);
+ REFERENCE_TIME getStartOffset(){return laststart;};
+ BOOL IsActive() {EnterCriticalSection(&filterlock);
+ FILTER_STATE tempstate=mystate;LeaveCriticalSection(&filterlock);
+ return (tempstate==State_Running) || (tempstate==State_Paused);};
/* IUnknown */
- virtual HRESULT STDMETHODCALLTYPE QueryInterface(REFIID id,void ** object);
- virtual ULONG STDMETHODCALLTYPE AddRef();
+ virtual HRESULT STDMETHODCALLTYPE QueryInterface(REFIID id,void ** object);
+ virtual ULONG STDMETHODCALLTYPE AddRef();
virtual ULONG STDMETHODCALLTYPE Release();
/*IPersist*/
- virtual HRESULT STDMETHODCALLTYPE GetClassID(CLSID *clsid);
+ virtual HRESULT STDMETHODCALLTYPE GetClassID(CLSID *clsid);
/*IBaseFilter*/
- virtual HRESULT STDMETHODCALLTYPE EnumPins(IEnumPins **enumar);
- virtual HRESULT STDMETHODCALLTYPE FindPin(LPCWSTR iden,IPin **pin);
- virtual HRESULT STDMETHODCALLTYPE QueryFilterInfo(FILTER_INFO *info);
- virtual HRESULT STDMETHODCALLTYPE JoinFilterGraph(IFilterGraph *graph,LPCWSTR name);
- virtual HRESULT STDMETHODCALLTYPE QueryVendorInfo(LPWSTR *vendinf);
+ virtual HRESULT STDMETHODCALLTYPE EnumPins(IEnumPins **enumar);
+ virtual HRESULT STDMETHODCALLTYPE FindPin(LPCWSTR iden,IPin **pin);
+ virtual HRESULT STDMETHODCALLTYPE QueryFilterInfo(FILTER_INFO *info);
+ virtual HRESULT STDMETHODCALLTYPE JoinFilterGraph(IFilterGraph *graph,LPCWSTR name);
+ virtual HRESULT STDMETHODCALLTYPE QueryVendorInfo(LPWSTR *vendinf);
/*IMediaFilter*/
- virtual HRESULT STDMETHODCALLTYPE GetState(DWORD timeout,FILTER_STATE *state);
- virtual HRESULT STDMETHODCALLTYPE SetSyncSource(IReferenceClock *uhr);
- virtual HRESULT STDMETHODCALLTYPE GetSyncSource(IReferenceClock **uhr);
- virtual HRESULT STDMETHODCALLTYPE Stop();
- virtual HRESULT STDMETHODCALLTYPE Pause();
- virtual HRESULT STDMETHODCALLTYPE Run(REFERENCE_TIME start);
+ virtual HRESULT STDMETHODCALLTYPE GetState(DWORD timeout,FILTER_STATE *state);
+ virtual HRESULT STDMETHODCALLTYPE SetSyncSource(IReferenceClock *uhr);
+ virtual HRESULT STDMETHODCALLTYPE GetSyncSource(IReferenceClock **uhr);
+ virtual HRESULT STDMETHODCALLTYPE Stop();
+ virtual HRESULT STDMETHODCALLTYPE Pause();
+ virtual HRESULT STDMETHODCALLTYPE Run(REFERENCE_TIME start);
- DsSourcePin *GetAudioPin() {return audiopin;};
- DsSourcePin *GetVideoPin() {return videopin;};
+ DsSourcePin *GetAudioPin() {return audiopin;};
+ DsSourcePin *GetVideoPin() {return videopin;};
+ bool supportsAc3();
+ bool changeAType(int type,IMediaSample* ms);
protected:
- DsSourcePin *audiopin;
- DsSourcePin *videopin;
- IFilterGraph* filtergraph;
- IReferenceClock* clock;
- FILTER_STATE mystate;
- REFERENCE_TIME laststart;
- CRITICAL_SECTION filterlock;
-
- volatile long refs;
+ DsSourcePin *audiopin;
+ DsSourcePin *videopin;
+ IFilterGraph* filtergraph;
+ IReferenceClock* clock;
+ FILTER_STATE mystate;
+ REFERENCE_TIME laststart;
+ CRITICAL_SECTION filterlock;
+
+ volatile long refs;
};
#include "dssourcefilter.h"
#include <Dvdmedia.h>
#include <mmreg.h>
-
+#include "draintarget.h"
class DsSFEnumMediaTypes: public IEnumMediaTypes {
public:
for (i=0;(i<numpin);i++) {
pins[i]=(AM_MEDIA_TYPE*)CoTaskMemAlloc(sizeof(AM_MEDIA_TYPE));
- if (parent->GetMediaType(curpos+i,pins[i])!=S_OK) {
- CoTaskMemFree(pins[i]);
- pins[i]=NULL;
- return S_FALSE;
- } curpos++;
+ if (parent->GetMediaType(curpos+i,pins[i])!=S_OK) {
+ CoTaskMemFree(pins[i]);
+ pins[i]=NULL;
+ return S_FALSE;
+ } curpos++;
if (fetched!=NULL) (*fetched)++;
}
return S_OK;
connected=NULL;
connectedinput=NULL;
allocator=NULL;
-
-
+ if (isaudiopin)
+ {
+ pinmode=MPTYPE_MPEG_AUDIO;
+ //pinmode=MPTYPE_AC3;
+ }
+ else
+ {
+ pinmode=MPTYPE_VIDEO;
+ }
}
if (connected!=NULL) {LeaveCriticalSection(&m_pFilter->filterlock);return VFW_E_ALREADY_CONNECTED;}
if (m_pFilter->mystate!=State_Stopped) {LeaveCriticalSection(&m_pFilter->filterlock);return VFW_E_NOT_STOPPED;}
-
bool gotmt=false;
if (mtype!=NULL) {
AM_MEDIA_TYPE * emtype;
ULONG fetched=0;
pinempf->AddRef();
+
+
while (emt->Next(1,&emtype,&fetched)==S_OK) {
if (CheckMediaType(emtype)==S_OK){
-/* PIN_INFO pini;
- pinempf->QueryPinInfo(&pini);
- if (pini.pFilter!=NULL) {
- FILTER_INFO filti;
- pini.pFilter->QueryFilterInfo(&filti);
-
- if (filti.pGraph!=NULL) filti.pGraph->Release();
- char buffer[MAX_FILTER_NAME*2];
- wcstombs(buffer,filti.achName,MAX_FILTER_NAME*2);
- MessageBox(0,buffer,"Filter",0);
- pini.pFilter->Release();
- }*/
+ /* PIN_INFO pini;
+ pinempf->QueryPinInfo(&pini);
+ if (pini.pFilter!=NULL) {
+ FILTER_INFO filti;
+ pini.pFilter->QueryFilterInfo(&filti);
+
+ if (filti.pGraph!=NULL) filti.pGraph->Release();
+ char buffer[MAX_FILTER_NAME*2];
+ wcstombs(buffer,filti.achName,MAX_FILTER_NAME*2);
+ MessageBox(0,buffer,"Filter",0);
+ pini.pFilter->Release();
+ }*/
if (pinempf->ReceiveConnection((IPin*)this,emtype)==S_OK) {
connected=pinempf;
CopyMType(&medtype,emtype);
- if (emtype->pbFormat!=NULL) CoTaskMemFree(emtype->pbFormat);
-
- CoTaskMemFree(emtype);
+ if (emtype->pbFormat!=NULL) CoTaskMemFree(emtype->pbFormat);
+
+ CoTaskMemFree(emtype);
gotmt=true;
break;
}
}
if (emtype->pbFormat!=NULL) CoTaskMemFree(emtype->pbFormat);
- CoTaskMemFree(emtype);
+ CoTaskMemFree(emtype);
}
emt->Release();
if (gotmt==false) {
connected=pinempf;
CopyMType(&medtype,emtype);
if (emtype->pbFormat!=NULL) CoTaskMemFree(emtype->pbFormat);
- CoTaskMemFree(emtype);
+ CoTaskMemFree(emtype);
gotmt=true;
break;
}
}
if (emtype->pbFormat!=NULL) CoTaskMemFree(emtype->pbFormat);
- CoTaskMemFree(emtype);
+ CoTaskMemFree(emtype);
}
emt->Release();
if (gotmt==false) {
HRESULT DsSourcePin::deliver(IMediaSample * ms){
//EnterCriticalSection(&m_pFilter->filterlock);
HRESULT hres;
+
+
if (connectedinput!=NULL)hres= connectedinput->Receive(ms);
else hres= VFW_E_NOT_CONNECTED;
//LeaveCriticalSection(&m_pFilter->filterlock);
}
-HRESULT DsSourcePin::GetMediaType(int iPosition, AM_MEDIA_TYPE *pmt)
+void DsSourcePin::SetMsToMt(IMediaSample *ms) {
+ ms->SetMediaType(&medtype);
+}
+
+bool DsSourcePin::supportsAc3() {
+ if (!isaudiopin)
+ {
+ return false; //Haha a video pin that supports ac3
+ }
+ if (!IsConnected())
+ {
+ return false; //Graph is not build, please wait
+ }
+ if (connected==NULL)
+ {
+ return false; //Graph is not build, please wait
+ }
+ IPinConnection *pinconn=NULL; //according to docs, this is the prefered method
+ if (connected->QueryInterface(IID_IPinConnection,(void**)&pinconn)==S_OK) {
+ AM_MEDIA_TYPE test;
+ GetMediaType(10,&test);
+ if (pinconn->DynamicQueryAccept(&test)==S_OK)
+ {
+ pinconn->Release();
+ CoTaskMemFree(test.pbFormat);
+ return true;
+ } else {
+ pinconn->Release();
+ CoTaskMemFree(test.pbFormat);
+ return false;
+ }
+ }
+ AM_MEDIA_TYPE test;
+ GetMediaTypeAc3(0,&test);
+ if (connected->QueryAccept(&test)==S_OK)
+ {
+ CoTaskMemFree(test.pbFormat);
+ return true;
+ }
+ CoTaskMemFree(test.pbFormat);
+ return false;
+
+}
+
+
+HRESULT DsSourcePin::GetMediaTypeMpegAudio(int iPosition, AM_MEDIA_TYPE *pmt)
{
HRESULT hr;
+ switch (iPosition)
+ {
+ /* case 0: {
+ ZeroMemory(pmt,sizeof(*pmt));
+ pmt->lSampleSize = 1;
+ pmt->bFixedSizeSamples = TRUE;
+ pmt->majortype=MEDIATYPE_Audio;
+ MPEG1WAVEFORMAT wfe;
+ ZeroMemory(&wfe,sizeof(wfe));
+ wfe.wfx.cbSize=22;
+ wfe.wfx.nSamplesPerSec=48000;
+ wfe.wfx.nChannels=2;
+ wfe.wfx.nAvgBytesPerSec=32000;
+ wfe.wfx.nBlockAlign=768;
+ wfe.wfx.wFormatTag=WAVE_FORMAT_MPEG;
+ wfe.wfx.wBitsPerSample=0;
+ wfe.fwHeadLayer=2;
+ wfe.dwHeadBitrate=256000;
+ wfe.fwHeadMode=ACM_MPEG_STEREO;
+ wfe.fwHeadModeExt=1;
+ wfe.wHeadEmphasis=1;
+ wfe.fwHeadFlags=ACM_MPEG_ID_MPEG1 |ACM_MPEG_ORIGINALHOME | ACM_MPEG_PROTECTIONBIT;
+ pmt->subtype=MEDIASUBTYPE_MPEG2_AUDIO;
+ pmt->formattype=FORMAT_WaveFormatEx;
+ pmt->cbFormat=sizeof(wfe);
+ pmt->pbFormat=(BYTE*)CoTaskMemAlloc(sizeof(wfe));
+ memcpy(pmt->pbFormat,&wfe,sizeof(wfe));
+ pmt->lSampleSize=0;
+ hr=S_OK;
+ } break;*/
+ case 0:
+ {
+ ZeroMemory(pmt,sizeof(*pmt));
+ pmt->lSampleSize = 1;
+ pmt->bFixedSizeSamples = TRUE;
+ pmt->majortype = MEDIATYPE_Audio;
+ WAVEFORMATEX wfe;
+ ZeroMemory(&wfe,sizeof(wfe));
+ wfe.cbSize = 22;
+ wfe.nSamplesPerSec = 48000;
+ wfe.nChannels = 2;
+ wfe.nAvgBytesPerSec = 32000;
+ wfe.nBlockAlign = 768;
+ wfe.wFormatTag = WAVE_FORMAT_UNKNOWN;
+ wfe.wBitsPerSample = 0;
+ pmt->subtype = MEDIASUBTYPE_MPEG2_AUDIO;
+ pmt->formattype = FORMAT_WaveFormatEx;
+ pmt->cbFormat = sizeof(wfe);
+ pmt->pbFormat = (BYTE*)CoTaskMemAlloc(sizeof(wfe));
+ memcpy(pmt->pbFormat,&wfe,sizeof(wfe));
+ pmt->lSampleSize=0;
+ hr=S_OK;
+ } break;
+ case 1: {
+ ZeroMemory(pmt,sizeof(*pmt));
+ pmt->lSampleSize = 1;
+ pmt->bFixedSizeSamples = TRUE;
+ pmt->majortype = MEDIATYPE_Audio;
+ MPEG1WAVEFORMAT wfe;
+ ZeroMemory(&wfe,sizeof(wfe));
+ wfe.wfx.cbSize = 22;
+ wfe.wfx.nSamplesPerSec = 48000;
+ wfe.wfx.nChannels = 2;
+ wfe.wfx.nAvgBytesPerSec = 32000;
+ wfe.wfx.nBlockAlign = 768;
+ wfe.wfx.wFormatTag = WAVE_FORMAT_UNKNOWN;
+ wfe.wfx.wBitsPerSample = 0;
+ /* wfe.fwHeadLayer=2;
+ wfe.dwHeadBitrate=256000;
+ wfe.fwHeadMode=ACM_MPEG_STEREO;
+ wfe.fwHeadModeExt=1;
+ wfe.wHeadEmphasis=1;
+ wfe.fwHeadFlags=ACM_MPEG_ID_MPEG1 |ACM_MPEG_ORIGINALHOME | ACM_MPEG_PROTECTIONBIT;*/
+ pmt->subtype=MEDIASUBTYPE_MPEG1Payload;
+ pmt->formattype=FORMAT_WaveFormatEx;
+ pmt->cbFormat=sizeof(wfe);
+ pmt->pbFormat=(BYTE*)CoTaskMemAlloc(sizeof(wfe));
+ memcpy(pmt->pbFormat,&wfe,sizeof(wfe));
+ pmt->lSampleSize=0;
+ hr=S_OK;
+ } break;
+ default: {
+ hr=VFW_S_NO_MORE_ITEMS;
+ }break;
+ };
+ return hr ;
+}
- if (isaudiopin){
- if (iPosition==0) {
- ZeroMemory(pmt,sizeof(*pmt));
- pmt->lSampleSize = 1;
- pmt->bFixedSizeSamples = TRUE;
- pmt->majortype=MEDIATYPE_Audio;
- MPEG1WAVEFORMAT wfe;
- ZeroMemory(&wfe,sizeof(wfe));
- wfe.wfx.cbSize=22;
- wfe.wfx.nSamplesPerSec=48000;
- wfe.wfx.nChannels=2;
- wfe.wfx.nAvgBytesPerSec=32000;
- wfe.wfx.nBlockAlign=768;
- wfe.wfx.wFormatTag=WAVE_FORMAT_MPEG;
- wfe.wfx.wBitsPerSample=0;
- wfe.fwHeadLayer=2;
- wfe.dwHeadBitrate=256000;
- wfe.fwHeadMode=ACM_MPEG_STEREO;
- wfe.fwHeadModeExt=1;
- wfe.wHeadEmphasis=1;
- wfe.fwHeadFlags=ACM_MPEG_ID_MPEG1 |ACM_MPEG_ORIGINALHOME | ACM_MPEG_PROTECTIONBIT;
- pmt->subtype=MEDIASUBTYPE_MPEG2_AUDIO;
- pmt->formattype=FORMAT_WaveFormatEx;
- pmt->cbFormat=sizeof(wfe);
- pmt->pbFormat=(BYTE*)CoTaskMemAlloc(sizeof(wfe));
+HRESULT DsSourcePin::GetMediaTypeAc3(int iPosition, AM_MEDIA_TYPE *pmt)
+{
+ HRESULT hr;
+ switch (iPosition)
+ {
+ case 0:
+ { //AC3 for future use
+ ZeroMemory(pmt,sizeof(*pmt));
+ pmt->lSampleSize = 1;
+ pmt->bFixedSizeSamples = TRUE;
+ pmt->majortype = MEDIATYPE_Audio;
+ WAVEFORMATEX wfe;
+ ZeroMemory(&wfe,sizeof(wfe));
+ wfe.cbSize = 22;
+ wfe.nSamplesPerSec = 48000;
+ wfe.nChannels = 2;
+ wfe.nAvgBytesPerSec = 32000;
+ wfe.nBlockAlign = 768;
+ wfe.wFormatTag = WAVE_FORMAT_UNKNOWN;
+ wfe.wBitsPerSample = 0;
+ pmt->subtype = MEDIASUBTYPE_DOLBY_AC3;
+ // pmt->subtype = MEDIASUBTYPE_DOLBY_AC3_SPDIF;
+ pmt->formattype = FORMAT_WaveFormatEx;
+ pmt->cbFormat = sizeof(wfe);
+ pmt->pbFormat = (BYTE*)CoTaskMemAlloc(sizeof(wfe));
memcpy(pmt->pbFormat,&wfe,sizeof(wfe));
- pmt->lSampleSize=0;
- hr=S_OK;
-
+ pmt->lSampleSize = 0;
+ hr = S_OK;
+ } break;
+ default: {
+ hr=VFW_S_NO_MORE_ITEMS;
+ }break;
+ };
+ return hr ;
+}
- } else {
- hr=VFW_S_NO_MORE_ITEMS ;
- }
- } else {
- if (iPosition == 0) {
+HRESULT DsSourcePin::GetMediaTypeMpegVideo(int iPosition, AM_MEDIA_TYPE *pmt)
+{
+ HRESULT hr;
+ if (iPosition == 0)
+ {
ZeroMemory(pmt,sizeof(*pmt));
pmt->lSampleSize = 1;
pmt->bFixedSizeSamples = TRUE;
- pmt->majortype=MEDIATYPE_Video;
- hr=S_OK;
- pmt->subtype=MEDIASUBTYPE_MPEG2_VIDEO;
- pmt->formattype=FORMAT_MPEG2Video;
-
- MPEG2VIDEOINFO hdr;
- ZeroMemory(&hdr,sizeof(hdr));
- hdr.dwProfile=AM_MPEG2Profile_Main;
- hdr.dwLevel=AM_MPEG2Level_Main;
- hdr.hdr.bmiHeader.biSize = sizeof(hdr.hdr.bmiHeader);
- hdr.hdr.bmiHeader.biWidth = 720;
- hdr.hdr.bmiHeader.biHeight = 568;
- pmt->cbFormat=sizeof(hdr);
- pmt->pbFormat=(BYTE*)CoTaskMemAlloc(sizeof(hdr));
+ pmt->majortype = MEDIATYPE_Video;
+ hr = S_OK;
+ pmt->subtype = MEDIASUBTYPE_MPEG2_VIDEO;
+ pmt->formattype = FORMAT_MPEG2Video;
+ MPEG2VIDEOINFO hdr;
+ ZeroMemory(&hdr,sizeof(hdr));
+ hdr.dwProfile = AM_MPEG2Profile_Main;
+ hdr.dwLevel = AM_MPEG2Level_Main;
+ hdr.hdr.bmiHeader.biSize = sizeof(hdr.hdr.bmiHeader);
+ hdr.hdr.bmiHeader.biWidth = 720;
+ hdr.hdr.bmiHeader.biHeight = 568;
+ pmt->cbFormat = sizeof(hdr);
+ pmt->pbFormat = (BYTE*)CoTaskMemAlloc(sizeof(hdr));
memcpy(pmt->pbFormat,&hdr,sizeof(hdr));
-
- } else {
+ } else {
hr=VFW_S_NO_MORE_ITEMS;
- }
}
- return hr ;
+
+ return hr;
+}
+
+HRESULT DsSourcePin::GetMediaType(int iPosition, AM_MEDIA_TYPE *pmt)
+{
+
+ switch (pinmode){
+ case MPTYPE_MPEG_AUDIO:
+ return GetMediaTypeMpegAudio(iPosition,pmt);
+ break;
+ case MPTYPE_VIDEO:
+ return GetMediaTypeMpegVideo(iPosition,pmt);
+ break;
+ case MPTYPE_AC3_PRE13:
+ case MPTYPE_AC3:
+ return GetMediaTypeAc3(iPosition,pmt);
+ };
+}
+
+void DsSourcePin::SetPinMode(int mode) {
+ pinmode=mode;
+ AM_MEDIA_TYPE amtype;
+ ReleaseMType(&medtype);
+ GetMediaType(0,&medtype);
}
HRESULT DsSourcePin::Inactive() {
// No description
HRESULT DsSourcePin::CheckMediaType(const AM_MEDIA_TYPE *pmt)
{
- HRESULT res;
-
- if (isaudiopin) {
- bool subtype=false;
-#if 0 /* For future demands ac3 */
- subtype=pmt->subtype==(MEDIASUBTYPE_DOLBY_AC3);
-#endif
+ HRESULT res=S_FALSE;
+ bool subtype=false;
+ switch (pinmode) {
+ case MPTYPE_MPEG_AUDIO:
subtype=(pmt->subtype==(MEDIASUBTYPE_MPEG2_AUDIO));
- if (pmt->majortype==MEDIATYPE_Audio && subtype) {
- res = S_OK ;
- } else {
- res = S_FALSE ;
+ subtype=(pmt->subtype==MEDIASUBTYPE_MPEG1Payload) || subtype;
+ if (pmt->majortype==MEDIATYPE_Audio && subtype)
+ {
+ res = S_OK ;
+ }
+ else
+ {
+ res = S_FALSE ;
+ }
+ break;
+ case MPTYPE_VIDEO:
+ if (pmt->majortype==MEDIATYPE_Video &&
+ pmt-> subtype==MEDIASUBTYPE_MPEG2_VIDEO)
+ {
+ res = S_OK ;
}
- } else {
- if (pmt->majortype==MEDIATYPE_Video &&
- pmt-> subtype==MEDIASUBTYPE_MPEG2_VIDEO) {
- res = S_OK ;
- } else {
+ else
+ {
res = S_FALSE ;
}
- }
+ break;
+ case MPTYPE_AC3_PRE13:
+ case MPTYPE_AC3:
+ subtype=pmt->subtype==(MEDIASUBTYPE_DOLBY_AC3);
+ subtype=pmt->subtype==(MEDIASUBTYPE_DOLBY_AC3_SPDIF) || subtype;
+ if (pmt->majortype==MEDIATYPE_Audio && subtype)
+ {
+ res = S_OK ;
+ }
+ else
+ {
+ res = S_FALSE ;
+ }
+ break;
+ };
return res;
}
if (all_pp->cBuffers*all_pp->cbBuffer < 300*64*1024)
{
//all_pp->cBuffers = 300;//old
- all_pp->cBuffers = 10;
+ all_pp->cBuffers = 50;
all_pp->cbBuffer = 64*1024;
}
} else {
if (all_pp->cBuffers*all_pp->cbBuffer < 300*64*1024)
{
//all_pp->cBuffers = 300;//old
- all_pp->cBuffers = 30;
+ all_pp->cBuffers = 300;
all_pp->cbBuffer = 64*1024;
}
}
return S_OK;
}
-
#include <winsock2.h>
-#include <dshow.h>
+#include <dshow.h>
class DsSourcePin: public IPin {
public:
- DsSourcePin(DsSourceFilter *pFilter,HRESULT *phr,LPCWSTR pName,bool audio);
- ~DsSourcePin();
- BOOL IsConnected() {return (connected!=NULL);};
- HRESULT getCurrentMediaSample(IMediaSample**ms);
- HRESULT deliver(IMediaSample * ms);
-
- virtual HRESULT DecideBufferSize(IMemAllocator *pa,ALLOCATOR_PROPERTIES *all_pp);
-
- HRESULT Inactive();
- HRESULT Active();
- HRESULT Run(REFERENCE_TIME reftime);
- /*IPin*/
-
- virtual HRESULT STDMETHODCALLTYPE Connect(IPin *pinempf,const AM_MEDIA_TYPE *mtype);
- virtual HRESULT STDMETHODCALLTYPE ReceiveConnection(IPin *connect,const AM_MEDIA_TYPE *mtype);
- virtual HRESULT STDMETHODCALLTYPE Disconnect();
- virtual HRESULT STDMETHODCALLTYPE ConnectedTo(IPin **pin);
- virtual HRESULT STDMETHODCALLTYPE ConnectionMediaType(AM_MEDIA_TYPE *mtype);
- virtual HRESULT STDMETHODCALLTYPE QueryPinInfo(PIN_INFO *info);
- virtual HRESULT STDMETHODCALLTYPE QueryDirection(PIN_DIRECTION *dir);
- virtual HRESULT STDMETHODCALLTYPE QueryId(LPWSTR *id);
- virtual HRESULT STDMETHODCALLTYPE QueryAccept(const AM_MEDIA_TYPE *mtype);
- virtual HRESULT STDMETHODCALLTYPE EnumMediaTypes(IEnumMediaTypes **enuma);
- virtual HRESULT STDMETHODCALLTYPE QueryInternalConnections(IPin **pin,ULONG *numpin);
- virtual HRESULT STDMETHODCALLTYPE EndOfStream();
- virtual HRESULT STDMETHODCALLTYPE NewSegment(REFERENCE_TIME start,REFERENCE_TIME stop,double rate);
- /* IUnknown */
- virtual HRESULT STDMETHODCALLTYPE QueryInterface(REFIID id,void ** object);
- virtual ULONG STDMETHODCALLTYPE AddRef();
+ DsSourcePin(DsSourceFilter *pFilter,HRESULT *phr,LPCWSTR pName,bool audio);
+ ~DsSourcePin();
+ BOOL IsConnected() {return (connected!=NULL);};
+ HRESULT getCurrentMediaSample(IMediaSample**ms);
+ HRESULT deliver(IMediaSample * ms);
+ void SetMsToMt(IMediaSample *ms);
+ bool supportsAc3();
+
+ virtual HRESULT DecideBufferSize(IMemAllocator *pa,ALLOCATOR_PROPERTIES *all_pp);
+
+ HRESULT Inactive();
+ HRESULT Active();
+ HRESULT Run(REFERENCE_TIME reftime);
+ /*IPin*/
+
+ virtual HRESULT STDMETHODCALLTYPE Connect(IPin *pinempf,const AM_MEDIA_TYPE *mtype);
+ virtual HRESULT STDMETHODCALLTYPE ReceiveConnection(IPin *connect,const AM_MEDIA_TYPE *mtype);
+ virtual HRESULT STDMETHODCALLTYPE Disconnect();
+ virtual HRESULT STDMETHODCALLTYPE ConnectedTo(IPin **pin);
+ virtual HRESULT STDMETHODCALLTYPE ConnectionMediaType(AM_MEDIA_TYPE *mtype);
+ virtual HRESULT STDMETHODCALLTYPE QueryPinInfo(PIN_INFO *info);
+ virtual HRESULT STDMETHODCALLTYPE QueryDirection(PIN_DIRECTION *dir);
+ virtual HRESULT STDMETHODCALLTYPE QueryId(LPWSTR *id);
+ virtual HRESULT STDMETHODCALLTYPE QueryAccept(const AM_MEDIA_TYPE *mtype);
+ virtual HRESULT STDMETHODCALLTYPE EnumMediaTypes(IEnumMediaTypes **enuma);
+ virtual HRESULT STDMETHODCALLTYPE QueryInternalConnections(IPin **pin,ULONG *numpin);
+ virtual HRESULT STDMETHODCALLTYPE EndOfStream();
+ virtual HRESULT STDMETHODCALLTYPE NewSegment(REFERENCE_TIME start,REFERENCE_TIME stop,double rate);
+ /* IUnknown */
+ virtual HRESULT STDMETHODCALLTYPE QueryInterface(REFIID id,void ** object);
+ virtual ULONG STDMETHODCALLTYPE AddRef();
virtual ULONG STDMETHODCALLTYPE Release();
- virtual HRESULT STDMETHODCALLTYPE BeginFlush(){return E_UNEXPECTED;};
- virtual HRESULT STDMETHODCALLTYPE EndFlush(){return E_UNEXPECTED;};
- virtual HRESULT GetMediaType(int iPosition, AM_MEDIA_TYPE *pmt);
+ virtual HRESULT STDMETHODCALLTYPE BeginFlush(){return E_UNEXPECTED;};
+ virtual HRESULT STDMETHODCALLTYPE EndFlush(){return E_UNEXPECTED;};
+ virtual HRESULT GetMediaType(int iPosition, AM_MEDIA_TYPE *pmt);
protected:
- virtual HRESULT CheckMediaType(const AM_MEDIA_TYPE *pmt);
+ virtual HRESULT CheckMediaType(const AM_MEDIA_TYPE *pmt);
+ HRESULT GetMediaTypeMpegAudio(int iPosition, AM_MEDIA_TYPE *pmt);
+ HRESULT GetMediaTypeAc3(int iPosition, AM_MEDIA_TYPE *pmt);
+ HRESULT GetMediaTypeMpegVideo(int iPosition, AM_MEDIA_TYPE *pmt);
+
+ void SetPinMode(int mode);
+ int pinmode;
+ bool isaudiopin;
+ DsSourceFilter *m_pFilter;
+ IPin* connected;
+ IMemInputPin* connectedinput;
+ AM_MEDIA_TYPE medtype;
+ IMemAllocator* allocator;
- bool isaudiopin;
- DsSourceFilter *m_pFilter;
- IPin* connected;
- IMemInputPin* connectedinput;
- AM_MEDIA_TYPE medtype;
- IMemAllocator* allocator;
-
};
}
}
-bool* Player::getDemuxerAudioChannels()
+bool* Player::getDemuxerMpegAudioChannels()
{
return demuxer->getmpAudioChannels();
}
+bool* Player::getDemuxerAc3AudioChannels()
+{
+ return demuxer->getac3AudioChannels();
+}
+
int Player::getCurrentAudioChannel()
{
return demuxer->getselAudioChannel();
void Player::setAudioChannel(int newChannel)
{
- demuxer->setmpAudioChannel(newChannel);
+ demuxer->setAudioChannel(newChannel);
}
// ----------------------------------- Externally called events
ULONG getCurrentFrameNum();
ULONG getLengthFrames();
UCHAR getIScanRate() { return ifactor; }
- bool* getDemuxerAudioChannels();
+ bool* getDemuxerMpegAudioChannels();
+ bool* getDemuxerAc3AudioChannels();
int getCurrentAudioChannel();
void call(void*); // for callback interface
if (draintarget) draintarget->ResetTimeOffsets();
}
-int Stream::put(const UCHAR* inbuf, int len)
+int Stream::put(const UCHAR* inbuf, int len, UCHAR type)
{
int ret = 0;
if (!draintarget) return 0;
MediaPacket newPacket;
newPacket.length = len;
newPacket.pos_buffer = 0;
+ newPacket.type = type;
#ifdef WIN32
newPacket.synched=false;
newPacket.disconti=false;
int init(DrainTarget* tdt, int bufsize);
void shutdown();
void flush();
- int put(const UCHAR* inbuf, int len);
+ int put(const UCHAR* inbuf, int len, UCHAR type);
bool drain();
private:
#include "vaudioselector.h"
-VAudioSelector::VAudioSelector(void* tparent, bool* availableAudioChannels, int currentAudioChannel, RecInfo* recInfo)
+VAudioSelector::VAudioSelector(void* tparent,bool* availableMpegAudioChannels,
+ bool* availableAc3AudioChannels,
+ int currentAudioChannel, RecInfo* recInfo)
{
Log::getInstance()->log("VAS", Log::DEBUG, "%i", currentAudioChannel);
for (i = 0; i < PES_AUDIO_MAXCHANNELS; i++)
{
- if (availableAudioChannels[i])
+ if (availableMpegAudioChannels[i])
{
AudioChannel* ac = new AudioChannel();
ac->type = 0;
acl.push_back(ac);
}
}
+ if (availableAc3AudioChannels != NULL)
+ {
+ for (i = 0; i < PES_AUDIO_AC3_MAXCHANNELS; i++)
+ {
+ if (availableAc3AudioChannels[i])
+ {
+ AudioChannel* ac = new AudioChannel();
+ ac->type = 1;//ac3
+ ac->name = NULL;
+ ac->pestype = PES_AUDIO_AC3_START + i;
+ acl.push_back(ac);
+ }
+ }
+ }
unsigned char numchan_recinfo = recInfo->numComponents;
unsigned char numchan_siz = acl.size();
}
else
{
- SNPRINTF(tempString, 299, "%lu", (ULONG)(ac->pestype - PES_AUDIO_START));
+ if (ac->type==0)
+ {
+ SNPRINTF(tempString, 299, "%lu", (ULONG)(ac->pestype - PES_AUDIO_START));
+ }
+ else if (ac->type==1)
+ {
+ SNPRINTF(tempString, 299, "ac3 %lu", (ULONG)(ac->pestype - PES_AUDIO_AC3_START));
+ }
+ else
+ {
+ SNPRINTF(tempString, 299, "unknown");
+ }
sl.addOption(tempString, (ULONG)ac, (ac->pestype == currentAudioChannel));
}
}
#define PES_AUDIO_START 0xc0
#define PES_AUDIO_MAXCHANNELS 0x20
+#define PES_AUDIO_AC3_MAXCHANNELS 0x08
+#define PES_AUDIO_AC3_START 0x80
class AudioChannel
{
class VAudioSelector : public View
{
public:
- VAudioSelector(void* parent, bool* availableAudioChannels, int currentAudioChannel, RecInfo* recInfo);
+ VAudioSelector(void* parent, bool* availableMpegAudioChannels,
+ bool* availableAc3AudioChannels, int currentAudioChannel, RecInfo* recInfo);
~VAudioSelector();
int handleCommand(int command);
- void processMessage(Message* m);
+ void processMessage(Message* m);
void draw();
private:
};
#endif
+
sourcefilter=NULL;
allocatorvmr=NULL;
cr_time=0;
+ lastaudiomode=MPTYPE_MPEG_AUDIO;
+ //lastaudiomode=MPTYPE_AC3;
dsvmrsurfnotify=NULL;
filtermutex=CreateMutex(NULL,FALSE,NULL);
offsetnotset=true;
WaitForSingleObject(filtermutex,INFINITE);
if (hres=CoCreateInstance(CLSID_FilterGraph,NULL,CLSCTX_INPROC_SERVER,
IID_IGraphBuilder,(void**)&dsgraphbuilder)!=S_OK) {
- ReleaseMutex(filtermutex);
+ ReleaseMutex(filtermutex);
return 0;
}
#ifdef DS_DEBUG
#endif
//This is just a try to see if building the graph works
// dsgraphbuilder->RenderFile(L"D:\\Projekte\\VTP Client\\test.mpa" ,NULL);
-
+
firstsynched=false;
+ lastaudiomode=MPTYPE_MPEG_AUDIO;
+ //lastaudiomode=MPTYPE_AC3;
sourcefilter=new DsSourceFilter(); //Creating our Source filter for pushing Data
// to DirectShow
if (hres=dsgraphbuilder->AddFilter(sourcefilter,L"Vomp Win Source Filter")!=S_OK) {
Log::getInstance()->log("VideoWin", Log::WARN , "Failed adding Vomp Source Filter!");
- ReleaseMutex(filtermutex);
+ ReleaseMutex(filtermutex);
CleanupDS();
return 0;
}
//if (audioon) {
if (hres=dsgraphbuilder->Render((IPin*)sourcefilter->GetAudioPin()/*audio*/)!=S_OK) {
Log::getInstance()->log("VideoWin", Log::WARN , "Failed rendering audio!");
- ReleaseMutex(filtermutex);
+ ReleaseMutex(filtermutex);
CleanupDS();
return 0;
}
if (hres=CoCreateInstance(CLSID_VideoMixingRenderer9,0,
CLSCTX_INPROC_SERVER,IID_IBaseFilter,(void**) &dsvmrrenderer)!=S_OK) {
Log::getInstance()->log("VideoWin", Log::WARN ,"Failed creating VMR9 renderer!");
- ReleaseMutex(filtermutex);
+ ReleaseMutex(filtermutex);
CleanupDS();
-
+
}
/*VMR 9 stuff**/
if (hres=dsgraphbuilder->AddFilter(dsvmrrenderer,L"VMR9")!=S_OK) {
- ReleaseMutex(filtermutex);
+ ReleaseMutex(filtermutex);
CleanupDS();
Log::getInstance()->log("VideoWin", Log::WARN ,"Failed adding VMR9 renderer!");
-
+
return 0;
}
IVMRFilterConfig9* vmrfilconfig;
if (dsvmrrenderer->QueryInterface(IID_IVMRFilterConfig9,(void**)&vmrfilconfig)!=S_OK) {
ReleaseMutex(filtermutex);
- CleanupDS();
+ CleanupDS();
Log::getInstance()->log("VideoWin", Log::WARN ,"Failed getting VMR9 Filterconfig interface!");
return 0;
}
if (dsvmrrenderer->QueryInterface(IID_IVMRSurfaceAllocatorNotify9,(void**)& dsvmrsurfnotify)!=S_OK) {
ReleaseMutex(filtermutex);
- CleanupDS();
+ CleanupDS();
Log::getInstance()->log("VideoWin", Log::WARN ,"Failed getting VMR9 Surface Allocator interface!");
-
+
return 0;
}
allocatorvmr=new DsAllocator();
dsvmrsurfnotify->AdviseSurfaceAllocator(NULL,allocatorvmr);
allocatorvmr->AdviseNotify(dsvmrsurfnotify);
-
+
if (dsgraphbuilder->QueryInterface(IID_IFilterGraph2,(void**)&fg2)!=S_OK) {
Log::getInstance()->log("VideoWin", Log::WARN , "Failed querying for FilterGraph2 Interface!");
ReleaseMutex(filtermutex);
- CleanupDS();
+ CleanupDS();
return 0;
}
if (hres=fg2->RenderEx((IPin*)sourcefilter->GetVideoPin()/*video*/,
AM_RENDEREX_RENDERTOEXISTINGRENDERERS,NULL)!=S_OK) {
Log::getInstance()->log("VideoWin", Log::WARN , "Failed rendering Video!");
- fg2->Release();
- ReleaseMutex(filtermutex);
- CleanupDS();
+ fg2->Release();
+ ReleaseMutex(filtermutex);
+ CleanupDS();
return 0;
}
- fg2->Release();
+ fg2->Release();
}
#endif
if (hres=CoCreateInstance(CLSID_SystemClock,NULL,CLSCTX_INPROC_SERVER,
HRESULT hresdeb=dsmediafilter->SetSyncSource(dsrefclock);
dsgraphbuilder->QueryInterface(IID_IMediaControl,(void **) &dsmediacontrol);
- dsgraphbuilder->QueryInterface(IID_IBasicAudio,(void **) &dsbasicaudio);
+ dsgraphbuilder->QueryInterface(IID_IBasicAudio,(void **) &dsbasicaudio);
dsinited=true;
//MILLISLEEP(100);
int VideoWin::EnterIframePlayback()
{
- if (!initted) return 0;
- CleanupDS();
- //So this is the real code, this prevents the feeder from calling noexisting objects!
+ if (!initted) return 0;
+ CleanupDS();
+ //So this is the real code, this prevents the feeder from calling noexisting objects!
WaitForSingleObject(filtermutex,INFINITE);
- iframemode=true;//enter iframe mode
- //Build filter graph
- HRESULT hres;
- if (hres=CoCreateInstance(CLSID_FilterGraph,NULL,CLSCTX_INPROC_SERVER,
- IID_IGraphBuilder,(void**)&dsgraphbuilder)!=S_OK) {
- ReleaseMutex(filtermutex);
- return 0;
- }
+ iframemode=true;//enter iframe mode
+ //Build filter graph
+ HRESULT hres;
+ if (hres=CoCreateInstance(CLSID_FilterGraph,NULL,CLSCTX_INPROC_SERVER,
+ IID_IGraphBuilder,(void**)&dsgraphbuilder)!=S_OK) {
+ ReleaseMutex(filtermutex);
+ return 0;
+ }
#ifdef DS_DEBUG
- AddToRot(dsgraphbuilder,&graphidentifier);
+ AddToRot(dsgraphbuilder,&graphidentifier);
#endif
-
+
//firstsynched=false;
sourcefilter=new DsSourceFilter(); //Creating our Source filter for pushing Data
// to DirectShow
if (hres=dsgraphbuilder->AddFilter(sourcefilter,L"Vomp Win Source Filter")!=S_OK) {
Log::getInstance()->log("VideoWin", Log::WARN , "Failed adding Vomp Source Filter!");
- ReleaseMutex(filtermutex);
+ ReleaseMutex(filtermutex);
CleanupDS();
return 0;
}
CLSCTX_INPROC_SERVER,IID_IBaseFilter,(void**) &dsvmrrenderer)!=S_OK) {
Log::getInstance()->log("VideoWin", Log::WARN ,"Failed creating VMR9 renderer!");
ReleaseMutex(filtermutex);
- CleanupDS();
- return 0;
+ CleanupDS();
+ return 0;
}
/*VMR 9 stuff**/
if (hres=dsgraphbuilder->AddFilter(dsvmrrenderer,L"VMR9")!=S_OK) {
Log::getInstance()->log("VideoWin", Log::WARN ,"Failed adding VMR9 renderer!");
ReleaseMutex(filtermutex);
- CleanupDS();
+ CleanupDS();
return 0;
}
IVMRFilterConfig9* vmrfilconfig;
if (dsvmrrenderer->QueryInterface(IID_IVMRFilterConfig9,(void**)&vmrfilconfig)!=S_OK) {
ReleaseMutex(filtermutex);
- CleanupDS();
+ CleanupDS();
Log::getInstance()->log("VideoWin", Log::WARN ,"Failed getting VMR9 Filterconfig interface!");
-
+
return 0;
}
vmrfilconfig->SetRenderingMode(VMR9Mode_Renderless);
vmrfilconfig->Release();
- if (dsvmrrenderer->QueryInterface(IID_IVMRSurfaceAllocatorNotify9,(void**)& dsvmrsurfnotify)!=S_OK) {
+ if (dsvmrrenderer->QueryInterface(IID_IVMRSurfaceAllocatorNotify9,(void**)& dsvmrsurfnotify)!=S_OK) {
Log::getInstance()->log("VideoWin", Log::WARN ,"Failed getting VMR9 Surface Allocator interface!");
ReleaseMutex(filtermutex);
- CleanupDS();
+ CleanupDS();
return 0;
}
allocatorvmr=new DsAllocator();
dsvmrsurfnotify->AdviseSurfaceAllocator(NULL,allocatorvmr);
allocatorvmr->AdviseNotify(dsvmrsurfnotify);
-
+
/*VMR 9 stuff end */
IFilterGraph2*fg2=NULL;
if (dsgraphbuilder->QueryInterface(IID_IFilterGraph2,(void**)&fg2)!=S_OK) {
Log::getInstance()->log("VideoWin", Log::WARN , "Failed querying for FilterGraph2 Interface!");
ReleaseMutex(filtermutex);
- CleanupDS();
+ CleanupDS();
return 0;
}
if (hres=fg2->RenderEx((IPin*)sourcefilter->GetVideoPin()/*video*/,
AM_RENDEREX_RENDERTOEXISTINGRENDERERS,NULL)!=S_OK) {
Log::getInstance()->log("VideoWin", Log::WARN , "Failed rendering Video!");
- fg2->Release();
- ReleaseMutex(filtermutex);
+ fg2->Release();
+ ReleaseMutex(filtermutex);
CleanupDS();
return 0;
}
- fg2->Release();
+ fg2->Release();
}
#endif
/* if (hres=CoCreateInstance(CLSID_SystemClock,NULL,CLSCTX_INPROC_SERVER,
dsmediafilter->SetSyncSource(/*dsrefclock*/NULL); //Run as fast as you can!
dsgraphbuilder->QueryInterface(IID_IMediaControl,(void **) &dsmediacontrol);
- dsgraphbuilder->QueryInterface(IID_IBasicAudio,(void **) &dsbasicaudio);
+ dsgraphbuilder->QueryInterface(IID_IBasicAudio,(void **) &dsbasicaudio);
dsinited=true;
-
+
dsmediacontrol->Run();
ReleaseMutex(filtermutex);
int VideoWin::reset()
{
if (!initted) return 0;
-
+
return 1;
}
int VideoWin::pause()
{
if (!initted) return 0;
-
+
return 1;
}
int VideoWin::unFastForward()
{
if (!initted) return 0;
-
+
return 1;
}
ULLONG VideoWin::getCurrentTimestamp()
{
- REFERENCE_TIME startoffset;
- REFERENCE_TIME ncr_time;
+ REFERENCE_TIME startoffset;
+ REFERENCE_TIME ncr_time;
if (iframemode) return 0; //Not in iframe mode!
if (!dsrefclock || !sourcefilter) return 0;
- FILTER_STATE state;
- sourcefilter->GetState(10,&state);
+ FILTER_STATE state;
+ sourcefilter->GetState(10,&state);
- if (state==State_Running) dsrefclock->GetTime(&cr_time);
- ncr_time=cr_time;
+ if (state==State_Running) dsrefclock->GetTime(&cr_time);
+ ncr_time=cr_time;
startoffset=sourcefilter->getStartOffset();
- ncr_time-=startoffset;
- ncr_time-=lastreftimeRT;
+ ncr_time-=startoffset;
+ ncr_time-=lastreftimeRT;
/* ULLONG result=frameNumberToTimecode(
VDR::getInstance()->frameNumberFromPosition(lastreftimeBYTE));*/
- ULLONG result=lastreftimePTS;
- result+=(ULLONG)(ncr_time/10000LL*90LL);
+ ULLONG result=lastreftimePTS;
+ result+=(ULLONG)(ncr_time/10000LL*90LL);
return result;
}
cur_video_media_sample=NULL;
}
if (dsbasicaudio) {
- dsbasicaudio->Release();
- dsbasicaudio=NULL;
+ dsbasicaudio->Release();
+ dsbasicaudio=NULL;
}
if (dsvmrsurfnotify) {
dsvmrsurfnotify->Release();
#ifdef DS_DEBUG
RemoveFromRot(graphidentifier);
#endif
- dsgraphbuilder->Release();
+ dsgraphbuilder->Release();
dsgraphbuilder=NULL;
-
+
sourcefilter=NULL; //The Graph Builder destroys our SourceFilter
}
ReleaseMutex(filtermutex);
UINT *samplepos)
{
/*First Check, if we have an audio sample*/
- if (!isdsinited()) return 0;
+ if (!isdsinited()) return 0;
#ifdef DO_VIDEO
- if (!videoon) {
- *samplepos+=packet.length;
+ if (!videoon) {
+ *samplepos+=packet.length;
MILLISLEEP(0); //yet not implemented//bad idea
return packet.length;
- }
+ }
/*First Check, if we have an audio sample*/
if (iframemode) {
- samplepos=0;
- MILLISLEEP(10);
- return 0; //Not in iframe mode!
+ samplepos=0;
+ MILLISLEEP(10);
+ return 0; //Not in iframe mode!
}
IMediaSample* ms=NULL;
REFERENCE_TIME reftime1=0;
DeliverVideoMediaSample();
}
-
-
/*Inspect PES-Header */
if (*samplepos==0) {//stripheader
UINT ms_length;
UINT ms_pos;
UINT haveToCopy;
-
+
if (!getCurrentVideoMediaSample(&ms) || ms==NULL) {// get the current sample
samplepos=0;
MILLISLEEP(10);
else ms->SetPreroll(FALSE);
/*Timecode handling*/
lastreftimeRT=reftime1;
- lastreftimePTS=packet.pts;
+ lastreftimePTS=packet.pts;
}else {
ms->SetSyncPoint(FALSE);
ms->SetTime(NULL,NULL);
ms->SetMediaTime(NULL, NULL);
- ms->SetPreroll(FALSE);
+ ms->SetPreroll(FALSE);
// ms->SetSyncPoint(TRUE);
}
}
lastrefvideotime=curreftime;
-
+
return startoffset;
}
void VideoWin::SetAudioVolume(long volume)
{
- if (dsbasicaudio) dsbasicaudio->put_Volume(volume);
+ if (dsbasicaudio) dsbasicaudio->put_Volume(volume);
}
void VideoWin::displayIFrame(const UCHAR* buffer, UINT length)
{
- if (!iframemode) EnterIframePlayback();
+ if (!iframemode) EnterIframePlayback();
- if (!isdsinited()) return ;
+ if (!isdsinited()) return ;
#ifdef DO_VIDEO
IMediaSample* ms=NULL;
REFERENCE_TIME reftime1=0;
DWORD ms_length;
ms->GetPointer(&ms_buf);
ms_length=ms->GetSize();
-
+
/*First Check, if we have an video sample*/
DWORD read_pos = 0, write_pos = 0;
DWORD pattern, packet_length;
read_pos++;
else
{
- headerstrip=buffer[read_pos+8]+9/*is this right*/;
+ headerstrip=buffer[read_pos+8]+9/*is this right*/;
packet_length = ((buffer[read_pos+4] << 8) | (buffer[read_pos+5])) + 6;
if (read_pos + packet_length > length)
read_pos = length;
else
{
- if ((write_pos+packet_length-headerstrip)>ms_length) {
- if (first) {ms->SetSyncPoint(TRUE);first=false;}
- else ms->SetSyncPoint(FALSE);
- ms->SetTime(NULL,NULL);
- ms->SetMediaTime(NULL, NULL);
- ms->SetActualDataLength(write_pos);
- DeliverVideoMediaSample();
-
- if (!getCurrentVideoMediaSample(&ms) || ms==NULL) {// get the current sample
- MILLISLEEP(10);
- return ;
- }
- write_pos=0;
- ms_length=ms->GetSize();
- ms->GetPointer(&ms_buf);
- }
- if (packet_length-headerstrip>0) {
- memcpy(ms_buf+write_pos, buffer+read_pos+headerstrip, packet_length-headerstrip);
- write_pos += packet_length-headerstrip;
- }
- read_pos += packet_length;
-
- pattern = (buffer[read_pos] << 16) | (buffer[read_pos+1] << 8)
+ if ((write_pos+packet_length-headerstrip)>ms_length) {
+ if (first) {
+ ms->SetSyncPoint(TRUE);
+ ms->SetDiscontinuity(TRUE);
+ first=false;
+ } else ms->SetSyncPoint(FALSE);
+ ms->SetTime(NULL,NULL);
+ ms->SetMediaTime(NULL, NULL);
+ ms->SetActualDataLength(write_pos);
+ DeliverVideoMediaSample();
+
+ if (!getCurrentVideoMediaSample(&ms) || ms==NULL) {// get the current sample
+ MILLISLEEP(10);
+ return ;
+ }
+ write_pos=0;
+ ms_length=ms->GetSize();
+ ms->GetPointer(&ms_buf);
+ }
+ if (packet_length-headerstrip>0) {
+ memcpy(ms_buf+write_pos, buffer+read_pos+headerstrip, packet_length-headerstrip);
+ write_pos += packet_length-headerstrip;
+ }
+ read_pos += packet_length;
+
+ pattern = (buffer[read_pos] << 16) | (buffer[read_pos+1] << 8)
| (buffer[read_pos+2]);
}
}
}
- if (first) {ms->SetSyncPoint(TRUE);first=false;}
+ if (first) {ms->SetSyncPoint(TRUE);first=false;}
else ms->SetSyncPoint(FALSE);
ms->SetTime(NULL,NULL);
ms->SetMediaTime(NULL, NULL);
#endif
}
+bool VideoWin::supportsAc3(){
+ if (sourcefilter != NULL) {
+ return sourcefilter->supportsAc3();
+ } else {
+ return false;
+ }
+}
+
+bool VideoWin::changeAType(int type,IMediaSample* ms){
+ if (sourcefilter!= NULL) {
+ lastaudiomode=type;
+ return sourcefilter->changeAType(type,ms);
+ }
+ else
+ {
+ return false;
+ }
+}
#ifdef DEV
int VideoWin::test()
virtual void PrepareMediaSample(const MediaPacketList&, UINT samplepos);
virtual UINT DeliverMediaSample(const UCHAR* buffer, UINT *samplepos);
UINT DeliverMediaPacket(MediaPacket packet, const UCHAR* buffer, UINT *samplepos);
+
+ virtual bool supportsAc3();
private:
MediaPacket mediapacket;
public:
unsigned int getPosy() {return videoposy;};
bool isVideoOn() {return videoon;};
bool isdsinited() {return dsinited;};
+ int lastAType() {return lastaudiomode;};
+ bool changeAType(int type,IMediaSample* ms);
#ifdef DEV
int test();
ULLONG lastreftimePTS;
unsigned int videoposx;
unsigned int videoposy;
+ int lastaudiomode;
#ifdef DS_DEBUG
DWORD graphidentifier;
#endif
#endif
-
void VVideoRec::doAudioSelector()
{
- bool* availableAudioChannels = player->getDemuxerAudioChannels();
+ bool* availableMpegAudioChannels = player->getDemuxerMpegAudioChannels();
+ bool* availableAc3AudioChannels = 0;
int currentAudioChannel = player->getCurrentAudioChannel();
+ if (Audio::getInstance()->supportsAc3())
+ {
+ availableAc3AudioChannels = player->getDemuxerAc3AudioChannels();
+ }
- vas = new VAudioSelector(this, availableAudioChannels, currentAudioChannel, myRec->recInfo);
+ vas = new VAudioSelector(this, availableMpegAudioChannels,availableAc3AudioChannels, currentAudioChannel, myRec->recInfo);
vas->setBackgroundColour(barBlue);
if (video->getFormat() == Video::PAL)
{