Win code for ffwd/fbwd
authorChris Tallon <chris@vomp.tv>
Sun, 24 Sep 2006 15:19:21 +0000 (15:19 +0000)
committerChris Tallon <chris@vomp.tv>
Sun, 24 Sep 2006 15:19:21 +0000 (15:19 +0000)
audiowin.cc
dssourcepin.cc
readme.win
videowin.cc
videowin.h
vompwin.rc

index 3ab1b7805e303fbd8e2c96cfdd5db56b32056655..3e04813c2f135e2240611f1c69192121b73e0400 100644 (file)
@@ -113,7 +113,8 @@ int AudioWin::unPause()
 \r
 int AudioWin::reset()\r
 {\r
-  if (!initted) return 0;\r
+  \r
+  if (!initted){return 0;}\r
   return ((VideoWin*)Video::getInstance())->dsreset();\r
 }\r
 \r
@@ -164,8 +165,14 @@ UINT AudioWin::DeliverMediaPacket(MediaPacket packet,
      const UCHAR* buffer,\r
      UINT *samplepos)\r
 {\r
+\r
   /*First Check, if we have an audio sample*/\r
   VideoWin *vw=(VideoWin*)Video::getInstance();\r
+  if (vw->InIframemode()) {\r
+               samplepos=0;\r
+               MILLISLEEP(10);\r
+               return 0; //Not in iframe mode!\r
+  }\r
   IMediaSample* ms=NULL;\r
   REFERENCE_TIME reftime1=0;\r
   REFERENCE_TIME reftime2=0;\r
@@ -197,6 +204,7 @@ UINT AudioWin::DeliverMediaPacket(MediaPacket packet,
     } else {\r
       if (!firstsynched) {//\r
         *samplepos=packet.length;//if we have not processed at least one\r
+       \r
         return packet.length;//synched packet ignore it!\r
       }\r
     }\r
index 0ce629a15fdadbc3f3e7f25c7f941e877dca3d3c..fab2c86ece2b572bf1d8eb184e6fea7e2c0f421e 100644 (file)
@@ -37,116 +37,118 @@ DsSourcePin::~DsSourcePin()
 
 }
 
