]> git.vomp.tv Git - vompclient.git/commitdiff
Ac3 for Windows
authorChris Tallon <chris@vomp.tv>
Sat, 10 Feb 2007 15:18:08 +0000 (15:18 +0000)
committerChris Tallon <chris@vomp.tv>
Sat, 10 Feb 2007 15:18:08 +0000 (15:18 +0000)
19 files changed:
audio.h
audiomvp.h
audiowin.cc
demuxer.cc
demuxer.h
draintarget.h
dssourcefilter.cc
dssourcefilter.h
dssourcepin.cc
dssourcepin.h
player.cc
player.h
stream.cc
stream.h
vaudioselector.cc
vaudioselector.h
videowin.cc
videowin.h
vvideorec.cc

diff --git a/audio.h b/audio.h
index 0baaeb2236c8d5d8d00e19602e4cc509b46e710f..3eba64269da8da8705252d1ad81e3fbca8276b3d 100644 (file)
--- a/audio.h
+++ b/audio.h
@@ -57,6 +57,7 @@ class Audio : public DrainTarget
     virtual int setVolume(int volume)=0;
     virtual int mute()=0;
     virtual int unMute()=0;
+    virtual bool supportsAc3()=0;
 
     int volumeUp();
     int volumeDown();
index 40694ab88fc2134286e486000d7b0068623c083d..fdd6f178dafdc66b8a6fe6fecbc2d6b567bf18b4 100644 (file)
@@ -87,6 +87,7 @@ class AudioMVP : public Audio
     int setVolume(int volume);
     int mute();
     int unMute();
+    bool supportsAc3() { return false; }
 
     //Writing Data to Audiodevice
     virtual void PrepareMediaSample(const MediaPacketList&, UINT samplepos);
index 7bae0bea2f35e19016fdd04eda5a3cbbe4091f5f..8de6da657b3518b73c1426cccb2b236e36cb5e80 100644 (file)
@@ -24,7 +24,6 @@
 
 
 
-
 AudioWin::AudioWin()
 {
   initted = 0;
@@ -39,7 +38,6 @@ AudioWin::AudioWin()
 AudioWin::~AudioWin()
 {
 
-
 }
 
 int AudioWin::init(UCHAR tstreamType)
@@ -113,7 +111,7 @@ int AudioWin::unPause()
 
 int AudioWin::reset()
 {
-  
+
   if (!initted){return 0;}
   return ((VideoWin*)Video::getInstance())->dsreset();
 }
@@ -168,11 +166,11 @@ UINT AudioWin::DeliverMediaPacket(MediaPacket packet,
 
   /*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;
@@ -181,7 +179,12 @@ UINT AudioWin::DeliverMediaPacket(MediaPacket packet,
   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();
   }
 
 
@@ -191,6 +194,7 @@ UINT AudioWin::DeliverMediaPacket(MediaPacket packet,
 */
   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
@@ -205,7 +209,7 @@ UINT AudioWin::DeliverMediaPacket(MediaPacket packet,
     } else {
       if (!firstsynched) {//
         *samplepos=packet.length;//if we have not processed at least one
-       
+
         return packet.length;//synched packet ignore it!
       }
     }
@@ -235,6 +239,7 @@ UINT AudioWin::DeliverMediaPacket(MediaPacket packet,
   }
   ms->GetPointer(&ms_buf);
 
+
   if (ms_pos==0) {//will only be changed on first packet
     if (packet.disconti) {
       ms->SetDiscontinuity(TRUE);
@@ -257,9 +262,14 @@ UINT AudioWin::DeliverMediaPacket(MediaPacket packet,
     //  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;
@@ -278,6 +288,11 @@ void AudioWin::ResetTimeOffsets() {
   return vw->ResetTimeOffsets();
 }
 
+bool AudioWin::supportsAc3(){
+    VideoWin *vw=(VideoWin*)Video::getInstance();
+    return vw->supportsAc3();
+}
+
 #ifdef DEV
 int AudioWin::test()
 {
@@ -286,4 +301,3 @@ int AudioWin::test()
 #endif
 
 
-
index 1a7804686b6a5a8cf82040c5fa231f198dd0ca6d..f61596445dad9a0e366b6b695aa71dbf92bf6cb9 100644 (file)
@@ -51,6 +51,7 @@ Demuxer::Demuxer()
   arcnt = 0;
   vid_seeking = aud_seeking = false;
   video_pts = audio_pts = 0;
+  ispre_1_3_19 = false;
 }
 
 Demuxer::~Demuxer()
@@ -91,11 +92,16 @@ void Demuxer::reset()
   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()
@@ -208,7 +214,7 @@ int Demuxer::PESPacket::submit()
   {
     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;
   }
@@ -220,10 +226,25 @@ int Demuxer::PESPacket::submit()
 
     //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;
@@ -267,6 +288,67 @@ void Demuxer::PESPacket::parseDetails()
       }
     }
   }
+  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
@@ -379,12 +461,17 @@ bool* Demuxer::getmpAudioChannels()
   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;
 }
index 0baa8154eb9539611d937a3a8a6e2fc8318a398c..104ed9665f9cd0f89367d7c31afd8f8a55a8d249 100644 (file)
--- a/demuxer.h
+++ b/demuxer.h
@@ -56,12 +56,14 @@ protected:
       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;
@@ -89,8 +91,9 @@ protected:
     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; }