-HRESULT DsSourcePin::GetMediaType(int iPosition, CMediaType *pmt)
-{
-       HRESULT hr;
-       ASSERT(pmt);
-       pmt->InitMediaType();
-       if (isaudiopin){
-               if (iPosition==0) {
-                       pmt->SetType(&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.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->SetSubtype(&MEDIASUBTYPE_MPEG2_AUDIO);
-                       pmt->SetFormatType(&FORMAT_WaveFormatEx);
-                       pmt->SetFormat((BYTE*)&wfe,sizeof(wfe));
-                       pmt->SetSampleSize(0);
-                       hr=S_OK;
-
-               
-        } else  {
-                       hr=VFW_S_NO_MORE_ITEMS ;
-               }
-       } else {
-               if (iPosition == 0) {
-                       pmt->SetType(&MEDIATYPE_Video);
-                       hr=S_OK;
-                       pmt->SetSubtype(&MEDIASUBTYPE_MPEG2_VIDEO);
-            pmt->SetFormatType(&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->SetFormat((BYTE*)&hdr,sizeof(hdr));
-               } else {
-                       hr=VFW_S_NO_MORE_ITEMS;
-               }
-       }
-       return hr ;
-}
-
-// No description
-HRESULT DsSourcePin::CheckMediaType(const CMediaType *pmt)
-{
-    HRESULT res;
-    ASSERT (pmt);
-    if (isaudiopin) {
-        bool subtype=false;
-#if 0 /* For future demands ac3 */
-               subtype=pmt->subtype==(MEDIASUBTYPE_DOLBY_AC3);
-#endif
-               subtype=(pmt->subtype==(MEDIASUBTYPE_MPEG2_AUDIO));
-        if (pmt->majortype==MEDIATYPE_Audio && subtype) {
-                       res = S_OK ;
-        } else {
-            res = S_FALSE ;
-        }    
-    } else {
-        if (pmt->majortype==MEDIATYPE_Video &&
-                  pmt-> subtype==MEDIASUBTYPE_MPEG2_VIDEO) {
-                       res = S_OK ;
-        } else {
-            res = S_FALSE ;
-        }  
-    }
-    return res;
-}
-
-HRESULT DsSourcePin::DecideBufferSize(IMemAllocator *pa,ALLOCATOR_PROPERTIES *all_pp){
-       HRESULT hr;
-    CAutoLock al(m_pFilter->GetLock());
-    CheckPointer(pa, E_POINTER);
-    CheckPointer(all_pp, E_POINTER);
-       if (isaudiopin) {
-               if (all_pp->cBuffers*all_pp->cbBuffer < 300*64*1024)
-               {
-                       all_pp->cBuffers = 300;
-                       all_pp->cbBuffer = 64*1024;
-               }
-       } else {
-               if (all_pp->cBuffers*all_pp->cbBuffer < 300*64*1024)
-               {
-                       all_pp->cBuffers = 300;
-                       all_pp->cbBuffer = 64*1024;
-               }
-       }
-
-    ALLOCATOR_PROPERTIES all_pp_cur;
-    hr =pa->SetProperties(all_pp,&all_pp_cur);
-    if (FAILED(hr)) 
-    {
-        return hr;
-    }
-    if (all_pp_cur.cbBuffer*all_pp_cur.cBuffers < all_pp->cBuffers*all_pp->cbBuffer) 
-    {
-        return E_FAIL;
-    }
-
-    return S_OK;
-}
+HRESULT DsSourcePin::GetMediaType(int iPosition, CMediaType *pmt)\r
+{\r
+       HRESULT hr;\r
+       ASSERT(pmt);\r
+       pmt->InitMediaType();\r
+       if (isaudiopin){\r
+               if (iPosition==0) {\r
+                       pmt->SetType(&MEDIATYPE_Audio);\r
+                       MPEG1WAVEFORMAT wfe;\r
+                       ZeroMemory(&wfe,sizeof(wfe));\r
+                       wfe.wfx.cbSize=22;\r
+                       wfe.wfx.nSamplesPerSec=48000;\r
+                       wfe.wfx.nChannels=2;\r
+                       wfe.wfx.nAvgBytesPerSec=32000;\r
+                       wfe.wfx.nBlockAlign=768;\r
+                       wfe.wfx.wFormatTag=WAVE_FORMAT_MPEG;\r
+                       wfe.fwHeadLayer=2;\r
+                       wfe.dwHeadBitrate=256000;\r
+                       wfe.fwHeadMode=ACM_MPEG_STEREO;\r
+                       wfe.fwHeadModeExt=1;\r
+                       wfe.wHeadEmphasis=1;\r
+                       wfe.fwHeadFlags=ACM_MPEG_ID_MPEG1 |ACM_MPEG_ORIGINALHOME | ACM_MPEG_PROTECTIONBIT;\r
+                       pmt->SetSubtype(&MEDIASUBTYPE_MPEG2_AUDIO);\r
+                       pmt->SetFormatType(&FORMAT_WaveFormatEx);\r
+                       pmt->SetFormat((BYTE*)&wfe,sizeof(wfe));\r
+                       pmt->SetSampleSize(0);\r
+                       hr=S_OK;\r
+\r
+               \r
+        } else  {\r
+                       hr=VFW_S_NO_MORE_ITEMS ;\r
+               }\r
+       } else {\r
+               if (iPosition == 0) {\r
+                       pmt->SetType(&MEDIATYPE_Video);\r
+                       hr=S_OK;\r
+                       pmt->SetSubtype(&MEDIASUBTYPE_MPEG2_VIDEO);\r
+            pmt->SetFormatType(&FORMAT_MPEG2Video);\r
+\r
+            MPEG2VIDEOINFO hdr;\r
+            ZeroMemory(&hdr,sizeof(hdr));\r
+            hdr.dwProfile=AM_MPEG2Profile_Main;\r
+            hdr.dwLevel=AM_MPEG2Level_Main;\r
+            hdr.hdr.bmiHeader.biSize = sizeof(hdr.hdr.bmiHeader);\r
+            hdr.hdr.bmiHeader.biWidth = 720;\r
+            hdr.hdr.bmiHeader.biHeight = 568;\r
+            pmt->SetFormat((BYTE*)&hdr,sizeof(hdr));\r
+               } else {\r
+                       hr=VFW_S_NO_MORE_ITEMS;\r
+               }\r
+       }\r
+       return hr ;\r
+}\r
+\r
+// No description\r
+HRESULT DsSourcePin::CheckMediaType(const CMediaType *pmt)\r
+{\r
+    HRESULT res;\r
+    ASSERT (pmt);\r
+    if (isaudiopin) {\r
+        bool subtype=false;\r
+#if 0 /* For future demands ac3 */\r
+               subtype=pmt->subtype==(MEDIASUBTYPE_DOLBY_AC3);\r
+#endif\r
+               subtype=(pmt->subtype==(MEDIASUBTYPE_MPEG2_AUDIO));\r
+        if (pmt->majortype==MEDIATYPE_Audio && subtype) {\r
+                       res = S_OK ;\r
+        } else {\r
+            res = S_FALSE ;\r
+        }    \r
+    } else {\r
+        if (pmt->majortype==MEDIATYPE_Video &&\r
+                  pmt-> subtype==MEDIASUBTYPE_MPEG2_VIDEO) {\r
+                       res = S_OK ;\r
+        } else {\r
+            res = S_FALSE ;\r
+        }  \r
+    }\r
+    return res;\r
+}\r
+\r
+HRESULT DsSourcePin::DecideBufferSize(IMemAllocator *pa,ALLOCATOR_PROPERTIES *all_pp){\r
+       HRESULT hr;\r
+    CAutoLock al(m_pFilter->GetLock());\r
+    CheckPointer(pa, E_POINTER);\r
+    CheckPointer(all_pp, E_POINTER);\r
+       if (isaudiopin) {\r
+               if (all_pp->cBuffers*all_pp->cbBuffer < 300*64*1024)\r
+               {\r
+                       //all_pp->cBuffers = 300;//old\r
+                       all_pp->cBuffers = 10;\r
+                       all_pp->cbBuffer = 64*1024;\r
+               }\r
+       } else {\r
+               if (all_pp->cBuffers*all_pp->cbBuffer < 300*64*1024)\r
+               {\r
+                       //all_pp->cBuffers = 300;//old\r
+                       all_pp->cBuffers = 30;\r
+                       all_pp->cbBuffer = 64*1024;\r
+               }\r
+       }\r
+\r
+    ALLOCATOR_PROPERTIES all_pp_cur;\r
+    hr =pa->SetProperties(all_pp,&all_pp_cur);\r
+    if (FAILED(hr)) \r
+    {\r
+        return hr;\r
+    }\r
+    if (all_pp_cur.cbBuffer*all_pp_cur.cBuffers < all_pp->cBuffers*all_pp->cbBuffer) \r
+    {\r
+        return E_FAIL;\r
+    }\r
+\r
+    return S_OK;\r
+}\r
index d487b4c8ebc02f4f404c2404f77aef46c4e0736c..2ac59dd8624753e35361e6b7de8ec27761e6d023 100644 (file)
@@ -103,3 +103,4 @@ Firewall
 If vomp for Windows stops at "Locating server" or "Connecting to VDR",\r
 please configure your firewall so that vomp for windows can communicate\r
 with the vompserver on port 3024 (UDP and TCP).\r
+\r
index b2cd88035b602e1af045c0f3a11cfe4bffc80548..e8b014a109f01885872af4bf4fbdf01b403459a7 100644 (file)
@@ -58,6 +58,7 @@ VideoWin::VideoWin()
   pseudotvsize=0;\r
   videoposx=0;\r
   videoposy=0;\r
+  iframemode=false;//We are not in Iframe mode at begining\r
 \r
 \r
 \r
@@ -207,6 +208,7 @@ int VideoWin::dsplay()
 {\r
   if (!initted) return 0;\r
  CleanupDS();\r
+\r
   //Build filter graph\r
   HRESULT hres;\r
 \r
@@ -308,10 +310,109 @@ int VideoWin::dsplay()
    dsgraphbuilder->QueryInterface(IID_IBasicAudio,(void **) &dsbasicaudio);    \r
 \r
    dsmediacontrol->Run();\r
+   iframemode=false;//exit iframe mode\r
    ReleaseMutex(filtermutex);\r
   return 1;\r
 }\r
 \r
+int VideoWin::EnterIframePlayback()\r
+{\r
+       if (!initted) return 0;\r
+       CleanupDS();\r
+       iframemode=true;//enter iframe mode\r
+       //Build filter graph\r
+       HRESULT hres;\r
+       if (hres=CoCreateInstance(CLSID_FilterGraph,NULL,CLSCTX_INPROC_SERVER,\r
+                IID_IGraphBuilder,(void**)&dsgraphbuilder)!=S_OK) {\r
+                        return 0;\r
+       }\r
+#ifdef DS_DEBUG\r
+       AddToRot(dsgraphbuilder,&graphidentifier);\r
+#endif\r
+   //So this is the real code, this prevents the feeder from calling noexisting objects!\r
+   WaitForSingleObject(filtermutex,INFINITE);\r
+   //firstsynched=false;\r
+   sourcefilter=new DsSourceFilter(); //Creating our Source filter for pushing Data\r
+   // to DirectShow\r
+   if (hres=dsgraphbuilder->AddFilter(sourcefilter,L"Vomp Win Source Filter")!=S_OK) {\r
+   Log::getInstance()->log("VideoWin", Log::WARN , "Failed adding Vomp Source Filter!");\r
+     CleanupDS();\r
+     ReleaseMutex(filtermutex);\r
+     return 0;\r
+   }\r
+#ifdef DO_VIDEO\r
+    if (videoon) {\r
+    //We alloc the vmr9 as next step\r
+    if (hres=CoCreateInstance(CLSID_VideoMixingRenderer9,0,\r
+      CLSCTX_INPROC_SERVER,IID_IBaseFilter,(void**) &dsvmrrenderer)!=S_OK) {\r
+      Log::getInstance()->log("VideoWin", Log::WARN ,"Failed creating VMR9 renderer!");\r
+      CleanupDS();\r
+      ReleaseMutex(filtermutex);\r
+         return 0;\r
+    }\r
+      /*VMR 9 stuff**/\r
+    if (hres=dsgraphbuilder->AddFilter(dsvmrrenderer,L"VMR9")!=S_OK) {\r
+      CleanupDS();\r
+      Log::getInstance()->log("VideoWin", Log::WARN ,"Failed adding VMR9 renderer!");\r
+      ReleaseMutex(filtermutex);\r
+      return 0;\r
+    }\r
+    IVMRFilterConfig9* vmrfilconfig;\r
+    if (dsvmrrenderer->QueryInterface(IID_IVMRFilterConfig9,(void**)&vmrfilconfig)!=S_OK) {\r
+      CleanupDS();\r
+      Log::getInstance()->log("VideoWin", Log::WARN ,"Failed getting VMR9 Filterconfig interface!");\r
+      ReleaseMutex(filtermutex);\r
+      return 0;\r
+    }\r
+    vmrfilconfig->SetRenderingMode(VMR9Mode_Renderless);\r
+    vmrfilconfig->Release();\r
+\r
+    if (dsvmrrenderer->QueryInterface(IID_IVMRSurfaceAllocatorNotify9,(void**)& dsvmrsurfnotify)!=S_OK) {\r
+      CleanupDS();\r
+      Log::getInstance()->log("VideoWin", Log::WARN ,"Failed getting VMR9 Surface Allocator interface!");\r
+      ReleaseMutex(filtermutex);\r
+      return 0;\r
+    }\r
+    allocatorvmr=new DsAllocator();\r
+    dsvmrsurfnotify->AdviseSurfaceAllocator(NULL,allocatorvmr);\r
+    allocatorvmr->AdviseNotify(dsvmrsurfnotify);\r
+       \r
+    /*VMR 9 stuff end */\r
+    IFilterGraph2*fg2=NULL;\r
+    if (dsgraphbuilder->QueryInterface(IID_IFilterGraph2,(void**)&fg2)!=S_OK) {\r
+      Log::getInstance()->log("VideoWin", Log::WARN , "Failed querying for FilterGraph2 Interface!");\r
+      CleanupDS();\r
+      ReleaseMutex(filtermutex);\r
+      return 0;\r
+    }\r
+    if (hres=fg2->RenderEx(sourcefilter->GetPin(1)/*video*/,\r
+        AM_RENDEREX_RENDERTOEXISTINGRENDERERS,NULL)!=S_OK) {\r
+      Log::getInstance()->log("VideoWin", Log::WARN , "Failed rendering Video!");\r
+         fg2->Release();\r
+      CleanupDS();\r
+      ReleaseMutex(filtermutex);\r
+      return 0;\r
+    }\r
+       fg2->Release();\r
+   }\r
+#endif\r
+/*   if (hres=CoCreateInstance(CLSID_SystemClock,NULL,CLSCTX_INPROC_SERVER,\r
+    IID_IReferenceClock,(void**)&dsrefclock)!=S_OK) {\r
+      return 0;\r
+   }*/\r
+\r
+   dsgraphbuilder->QueryInterface(IID_IMediaFilter,(void **) &dsmediafilter);\r
+   dsmediafilter->SetSyncSource(/*dsrefclock*/NULL); //Run as fast as you can!\r
+\r
+   dsgraphbuilder->QueryInterface(IID_IMediaControl,(void **) &dsmediacontrol);\r
+   dsgraphbuilder->QueryInterface(IID_IBasicAudio,(void **) &dsbasicaudio);    \r
+\r
+   dsmediacontrol->Run();\r
+   ReleaseMutex(filtermutex);\r
+  return 1;\r
+\r
+}\r
+\r
 int VideoWin::dsstop()\r
 {\r
   if (!initted) return 0;\r
@@ -343,6 +444,7 @@ int VideoWin::dsreset()
   if (!initted) return 0;\r
   videoposx=0;\r
   videoposy=0;\r
+  iframemode=false;//exit iframe mode\r
   CleanupDS();\r
 \r
   return 1;\r
@@ -405,7 +507,7 @@ ULLONG VideoWin::getCurrentTimestamp()
 {\r
        REFERENCE_TIME startoffset;\r
        REFERENCE_TIME ncr_time;\r
-\r
+  if (iframemode) return 0; //Not in iframe mode!\r
   if (!dsrefclock || !sourcefilter) return 0;\r
        FILTER_STATE state;\r
        sourcefilter->GetState(10,&state);\r
@@ -516,7 +618,11 @@ UINT VideoWin::DeliverMediaPacket(MediaPacket packet,
   /*First Check, if we have an audio sample*/\r
 #ifdef DO_VIDEO\r
   /*First Check, if we have an audio sample*/\r
-\r
+  if (iframemode) {\r
+               samplepos=0;\r
+               MILLISLEEP(10);\r
+               return 0; //Not in iframe mode!\r
+  }\r
   IMediaSample* ms=NULL;\r
   REFERENCE_TIME reftime1=0;\r
   REFERENCE_TIME reftime2=0;\r
@@ -756,6 +862,89 @@ void VideoWin::SetAudioVolume(long volume)
        if (dsbasicaudio) dsbasicaudio->put_Volume(volume);\r
 }\r
 \r
+void VideoWin::displayIFrame(const UCHAR* buffer, UINT length)\r
+{\r
+       if (!iframemode) EnterIframePlayback();\r
+\r
+\r
+#ifdef DO_VIDEO\r
+  IMediaSample* ms=NULL;\r
+  REFERENCE_TIME reftime1=0;\r
+  REFERENCE_TIME reftime2=0;\r
+  if (!getCurrentVideoMediaSample(&ms) || ms==NULL) {// get the current sample\r
+    MILLISLEEP(10);\r
+    return ;\r
+  }\r
+  BYTE *ms_buf;\r
+  DWORD ms_length;\r
+  ms->GetPointer(&ms_buf);\r
+  ms_length=ms->GetSize();\r
+\r
+  /*First Check, if we have an video sample*/\r
+  DWORD read_pos = 0, write_pos = 0;\r
+  DWORD pattern, packet_length;\r
+  DWORD headerstrip=0;\r
+  bool first=true;\r
+  if (length < 4) return ;\r
+  //Now we strip the pes header\r
+  pattern = (buffer[0] << 16) | (buffer[1] << 8) | (buffer[2]);\r
+  while (read_pos + 7 <= length)\r
+  {\r
+    pattern = ((pattern << 8) & 0xFFFFFFFF) | buffer[read_pos+3];\r
+    if (pattern < 0x000001E0 || pattern > 0x000001EF)\r
+      read_pos++;\r
+    else\r
+    {\r
+         headerstrip=buffer[read_pos+8]+9/*is this right*/;\r
+      packet_length = ((buffer[read_pos+4] << 8) | (buffer[read_pos+5])) + 6;\r
+      if (read_pos + packet_length > length)\r
+        read_pos = length;\r
+      else\r
+      {\r
+                 if ((write_pos+packet_length-headerstrip)>ms_length) {\r
+                         if (first) {ms->SetSyncPoint(TRUE);first=false;} \r
+                         else ms->SetSyncPoint(FALSE);\r
+                         ms->SetTime(NULL,NULL);\r
+                         ms->SetMediaTime(NULL, NULL);\r
+                         ms->SetActualDataLength(write_pos);\r
+                         DeliverVideoMediaSample();\r
+\r
+                         if (!getCurrentVideoMediaSample(&ms) || ms==NULL) {// get the current sample\r
+                               MILLISLEEP(10);\r
+                               return ;\r
+                         }\r
+                         write_pos=0;\r
+                         ms_length=ms->GetSize();\r
+                         ms->GetPointer(&ms_buf);\r
+                 }\r
+                 if (packet_length-headerstrip>0) {\r
+                       memcpy(ms_buf+write_pos, buffer+read_pos+headerstrip, packet_length-headerstrip);\r
+                       write_pos += packet_length-headerstrip;\r
+                 }\r
+                 read_pos += packet_length;\r
+                 \r
+                 pattern = (buffer[read_pos] << 16) | (buffer[read_pos+1] << 8)\r
+                                        | (buffer[read_pos+2]);\r
+      }\r
+    }\r
+  }\r
+\r
+  if (first) {ms->SetSyncPoint(TRUE);first=false;} \r
+  else ms->SetSyncPoint(FALSE);\r
+  ms->SetTime(NULL,NULL);\r
+  ms->SetMediaTime(NULL, NULL);\r
+  ms->SetActualDataLength(write_pos);\r
+  DeliverVideoMediaSample();\r
+\r
+#else\r
+\r
+       *samplepos+=packet.length;\r
+      MILLISLEEP(0); //yet not implemented//bad idea\r
+       return packet.length;\r
+#endif\r
+}\r
+\r
+\r
 #ifdef DEV\r
 int VideoWin::test()\r
 {\r
index 23da5fef930cd6006bd0480c3c4408ff0c7c5a03..e4e8603cc16ed76a034181cf79457f4df21d0125 100644 (file)
@@ -59,6 +59,7 @@ class VideoWin : public Video
     int sync();\r
     int play();\r
        int dsplay();\r
+       bool InIframemode() {return iframemode;};\r
     int stop();\r
        int dsstop();\r
     int pause();\r
@@ -100,6 +101,8 @@ class VideoWin : public Video
 \r
     void turnVideoOn(){videoon=true;};\r
     void turnVideoOff(){videoon=false;};\r
+       \r
+    virtual void displayIFrame(const UCHAR* buffer, UINT length);\r
 \r
   unsigned int getPosx() {return videoposx;};\r
   unsigned int getPosy() {return videoposy;};\r
@@ -110,6 +113,7 @@ class VideoWin : public Video
     int test2();\r
 #endif\r
 private:\r
+  int EnterIframePlayback();\r
   IMediaControl* dsmediacontrol;\r
 \r
   IGraphBuilder* dsgraphbuilder;\r
@@ -136,6 +140,7 @@ private:
   bool firstsynched;\r
   bool audioon;\r
   bool videoon;\r
+  bool iframemode;\r
   UCHAR pseudotvsize;\r
   REFERENCE_TIME lastreftimeRT;\r
   ULLONG lastreftimePTS;\r
index 29410adb9b31957b78c62925d1e691c5a290b682..b4620a37fc6bbb9737fffc859be5e77ce7be6a4d 100644 (file)
@@ -24,8 +24,8 @@ BEGIN
     VK_OEM_PLUS,    APPCOMMAND_MEDIA_CHANNEL_UP, VIRTKEY, CONTROL, NOINVERT\r
     VK_OEM_PLUS,    APPCOMMAND_MEDIA_CHANNEL_UP, VIRTKEY, NOINVERT\r
     VK_PRIOR,        APPCOMMAND_MEDIA_CHANNEL_UP, VIRTKEY, NOINVERT\r
-    "F",            APPCOMMAND_MEDIA_FAST_FORWARD, VIRTKEY, SHIFT, CONTROL, \r
-                                                    NOINVERT\r
+    "F",            APPCOMMAND_MEDIA_FAST_FORWARD, VIRTKEY, SHIFT, CONTROL, NOINVERT \r
+       "B",            APPCOMMAND_MEDIA_REWIND, VIRTKEY, SHIFT, CONTROL, NOINVERT\r
     VK_F8,          APPCOMMAND_VOLUME_MUTE, VIRTKEY, NOINVERT\r
     "P",            APPCOMMAND_MEDIA_PAUSE, VIRTKEY, CONTROL, NOINVERT\r
     "P",            APPCOMMAND_MEDIA_PLAY,  VIRTKEY, SHIFT, CONTROL, \r