@@ -166,8 +169,18 @@ protected:
       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
index 74d5862bc72bbbc2cd776ebf0e908adf4fe27625..2e473beafe83f6da61d3184cd79f1fdd9c8b8ecb 100644 (file)
 #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;
index 13948b738afff3a0724d3a0310ccd0a154d5bd9e..4720bf9fbff44e29d6c7469c765eb6d5eb35d0c7 100644 (file)
 
 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;
+  }
 }
 
 
@@ -132,305 +133,322 @@ ULONG STDMETHODCALLTYPE DsSFEnumPins::Release(){
 
 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;
+}
index 9adb656a287b5a4d18d3be9b26c2adce5dcce973..ba3f12e1cfb0d1891a3959870d261adc4aeb0bae 100644 (file)
 
 [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;
 
 
 };
index a55016ee2d77da5b99d1f188cd067d09d3cb56f4..8840e2877c51bb2743d89dfc51a7a09e2d716051 100644 (file)
@@ -21,7 +21,7 @@
 #include "dssourcefilter.h"
 #include <Dvdmedia.h>
 #include <mmreg.h>
-
+#include "draintarget.h"
 
 class DsSFEnumMediaTypes: public IEnumMediaTypes {
 public:
@@ -60,11 +60,11 @@ HRESULT STDMETHODCALLTYPE DsSFEnumMediaTypes::Next(ULONG numpin, AM_MEDIA_TYPE *
 
   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;
@@ -141,8 +141,15 @@ DsSourcePin::DsSourcePin(DsSourceFilter *pFilter,
   connected=NULL;
   connectedinput=NULL;
   allocator=NULL;
-
-
+  if (isaudiopin)
+  {
+      pinmode=MPTYPE_MPEG_AUDIO;
+      //pinmode=MPTYPE_AC3;
+  }
+  else
+  {
+      pinmode=MPTYPE_VIDEO;
+  }
 
 }
 
@@ -186,7 +193,6 @@ HRESULT STDMETHODCALLTYPE DsSourcePin::Connect(IPin *pinempf,const AM_MEDIA_TYPE
   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) {
@@ -214,34 +220,36 @@ HRESULT STDMETHODCALLTYPE DsSourcePin::Connect(IPin *pinempf,const AM_MEDIA_TYPE
     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) {
@@ -252,14 +260,14 @@ HRESULT STDMETHODCALLTYPE DsSourcePin::Connect(IPin *pinempf,const AM_MEDIA_TYPE
             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) {
@@ -417,6 +425,8 @@ HRESULT DsSourcePin::getCurrentMediaSample(IMediaSample**ms){
 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);
@@ -424,69 +434,228 @@ HRESULT DsSourcePin::deliver(IMediaSample * ms){
 
 }
 
-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() {
@@ -507,27 +676,46 @@ HRESULT DsSourcePin::Run(REFERENCE_TIME reftime){
 // 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;
 }
 
@@ -540,14 +728,14 @@ HRESULT DsSourcePin::DecideBufferSize(IMemAllocator *pa,ALLOCATOR_PROPERTIES *al
     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;
     }
   }
@@ -566,4 +754,3 @@ HRESULT DsSourcePin::DecideBufferSize(IMemAllocator *pa,ALLOCATOR_PROPERTIES *al
     return S_OK;
 }
 
-
index 8b023d395a8512c1a67291e7c227d98c8c74113b..bb2a8e2162111fb2dfc977b57e64d49525ca38ca 100644 (file)
@@ -23,7 +23,7 @@
 
 #include <winsock2.h>
 
-#include <dshow.h> 
+#include <dshow.h>
 
 
 
@@ -33,53 +33,60 @@ class DsSourceFilter;
 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;
 
-       
 
 
 };
index 62660411eda204f9bde62e5fb28803bbac92908c..8ea268ce1951485550dfe5b357ef2791e2495694 100644 (file)
--- a/player.cc
+++ b/player.cc
@@ -143,11 +143,16 @@ ULONG Player::getCurrentFrameNum()
   }
 }
 
-bool* Player::getDemuxerAudioChannels()
+bool* Player::getDemuxerMpegAudioChannels()
 {
   return demuxer->getmpAudioChannels();
 }
 
+bool* Player::getDemuxerAc3AudioChannels()
+{
+  return demuxer->getac3AudioChannels();
+}
+
 int Player::getCurrentAudioChannel()
 {
   return demuxer->getselAudioChannel();
@@ -155,7 +160,7 @@ int Player::getCurrentAudioChannel()
 
 void Player::setAudioChannel(int newChannel)
 {
-  demuxer->setmpAudioChannel(newChannel);
+  demuxer->setAudioChannel(newChannel);
 }
 
 // ----------------------------------- Externally called events
index 666cc17628a7db8fc0d49548b41fd50614cfa173..4c884e85741605f8b4b7f1ace1c993081d83142b 100644 (file)
--- a/player.h
+++ b/player.h
@@ -74,7 +74,8 @@ class Player : public Thread_TYPE, public Callback
     ULONG getCurrentFrameNum();
     ULONG getLengthFrames();
     UCHAR getIScanRate() { return ifactor; }
-    bool* getDemuxerAudioChannels();
+    bool* getDemuxerMpegAudioChannels();
+    bool* getDemuxerAc3AudioChannels();
     int getCurrentAudioChannel();
 
     void call(void*); // for callback interface
index 21b847a93ca93766ccb2e0db115cb879296c4227..556d7b34945fb8856ed1fce890e8748f951cfcfe 100644 (file)
--- a/stream.cc
+++ b/stream.cc
@@ -68,13 +68,14 @@ void Stream::flush()
   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;
index d9633308426389c1a6617437db7f29b8725e7396..59c5575cb2aede91b81d6e996bb0427c0267324d 100644 (file)
--- a/stream.h
+++ b/stream.h
@@ -44,7 +44,7 @@ class Stream
     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:
index d800f6245e0c7039337f0bd8587539f04d37cfe1..61782f31ab84ad749455579b41a41f4bec772e7e 100644 (file)
@@ -20,7 +20,9 @@
 
 #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);
 
@@ -42,7 +44,7 @@ VAudioSelector::VAudioSelector(void* tparent, bool* availableAudioChannels, int
 
   for (i = 0; i < PES_AUDIO_MAXCHANNELS; i++)
   {
-    if (availableAudioChannels[i])
+    if (availableMpegAudioChannels[i])
     {
       AudioChannel* ac = new AudioChannel();
       ac->type = 0;
@@ -51,6 +53,20 @@ VAudioSelector::VAudioSelector(void* tparent, bool* availableAudioChannels, int
       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();
@@ -142,7 +158,18 @@ VAudioSelector::VAudioSelector(void* tparent, bool* availableAudioChannels, int
       }
       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));
       }
     }
index d6aebefe4bfeefbe89e14e5aafa8ad1a1bda893c..e1efc04019b73e91303224fe3add3a5defc99a96 100644 (file)
@@ -38,6 +38,8 @@
 
 #define PES_AUDIO_START 0xc0
 #define PES_AUDIO_MAXCHANNELS 0x20
+#define PES_AUDIO_AC3_MAXCHANNELS 0x08
+#define PES_AUDIO_AC3_START 0x80
 
 class AudioChannel
 {
@@ -52,11 +54,12 @@ typedef vector<AudioChannel*> AudioChannelList;
 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:
@@ -67,3 +70,4 @@ class VAudioSelector : public View
 };
 
 #endif
+
index c27268ecd3ed1cfad0434630f32974a1a3e4826e..4307b6229d499b593779270daa833fb1a26520d3 100644 (file)
@@ -41,6 +41,8 @@ VideoWin::VideoWin()
   sourcefilter=NULL;
   allocatorvmr=NULL;
   cr_time=0;
+  lastaudiomode=MPTYPE_MPEG_AUDIO;
+  //lastaudiomode=MPTYPE_AC3;
   dsvmrsurfnotify=NULL;
   filtermutex=CreateMutex(NULL,FALSE,NULL);
   offsetnotset=true;
@@ -216,7 +218,7 @@ int VideoWin::dsplay()
    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
@@ -224,20 +226,22 @@ int VideoWin::dsplay()
    #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;
      }
@@ -248,22 +252,22 @@ int VideoWin::dsplay()
     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;
     }
@@ -272,15 +276,15 @@ int VideoWin::dsplay()
 
     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);
-       
+
 
 
 
@@ -289,18 +293,18 @@ int VideoWin::dsplay()
     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,
@@ -312,7 +316,7 @@ int VideoWin::dsplay()
    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);
 
@@ -324,28 +328,28 @@ int VideoWin::dsplay()
 
 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;
    }
@@ -356,54 +360,54 @@ int VideoWin::EnterIframePlayback()
       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,
@@ -415,9 +419,9 @@ int VideoWin::EnterIframePlayback()
    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);
@@ -446,7 +450,7 @@ int VideoWin::stop()
 int VideoWin::reset()
 {
   if (!initted) return 0;
-  
+
 
   return 1;
 }
@@ -474,7 +478,7 @@ int VideoWin::dspause()
 int VideoWin::pause()
 {
   if (!initted) return 0;
-  
+
   return 1;
 }
 
@@ -504,7 +508,7 @@ int VideoWin::fastForward()
 int VideoWin::unFastForward()
 {
   if (!initted) return 0;
-  
+
   return 1;
 }
 
@@ -522,22 +526,22 @@ int VideoWin::blank(void)
 
 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;
 
 }
@@ -568,8 +572,8 @@ void VideoWin::CleanupDS()
     cur_video_media_sample=NULL;
   }
   if (dsbasicaudio) {
-         dsbasicaudio->Release();
-         dsbasicaudio=NULL;
+    dsbasicaudio->Release();
+    dsbasicaudio=NULL;
   }
   if (dsvmrsurfnotify) {
     dsvmrsurfnotify->Release();
@@ -605,9 +609,9 @@ void VideoWin::CleanupDS()
 #ifdef DS_DEBUG
     RemoveFromRot(graphidentifier);
 #endif
-       dsgraphbuilder->Release();
+  dsgraphbuilder->Release();
     dsgraphbuilder=NULL;
-       
+
     sourcefilter=NULL; //The Graph Builder destroys our SourceFilter
   }
   ReleaseMutex(filtermutex);
@@ -635,18 +639,18 @@ UINT VideoWin::DeliverMediaPacket(MediaPacket packet,
      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;
@@ -658,8 +662,6 @@ UINT VideoWin::DeliverMediaPacket(MediaPacket packet,
     DeliverVideoMediaSample();
 
   }
-
-
   /*Inspect PES-Header */
 
   if (*samplepos==0) {//stripheader
@@ -686,7 +688,7 @@ UINT VideoWin::DeliverMediaPacket(MediaPacket packet,
   UINT ms_length;
   UINT ms_pos;
   UINT haveToCopy;
-  
+
   if (!getCurrentVideoMediaSample(&ms) || ms==NULL) {// get the current sample
     samplepos=0;
     MILLISLEEP(10);
@@ -724,13 +726,13 @@ UINT VideoWin::DeliverMediaPacket(MediaPacket packet,
     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);
     }
@@ -838,7 +840,7 @@ long long VideoWin::SetStartOffset(long long curreftime, bool *rsync)
   }
 
   lastrefvideotime=curreftime;
-  
+
   return startoffset;
 
 }
@@ -885,14 +887,14 @@ void VideoWin::ResetTimeOffsets() {
 
 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;
@@ -907,7 +909,7 @@ void VideoWin::displayIFrame(const UCHAR* buffer, UINT length)
   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;
@@ -923,41 +925,44 @@ void VideoWin::displayIFrame(const UCHAR* buffer, UINT 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);
@@ -972,6 +977,24 @@ void VideoWin::displayIFrame(const UCHAR* buffer, UINT length)
 #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()
index 8fbb07cfccd3171c686417d4b1fc8221d6f5c504..2a64edfd279924f74944786f130e14b707f74316 100644 (file)
@@ -82,6 +82,8 @@ class VideoWin : public Video
     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:
@@ -108,6 +110,8 @@ class VideoWin : public Video
   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();
@@ -147,6 +151,7 @@ private:
   ULLONG lastreftimePTS;
   unsigned int videoposx;
   unsigned int videoposy;
+  int lastaudiomode;
 #ifdef DS_DEBUG
   DWORD graphidentifier;
 #endif
@@ -155,4 +160,3 @@ private:
 #endif
 
 
-
index afe0ef09a8d179d7096c29494097eaeb4a457af0..fdd81d7c5857918926009945692ae36696ecabf6 100644 (file)
@@ -532,10 +532,15 @@ void VVideoRec::toggleChopSides()
 
 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)
   {