]> git.vomp.tv Git - vompclient-marten.git/commitdiff
Windows port. New sync code. Various other bug fixes.
authorChris Tallon <chris@vomp.tv>
Sat, 22 Apr 2006 23:35:06 +0000 (23:35 +0000)
committerChris Tallon <chris@vomp.tv>
Sat, 22 Apr 2006 23:35:06 +0000 (23:35 +0000)
60 files changed:
Makefile
afeed.cc
afeed.h
afeedr.cc
afeedr.h
audio.h
audiomvp.cc
audiomvp.h
audiowin.cc
audiowin.h
command.cc
defines.h
demuxer.cc
demuxer.h
draintarget.cc [new file with mode: 0644]
draintarget.h [new file with mode: 0644]
dsock.h
dssourcefilter.cc [new file with mode: 0644]
dssourcefilter.h [new file with mode: 0644]
dssourcepin.cc [new file with mode: 0644]
dssourcepin.h [new file with mode: 0644]
ledwin.cc
log.cc
log.h
main.cc
mtdwin.cc
mtdwin.h
osd.h
osdmvp.cc
osdmvp.h
osdwin.cc
osdwin.h
player.cc
player.h
remotewin.cc
remotewin.h
stream.cc
stream.h
surfacewin.cc
surfacewin.h
tcp.cc
threadwin.cc
threadwin.h
timers.cc
vepg.cc
vepgsettimer.cc
vfeed.cc
vfeed.h
video.h
videomvp.cc
videomvp.h
videowin.cc
videowin.h
vlivebanner.cc
vompreswin.h [new file with mode: 0644]
vompwin.rc [new file with mode: 0644]
vrecordinglist.cc
vvideolive.cc
winmain.cc [new file with mode: 0644]
wjpeg.cc

index 3a47e85ade2f266def85770f9a2eb9754f9f4a36..4987f72623c597323b1d55b6c2ebd361a30398f9 100644 (file)
--- a/Makefile
+++ b/Makefile
@@ -14,7 +14,7 @@ CROSSLIBS = ../jpeg-6b/libjpeg.a
 OBJECTS1 = main.o command.o log.o tcp.o dsock.o thread.o timers.o i18n.o               \
            message.o messagequeue.o                                                    \
            vdr.o recording.o channel.o rectimer.o event.o directory.o                  \
-           player.o demuxer.o stream.o vfeed.o afeed.o afeedr.o                        \
+           player.o demuxer.o stream.o vfeed.o afeed.o afeedr.o draintarget.o          \
            viewman.o box.o region.o colour.o view.o                                    \
            vinfo.o vwallpaper.o vvolume.o vrecordinglist.o vlivebanner.o vmute.o       \
            vtimerlist.o vtimeredit.o voptionsmenu.o vrecordingmenu.o vquestion.o       \
index a61f2868cc5b8567aeaeeb40c7b7ecefd7cf4311..bb15a731f1421709c7fa89fd71711b2c078d7b7e 100644 (file)
--- a/afeed.cc
+++ b/afeed.cc
@@ -26,11 +26,19 @@ AFeed::AFeed(Callback* tcb)
   audioEnabled = 1;
 }
 
+#ifndef NEW_DEMUXER
 int AFeed::init(int tfd)
 {
   fd = tfd;
   return 1;
 }
+#else
+int AFeed::init(DrainTarget* tdt)
+{
+  dt = tdt;
+  return 1;
+}
+#endif
 
 int AFeed::shutdown()
 {
@@ -71,7 +79,11 @@ void AFeed::threadMethod()
 
     if (audioEnabled)
     {
+#ifndef NEW_DEMUXER
       alen = Demuxer::getInstance()->writeAudio(fd); // FIXME ?
+#else
+      alen = Demuxer::getInstance()->writeAudio(dt); // FIXME ?
+#endif
 
       if (alen)
       {
diff --git a/afeed.h b/afeed.h
index d5739fb7efabb743046fea577954adada6f94b6f..f67770b373e187775d471de5f41c72c5f9fe823b 100644 (file)
--- a/afeed.h
+++ b/afeed.h
@@ -27,6 +27,7 @@
 #include "log.h"
 #include "demuxer.h"
 #include "callback.h"
+#include "draintarget.h"
 
 #ifdef WIN32
 #include "threadwin.h"
 #include "threadp.h"
 #endif
 
+
 class AFeed : public Thread_TYPE
 {
   public:
     AFeed(Callback* tcb);
-
+#ifndef NEW_DEMUXER
     int init(int fd);
+#else
+    int init(DrainTarget* tdt);
+#endif
     int shutdown();
 
     int start();
@@ -51,7 +56,11 @@ class AFeed : public Thread_TYPE
     void threadMethod();
     void threadPostStopCleanup() {};
     int audioEnabled;
+#ifndef NEW_DEMUXER
     int fd;
+#else
+    DrainTarget* dt;
+#endif
     Callback& cb;
 };
 
index 6abc7379fa1961c060153839735898ea2435da53..f88c9969649dba66b1f1c999f403b4703c22794e 100644 (file)
--- a/afeedr.cc
+++ b/afeedr.cc
@@ -25,11 +25,20 @@ AFeedR::AFeedR(Callback* tcb, Stream* tstream)
 {
 }
 
+#ifndef NEW_DEMUXER
 int AFeedR::init(int tfd)
 {
   fd = tfd;
   return 1;
 }
+#else
+int AFeedR::init(DrainTarget* tdt)
+{
+  dt = tdt;
+  return 1;
+}
+#endif
+
 
 int AFeedR::shutdown()
 {
@@ -55,7 +64,12 @@ void AFeedR::threadMethod()
 
   while(1)
   {
+#ifndef NEW_DEMUXER
     alen = stream.drain(fd);
+#else
+    alen = stream.drain(dt);
+    threadCheckExit();
+#endif
 
     if (alen)
     {
index 8f12e206afc22624c102103d647105fe95abc44b..99674201aefd7829b6858f598b689ffb6d0428a4 100644 (file)
--- a/afeedr.h
+++ b/afeedr.h
@@ -27,6 +27,7 @@
 #include "log.h"
 #include "callback.h"
 #include "stream.h"
+#include "draintarget.h"
 
 #ifdef WIN32
 #include "threadwin.h"
@@ -38,8 +39,11 @@ class AFeedR : public Thread_TYPE
 {
   public:
     AFeedR(Callback* tcb, Stream* tstream);
-
+#ifndef NEW_DEMUXER
     int init(int fd);
+#else
+    int init(DrainTarget* tdt);
+#endif
     int shutdown();
 
     int start();
@@ -48,8 +52,11 @@ class AFeedR : public Thread_TYPE
   private:
     void threadMethod();
     void threadPostStopCleanup() {};
-
+#ifndef NEW_DEMUXER
     int fd;
+#else
+    DrainTarget* dt;
+#endif
     Callback& cb;
     Stream& stream;
 };
diff --git a/audio.h b/audio.h
index 8144d97fe061eedaa01867516dc13b23e334c248..23751d83119e0cfd5de38a290970e73d06ff7aa3 100644 (file)
--- a/audio.h
+++ b/audio.h
@@ -24,6 +24,7 @@
 #include <stdio.h>
 #include "defines.h"
 #include "log.h"
+#include "draintarget.h"
 
 typedef struct
 {
@@ -35,7 +36,7 @@ typedef struct
     unsigned char lfe;
 } audio_volume;
 
-class Audio
+class Audio : public DrainTarget
 {
   public:
     Audio();
index 9ab525355d467571603a577b2e102ddd552775a4..d9218c69074eba5daee4da4db4940e6562860340 100644 (file)
@@ -239,3 +239,10 @@ int AudioMVP::test()
 
 }
 #endif
+
+
+// unused
+UINT AudioMVP::DeliverMediaSample(MediaPacket packet, UCHAR* buffer, UINT *samplepos)
+{
+  return 0;
+}
index 7b48a10d836b6bb260e21ed80e3cfdd531b9ba89..a9223b3afe3ec55a53661bd55fd8d919d9a4d3fb 100644 (file)
@@ -57,6 +57,10 @@ class AudioMVP : public Audio
     int write(char *buf, int len);
     int getFD();
 
+    //Writing Data to Audiodevice -- unused in MVP code so far
+    virtual UINT DeliverMediaSample(MediaPacket packet, UCHAR* buffer, UINT *samplepos);
+    virtual long long SetStartOffset(long long curreftime, bool *rsync) { return 0; };
+
 #ifdef DEV
     int test();
 #endif
index 75019e35c63b83299ae6ec4c4f319588d2d44352..db3f932baaaf08e01084c8f6814b1058891c2452 100644 (file)
 */
 
 #include "audiowin.h"
+#include "videowin.h"
+
+
+
+
 
 AudioWin::AudioWin()
 {
-  if (instance) return;
   initted = 0;
+  firstsynched=false;
+
+
 }
 
 AudioWin::~AudioWin()
 {
+
 }
 
 int AudioWin::init(UCHAR tstreamType)
@@ -81,6 +89,8 @@ int AudioWin::sync()
 int AudioWin::play()
 {
   if (!initted) return 0;
+  firstsynched=false;
+
   return 1;
 }
 
@@ -118,15 +128,117 @@ int AudioWin::setVolume(int tvolume)
 int AudioWin::mute()
 {
   if (!initted) return 0;
+  ((VideoWin*)Video::getInstance())->SetAudioState(false);
   return 1;
 }
 
 int AudioWin::unMute()
 {
   if (!initted) return 0;
+  ((VideoWin*)Video::getInstance())->SetAudioState(true);
   return 1;
 }
 
+UINT AudioWin::DeliverMediaSample(MediaPacket packet,
+     UCHAR* buffer,
+     UINT *samplepos)
+{
+  /*First Check, if we have an audio sample*/
+  VideoWin *vw=(VideoWin*)Video::getInstance();
+  IMediaSample* ms=NULL;
+  REFERENCE_TIME reftime1=0;
+  REFERENCE_TIME reftime2=0;
+
+  UINT headerstrip=0;
+  if (packet.disconti) {
+    firstsynched=false;
+    vw->DeliverVideoMediaSample();
+  }
+
+
+
+  /*Inspect PES-Header */
+/*  UINT header_length=buffer[(packet.pos_buffer+8)%bufferlength]+8/*is this right*;
+*/
+  if (*samplepos==0) {//stripheader
+    headerstrip=buffer[packet.pos_buffer+8]+9/*is this right*/;
+    *samplepos+=headerstrip;
+    if ( packet.synched ) {
+      vw->DeliverAudioMediaSample();//write out old data
+      if (packet.presentation_time<0) { //Preroll?
+        *samplepos=packet.length;//if we have not processed at least one
+        return packet.length;//synched packet ignore it!
+      }
+
+      reftime1=packet.presentation_time;
+      reftime2=reftime1+1;
+      firstsynched=true;
+    } else {
+      if (!firstsynched) {//
+        *samplepos=packet.length;//if we have not processed at least one
+        return packet.length;//synched packet ignore it!
+      }
+    }
+  }
+  BYTE *ms_buf;
+  UINT ms_length;
+  UINT ms_pos;
+  UINT haveToCopy;
+  if (!vw->getCurrentAudioMediaSample(&ms) || ms==NULL) {// get the current sample
+    samplepos=0;
+    MILLISLEEP(10);
+    return 0;
+  }
+  ms_pos=ms->GetActualDataLength();
+  ms_length=ms->GetSize();
+  haveToCopy=min(ms_length-ms_pos,packet.length-*samplepos);
+  if ((ms_length-ms_pos)<1) {
+    vw->DeliverAudioMediaSample(); //we are full!
+    if (!vw->getCurrentAudioMediaSample(&ms) || ms==NULL) {// get the current sample
+      samplepos=0;
+      MILLISLEEP(10);
+      return 0;
+    }
+    ms_pos=ms->GetActualDataLength();
+    ms_length=ms->GetSize();
+    haveToCopy=min(ms_length-ms_pos,packet.length-*samplepos);
+  }
+  ms->GetPointer(&ms_buf);
+
+  if (ms_pos==0) {//will only be changed on first packet
+    if (packet.disconti) {
+      ms->SetDiscontinuity(TRUE);
+    } else {
+      ms->SetDiscontinuity(FALSE);
+    }
+    if (packet.synched) {
+      ms->SetSyncPoint(TRUE);
+      ms->SetTime(&reftime1,&reftime2);
+      //ms->SetTime(NULL,NULL);
+      ms->SetMediaTime(NULL, NULL);
+    }else {
+      ms->SetSyncPoint(FALSE);
+      ms->SetTime(NULL,NULL);
+      ms->SetMediaTime(NULL, NULL);
+      ms->SetSyncPoint(TRUE);
+    }
+  }
+
+
+  memcpy(ms_buf+ms_pos,buffer+packet.pos_buffer+*samplepos,haveToCopy);
+    ms->SetActualDataLength(haveToCopy+ms_pos);
+
+  *samplepos+=haveToCopy;
+
+  return haveToCopy+headerstrip;
+
+}
+
+long long AudioWin::SetStartOffset(long long curreftime, bool *rsync){
+  VideoWin *vw=(VideoWin*)Video::getInstance();
+  return vw->SetStartAudioOffset(curreftime,rsync);
+}
+
 #ifdef DEV
 int AudioWin::test()
 {
index e1c2e0c8f039ae536623ed0eae20498411973f22..a31bf91677f9f52fd1f175a1f51fbed99e85154d 100644 (file)
@@ -49,6 +49,12 @@ class AudioWin : public Audio
     int write(char *buf, int len);
     int getFD();
 
+    // Writing Data to Audiodevice
+    virtual UINT DeliverMediaSample(MediaPacket packet, UCHAR* buffer, UINT *samplepos);
+    virtual long long SetStartOffset(long long curreftime, bool *rsync);
+
+private:
+  bool firstsynched;
 #ifdef DEV
     int test();
 #endif
index 023debc4597bcb1f2b91e4c7d9818ae9d5d0f123..63b381703c6647e784af25b90bf47848267d5a61 100644 (file)
@@ -19,6 +19,9 @@
 */
 
 #include "command.h"
+#ifdef WIN32
+#include "remotewin.h"
+#endif
 
 Command* Command::instance = NULL;
 
@@ -147,9 +150,9 @@ void Command::run()
     // something happened, lock and process
 
 #ifndef WIN32
-  pthread_mutex_lock(&masterLock);
+    pthread_mutex_lock(&masterLock);
 #else
-  WaitForSingleObject(masterLock, INFINITE );
+    WaitForSingleObject(masterLock, INFINITE );
 #endif
 
     if ((button == Remote::NA_NONE) || (button == Remote::NA_UNKNOWN)) continue;
@@ -159,9 +162,9 @@ void Command::run()
   }
 
 #ifndef WIN32
-    pthread_mutex_unlock(&masterLock);
+  pthread_mutex_unlock(&masterLock);
 #else
-    ReleaseMutex(masterLock);
+  ReleaseMutex(masterLock);
 #endif
 }
 
@@ -174,18 +177,18 @@ void Command::postMessage(Message* m)
 
 
 #ifndef WIN32
-    pthread_mutex_lock(&masterLock);
+  pthread_mutex_lock(&masterLock);
 #else
-    WaitForSingleObject(masterLock, INFINITE );
+  WaitForSingleObject(masterLock, INFINITE );
 #endif
-    MessageQueue::postMessage(m);
+  MessageQueue::postMessage(m);
 
 #ifndef WIN32
-    kill(mainPid, SIGURG);
-    pthread_mutex_unlock(&masterLock);
+  kill(mainPid, SIGURG);
+  pthread_mutex_unlock(&masterLock);
 #else
-    //TODO: send Window Message
-    ReleaseMutex(masterLock);
+  ((RemoteWin*)Remote::getInstance())->Signal();
+  ReleaseMutex(masterLock);
 #endif
 }
 
@@ -215,17 +218,19 @@ bool Command::postMessageIfNotBusy(Message* m)
     return false;
   }
 #else
-  if (WaitForSingleObject(masterLock, INFINITE ) == WAIT_OBJECT_0)
-  {
+  switch (WaitForSingleObject(masterLock, 0 ))
+  { //FIXME this is not "if not busy" check
+    case WAIT_OBJECT_0: //but with proper argument 0 this did not work
+    // case WAIT_ABANDONED:
     MessageQueue::postMessage(m);
-    //TODO: send Window Message
+    ((RemoteWin*)Remote::getInstance())->Signal();
     ReleaseMutex(masterLock);
     return true;
+
+    case WAIT_ABANDONED: return false;
+    case WAIT_TIMEOUT: return false;
   }
-  else
-  {
     return false;
-  }
 #endif
 }
 
@@ -459,7 +464,7 @@ void Command::doJustConnected(VConnect* vconnect)
         logger->log("Command", Log::DEBUG, "Switching to NTSC");
         video->init(Video::NTSC);
       }
-      osd->init("/dev/stbgfx");
+      osd->init((char*)("/dev/stbgfx"));
 
       // Put the wallpaper back
       doWallpaper();
index d4c13bc5aea221540bed46591dd4af401fe11a06..2fc1292324cd0b8e4a2ee1f4d95daaf8c3115363 100644 (file)
--- a/defines.h
+++ b/defines.h
 #ifndef DEFINES_H
 #define DEFINES_H
 
+//#define NEW_DEMUXER //Switch for the new demuxer code
+//At the beginning the changed code will be switchable
+//in order to apply the changes also to the mvp code
+
 typedef unsigned char UCHAR;
 typedef unsigned short USHORT;
 typedef unsigned int UINT;
@@ -41,7 +45,7 @@ void MILLISLEEP(ULONG a);
 
   #define SNPRINTF _snprintf
   #define VSNPRINTF _vsnprintf
-  #define STRCASECMP stricmp
+  #define STRCASECMP _stricmp
   #define STRCASESTR StrStrI
   #define STRTOULL _strtoui64
   #define CLOSESOCKET closesocket
index f9c22f9345c0cb92b8aceb2a0676d16b9139538d..1911f4404945db95bc9e4a51f83d571f546839f1 100644 (file)
@@ -52,10 +52,14 @@ int Demuxer::init(Callback* tcallback)
          !audiostream.init(demuxMemoryA) ||
          !(local_frame = (UCHAR *) malloc(0x10000)))
     {
-    //  printf("failed to initialize demuxer\n");
+      Log::getInstance()->log("Demuxer", Log::CRIT, "Failed to initialize demuxer");
       shutdown();
       return 0;
     }
+#ifdef NEW_DEMUXER
+    videostream.setDrainTarget(Video::getInstance());
+    audiostream.setDrainTarget(Audio::getInstance());
+#endif
   }
 
   reset();
@@ -125,7 +129,7 @@ void Demuxer::setAspectRatio(enum AspectRatio ar)
   else
     arcnt = 0;
 }
-
+#ifndef NEW_DEMUXER
 int Demuxer::writeAudio(int fd)
 {
   return audiostream.drain(fd);
@@ -135,6 +139,18 @@ int Demuxer::writeVideo(int fd)
 {
   return videostream.drain(fd);
 }
+#else
+int Demuxer::writeAudio(DrainTarget* dt)
+{
+  return audiostream.drain(dt);
+}
+
+int Demuxer::writeVideo(DrainTarget* dt)
+{
+  return videostream.drain(dt);
+}
+#endif
+
 
 int Demuxer::scan(UCHAR *buf, int len)
 {
index f935dbccbf51260d41a48620bf0ee40c4a83925a..604b3cd6e6039343b245c2493e499b9ffd4f1586 100644 (file)
--- a/demuxer.h
+++ b/demuxer.h
@@ -36,6 +36,11 @@ however, no code was copied verbatim.
 #include "log.h"
 #include "defines.h"
 #include "callback.h"
+#include "draintarget.h"
+
+#include "audio.h"
+#include "video.h"
+
 
 class Demuxer
 {
@@ -50,8 +55,14 @@ class Demuxer
     void seek();
     void setVideoStream(int id);
     void setAudioStream(int id);
+#ifndef NEW_DEMUXER
     int writeAudio(int fd);
     int writeVideo(int fd);
+#else
+  int writeAudio(DrainTarget* dt);
+    int writeVideo(DrainTarget* dt);
+#endif
+
     int scan(UCHAR* buf, int len);
     int findVideoPTS(UCHAR* buf, int len, ULLONG* dest);
     int put(UCHAR* buf, int len);
diff --git a/draintarget.cc b/draintarget.cc
new file mode 100644 (file)
index 0000000..25b89e4
--- /dev/null
@@ -0,0 +1,27 @@
+/*
+    Copyright 2004-2005 Chris Tallon
+
+    This file is part of VOMP.
+
+    VOMP is free software; you can redistribute it and/or modify
+    it under the terms of the GNU General Public License as published by
+    the Free Software Foundation; either version 2 of the License, or
+    (at your option) any later version.
+
+    VOMP is distributed in the hope that it will be useful,
+    but WITHOUT ANY WARRANTY; without even the implied warranty of
+    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+    GNU General Public License for more details.
+
+    You should have received a copy of the GNU General Public License
+    along with VOMP; if not, write to the Free Software
+    Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+*/
+#include "draintarget.h"
+DrainTarget::DrainTarget(){
+
+
+}
+DrainTarget::~DrainTarget(){
+
+}
\ No newline at end of file
diff --git a/draintarget.h b/draintarget.h
new file mode 100644 (file)
index 0000000..4196e2a
--- /dev/null
@@ -0,0 +1,66 @@
+/*
+    Copyright 2004-2005 Chris Tallon
+
+    This file is part of VOMP.
+
+    VOMP is free software; you can redistribute it and/or modify
+    it under the terms of the GNU General Public License as published by
+    the Free Software Foundation; either version 2 of the License, or
+    (at your option) any later version.
+
+    VOMP is distributed in the hope that it will be useful,
+    but WITHOUT ANY WARRANTY; without even the implied warranty of
+    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+    GNU General Public License for more details.
+
+    You should have received a copy of the GNU General Public License
+    along with VOMP; if not, write to the Free Software
+    Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+*/
+
+#ifndef DRAINTARGET_H
+#define DRAINTARGET_H
+
+#include "defines.h"
+#include <list>
+
+
+
+
+struct MediaPacket{
+  ULLONG recording_byte_pos; //position in recording
+  ULLONG pts;
+  ULONG pos_buffer; //position in stream buffer
+  ULONG length; //length of the packet
+  //The last to are only needed on windows, for memory reasons they can be excluded in mvp
+  long long presentation_time;/* in 100 ns units*/
+  bool synched;
+  bool disconti;
+};
+
+using namespace std;
+
+typedef list<MediaPacket> MediaPacketList;
+
+
+class DrainTarget {
+public:
+  DrainTarget();
+  virtual ~DrainTarget();
+  virtual UINT DeliverMediaSample(MediaPacket packet, UCHAR* buffer,
+        UINT *samplepos)=0;
+
+/* This function behaviour should be:
+Try to deliver the Data from packet.pos_buffer+samplepos to packet.pos_buffer+packet.length,
+with considering the bufferwraparound according to buffersize.
+Then increasing samplepos, so that on the next call delivering can proceed. So if writebytes are
+writen samplepos=samplepos+writebytes!
+If samplepos>=packet.length is returned, the next packet can be used for the next call.*/
+
+  virtual long long SetStartOffset(long long curreftime, bool *rsync)=0;
+};
+
+
+
+
+#endif
\ No newline at end of file
diff --git a/dsock.h b/dsock.h
index 15f3700576e5a2f131a3fb4b303d41032afd8b0b..ba99d47d6c13a3f3e27060c48ea6607a92879bd3 100644 (file)
--- a/dsock.h
+++ b/dsock.h
 #include <Ws2tcpip.h>
 #endif
 
-#include <sys/types.h>
 
+#include <sys/types.h>
 #ifndef WIN32
 #include <sys/time.h>
 #else
 #include <sys/timeb.h>
 #endif
-
 #include <stdio.h>
 #include <stdlib.h>
 #include <string.h>
diff --git a/dssourcefilter.cc b/dssourcefilter.cc
new file mode 100644 (file)
index 0000000..c779dfd
--- /dev/null
@@ -0,0 +1,103 @@
+/*
+    Copyright 2004-2005 Chris Tallon
+
+    This file is part of VOMP.
+
+    VOMP is free software; you can redistribute it and/or modify
+    it under the terms of the GNU General Public License as published by
+    the Free Software Foundation; either version 2 of the License, or
+    (at your option) any later version.
+
+    VOMP is distributed in the hope that it will be useful,
+    but WITHOUT ANY WARRANTY; without even the implied warranty of
+    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+    GNU General Public License for more details.
+
+    You should have received a copy of the GNU General Public License
+    along with VOMP; if not, write to the Free Software
+    Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+*/
+#include "dssourcefilter.h"
+
+DsSourceFilter::DsSourceFilter():CBaseFilter("Vomp Source Filter",NULL,&crit_sec,_uuidof(this))
+{
+  //add audio pin
+  HRESULT res;
+  audiopin=new DsSourcePin(this,&crit_sec,&res,L"Vomp Audio Out",true);
+  videopin=new DsSourcePin(this,&crit_sec,&res,L"Vomp Video Out",false);
+
+}
+
+DsSourceFilter::~DsSourceFilter()
+{
+  if (audiopin) delete audiopin;
+  if (videopin) delete videopin;
+}
+
+int DsSourceFilter::GetPinCount()
+{
+  return 2; //audio and video
+}
+
+CBasePin *DsSourceFilter::GetPin(int n){
+  switch (n) {
+  case 0:
+    return audiopin;
+  case 1:
+    return videopin;
+  default:
+    return 0;
+  };
+}
+
+int DsSourceFilter::getCurrentAudioMediaSample(IMediaSample** ms)
+{
+  if (!audiopin || !IsActive()) {
+    return 0;
+  }
+  if (audiopin->GetDeliveryBuffer(ms,NULL,NULL,0)!=S_OK) {
+    return 0;
+  }
+  return 1;
+}
+
+int DsSourceFilter::getCurrentVideoMediaSample(IMediaSample** ms)
+{
+  if (!videopin || !IsActive()) {
+    return 0;
+  }
+  if (videopin->GetDeliveryBuffer(ms,NULL,NULL,0)!=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;
+
+}
+
+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;
+
+}
diff --git a/dssourcefilter.h b/dssourcefilter.h
new file mode 100644 (file)
index 0000000..e0d4597
--- /dev/null
@@ -0,0 +1,47 @@
+/*
+    Copyright 2004-2005 Chris Tallon
+
+    This file is part of VOMP.
+
+    VOMP is free software; you can redistribute it and/or modify
+    it under the terms of the GNU General Public License as published by
+    the Free Software Foundation; either version 2 of the License, or
+    (at your option) any later version.
+
+    VOMP is distributed in the hope that it will be useful,
+    but WITHOUT ANY WARRANTY; without even the implied warranty of
+    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+    GNU General Public License for more details.
+
+    You should have received a copy of the GNU General Public License
+    along with VOMP; if not, write to the Free Software
+    Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+*/
+
+#ifndef DSSOURCEFILTER_H
+#define DSSOURCEFILTER_H
+
+
+#include "dssourcepin.h"
+
+[uuid("EB87AB22-7A95-49c3-8CCE-2F6D61A87009")]
+class DsSourceFilter: public CBaseFilter {
+public:
+  DsSourceFilter();
+  ~DsSourceFilter();
+  CCritSec* GetLock(){return &crit_sec;};
+  virtual int GetPinCount();
+  virtual CBasePin *GetPin(int n);
+  int getCurrentAudioMediaSample(IMediaSample** ms);
+  int DeliverAudioMediaSample(IMediaSample* ms);
+  int getCurrentVideoMediaSample(IMediaSample** ms);
+  int DeliverVideoMediaSample(IMediaSample* ms);
+protected:
+  CCritSec crit_sec;
+  DsSourcePin *audiopin;
+  DsSourcePin *videopin;
+
+
+};
+
+#endif
\ No newline at end of file
diff --git a/dssourcepin.cc b/dssourcepin.cc
new file mode 100644 (file)
index 0000000..70286ee
--- /dev/null
@@ -0,0 +1,143 @@
+/*
+    Copyright 2004-2005 Chris Tallon
+
+    This file is part of VOMP.
+
+    VOMP is free software; you can redistribute it and/or modify
+    it under the terms of the GNU General Public License as published by
+    the Free Software Foundation; either version 2 of the License, or
+    (at your option) any later version.
+
+    VOMP is distributed in the hope that it will be useful,
+    but WITHOUT ANY WARRANTY; without even the implied warranty of
+    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+    GNU General Public License for more details.
+
+    You should have received a copy of the GNU General Public License
+    along with VOMP; if not, write to the Free Software
+    Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+*/
+#include "dssourcepin.h"
+#include "dssourcefilter.h"
+#include <Dvdmedia.h>
+#include <mmreg.h>
+
+DsSourcePin::DsSourcePin(DsSourceFilter *pFilter,
+             CCritSec *pLock,HRESULT *phr,LPCWSTR pName,bool audio):
+CBaseOutputPin(NAME("dssourcepin"),pFilter,pLock,phr,pName)
+{
+  isaudiopin=audio;
+  m_pFilter=pFilter;
+
+}
+
+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 (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;
+}
\ No newline at end of file
diff --git a/dssourcepin.h b/dssourcepin.h
new file mode 100644 (file)
index 0000000..4fe80d3
--- /dev/null
@@ -0,0 +1,48 @@
+/*
+    Copyright 2004-2005 Chris Tallon
+
+    This file is part of VOMP.
+
+    VOMP is free software; you can redistribute it and/or modify
+    it under the terms of the GNU General Public License as published by
+    the Free Software Foundation; either version 2 of the License, or
+    (at your option) any later version.
+
+    VOMP is distributed in the hope that it will be useful,
+    but WITHOUT ANY WARRANTY; without even the implied warranty of
+    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+    GNU General Public License for more details.
+
+    You should have received a copy of the GNU General Public License
+    along with VOMP; if not, write to the Free Software
+    Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+*/
+
+#ifndef DSPINFILTER_H
+#define DSPINFILTER_H
+
+#include <streams.h>
+
+class DsSourceFilter;
+
+[uuid("17F931AB-9A87-4c65-B99E-84F5BC5F7B09")]
+class DsSourcePin: public CBaseOutputPin {
+public:
+  DsSourcePin(DsSourceFilter *pFilter,
+             CCritSec *pLock,HRESULT *phr,LPCWSTR pName,bool audio);
+  ~DsSourcePin();
+
+  virtual  HRESULT DecideBufferSize(IMemAllocator *pa,ALLOCATOR_PROPERTIES *all_pp);
+protected:
+  virtual  HRESULT CheckMediaType(const CMediaType *pmt);
+  virtual HRESULT GetMediaType(int iPosition, CMediaType *pmt);
+  bool isaudiopin;
+  DsSourceFilter *m_pFilter;
+
+
+
+};
+
+
+
+#endif
\ No newline at end of file
index 5968ca9ebd013ec00e4d6083f0cb1cea9e439782..100e623abe865de3b30fc50642fbf967845df8ed 100644 (file)
--- a/ledwin.cc
+++ b/ledwin.cc
@@ -22,7 +22,6 @@
 
 LedWin::LedWin()
 {
-  if (instance) return;
   initted = 0;
 }
 
diff --git a/log.cc b/log.cc
index 812ad1351c4299e3c90c898e55cba5a9a1c88257..5aa1f4c98a8c1b3bfd280f71cb360318d062e5c8 100644 (file)
--- a/log.cc
+++ b/log.cc
@@ -104,10 +104,12 @@ int Log::log(char *fromModule, int level, char* message, ...)
   _ftime(&tb);
   struct tm* tms = localtime(&tb.time);
 #endif
-
   spaceLeft -= strftime(buffer, spaceLeft, "%H:%M:%S.", tms);
+#ifndef _MSC_VER
   spaceLeft -= SNPRINTF(&buffer[150-spaceLeft], spaceLeft, "%06lu ", (unsigned long)tv.tv_usec);
-
+#else
+  spaceLeft -= SNPRINTF(&buffer[150-spaceLeft], spaceLeft, "%06lu ", (unsigned long)tb.millitm);
+#endif
 
   char levelString[10];
   if (level == CRAZY)   strcpy(levelString, "[CRAZY] ");
diff --git a/log.h b/log.h
index 4f8e80c3c4620bf388a710a4193bbc9c6d3b5851..0b5c197bed65e4ef3b95b0a7cfea1413a668c213 100644 (file)
--- a/log.h
+++ b/log.h
@@ -26,7 +26,6 @@
 #ifndef WIN32
  #include <sys/time.h>
 #else
- #include <winsock2.h>
  #include <sys/timeb.h>
 #endif
 
diff --git a/main.cc b/main.cc
index ddff33e84844c9c0631bca65e945868c53f6ac39..7c8e1473b6eb9d6f93b627ceab13292e3d4bd118 100644 (file)
--- a/main.cc
+++ b/main.cc
@@ -237,7 +237,7 @@ int main(int argc, char** argv)
     shutdown(1);
   }
 
-  success = osd->init("/dev/stbgfx");
+  success = osd->init((void*)("/dev/stbgfx"));
   if (success)
   {
     logger->log("Core", Log::INFO, "OSD module initialised");
index 0c7e3384386f3766a14b6bb8d7e1a610ad32e6e2..51cc3c6761029deba971e63b3005d54b4fd01b16 100644 (file)
--- a/mtdwin.cc
+++ b/mtdwin.cc
 */
 
 #include "mtdwin.h"
+#include "video.h"
 
 MtdWin::MtdWin()
 {
-  if (instance) return;
   initted = 0;
 }
 
@@ -46,5 +46,5 @@ int MtdWin::shutdown()
 
 short MtdWin::getPALorNTSC()
 {
-  return 0;
+  return Video::PAL; //Fixme!
 }
index 4a6086eab1a5ded9146b5347330fa1b6a7dd66b9..debd5d43eee72b753d760fc14dc68ef0c13bbc77 100644 (file)
--- a/mtdwin.h
+++ b/mtdwin.h
@@ -29,10 +29,10 @@ class MtdWin : public Mtd
     MtdWin();
     ~MtdWin();
 
-    int init(char* device);
-    int shutdown();
virtual   int init(char* device);
virtual   int shutdown();
 
-    short getPALorNTSC();
+virtual    short getPALorNTSC();
 
   private:
     int initted;
diff --git a/osd.h b/osd.h
index e0d57b225d1aac4d93e44ffdf1cd20c13f2e694e..c22dfe0e98ea96edca4d4a95646befa88825b65b 100644 (file)
--- a/osd.h
+++ b/osd.h
@@ -32,7 +32,7 @@ class Osd
     virtual ~Osd();
     static Osd* getInstance();
 
-    virtual int init(char* device)=0;
+    virtual int init(void* device)=0;
     virtual int shutdown()=0;
 
     virtual int getFD()=0;
index a86f9a01f13b68ef91c3ccb8298bfb0274cd3292..531d57038e2831656fcd61d70fbe0c951efd7b72 100644 (file)
--- a/osdmvp.cc
+++ b/osdmvp.cc
@@ -36,11 +36,11 @@ int OsdMVP::getFD()
   return fdOsd;
 }
 
-int OsdMVP::init(char* device)
+int OsdMVP::init(void* device)
 {
   if (initted) return 0;
 
-  fdOsd = open(device, O_RDWR);
+  fdOsd = open((char*)device, O_RDWR);
   if (!fdOsd)
   {
     Log::getInstance()->log("OSD", Log::DEBUG, "Could not open OSD device!");
index 5b6dfc407a6846284682c484ed95405cfd691f10..ce91121a38d2dfdc313329d3f8fa8fff4512525c 100644 (file)
--- a/osdmvp.h
+++ b/osdmvp.h
@@ -37,7 +37,7 @@ class OsdMVP : public Osd
     OsdMVP();
     ~OsdMVP();
 
-    int init(char* device);
+    int init(void* device);
     int shutdown();
 
     int getFD();
index 9e4c9a5aaced99e9ee3b465785e91729b48ef5ca..8b2a2c4148fa58dfe824c062b493f8aa9d3d148e 100644 (file)
--- a/osdwin.cc
+++ b/osdwin.cc
 */
 
 #include "osdwin.h"
+#include "mtd.h"
+#include "video.h"
+#include "surfacewin.h"
+
+//This is stuff for rendering the OSD
+
 
 OsdWin::OsdWin()
 {
-  if (instance) return;
+  d3d=NULL;
+  d3ddevice=NULL;
+  d3dvb=NULL;
+  external_driving=false;
+  event = CreateEvent(NULL,/*FALSE*/TRUE,FALSE,NULL);
+  d3dmutex = CreateMutex(NULL,FALSE,NULL);
+
 }
 
 OsdWin::~OsdWin()
 {
   if (initted) shutdown();
+  CloseHandle(event);
+  CloseHandle(d3dmutex);
 }
 
 int OsdWin::getFD()
@@ -36,18 +50,104 @@ int OsdWin::getFD()
   return fdOsd;
 }
 
-int OsdWin::init(char* device)
+int OsdWin::init(void* device)
 {
   if (initted) return 0;
+   Video* video = Video::getInstance();
+  //First Create Direct 3D Object
+  d3d=Direct3DCreate9(D3D_SDK_VERSION);
+  if (!d3d)
+  {
+    Log::getInstance()->log("OSD", Log::DEBUG, "Could not create Direct3D9 object!");
+    return 0;
+  }
+  // then create the Device
+  D3DPRESENT_PARAMETERS d3dparas;
+  ZeroMemory(&d3dparas,sizeof(d3dparas));
+  d3dparas.BackBufferWidth=video->getScreenWidth();
+  d3dparas.BackBufferHeight=video->getScreenHeight();
+  d3dparas.Windowed=TRUE;
+  d3dparas.SwapEffect=D3DSWAPEFFECT_COPY;
+  if (d3d->CreateDevice(D3DADAPTER_DEFAULT,D3DDEVTYPE_HAL,*((HWND*) device),
+    D3DCREATE_SOFTWARE_VERTEXPROCESSING,&d3dparas,&d3ddevice)!=D3D_OK) {
+     Log::getInstance()->log("OSD", Log::DEBUG, "Could not create Direct3D9 device!");
+       return 0;
+  }
+  //TODO a render function and a device lost detection
+
+  if (!InitVertexBuffer()) {
+     Log::getInstance()->log("OSD", Log::DEBUG, "Could not create Direct3D9 vertex buf!");
+      return 0;
+  }
+
+  //Now we will create the Screen
+  screen = new SurfaceWin(Surface::SCREEN);
+  SetEvent(event);//Now all devices are ready
+  screen->create(video->getScreenWidth(), video->getScreenHeight());
+  screen->display();
   initted = 1; // must set this here or create surface won't work
 
   return 1;
 }
 
+
+int OsdWin::InitVertexBuffer() {
+  Video* video = Video::getInstance();
+  FLOAT texx=((float)video->getScreenWidth())/1024.f;
+  FLOAT texy=((float)video->getScreenHeight())/1024.f;
+  D3DCOLOR osdcolor=D3DCOLOR_RGBA(255,255,255,255);
+  osdvertices[0].c=osdcolor;
+  osdvertices[0].x=0.f-0.5f;
+  osdvertices[0].y=0.f-0.5f;
+  osdvertices[0].z=0.5f;
+  osdvertices[0].rhw=1.f;
+  osdvertices[0].u=0.f;
+  osdvertices[0].v=0.f;
+  osdvertices[1].c=osdcolor;
+  osdvertices[1].x=((float)video->getScreenWidth())-0.5f;-0.5f;
+  osdvertices[1].y=0.f-0.5f;
+  osdvertices[1].z=0.5f;
+  osdvertices[1].u=texx;
+  osdvertices[1].v=0.f;
+  osdvertices[1].rhw=1.f;
+  osdvertices[2].c=osdcolor;
+  osdvertices[2].x=((float)video->getScreenWidth())-0.5f;
+  osdvertices[2].y=((float)video->getScreenHeight())-0.5f;
+  osdvertices[2].z=0.5f;
+  osdvertices[2].rhw=1.f;
+  osdvertices[2].u=texx;
+  osdvertices[2].v=texy;
+  osdvertices[3].c=osdcolor;
+  osdvertices[3].x=0.f-0.5f;
+  osdvertices[3].y=((float)video->getScreenHeight())-0.5f;
+  osdvertices[3].z=0;
+  osdvertices[3].rhw=1.f;
+  osdvertices[3].u=0.f;
+  osdvertices[3].v=texy;
+  if (d3dvb) {
+    d3dvb->Release();
+    d3dvb=NULL;
+  }
+  if (d3ddevice->CreateVertexBuffer(4*sizeof(OSDVERTEX),0,D3DFVF_OSDVERTEX,D3DPOOL_MANAGED,
+    &d3dvb,NULL)!=D3D_OK) {
+    return 0;
+  }
+  void *pvertex=NULL;
+  if (d3dvb->Lock(0,sizeof(osdvertices),&pvertex,0)!=D3D_OK) {
+    return 0;
+  }
+  memcpy(pvertex,osdvertices,sizeof(osdvertices));
+  d3dvb->Unlock();
+  return 1;
+}
+
 int OsdWin::shutdown()
 {
   if (!initted) return 0;
   initted = 0;
+  d3ddevice->Release();
+  d3d->Release();
+
   return 1;
 }
 
@@ -55,3 +155,90 @@ void OsdWin::screenShot(char* fileName)
 {
   screen->screenShot(fileName);
 }
+
+// This function is called from the WinMain function in order to get Screen updates
+void OsdWin::Render()
+{
+  if (!initted) return ;
+  if (external_driving) {
+    Sleep(5); //Sleep for 5 ms, in order to avoid blocking the other threads
+  } else {
+    InternalRendering();
+  }
+}
+
+
+void OsdWin::InternalRendering(){
+  WaitForSingleObject(event,INFINITE);
+  BeginPainting();
+  if (external_driving) {
+    //Copy video to Backbuffer
+  } else {
+    //Clear Background
+    d3ddevice->Clear(0,NULL,D3DCLEAR_TARGET,D3DCOLOR_XRGB(0,0,255),1.0f,0);
+  }
+  //Drawing the OSD
+  if (d3ddevice->BeginScene()==D3D_OK) {
+    d3ddevice->SetStreamSource(0,d3dvb,0,sizeof(OSDVERTEX));
+    d3ddevice->SetFVF(D3DFVF_OSDVERTEX);
+    d3ddevice->SetTexture(0,((SurfaceWin*)screen)->getD3dtexture());
+    //d3ddevice->SetTextureStageState(0,D3DTSS_COLOROP,D3DTOP_MODULATE);
+    d3ddevice->SetTextureStageState(0, D3DTSS_ALPHAOP,D3DTOP_MODULATE);
+    d3ddevice->SetRenderState(D3DRS_ALPHABLENDENABLE,TRUE);
+    d3ddevice->SetRenderState(D3DRS_DESTBLEND,D3DBLEND_INVSRCALPHA);
+    d3ddevice->SetRenderState(D3DRS_SRCBLEND, D3DBLEND_SRCALPHA);
+    d3ddevice->SetRenderState(D3DRS_LIGHTING,FALSE);
+
+
+    d3ddevice->DrawPrimitive(D3DPT_TRIANGLEFAN,0,2);
+    d3ddevice->EndScene();
+    //Show it to the user!
+    if (d3ddevice->Present(NULL,NULL,NULL,NULL)==D3DERR_DEVICELOST){
+      EndPainting();
+      DoLost();
+    }
+    EndPainting();
+  }
+  if (!external_driving) {
+    Sleep(4);//The User can wait for 4 milliseconds to see his changes
+  }
+}
+
+void OsdWin::DoLost(){
+  Log::getInstance()->log("OSD", Log::DEBUG, "Direct3D Device Lost! Reobtaining...");
+  ResetEvent(event);
+  //First we free up all resources
+  Video* video = Video::getInstance();
+  ((SurfaceWin*)screen)->ReleaseSurface();
+  d3dvb->Release();
+  d3dvb=NULL;
+  D3DPRESENT_PARAMETERS d3dparas;
+  ZeroMemory(&d3dparas,sizeof(d3dparas));
+  d3dparas.BackBufferWidth=video->getScreenWidth();
+  d3dparas.BackBufferHeight=video->getScreenHeight();
+  d3dparas.Windowed=TRUE;
+  d3dparas.SwapEffect=D3DSWAPEFFECT_COPY;
+  if (d3ddevice->Reset(&d3dparas)!=D3D_OK){
+    return;
+  }
+  screen->create(video->getScreenWidth(), video->getScreenHeight());
+  screen->display();
+  InitVertexBuffer();
+  //Redraw Views, Chris could you add a member function to viewman, so that
+  // I can cause it to completely redraw the Views?
+  // Otherwise the OSD would be distorted after Device Lost
+  SetEvent(event);
+
+}
+LPDIRECT3DDEVICE9 OsdWin::getD3dDev() {
+  WaitForSingleObject(event,INFINITE);//We will only return if we are initted
+  return d3ddevice;
+}
+
+void OsdWin::BeginPainting() {//We synchronize calls to d3d between different threads
+  WaitForSingleObject(d3dmutex,INFINITE);
+}
+
+void OsdWin::EndPainting() {
+  ReleaseMutex(d3dmutex);
+}
index 0a084be12f3b27f16eb72e82fffb923119406738..a22f356d8f7d69cb31a0b6aeed5eb712e5774e20 100644 (file)
--- a/osdwin.h
+++ b/osdwin.h
 #include "osd.h"
 #include "defines.h"
 #include "log.h"
+#include <winsock2.h>
+#include <d3d9.h>
+
+struct OSDVERTEX
+{
+  FLOAT x,y,z,rhw;
+  DWORD c;
+  FLOAT u,v;
+};
+
+#define D3DFVF_OSDVERTEX (D3DFVF_XYZRHW|D3DFVF_DIFFUSE| D3DFVF_TEX1)
+
 
 class OsdWin : public Osd
 {
@@ -33,14 +45,30 @@ class OsdWin : public Osd
     OsdWin();
     ~OsdWin();
 
-    int init(char* device);
+    int init(void* device);
     int shutdown();
 
     int getFD();
 
     void screenShot(char* fileName);
 
-  private:
+  LPDIRECT3DDEVICE9 getD3dDev() ;
+  // This function is called from the WinMain function in order to get Screen updates
+  void Render();
+  void BeginPainting();
+  void EndPainting();
+private:
+    LPDIRECT3D9 d3d;
+    LPDIRECT3DDEVICE9 d3ddevice;
+    LPDIRECT3DVERTEXBUFFER9 d3dvb;
+  // This indicates, that currently a video is played, thus the osd updates are driven by the Directshow Filtersystem
+  bool external_driving;
+  HANDLE d3dmutex;
+  void InternalRendering();
+  void DoLost();
+  int InitVertexBuffer();
+  OSDVERTEX osdvertices[4];
+  HANDLE event;
 };
 
 #endif
index 3dc1876e665dc9aa3f75ae362c6d1567ae2846c1..e17d7361708c86ef3e5d79730a98bd6331226201 100644 (file)
--- a/player.cc
+++ b/player.cc
@@ -35,6 +35,7 @@ Player::Player(MessageQueue* messageQueue, UCHAR tIsRecording, UCHAR isRadio)
   streamLength = 0;
   feedPosition = 0;
   feedMode = MODE_NORMAL;
+  videoStartup = false;
   isRecording = tIsRecording;
   lastRescan = 0;
   startTS = 0;
@@ -46,11 +47,13 @@ Player::Player(MessageQueue* messageQueue, UCHAR tIsRecording, UCHAR isRadio)
   {
     blockSize = 20000;
     startupBlockSize = 60000;
+  video->turnVideoOff();
   }
   else
   {
     blockSize = 100000;
     startupBlockSize = 250000;
+  video->turnVideoOn();
   }
 }
 
@@ -69,9 +72,13 @@ int Player::init()
     shutdown();
     return 0;
   }
-
+#ifndef NEW_DEMUXER
   vfeed.init(video->getFD());
   afeed.init(audio->getFD());
+#else
+  vfeed.init(video);
+  afeed.init(audio);
+#endif
 
   video->stop();
   video->blank();
@@ -166,29 +173,17 @@ int Player::play()
   demuxer.reset();
 
 // ------------------------ This one works, but doesn't allow any pre-buffering.
+  videoStartup = true;
   threadStart();
-  vfeed.start();
   afeed.start();
-  audio->play();
-  video->play();
   video->sync();
   audio->sync();
+  audio->play();
+  video->pause();
+
 
-  resyncVideo();
 // ------------------------ This one doesn't work, but it should, and would allow for prebuffering.
 
-/*
-  threadStart();
-//  MILLISLEEP(1000);
-
-  vfeed.start();
-  afeed.start();
-  video->play();
-  audio->play();
-  audio->sync();
-  video->sync();
-  resyncVideo();
-*/
 
 // ------------------------------------------------------------------------------------------------
 
@@ -263,13 +258,12 @@ void Player::setLength(ULLONG length)
   logger->log("Player", Log::DEBUG, "Player has received length of %llu", streamLength);
 }
 
-void Player::skipForward(int seconds)
+void Player::restartAt(ULLONG timecode)
 {
-  logger->log("Player", Log::DEBUG, "SKIP FORWARD %i SECONDS", seconds);
-
   if (paused) togglePause();
+  if (ffwd) toggleFastForward();
 
-  ULONG wantedFrameNumber = video->timecodeToFrameNumber(getPositionTS() + (seconds * 90000));
+  ULONG wantedFrameNumber = video->timecodeToFrameNumber(timecode);
   ULLONG newPosition = VDR::getInstance()->positionFromFrameNumber(wantedFrameNumber);
   if (!VDR::getInstance()->isConnected()) { doConnectionLost(); return; }
   logger->log("Player", Log::DEBUG, "wantedframe %i feedpos %llu goto %llu", wantedFrameNumber, feedPosition, newPosition);
@@ -280,66 +274,38 @@ void Player::skipForward(int seconds)
   video->stop();
   video->reset();
   audio->reset();
-  audio->doMuting();  // ???
   demuxer.flush();
   feedPosition = newPosition;
-  vfeed.start();
+  videoStartup = true;
   afeed.start();
   threadStart();
   audio->play();
-  video->play();
   video->sync();
   audio->sync();
   audio->systemMuteOff();
   audio->doMuting();
-  ffwd = false;
   fbwd = false;
-  paused = false;
+}
 
-  resyncVideo();
+void Player::skipForward(int seconds)
+{
+  logger->log("Player", Log::DEBUG, "SKIP FORWARD %i SECONDS", seconds);
+  restartAt(getPositionTS() + (seconds * 90000));
 }
 
 void Player::skipBackward(int seconds)
 {
   logger->log("Player", Log::DEBUG, "SKIP BACKWARD %i SECONDS", seconds);
-
-  if (paused) togglePause();
-
-  ULLONG newPosition = 0;
-
   long long newTimeCode = getPositionTS() - (seconds * 90000);
-  if (newTimeCode > 0)
-  {
-    ULONG wantedFrameNumber = video->timecodeToFrameNumber((ULLONG)newTimeCode);
-    newPosition = VDR::getInstance()->positionFromFrameNumber(wantedFrameNumber);
-    if (!VDR::getInstance()->isConnected()) { doConnectionLost(); return; }
-    logger->log("Player", Log::DEBUG, "wantedframe %i feedpos %llu goto %llu", wantedFrameNumber, feedPosition, newPosition);
-  }
-
-  vfeed.stop();
-  afeed.stop();
-  threadStop();
-  video->stop();
-  audio->stop();
-  video->reset();
-  audio->reset();
-  audio->doMuting(); // ???
-  demuxer.flush();
-  feedPosition = newPosition;
-  vfeed.start();
-  afeed.start();
-  threadStart();
-  audio->play();
-  video->play();
-  video->sync();
-  audio->sync();
-  audio->systemMuteOff();
-  audio->doMuting();
-  ffwd = false;
-  fbwd = false;
-  paused = false;
+  if (newTimeCode < 0) newTimeCode = 0;
+  restartAt(newTimeCode);
+}
 
-  resyncVideo();
+void Player::jumpToPercent(int percent)
+{
+  logger->log("Player", Log::DEBUG, "JUMP TO %i%%", percent);
+  ULLONG newTimeCode = (ULLONG)(getEndTS() * ((float)percent / 100));
+  restartAt(newTimeCode);
 }
 
 void Player::toggleFastForward()
@@ -353,41 +319,25 @@ void Player::toggleFastForward()
   if (ffwd)
   {
     ffwd = false;
-//    video->unFastForward();
-
-
+    threadStop();
     vfeed.stop();
     afeed.stop();
-    threadStop();
     video->stop();
     audio->stop();
     video->reset();
     audio->reset();
     demuxer.flush();
-//    demuxer.seek();
-    vfeed.start();
+
+    videoStartup = true;
     afeed.enable();
     afeed.start();
     threadStart();
-    video->play();
-    audio->play();
-    video->sync();
-    audio->sync();
-
-    audio->systemMuteOff();
-
-    resyncVideo();
-/*
-    demuxer.flushAudio();
-    audio->reset();
-    afeed.enable();
-    //video->reset();
     audio->play();
-    video->play();
     video->sync();
     audio->sync();
     audio->systemMuteOff();
-*/
+    audio->doMuting();
+    fbwd = false;
   }
   else
   {
@@ -431,32 +381,6 @@ void Player::toggleFastBackward()
   }
 }
 
-void Player::jumpToPercent(int percent)
-{
-  if (paused) togglePause();
-  if (ffwd) toggleFastForward();
-
-  vfeed.stop();
-  afeed.stop();
-  threadStop();
-  video->stop();
-  audio->stop();
-  video->reset();
-  audio->reset();
-  demuxer.flush();
-  demuxer.seek();
-  feedPosition = streamLength * percent / 100;
-  vfeed.start();
-  afeed.start();
-  threadStart();
-  audio->play();
-  video->play();
-  video->sync();
-  audio->sync();
-
-  resyncVideo();
-}
-
 ULLONG Player::getPositionTS()
 {
   if (startup) return 0ULL;
@@ -503,10 +427,21 @@ void Player::call(void* caller)
   }
   else
   {
+    if (videoStartup)
+    {
+      videoStartup = false;
+      logger->log("Player", Log::DEBUG, "Starting VFeed");
+      MILLISLEEP(500);
+      logger->log("Player", Log::DEBUG, "Starting VFeed2");
+      video->reset();
+      video->play();
+      video->sync();
+      vfeed.start();
+    }
+
     threadSignalNoLock();
   }
 }
-
 void Player::doConnectionLost()
 {
   Message* m = new Message();
@@ -698,10 +633,12 @@ void Player::setEndTS()
 void Player::test1()
 {
   logger->log("Player", Log::DEBUG, "PLAYER TEST 1");
+  video->setAspectRatio(Video::ASPECT4X3);
 }
 
 void Player::test2()
 {
   logger->log("Player", Log::DEBUG, "PLAYER TEST 2");
+  video->setAspectRatio(Video::ASPECT16X9);
 }
 #endif
index d7a5ec7ef786acfdf7a74a8e6329c09c5f97b67e..0fef7a1c8d82cd21cba5fbda03680824f830e5ba 100644 (file)
--- a/player.h
+++ b/player.h
@@ -81,6 +81,7 @@ class Player : public Thread_TYPE, public Callback
     void setStartTS(UINT dataInBuffer);
     void setEndTS();
     void doConnectionLost();
+    void restartAt(ULLONG timeCode);
 
    int initted;
     MessageQueue* commandMessageQueue;
@@ -91,6 +92,7 @@ class Player : public Thread_TYPE, public Callback
     int startup;
     VFeed vfeed;
     AFeed afeed;
+    bool videoStartup;
 
     ULLONG startTS;
     ULLONG endTS;
index 04e54758b466861b562b64fa60b9ab29a7da3853..37e1facefe6abbe5dda4bd6d45fd65b382f52e5f 100644 (file)
 
 #include "remotewin.h"
 
+
 RemoteWin::RemoteWin()
 {
-  if (instance) return;
   initted = 0;
+  curevent=NA_NONE;
+  signal=false;
 }
 
 RemoteWin::~RemoteWin()
@@ -34,6 +36,8 @@ int RemoteWin::init(char* devName)
 {
   if (initted) return 0;
   initted = 1;
+  event = CreateEvent(NULL,/*FALSE*/TRUE,FALSE,NULL);
+
 
   return 1;
 }
@@ -41,6 +45,7 @@ int RemoteWin::init(char* devName)
 int RemoteWin::shutdown()
 {
   if (!initted) return 0;
+  CloseHandle(event);
   initted = 0;
   return 1;
 }
@@ -52,11 +57,155 @@ UCHAR RemoteWin::getButtonPress(int waitType)
      how = 2 - continue wait
      how = 3 - no wait
   */
+  DWORD wait;
 
+  if (curevent!=NA_NONE) {
+    UCHAR temp=curevent;
+    curevent=NA_NONE;
+    return temp;
+  }
+  if (waitType==3) {
+    return NA_NONE;
+  }
+  if (waitType==0) {
+    wait=INFINITE;
+  } else { //We do not distingish between 2 and 3
+    wait=1000;
+
+  }
+  WaitForSingleObject(event,wait);
+  ResetEvent(event);
+  if (curevent==NA_NONE) {
+    if (signal) {
+      signal=false;
+    return NA_SIGNAL; //Since we have no signals on windows, we simulate this
+    } else {
+      return NA_NONE;
+    }
+  }
+  UCHAR temp2=curevent;
+  curevent=NA_NONE;
+  return temp2;
 
-  return NA_UNKNOWN;
 }
 
 void RemoteWin::clearBuffer()
 {
 }
+
+int RemoteWin::ReceiveButtonVK(UINT button) {
+  UCHAR pb=NA_NONE;
+  //should we use a translation table ? No APPCOMMAND iS DWORD!
+  switch (button) { //Processing VK_Messages
+  case VK_DOWN:
+    pb=DOWN; break;
+  case VK_RETURN:
+  case VK_SPACE:
+    pb=OK;break;
+  case VK_LEFT:
+    pb=LEFT;break;
+  case '9':
+  case VK_NUMPAD9:
+    pb=NINE;break;
+  case '8':
+  case VK_NUMPAD8:
+    pb=EIGHT;break;
+  case '7':
+  case VK_NUMPAD7:
+    pb=SEVEN;break;
+  case '6':
+  case VK_NUMPAD6:
+    pb=SIX;break;
+  case '5':
+  case VK_NUMPAD5:
+    pb=FIVE;break;
+  case '4':
+  case VK_NUMPAD4:
+    pb=FOUR;break;
+  case '3':
+  case VK_NUMPAD3:
+    pb=THREE;break;
+  case '2':
+  case VK_NUMPAD2:
+    pb=TWO;break;
+  case '1':
+  case VK_NUMPAD1:
+    pb=ONE;break;
+  case '0':
+  case VK_NUMPAD0:
+    pb=ZERO;break;
+  case VK_RIGHT:
+    pb=RIGHT;break;
+  case VK_UP:
+    pb=UP;break;
+  case VK_MULTIPLY:
+    pb=STAR;break;
+  case 'J'://j for JUMP TO instead of go to
+    pb=GO;break;
+  case VK_ESCAPE:
+    pb=POWER;break;
+  case VK_BACK:
+    pb=BACK;break;
+  case 'M':
+    pb=MENU;break;
+  case 'R':
+    pb=RED;break;
+  case 'G':
+    pb=GREEN;break;
+  case 'Y':
+    pb=YELLOW;break;
+  case 'B':
+    pb=BLUE; break;
+
+
+  }; //All other commands are process via APPCOMMAND_MESSAGES
+  if (pb==NA_NONE) return 0;
+  curevent=pb;
+  //PulseEvent(event);
+  SetEvent(event);
+  return 1;
+}
+
+int RemoteWin::ReceiveButtonAP(UINT button) {
+  UCHAR pb=NA_NONE;
+  //should we use a translation table ? No APPCOMMAND iS DWORD!
+  switch (button) { //Processing VK_Messages
+  case APPCOMMAND_MEDIA_CHANNEL_DOWN:
+    pb=CHANNELDOWN;break;
+  case APPCOMMAND_MEDIA_CHANNEL_UP:
+    pb=CHANNELUP;break;
+  case APPCOMMAND_MEDIA_FAST_FORWARD:
+    pb=FORWARD;break;
+  case APPCOMMAND_VOLUME_MUTE:
+    pb=MUTE;break;
+  case APPCOMMAND_MEDIA_PAUSE:
+    pb=PAUSE;break;
+  case APPCOMMAND_MEDIA_PLAY:
+    pb=PLAY;break;
+  case APPCOMMAND_MEDIA_RECORD:
+    pb=RECORD;break;
+  case APPCOMMAND_MEDIA_PREVIOUSTRACK:
+    pb=SKIPBACK;break;
+  case APPCOMMAND_MEDIA_REWIND:
+    pb=REVERSE;break;
+  case APPCOMMAND_MEDIA_NEXTTRACK:
+    pb=SKIPFORWARD;break;
+  case APPCOMMAND_MEDIA_STOP:
+    pb=STOP;break;
+  case APPCOMMAND_VOLUME_DOWN:
+    pb=VOLUMEDOWN;break;
+  case APPCOMMAND_VOLUME_UP:
+    pb=VOLUMEUP;break;
+  };
+  if (pb==NA_NONE) return 0;
+  curevent=pb;
+  //PulseEvent(event);
+  SetEvent(event);
+  return 1;
+}
+
+void RemoteWin::Signal() {
+  signal=true;
+  //PulseEvent(event);
+  SetEvent(event);
+}
index 1ec004703d24cbf20d42f92aa418d3c82676f242..4d122355dc6aefde14d5b8201c8ba55b6341ad44 100644 (file)
 #include "log.h"
 #include "remote.h"
 
+#define _WIN32_WINNT 0x501
+#include <winsock2.h>
+#include <windowsx.h>
+
+
+
 class RemoteWin : public Remote
 {
   public:
@@ -38,9 +44,15 @@ class RemoteWin : public Remote
     int getDevice();
     UCHAR getButtonPress(int how);
     void clearBuffer();
+    void Signal();
+    int ReceiveButtonVK(UINT button);//Windows Message from WND_PROC
+  int ReceiveButtonAP(UINT button);
 
   private:
     int initted;
+  bool signal;
+  UCHAR curevent;
+  HANDLE event;
 };
 
 #endif
index a04088b3bf3bcb9cf1501380da5fad58846a445d..a5ba6a4d3ebee3c1ac1f955d4bb0db4ae72434dc 100644 (file)
--- a/stream.cc
+++ b/stream.cc
 Stream::Stream()
 {
   initted = 0;
+#ifdef NEW_DEMUXER
+  cur_packet_pos=0;
+  draintarget=NULL;
+#endif
 }
 
 Stream::~Stream()
@@ -32,9 +36,7 @@ Stream::~Stream()
 
 void Stream::shutdown()
 {
-  if (initted) {
-    free(outbuf);
-  }
+  if (initted) free(outbuf);
   initted = 0;
 }
 
@@ -52,11 +54,15 @@ int Stream::init(int bufsize)
 
 void Stream::flush()
 {
+#ifdef NEW_DEMUXER
+  mediapackets.clear();
+#endif
   bufferHead = 0;
   bufferTail = 0;
   bufferMark = -1;
 }
 
+#ifndef NEW_DEMUXER
 int Stream::put(UCHAR* inbuf, int len)
 {
   int ret = 0;
@@ -93,7 +99,77 @@ int Stream::put(UCHAR* inbuf, int len)
   }
   return ret;
 }
-  
+#else
+int Stream::put(UCHAR* inbuf, int len)
+{
+  int ret = 0;
+  int tail = bufferTail;
+  int head = bufferHead;
+  if (tail == 0) tail = bufferSize;
+
+  if (!draintarget) return 0;
+  MediaPacket newPacket;
+  newPacket.length=len;
+  newPacket.pos_buffer=0;
+  newPacket.recording_byte_pos=0;
+  newPacket.synched=false;
+  newPacket.disconti=false;
+  newPacket.pts=0;
+  newPacket.presentation_time=0;
+  //Extract the pts...
+  if ((inbuf[7] & 0x80) && len>14 ) {
+    newPacket.synched=true;
+    newPacket.pts=((ULLONG)(inbuf[9] & 0x0E) << 29 ) |
+                ( (ULLONG)(inbuf[10])        << 22 ) |
+                ( (ULLONG)(inbuf[11] & 0xFE) << 14 ) |
+                ( (ULLONG)(inbuf[12])        <<  7 ) |
+                ( (ULLONG)(inbuf[13] & 0xFE) >>  1 );
+  //ok we have the pts now convert it to a continously time code in 100ns units
+    newPacket.presentation_time=(ULLONG)(newPacket.pts*10000LL/90LL);
+    newPacket.presentation_time-=draintarget->SetStartOffset(newPacket.presentation_time,&newPacket.disconti);
+  }
+
+  if (head < tail)
+  {
+    // The free space is in one continuous chunk.
+    if (len < tail - head)
+    {
+      memcpy(outbuf + head, inbuf, len);
+      bufferHead += len;
+      ret = len;
+      newPacket.pos_buffer=head;
+      mediapackets.push_front(newPacket);
+    }
+  }
+  else if (len <= bufferSize - head)
+  {
+    // There is enough space above the Head.
+    memcpy(outbuf + head, inbuf, len);
+    if (head + len == bufferSize)
+      bufferHead = 0;
+    else
+      bufferHead += len;
+
+    newPacket.pos_buffer=head;
+    mediapackets.push_front(newPacket);
+
+    ret = len;
+  }
+  else if (len < tail)
+  {
+    bufferMark = head;
+    memcpy(outbuf, inbuf, len);
+    bufferHead = len;
+    ret = len;
+    newPacket.pos_buffer=0;
+    mediapackets.push_front(newPacket);
+  }
+  return ret;
+}
+#endif
+
+#ifndef NEW_DEMUXER
+
 int Stream::drain(int fd)
 {
   int ret = 0;
@@ -101,13 +177,18 @@ int Stream::drain(int fd)
   int tail = bufferTail;
   int mark = bufferMark;
   int written;
-#ifndef WIN32
+
   if (mark == -1 && tail > head) mark = bufferSize;
 
   if (mark >= 0)
   {
     // Drain up to the marker.
+#ifndef WIN32
     written = write(fd, outbuf + tail, (mark - tail));
+#else
+    written=mark-tail;
+    MILLISLEEP(1);
+#endif
     if (written < 0) return ret;
     ret += written;
     if (written == (mark - tail))
@@ -123,14 +204,55 @@ int Stream::drain(int fd)
   }
 
   if (tail == head) return ret; // Empty
-
+#ifndef WIN32
   written = write(fd, outbuf + tail, (head - tail));
+#else
+  written=(head - tail);
+  MILLISLEEP(1);
+#endif
   if (written < 0) return ret;
   ret += written;
   bufferTail = tail + written;
   return ret;
-  #else
-  return 0; //to do!
-  #endif //Again this have to betransformed into abstract base class and derived class
+}
+#else
+int Stream::drain(DrainTarget* dt)
+{
+  int ret = 0;
+  int written=1;
+  draintarget=dt;
 
+
+
+  if (mediapackets.empty()) {
+    return 0;
+  }
+   // using mediapackets, may be this is slower but it is more flexible
+ // while (!mediapackets.empty() && written) {
+
+  int head = bufferHead;
+  int tail = bufferTail;
+  int mark = bufferMark;
+  if (mark == -1 && tail > head) mark = bufferSize;
+  MediaPacket cur_mp=mediapackets.back();
+  written=0;
+  written=dt->DeliverMediaSample(cur_mp,outbuf,&cur_packet_pos);
+
+  ret+=written;
+
+  if (cur_packet_pos==cur_mp.length) {
+    cur_packet_pos=0;
+    mediapackets.pop_back();
+    if ((int)(tail+cur_mp.length) < mark) {
+      bufferTail=tail+cur_mp.length;
+    } else {
+      bufferTail=0;
+      bufferMark=-1;
+    }
+
+  }
+
+  return ret;
 }
+
+#endif
index d7d02eab84be5c92ca000c718f200fc1f189c9d4..0b488406e450bc34e99b2fe1cbffee79dc5eb93a 100644 (file)
--- a/stream.h
+++ b/stream.h
@@ -27,6 +27,9 @@
 #endif
 #include <memory.h>
 #include "defines.h"
+#include "draintarget.h"
+
+
 
 class Stream
 {
@@ -37,9 +40,19 @@ class Stream
     void shutdown();
     void flush();
     int put(UCHAR* inbuf, int len);
+#ifndef NEW_DEMUXER
     int drain(int fd);
+#else
+    int drain(DrainTarget* fd);
+    void setDrainTarget(DrainTarget *dt) {draintarget=dt;};
+#endif
 
   private:
+#ifdef NEW_DEMUXER
+    MediaPacketList mediapackets;
+    UINT cur_packet_pos;
+    DrainTarget* draintarget;
+#endif
 
     int initted;
     UCHAR* outbuf;
index 34034d52e8ebc2b304742a5740876fdee1a1d688..d17195ce4dbbd0702aed595cbd608a46bffe1c66 100644 (file)
 */
 
 #include "surfacewin.h"
-#include "osd.h"
+#include "osdwin.h"
+#include <d3dx9tex.h>
 
 SurfaceWin::SurfaceWin(int id)
 : Surface(id)
 {
+  d3dtexture=NULL;
+  d3dsurface=NULL;
+  sheight=swidth=0;
+  event = CreateEvent(NULL,/*FALSE*/TRUE,FALSE,NULL);
 }
 
 SurfaceWin::~SurfaceWin()
 {
+  if (d3dsurface) d3dsurface->Release();
+  if (d3dtexture) d3dtexture->Release();
+  CloseHandle(event);
 }
 
 int SurfaceWin::create(UINT width, UINT height)
 {
-  return 0;
+  LPDIRECT3DDEVICE9 d3ddev=((OsdWin*)(Osd::getInstance()))->getD3dDev();
+  while (true) {
+    if (screen==this) {
+      if (d3ddev->CreateTexture(1024,1024,0,0,D3DFMT_A8R8G8B8,
+        // Does every adapter with alpha blending support this?
+        D3DPOOL_DEFAULT,&d3dtexture ,NULL)!=D3D_OK) {
+          MILLISLEEP(50);//wait maybe next time it will work
+          continue;
+      }
+      if (d3dtexture->GetSurfaceLevel(0,&d3dsurface)!=D3D_OK) {
+        d3dtexture->Release();
+        d3dtexture=NULL;
+        MILLISLEEP(50);
+        continue;
+      }
+    } else {
+      HRESULT hres;
+      if (hres=d3ddev->CreateOffscreenPlainSurface(width,height,D3DFMT_A8R8G8B8,
+        D3DPOOL_SYSTEMMEM,&d3dsurface,NULL)!=D3D_OK) {
+          MILLISLEEP(50);//wait maybe next time it will work
+          continue;
+      }
+
+    }
+    sheight=height;
+    swidth=width;
+    /* If someone does high performance Animations on the OSD, we have to change the types
+     of surface in order to address these performance issues, if we have only very few updates
+     per second this would be fast enough !*/
+    break;
+  }
+  SetEvent(event);
+  return 1;
 }
 
 void SurfaceWin::display()
@@ -42,35 +82,174 @@ void SurfaceWin::display()
 
 int SurfaceWin::fillblt(int x, int y, int width, int height, unsigned int c)
 {
+  WaitForSingleObject(event,INFINITE); //since this might be called before surface
+  //allocation we will wait in this case, hopefully without deadlocks
+  OsdWin* osd=((OsdWin*)(Osd::getInstance()));
+
+  if (!d3dsurface) {
+    return 0; //why does this happen
+  }
+
+  LPDIRECT3DDEVICE9 d3ddev=osd->getD3dDev();
+
+  if (screen==this) {
+    //This should not happen!
+    return 0;
+
+  } else {
+    osd->BeginPainting();
+    D3DLOCKED_RECT lockrect;
+    int cx,cy,cwidth,cheight;
+    cx=min(max(x,0),swidth);
+    cy=min(max(y,0),sheight);
+    cwidth=min(width,swidth-x);
+    cheight=min(height,sheight-y);
+    RECT rect={cx,cy,cwidth,cheight};
+
+    if (d3dsurface->LockRect(&lockrect,&rect,D3DLOCK_DISCARD)!=D3D_OK) {
+      return 0;
+    }
+    unsigned int line;
+    unsigned int column;
+    for (line=0;line<cheight;line++) {
+      unsigned int*row=((unsigned int*)(((char*)lockrect.pBits)+lockrect.Pitch*line));
+      for (column=0;column<cwidth;column++) {
+        row[column]=c;
+      }
+    }
+
+    if (d3dsurface->UnlockRect()!=D3D_OK) {
+      osd->EndPainting();
+      return 0;
+    }
+    osd->EndPainting();
+  }
+
   return 0;
 }
 
 void SurfaceWin::drawPixel(int x, int y, unsigned int c)
 {
+  //FixMe: locking for every single Pixel will be painfully slow
+  WaitForSingleObject(event,INFINITE); //since this might be called before surface
+  //allocation we will wait in this case, hopefully without deadlocks
+  if (!d3dsurface) {
+    return; //why does this happen
+  }
+  OsdWin* osd=((OsdWin*)(Osd::getInstance()));
+  LPDIRECT3DDEVICE9 d3ddev=osd->getD3dDev();
+  if (x>swidth || y>sheight) return; //do not draw outside the surface
+  if (screen==this) {
+    //This should not happen!
+    return ;
+
+  } else {
+    osd->BeginPainting();
+    D3DLOCKED_RECT lockrect;
+    RECT rect={x,y,x+1,y+1};
+    if (d3dsurface->LockRect(&lockrect,&rect,D3DLOCK_DISCARD)!=D3D_OK) {
+      osd->EndPainting();
+      return ;
+    }
+    unsigned int*row=(unsigned int*)(((char*)lockrect.pBits));
+    row[0]=c;
+    if (d3dsurface->UnlockRect()!=D3D_OK) {
+      osd->EndPainting();
+      return ;
+    }
+    osd->EndPainting();
+  }
+
 }
 
 void SurfaceWin::drawHorzLine(int x1, int x2, int y, unsigned int c)
 {
+   fillblt(x1, y, x2-x1, 1, c);
 }
 
 void SurfaceWin::drawVertLine(int x, int y1, int y2, unsigned int c)
 {
+  fillblt(x, y1, 1, y2-y1, c);
 }
 
 int SurfaceWin::updateToScreen(int sx, int sy, int w, int h, int dx, int dy) // FIXME new, replace others with this FIXME
 {
+  WaitForSingleObject(event,INFINITE); //since this might be called before surface
+  //allocation we will wait in this case, hopefully without deadlocks
+  if (!d3dsurface) {
+    return 0; //why does this happen
+  }
+  OsdWin* osd=((OsdWin*)(Osd::getInstance()));
+  LPDIRECT3DDEVICE9 d3ddev=osd->getD3dDev();
+    LPDIRECT3DSURFACE9 screensurface=((SurfaceWin*)screen)->getD3dsurface();
+  if (!screensurface) return 0;
+  RECT sourcerect={sx,sy,sx+w,sy+h};
+  POINT destpoint={dx,dy};
+  osd->BeginPainting();
+  if (d3ddev->UpdateSurface(d3dsurface,&sourcerect,screensurface,&destpoint)!=D3D_OK) {
+    Log::getInstance()->log("Surface", Log::DEBUG, "Could not update to Screen!");
+    osd->EndPainting();
+    return 0;
+  }
+  osd->EndPainting();
   return 0;
 }
 
 int SurfaceWin::blt(int fd, unsigned long shandle, int sx, int sy, int width, int height, unsigned long dhandle, int dx, int dy)
 {
+  //I don't see code using this function, so I skip it, since it is a MVP specific interface
   return 0;
 }
 
 void SurfaceWin::screenShot(char* fileName)
 {
+  //Isn't this for debugging only, so I won't implement it yet
 }
 
 void SurfaceWin::readPixel(int x, int y, unsigned char* r, unsigned char* g, unsigned char* b)
 {
+  //Isn't this for debugging only, so I won't implement it yet
+}
+void SurfaceWin::ReleaseSurface()
+{
+  ResetEvent(event);
+  LPDIRECT3DSURFACE9 temp_surf=d3dsurface;
+  LPDIRECT3DTEXTURE9 temp_text=d3dtexture;
+  d3dsurface=NULL;
+  d3dtexture=NULL;
+  sheight=swidth=0;
+  if (temp_surf) temp_surf->Release();
+  if (temp_text) temp_text->Release();
+}
+
+void SurfaceWin::drawJpeg(char *fileName,DWORD x, DWORD y,DWORD *width, DWORD *height){
+  WaitForSingleObject(event,INFINITE); //since this might be called before surface
+  //allocation we will wait in this case, hopefully without deadlocks
+  if (!d3dsurface) {
+    return ; //why does this happen
+  }
+  OsdWin* osd=((OsdWin*)(Osd::getInstance()));
+
+
+  D3DXIMAGE_INFO image_inf;
+  osd->BeginPainting();
+  D3DXGetImageInfoFromFile(fileName,&image_inf);
+  RECT dest_rec={x,y,x+image_inf.Width,
+    y+image_inf.Height};
+  if (D3DXLoadSurfaceFromFile(
+    d3dsurface,
+    NULL,
+    &dest_rec,
+    fileName,
+    NULL,
+    D3DX_FILTER_NONE,
+    0,
+    &image_inf)!=D3D_OK) {
+      Log::getInstance()->log("Surface", Log::DEBUG, "Could not open jpeg!");
+
+  }
+  osd->EndPainting();
+  *width=image_inf.Width;
+  *height=image_inf.Height;
+
 }
index 6b7eb70f65284bac672de86b76a5d41c6e2c5056..104aec6d89abc1c9f5e84a8c53e8e9c5ee60bc55 100644 (file)
@@ -25,6 +25,8 @@
 #include "defines.h"
 #include "log.h"
 #include "surface.h"
+#include <winsock2.h>
+#include <d3d9.h>
 
 class SurfaceWin : public Surface
 {
@@ -42,10 +44,17 @@ class SurfaceWin : public Surface
     int updateToScreen(int sx, int sy, int w, int h, int dx, int dy);
     void readPixel(int x, int y, unsigned char* r, unsigned char* g, unsigned char* b);
     void screenShot(char* fileName);
-
+  void ReleaseSurface();
     int blt(int fd, unsigned long shandle, int sx, int sy, int width, int height, unsigned long dhandle, int dx, int dy);
-
+  void drawJpeg(char *fileName,DWORD x, DWORD y,DWORD *width, DWORD *height);
+  LPDIRECT3DSURFACE9 getD3dsurface() {WaitForSingleObject(event,INFINITE);
+    return d3dsurface;};
+  LPDIRECT3DTEXTURE9 getD3dtexture() {return d3dtexture;};
   private:
+    LPDIRECT3DSURFACE9 d3dsurface;
+    LPDIRECT3DTEXTURE9 d3dtexture;
+    UINT sheight,swidth;
+    HANDLE event;
 };
 
 #endif
diff --git a/tcp.cc b/tcp.cc
index 6c56e383fb589c63635f8b2661c63c76f86da739..2600635b24162f3eed5491d41de7360de212cc47 100644 (file)
--- a/tcp.cc
+++ b/tcp.cc
@@ -20,6 +20,9 @@
 */
 
 #include "tcp.h"
+#ifdef WIN32
+#include <Iphlpapi.h>
+#endif
 
 TCP::TCP()
 {
@@ -51,7 +54,36 @@ void TCP::getMAC(char* dest)
   memcpy(dest, ifr.ifr_hwaddr.sa_data, 6);
 #else
   //TODO: Get MAC Address for windows
-  memcpy(dest, "ABCDEF", 6);
+  PIP_ADAPTER_INFO daptinfo=NULL;
+  DWORD size=0;
+  GetAdaptersInfo(daptinfo,&size);
+  daptinfo=(PIP_ADAPTER_INFO)new char[size+1];
+  memcpy(dest,"ABCDEF", 6);//Dummy Address
+  sockaddr_in sock_address;
+  int sockname_len=sizeof(sock_address);
+  getsockname(sock,(sockaddr*)&sock_address,&sockname_len);
+  ULONG sockip=sock_address.sin_addr.s_addr;
+  if (GetAdaptersInfo(daptinfo,&size)==ERROR_SUCCESS)
+  {
+    PIP_ADAPTER_INFO daptinfo_it=daptinfo;
+    while (daptinfo_it!=NULL)
+    {
+      ULONG ipaddress=inet_addr(daptinfo_it->IpAddressList.IpAddress.String);
+      if (ipaddress==sockip)
+      { //Is it our MAC?
+        memcpy(dest,daptinfo_it->Address, 6);
+        break;
+      }
+      daptinfo_it=daptinfo_it->Next;
+      if (daptinfo_it==daptinfo) break;
+    }
+  }
+  else
+  {
+    // Marten?
+  }
+
+  delete [] daptinfo;
 #endif
 }
 
index cc9645ba3b4d32434529407157e2d05d3fb062be..2d445bdfd194b9650daf65bccd575561cdd4144f 100644 (file)
@@ -30,7 +30,7 @@ DWORD WINAPI threadInternalStart(void *arg)
 
 int ThreadWin::threadStart()
 {
-  threadCond = CreateEvent(NULL,FALSE,FALSE,NULL);
+  threadCond = CreateEvent(NULL,/*FALSE*/TRUE,FALSE,NULL);
   if (threadCond == NULL) return 0;
   threadCondMutex = CreateMutex(NULL,FALSE,NULL);
   if (threadCondMutex == NULL)
@@ -63,7 +63,8 @@ void ThreadWin::threadStop()
 void ThreadWin::threadCancel()
 {
   threadActive = 0;
-  TerminateThread(pthread, 0);
+  //TerminateThread(pthread, 0);
+  threadSignalNoLock();
   WaitForSingleObject(pthread, INFINITE);
   this->threadPostStopCleanup();
 }
@@ -86,30 +87,37 @@ void ThreadWin::threadUnlock()
 void ThreadWin::threadSignal()
 {
   WaitForSingleObject(threadCondMutex, INFINITE);
-  PulseEvent(threadCond);
+ // PulseEvent(threadCond);
+  SetEvent(threadCond);
   ReleaseMutex(threadCondMutex);
 }
 
 void ThreadWin::threadSignalNoLock()
 {
-  PulseEvent(threadCond);
+//    PulseEvent(threadCond);
+  SetEvent(threadCond);
 }
 
 void ThreadWin::threadWaitForSignal()
 {
+  threadUnlock();
   WaitForSingleObject(threadCond,INFINITE);
+  ResetEvent(threadCond);
+  threadLock();
 }
 
 void ThreadWin::threadWaitForSignalTimed(struct timespec* ts)
 {
+  threadUnlock();
   HANDLE handles[2] ={threadCond, NULL};
   LARGE_INTEGER duration;
-  duration.QuadPart=ts->tv_sec*1000*1000*10+ts->tv_nsec/100;
-
+  duration.QuadPart=(ts->tv_sec*1000*1000*10+ts->tv_nsec/100)+WINDOWS_TIME_BASE_OFFSET;
   handles[1]=CreateWaitableTimer(NULL,TRUE,NULL);
   SetWaitableTimer(handles[1], &duration, 0, NULL, NULL, 0);
   WaitForMultipleObjects(2,handles,FALSE,INFINITE);
+  ResetEvent(threadCond);
   CloseHandle(handles[1]);
+  threadLock();
 }
 
 void ThreadWin::threadSetKillable()
index 1e55507d6adb80b66e2963ba6c91e3285f47821d..bc363dc7d2c22a8c8ffa97fe3c3787c58de47016 100644 (file)
@@ -21,7 +21,8 @@
 #ifndef THREADWIN_H
 #define THREADWIN_H
 
-#define _WIN32_WINNT 0x400
+
+#define _WIN32_WINNT 0x501
 #include <winsock2.h>
 #include <windows.h>
 typedef struct timespec
@@ -29,6 +30,7 @@ typedef struct timespec
   long tv_sec; /* seconds */
   long tv_nsec; /* nanoseconds */
 } timespec;
+#define WINDOWS_TIME_BASE_OFFSET 116444736000000000
 
 #include "thread.h"
 
index c94ee5889e3a6039f6ef8075a47428c90876f3e1..11fb3af19b53faf17e438828c3d522543916d4cf 100755 (executable)
--- a/timers.cc
+++ b/timers.cc
@@ -139,8 +139,9 @@ int Timers::setTimerD(TimerReceiver* client, int clientReference, long int reque
   __int64  test;\r
   GetSystemTime(&systime);\r
   SystemTimeToFileTime(&systime,(FILETIME*)&filetime);\r
-  currentTime.tv_sec=filetime/(10*1000*1000);\r
-  currentTime.tv_nsec=(filetime%(10*1000*1000))*100;\r
+   currentTime.tv_sec=(filetime-WINDOWS_TIME_BASE_OFFSET)/(10*1000*1000);\r
+   //#error "Hier gibt was zu tun!"\r
+   currentTime.tv_nsec=((filetime-WINDOWS_TIME_BASE_OFFSET)%(10*1000*1000))*100;\r
 #endif\r
 \r
   long int requestedTime;\r
@@ -278,7 +279,7 @@ void Timers::threadMethod()
 \r
     // Check for reset..\r
     // This can be caused by an addition or deletion to the list\r
-    if (resetThreadFlag) continue;\r
+    if (resetThreadFlag || (nextTimer == NULL)) continue;\r
 \r
     // timer ran out\r
 \r
diff --git a/vepg.cc b/vepg.cc
index ae4def1166ebc01ef445fd35890a1d0b93ad4301..afeb6d33fffc0b5a32ea345a7c3f03fc62080513 100644 (file)
--- a/vepg.cc
+++ b/vepg.cc
@@ -171,11 +171,19 @@ void VEpg::setInfo(Event* event)
   int length = strlen(event->title); // calculate length of programme title string\r
   char* title = new char[length + 15]; // create string to hold start time, end time and programme title\r
   btime = localtime((time_t*)&event->time); //get programme start time\r
-  strftime(timeString, 9, "%0H:%0M - ", btime); // and format it as hh:mm -\r
+#ifndef _MSC_VER
+  strftime(timeString, 9, "%0H:%0M - ", btime); // and format it as hh:mm -
+#else
+  strftime(timeString, 9, "%H:%M - ", btime); // and format it as hh:mm -
+#endif
   strcpy(title, timeString); // put it in our buffer\r
   t = event->time + event->duration; //get programme end time\r
   btime = localtime(&t);\r
-  strftime(timeString, 7, "%0H:%0M ", btime); // and format it as hh:mm -\r
+#ifndef _MSC_VER
+  strftime(timeString, 7, "%0H:%0M ", btime); // and format it as hh:mm -
+#else
+  strftime(timeString, 7, "%H:%M ", btime); // and format it as hh:mm -
+#endif
   strcat(title, timeString); // put it in our buffer\r
   strcat(title, event->title); // then add the programme title\r
   progTitle.setText(title); // sput this sring in our text box\r
index a997fb9d77f72859bac822adaac49b528a3c63fc..b406fed87674e3bd0d3353d196198fc5bc1e1907 100644 (file)
@@ -170,11 +170,20 @@ void VEpgSetTimer::draw()
   struct tm* btime;
   char timeString[10];
   btime = localtime((time_t*)&event->time);
+#ifndef _MSC_VER
   strftime(timeString, 9, "%0H:%0M - ", btime); // and format it as hh:mm -
+#else
+   strftime(timeString, 9, "%H:%M - ", btime); // and format it as hh:mm -
+#endif
   strcpy(fullString, timeString); // put it in our buffer
   t = event->time + event->duration; //get programme end time
   btime = localtime(&t);
+#ifndef _MSC_VER
   strftime(timeString, 9, "%0H:%0M", btime); // and format it as hh:mm -
+#else
+   strftime(timeString, 9, "%H:%M", btime); // and format it as hh:mm -
+#endif
+
   strcat(fullString, timeString); // put it in our buffer
 
   drawText(fullString, 10, 40 + (3 * surface->getFontHeight()), Colour::LIGHTTEXT);
index aaf72853990b80b9495b6b7c40c17b575890e73e..7890abd81357f762f961cbc4b2d5f755628eca52 100644 (file)
--- a/vfeed.cc
+++ b/vfeed.cc
@@ -25,11 +25,19 @@ VFeed::VFeed(Callback* tcb)
 {
 }
 
+#ifndef NEW_DEMUXER
 int VFeed::init(int tfd)
 {
   fd = tfd;
   return 1;
 }
+#else
+int VFeed::init(DrainTarget* tdt)
+{
+  dt = tdt;
+  return 1;
+}
+#endif
 
 int VFeed::shutdown()
 {
@@ -55,7 +63,12 @@ void VFeed::threadMethod()
 
   while(1)
   {
+#ifndef NEW_DEMUXER
     vlen = Demuxer::getInstance()->writeVideo(fd); // FIXME
+#else
+    threadCheckExit();
+    vlen = Demuxer::getInstance()->writeVideo(dt); // FIXME
+#endif
     if (vlen)
     {
 //      Log::getInstance()->log("VFeed", Log::DEBUG, "Written %i", vlen);
diff --git a/vfeed.h b/vfeed.h
index c8e6b0ca40bd65e2a097c7965df55199e9eb5ba4..1525b4131b40da75bfa66eadf0e728dade71d265 100644 (file)
--- a/vfeed.h
+++ b/vfeed.h
@@ -27,6 +27,7 @@
 #include "log.h"
 #include "demuxer.h"
 #include "callback.h"
+#include "draintarget.h"
 
 #ifdef WIN32
 #include "threadwin.h"
@@ -38,8 +39,12 @@ class VFeed : public Thread_TYPE
 {
   public:
     VFeed(Callback* tcb);
-
+#ifndef NEW_DEMUXER
     int init(int fd);
+#else
+    int init(DrainTarget *tdt);
+#endif
+
     int shutdown();
 
     int start();
@@ -48,7 +53,12 @@ class VFeed : public Thread_TYPE
   private:
     void threadMethod();
     void threadPostStopCleanup() {};
+#ifndef NEW_DEMUXER
     int fd;
+#else
+    DrainTarget *dt;
+#endif
+
     Callback& cb;
 };
 
diff --git a/video.h b/video.h
index 21b00d72c3e3c73a8bce2927fa025d7c4401c832..91d04591c47c3006fe549a54c6485465016f4b0a 100644 (file)
--- a/video.h
+++ b/video.h
@@ -23,8 +23,9 @@
 
 #include <stdio.h>
 #include "defines.h"
+#include "draintarget.h"
 
-class Video
+class Video: public DrainTarget
 {
   public:
     Video();
@@ -56,6 +57,8 @@ class Video
     virtual ULONG timecodeToFrameNumber(ULLONG timecode)=0;
     virtual int getFD()=0;
     virtual ULLONG getCurrentTimestamp()=0;
+  virtual void turnVideoOn(){};
+  virtual void turnVideoOff(){};
 
 #ifdef DEV
     virtual int test() { return 0; }
index f3e33cbf3b1a0cb1013d073586e250947713d1bc..8869322bc73aae786eb27a510b4bd814e55ce49a 100644 (file)
@@ -20,6 +20,9 @@
 
 #include "videomvp.h"
 
+// temp
+#include "log.h"
+
 VideoMVP::VideoMVP()
 {
   if (instance) return;
@@ -151,6 +154,8 @@ int VideoMVP::setAspectRatio(UCHAR taspectRatio)
   if ((taspectRatio != ASPECT4X3) && (taspectRatio != ASPECT16X9)) return 0;
   aspectRatio = taspectRatio;
 
+  Log::getInstance()->log("Video", Log::DEBUG, "Setting aspect to %i", aspectRatio);
+
   if (ioctl(fdVideo, AV_SET_VID_RATIO, aspectRatio) != 0) return 0;
   return 1;
 }
@@ -367,3 +372,9 @@ int VideoMVP::test2()
   return 0;
 }
 #endif
+
+// unused
+UINT VideoMVP::DeliverMediaSample(MediaPacket packet, UCHAR* buffer, UINT *samplepos)
+{
+  return 0;
+}
index be955eefad9d4db206d205f20cb2e0c5a39bb29e..b98418552c1dc342189042cd8dc440d7237005ae 100644 (file)
@@ -69,6 +69,10 @@ class VideoMVP : public Video
     int getFD();
     ULLONG getCurrentTimestamp();
 
+    //Writing Data to Videodevice
+    virtual UINT DeliverMediaSample(MediaPacket packet, UCHAR* buffer, UINT *samplepos);
+    virtual long long SetStartOffset(long long curreftime, bool *rsync) { return 0; };
+
 #ifdef DEV
     int test();
     int test2();
index b993812c4cb9f2ac9bb56318b2460aefd9535cec..f7e7da678a426bc461482c971531a5b610a947a5 100644 (file)
 */
 
 #include "videowin.h"
+#include "dssourcefilter.h"
+
+
+
+
 
 VideoWin::VideoWin()
 {
-  if (instance) return;
+  dsgraphbuilder=NULL;
+  dsmediacontrol=NULL;
+  sourcefilter=NULL;
+  filtermutex=CreateMutex(NULL,FALSE,NULL);
+  offsetnotset=true;
+  offsetvideonotset=true;
+  offsetaudionotset=true;
+  startoffset=0;
+  lastrefaudiotime=0;
+  lastrefvideotime=0;
+  firstsynched=false;
+  cur_audio_media_sample=NULL;
+  cur_video_media_sample=NULL;
+  videoon=true;
+  audioon=true;
+
+
 }
 
 VideoWin::~VideoWin()
 {
+  CleanupDS();
+  CloseHandle(filtermutex);
+
+
   instance = NULL;
 }
 
 int VideoWin::init(UCHAR tformat)
 {
   if (initted) return 0;
+
   initted = 1;
+  if (!setFormat(tformat)){ shutdown(); return 0; }
   return 1;
 }
 
@@ -59,6 +86,16 @@ int VideoWin::setFormat(UCHAR tformat)
   if (!initted) return 0;
   if ((tformat != PAL) && (tformat != NTSC)) return 0;
   format = tformat;
+  if (format == NTSC)
+  {
+    screenWidth = 720;
+    screenHeight = 480;
+  }
+  if (format == PAL)
+  {
+    screenWidth = 720;
+    screenHeight = 576;
+  }
 
   return 1;
 }
@@ -125,10 +162,62 @@ int VideoWin::sync()
   return 1;
 }
 
+#ifdef DS_DEBUG // This stuff would not included in vomp due to lincemse restrcitions
+#include "dshelper.h"
+#endif
+
+#define DO_VIDEO
+
 int VideoWin::play()
 {
   if (!initted) return 0;
 
+  //Build filter graph
+  HRESULT hres;
+  if (hres=CoCreateInstance(CLSID_FilterGraph,NULL,CLSCTX_INPROC_SERVER,
+    IID_IGraphBuilder,(void**)&dsgraphbuilder)!=S_OK) {
+      return 0;
+   }
+   #ifdef DS_DEBUG
+   AddToRot(dsgraphbuilder,&graphidentifier);
+   #endif
+   //This is just a try to see if building the graph works
+//   dsgraphbuilder->RenderFile(L"D:\\Projekte\\VTP Client\\test.mpa" ,NULL);
+   //So this is the real code, this prevents the feeder from calling noexisting objects!
+   WaitForSingleObject(filtermutex,INFINITE);
+   offsetnotset=true;
+   offsetvideonotset=true;
+   offsetaudionotset=true;
+   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) {
+     CleanupDS();
+     ReleaseMutex(filtermutex);
+     return 0;
+   }
+   if (audioon) {
+     if (hres=dsgraphbuilder->Render(sourcefilter->GetPin(0)/*audio*/)!=S_OK) {
+       CleanupDS();
+       ReleaseMutex(filtermutex);
+       return 0;
+     }
+   }
+#ifdef DO_VIDEO
+   if (videoon) {
+     if (hres=dsgraphbuilder->Render(sourcefilter->GetPin(1)/*video*/)!=S_OK) {
+       CleanupDS();
+       ReleaseMutex(filtermutex);
+       return 0;
+     }
+   }
+#endif
+
+
+
+   dsgraphbuilder->QueryInterface(IID_IMediaControl,(void **) &dsmediacontrol);
+   dsmediacontrol->Run();
+   ReleaseMutex(filtermutex);
   return 1;
 }
 
@@ -136,6 +225,9 @@ int VideoWin::stop()
 {
   if (!initted) return 0;
 
+  CleanupDS();
+
+
   return 1;
 }
 
@@ -149,13 +241,14 @@ int VideoWin::reset()
 int VideoWin::pause()
 {
   if (!initted) return 0;
-
+  if (dsmediacontrol) dsmediacontrol->Pause();
   return 1;
 }
 
 int VideoWin::unPause() // FIXME get rid - same as play!!
-{
+{//No on windows this is not the same, I don't get rid of!
   if (!initted) return 0;
+  if (dsmediacontrol) dsmediacontrol->Run();
   return 1;
 }
 
@@ -200,6 +293,256 @@ ULONG VideoWin::timecodeToFrameNumber(ULLONG timecode)
   else               return (ULONG)(((double)timecode / (double)90000) * (double)30);
 }
 
+void VideoWin::CleanupDS()
+{
+  WaitForSingleObject(filtermutex,INFINITE);
+  if (cur_audio_media_sample) {
+    cur_audio_media_sample->Release();
+    cur_audio_media_sample=NULL;
+  }
+  if (cur_video_media_sample) {
+    cur_video_media_sample->Release();
+    cur_video_media_sample=NULL;
+  }
+
+  if (dsmediacontrol) {
+    dsmediacontrol->Stop();
+    dsmediacontrol->Release();
+    dsmediacontrol=NULL;
+  }
+  if (dsgraphbuilder){
+#ifdef DS_DEBUG
+    RemoveFromRot(graphidentifier);
+#endif
+    dsgraphbuilder->Release();
+    dsgraphbuilder=NULL;
+    sourcefilter=NULL; //The Graph Builder destroys our SourceFilter
+  }
+  ReleaseMutex(filtermutex);
+
+}
+
+
+UINT VideoWin::DeliverMediaSample(MediaPacket packet,
+     UCHAR* buffer,
+     UINT *samplepos)
+{
+  /*First Check, if we have an audio sample*/
+#ifdef DO_VIDEO
+  /*First Check, if we have an audio sample*/
+
+  IMediaSample* ms=NULL;
+  REFERENCE_TIME reftime1=0;
+  REFERENCE_TIME reftime2=0;
+
+  UINT headerstrip=0;
+  if (packet.disconti) {
+    firstsynched=false;
+    DeliverVideoMediaSample();
+
+  }
+
+
+  /*Inspect PES-Header */
+
+  if (*samplepos==0) {//stripheader
+    headerstrip=buffer[packet.pos_buffer+8]+9/*is this right*/;
+    *samplepos+=headerstrip;
+    if ( packet.synched ) {
+      DeliverVideoMediaSample();//write out old data
+      if (packet.presentation_time<0) { //Preroll?
+        *samplepos=packet.length;//if we have not processed at least one
+        return packet.length;//synched packet ignore it!
+      }
+
+      reftime1=packet.presentation_time;
+      reftime2=reftime1+1;
+      firstsynched=true;
+    } else {
+      if (!firstsynched) {//
+        *samplepos=packet.length;//if we have not processed at least one
+        return packet.length;//synched packet ignore it!
+      }
+    }
+  }
+  BYTE *ms_buf;
+  UINT ms_length;
+  UINT ms_pos;
+  UINT haveToCopy;
+  if (!getCurrentVideoMediaSample(&ms) || ms==NULL) {// get the current sample
+    samplepos=0;
+    MILLISLEEP(10);
+    return 0;
+  }
+  ms_pos=ms->GetActualDataLength();
+  ms_length=ms->GetSize();
+  haveToCopy=min(ms_length-ms_pos,packet.length-*samplepos);
+  if ((ms_length-ms_pos)<1) {
+    DeliverVideoMediaSample(); //we are full!
+    if (!getCurrentVideoMediaSample(&ms) || ms==NULL) {// get the current sample
+      samplepos=0;
+      MILLISLEEP(10);
+      return 0;
+    }
+    ms_pos=ms->GetActualDataLength();
+    ms_length=ms->GetSize();
+    haveToCopy=min(ms_length-ms_pos,packet.length-*samplepos);
+  }
+  ms->GetPointer(&ms_buf);
+
+
+  if (ms_pos==0) {//will only be changed on first packet
+    if (packet.disconti) {
+      ms->SetDiscontinuity(TRUE);
+    } else {
+      ms->SetDiscontinuity(FALSE);
+    }
+    if (packet.synched) {
+      ms->SetSyncPoint(TRUE);
+      ms->SetTime(&reftime1,&reftime2);
+      //ms->SetTime(NULL,NULL);
+      ms->SetMediaTime(NULL, NULL);
+    }else {
+      ms->SetSyncPoint(FALSE);
+      ms->SetTime(NULL,NULL);
+      ms->SetMediaTime(NULL, NULL);
+      ms->SetSyncPoint(TRUE);
+    }
+  }
+
+
+  memcpy(ms_buf+ms_pos,buffer+packet.pos_buffer+*samplepos,haveToCopy);
+    ms->SetActualDataLength(haveToCopy+ms_pos);
+
+  *samplepos+=haveToCopy;
+
+  return haveToCopy+headerstrip;
+
+#else
+
+       *samplepos+=packet.length;
+      MILLISLEEP(0); //yet not implemented//bad idea
+       return packet.length;
+#endif
+}
+
+int VideoWin::getCurrentAudioMediaSample(IMediaSample** ms)
+{
+  //WaitForSingleObject(filtermutex,INFINITE);
+  if (!sourcefilter){
+  //  ReleaseMutex(filtermutex);
+    return 0;
+  }
+  if (cur_audio_media_sample) {
+    *ms=cur_audio_media_sample;//already open
+    return 1;
+  }
+  if (!sourcefilter->getCurrentAudioMediaSample(ms)) {
+  //  ReleaseMutex(filtermutex);
+  }
+  if (*ms) (*ms)->SetActualDataLength(0);
+  cur_audio_media_sample=*ms;
+  //Don't release the mutex before deliver
+  return 1;
+}
+
+int VideoWin::getCurrentVideoMediaSample(IMediaSample** ms)
+{
+  //WaitForSingleObject(filtermutex,INFINITE);
+  if (!sourcefilter){
+  //  ReleaseMutex(filtermutex);
+    return 0;
+  }
+  if (cur_video_media_sample) {
+    *ms=cur_video_media_sample;//already open
+    return 1;
+  }
+  if (!sourcefilter->getCurrentVideoMediaSample(ms)) {
+  //  ReleaseMutex(filtermutex);
+  }
+  if (*ms) (*ms)->SetActualDataLength(0);
+
+  cur_video_media_sample=*ms;
+  //Don't release the mutex before deliver
+  return 1;
+}
+
+int VideoWin::DeliverAudioMediaSample(){
+  if (cur_audio_media_sample) {
+    sourcefilter->DeliverAudioMediaSample(cur_audio_media_sample);
+    cur_audio_media_sample=NULL;
+  }
+  //ReleaseMutex(filtermutex);
+  return 1;
+}
+
+int VideoWin::DeliverVideoMediaSample(){
+  if (cur_video_media_sample) {
+    sourcefilter->DeliverVideoMediaSample(cur_video_media_sample);
+    cur_video_media_sample=NULL;
+  }
+  //ReleaseMutex(filtermutex);
+  return 1;
+}
+
+long long VideoWin::SetStartOffset(long long curreftime, bool *rsync)
+{
+  *rsync=false;
+  if (offsetnotset) {
+    startoffset=curreftime;//offset is set for audio
+    offsetnotset=false;
+    offsetvideonotset=false;
+  } else {
+    if (offsetvideonotset) {
+      offsetvideonotset=false;
+      *rsync=true;
+    } else {
+      if ( (curreftime-lastrefvideotime)>10000000LL
+        || (curreftime-lastrefvideotime)<-10000000LL) {//if pts jumps to big resync
+        startoffset+=curreftime-lastrefvideotime;
+        //lastrefaudiotime+=curreftime-lastrefvideotime;
+        *rsync=true;
+        offsetaudionotset=true;
+
+      }
+    }
+
+  }
+  lastrefvideotime=curreftime;
+  return startoffset;
+
+}
+
+long long VideoWin::SetStartAudioOffset(long long curreftime, bool *rsync)
+{
+  *rsync=false;
+  if (offsetnotset) {
+    startoffset=curreftime;
+    offsetnotset=false;
+    offsetaudionotset=false;
+  } else {
+    if (offsetaudionotset) {
+      offsetaudionotset=false;
+      *rsync=true;
+    } else {
+      if ( (curreftime-lastrefaudiotime)>10000000LL
+        || (curreftime-lastrefaudiotime)<-10000000LL) {//if pts jumps to big resync
+        startoffset+=curreftime-lastrefaudiotime;
+        lastrefvideotime+=curreftime-lastrefaudiotime;
+        *rsync=true;
+        offsetvideonotset=true;
+
+      }
+    }
+
+  }
+  lastrefaudiotime=curreftime;
+  return startoffset;
+
+}
+
+
+
 #ifdef DEV
 int VideoWin::test()
 {
index b736954aa5ba1a6e6e33b7171514590749ade708..6b4f2cb7a27a422e7b1fcac375c62e16ea555b8b 100644 (file)
 
 #include <stdio.h>
 #include <string.h>
+#include <winsock2.h>
+#include <dshow.h>
 
 #include "defines.h"
 #include "video.h"
 
+#define DS_DEBUG
+
+class DsSourceFilter;
+
 class VideoWin : public Video
 {
   public:
@@ -60,10 +66,49 @@ class VideoWin : public Video
     int getFD();
     ULLONG getCurrentTimestamp();
 
+    //Writing Data to Videodevice
+    virtual UINT DeliverMediaSample(MediaPacket packet, UCHAR* buffer, UINT *samplepos);
+
+    int getCurrentAudioMediaSample(IMediaSample** ms);
+    int DeliverAudioMediaSample();
+
+    int getCurrentVideoMediaSample(IMediaSample** ms);
+    int DeliverVideoMediaSample();
+
+    long long SetStartOffset(long long curreftime, bool *rsync);
+    long long SetStartAudioOffset(long long curreftime, bool *rsync);
+
+    void SetAudioState(bool state){audioon=state;};
+
+    void turnVideoOn(){videoon=true;};
+    void turnVideoOff(){videoon=false;};
+
 #ifdef DEV
     int test();
     int test2();
 #endif
+private:
+  IMediaControl* dsmediacontrol;
+  IGraphBuilder* dsgraphbuilder;
+  IMediaSample* cur_audio_media_sample;
+  IMediaSample* cur_video_media_sample;
+
+  DsSourceFilter* sourcefilter;
+  HANDLE filtermutex;
+  void CleanupDS();
+  bool offsetnotset;
+  bool offsetvideonotset;
+  bool offsetaudionotset;
+  long long startoffset;
+  long long lastrefvideotime;
+  long long lastrefaudiotime;
+
+  bool firstsynched;
+  bool audioon;
+  bool videoon;
+#ifdef DS_DEBUG
+  DWORD graphidentifier;
+#endif
 };
 
 #endif
index afb411d5fecfeaf5412c9f374c6bd8e5e3d4ec35..63d9a221561f2eecf085e1024c5c7a7faf2e6141 100644 (file)
@@ -117,7 +117,11 @@ void VLiveBanner::setChannel(Channel* tChannel)
       event = (*eventList)[i];
 
       btime = localtime((time_t*)&event->time);
+#ifndef _MSC_VER
       strftime(tempString2, 299, "%0H:%0M ", btime);
+#else
+    strftime(tempString2, 299, "%H:%M ", btime);
+#endif
       SNPRINTF(tempString, 299, "%s %s", tempString2, event->title);
       event->index = sl.addOption(tempString, first);
       first = 0;
diff --git a/vompreswin.h b/vompreswin.h
new file mode 100644 (file)
index 0000000..28facbe
--- /dev/null
@@ -0,0 +1,30 @@
+
+/*
+    Copyright 2004-2005 Chris Tallon
+
+    This file is part of VOMP.
+
+    VOMP is free software; you can redistribute it and/or modify
+    it under the terms of the GNU General Public License as published by
+    the Free Software Foundation; either version 2 of the License, or
+    (at your option) any later version.
+
+    VOMP is distributed in the hope that it will be useful,
+    but WITHOUT ANY WARRANTY; without even the implied warranty of
+    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+    GNU General Public License for more details.
+
+    You should have received a copy of the GNU General Public License
+    along with VOMP; if not, write to the Free Software
+    Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+*/
+
+#ifndef VOMPRESWIN_H
+#define _WIN32_WINNT 0x501
+
+#include <winsock2.h>
+#include <winuser.h>
+#define VOMPACCELERATOR 1
+
+#define VOMPRESWIN_H
+#endif
diff --git a/vompwin.rc b/vompwin.rc
new file mode 100644 (file)
index 0000000..103371a
--- /dev/null
@@ -0,0 +1,43 @@
+
+
+#include "vompreswin.h"
+
+
+
+//1 TEXTINCLUDE
+//BEGIN
+//    "#include ""winsock2.h""\r\n"
+//    "#include ""vompreswin.h""\r\n"
+//    "\0"
+//END
+
+
+
+
+
+VOMPACCELERATOR ACCELERATORS
+BEGIN
+    VK_INSERT,      APPCOMMAND_MEDIA_CHANNEL_DOWN, VIRTKEY, CONTROL,
+                                                    NOINVERT
+    VK_INSERT,      APPCOMMAND_MEDIA_CHANNEL_DOWN, VIRTKEY, NOINVERT
+    VK_PRIOR,       APPCOMMAND_MEDIA_CHANNEL_DOWN, VIRTKEY, NOINVERT
+    VK_OEM_PLUS,    APPCOMMAND_MEDIA_CHANNEL_UP, VIRTKEY, CONTROL, NOINVERT
+    VK_OEM_PLUS,    APPCOMMAND_MEDIA_CHANNEL_UP, VIRTKEY, NOINVERT
+    VK_NEXT,        APPCOMMAND_MEDIA_CHANNEL_UP, VIRTKEY, NOINVERT
+    "F",            APPCOMMAND_MEDIA_FAST_FORWARD, VIRTKEY, SHIFT, CONTROL,
+                                                    NOINVERT
+    VK_F8,          APPCOMMAND_VOLUME_MUTE, VIRTKEY, NOINVERT
+    "P",            APPCOMMAND_MEDIA_PAUSE, VIRTKEY, CONTROL, NOINVERT
+    "P",            APPCOMMAND_MEDIA_PLAY,  VIRTKEY, SHIFT, CONTROL,
+                                                    NOINVERT
+    "R",            APPCOMMAND_MEDIA_RECORD, VIRTKEY, CONTROL, NOINVERT
+    "B",            APPCOMMAND_MEDIA_PREVIOUSTRACK, VIRTKEY, CONTROL,
+                                                    NOINVERT
+    "F",            APPCOMMAND_MEDIA_NEXTTRACK, VIRTKEY, CONTROL, NOINVERT
+    "S",            APPCOMMAND_MEDIA_STOP,  VIRTKEY, CONTROL, NOINVERT
+    VK_F9,          APPCOMMAND_VOLUME_DOWN, VIRTKEY, NOINVERT
+    VK_F10,         APPCOMMAND_VOLUME_UP,   VIRTKEY, NOINVERT
+END
+
+
+
index c62c9d8f60d0b5cd62579a20eb2b93d185ba1263..aea31cae9c338af2d3d0ac4711629d9ecf7d1dd1 100644 (file)
@@ -111,7 +111,11 @@ void VRecordingList::drawData()
   {
     rec = recDir->recList[j];
     btime = localtime((time_t*)&rec->start);
+#ifndef _MSC_VER
     strftime(tempA, 299, "%0d/%0m %0H:%0M ", btime);
+#else
+    strftime(tempA, 299, "%d/%m %H:%M ", btime);
+#endif
     sprintf(tempB, "%s\t%s", tempA, rec->getProgName());
     rec->index = sl.addOption(tempB, first);
     first = 0;
index f854de43c091d9d7e1e1564b3eb2507da3398ff6..5281013dab45c7a9ede7db80be3188e957ee5c18 100644 (file)
@@ -154,6 +154,18 @@ int VVideoLive::handleCommand(int command)
       viewman->updateView(v);
       return 2;
     }
+#ifdef DEV
+    case Remote::YELLOW:
+    {
+      player->test1();
+      break;
+    }
+    case Remote::BLUE:
+    {
+      player->test2();
+      break;
+    }
+#endif
   }
 
   return 1;
diff --git a/winmain.cc b/winmain.cc
new file mode 100644 (file)
index 0000000..5ad7e89
--- /dev/null
@@ -0,0 +1,519 @@
+/*
+    Copyright 2004-2005 Chris Tallon
+
+    This file is part of VOMP.
+
+    VOMP is free software; you can redistribute it and/or modify
+    it under the terms of the GNU General Public License as published by
+    the Free Software Foundation; either version 2 of the License, or
+    (at your option) any later version.
+
+    VOMP is distributed in the hope that it will be useful,
+    but WITHOUT ANY WARRANTY; without even the implied warranty of
+    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+    GNU General Public License for more details.
+
+    You should have received a copy of the GNU General Public License
+    along with VOMP; if not, write to the Free Software
+    Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+*/
+#ifdef WIN32
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <signal.h>
+
+#define _WIN32_WINNT 0x501
+#include <winsock2.h>
+#include <windows.h>
+
+#include "vompreswin.h"
+
+#include "defines.h"
+#include "log.h"
+#include "remotewin.h"
+#include "ledwin.h"
+#include "mtdwin.h"
+#include "timers.h"
+#include "videowin.h"
+#include "audiowin.h"
+#include "vdr.h"
+#include "osdwin.h"
+#include "viewman.h"
+#include "command.h"
+
+void sighandler(int signalReceived);
+void shutdown(int code);
+
+// Global variables --------------------------------------------------------------------------------------------------
+int debugEnabled = 0;
+Log* logger;
+Remote* remote;
+Mtd* mtd;
+Led* led;
+Osd* osd;
+Timers* timers;
+ViewMan* viewman;
+Command* command;
+VDR* vdr;
+Video* video;
+Audio* audio;
+
+
+void MILLISLEEP(ULONG a)
+{
+
+  Sleep(a);
+
+}
+
+DWORD WINAPI commandthreadStart(void *arg)
+{
+   command->run();
+   return 0;
+}
+
+bool InitApp(HINSTANCE hinst,int cmdshow);
+
+HWND win;//global window handle
+HACCEL acc;
+
+#define ERROR_MSG(str) MessageBox(win,str,"Error!",MB_OK|MB_ICONWARNING)
+INT WINAPI WinMain( HINSTANCE hinst , HINSTANCE previnst, LPSTR cmdline, int cmdshow)
+{
+  //On Windows we have to init a window, we use DXUT
+  if (!InitApp(hinst,cmdshow)) return false;
+  //Starting Network support
+  WSADATA wsadat;
+  int result = WSAStartup(MAKEWORD(2,2),&wsadat);
+  if (result!=NO_ERROR) {
+        ERROR_MSG("Initialising WinSocked: Error at WSAStartup()\n");
+    return 0;
+  }
+  result= CoInitializeEx(NULL,COINIT_MULTITHREADED );//Initialize COM for DirectShow
+  if (result!=S_OK) {
+    ERROR_MSG("Initialising COM: Error at Coinitialize()\n");
+    return 0;
+  }
+
+
+
+
+  // Init global vars ------------------------------------------------------------------------------------------------
+
+  logger     = new Log();
+  remote     = new RemoteWin();
+  mtd        = new MtdWin();
+  led        = new LedWin();
+  timers     = new Timers();
+  osd        = new OsdWin();
+  vdr        = new VDR();
+  video      = new VideoWin();
+  audio      = new AudioWin();
+  viewman    = new ViewMan();
+  command    = new Command();
+
+  if (!logger || !remote || !mtd || !led || !osd || !video || !audio || !viewman || !command)
+  {
+    ERROR_MSG("Could not create objects. Memory problems?\n");
+    shutdown(1);
+  WSACleanup();
+  return 0;
+  }
+
+  // Get logging module started --------------------------------------------------------------------------------------
+
+  if (!logger->init(Log::DEBUG, "vompwin.log", true))
+  {
+    ERROR_MSG("Could not initialise log object. Aborting.\n");
+    shutdown(1);
+  WSACleanup();
+  return 0;
+  }
+
+  logger->log("Core", Log::INFO, "Starting up...");
+
+
+
+  // Init modules ----------------------------------------------------------------------------------------------------
+  int success;
+
+  success = remote->init("/dev/rawir");
+  if (success)
+  {
+    logger->log("Core", Log::INFO, "Remote module initialised");
+  }
+  else
+  {
+    logger->log("Core", Log::EMERG, "Remote module failed to initialise");
+    shutdown(1);
+  WSACleanup();
+  return 0;
+  }
+
+  success = led->init(0);
+  if (success)
+  {
+    logger->log("Core", Log::INFO, "LED module initialised");
+  }
+  else
+  {
+    logger->log("Core", Log::EMERG, "LED module failed to initialise");
+    shutdown(1);
+  WSACleanup();
+  return 0;
+  }
+
+  success = mtd->init("/dev/mtd1");
+  if (success)
+  {
+    logger->log("Core", Log::INFO, "Mtd module initialised");
+  }
+  else
+  {
+    logger->log("Core", Log::EMERG, "Mtd module failed to initialise");
+    shutdown(1);
+  WSACleanup();
+  return 0;
+  }
+
+  success = timers->init();
+  if (success)
+  {
+    logger->log("Core", Log::INFO, "Timers module initialised");
+  }
+  else
+  {
+    logger->log("Core", Log::EMERG, "Timers module failed to initialise");
+    shutdown(1);
+  WSACleanup();
+  return 0;
+  }
+
+  UCHAR videoFormat = (UCHAR)mtd->getPALorNTSC();
+  if      (videoFormat == Video::PAL)  logger->log("Core", Log::INFO, "Read from MTD: PAL 720x576");
+  else if (videoFormat == Video::NTSC) logger->log("Core", Log::INFO, "Read from MTD: NTSC 720x480");
+  else                                 logger->log("Core", Log::INFO, "No help from MTD. Assuming NTSC 720x480");
+
+  success = video->init(videoFormat);
+  if (success)
+  {
+    logger->log("Core", Log::INFO, "Video module initialised");
+  }
+  else
+  {
+    logger->log("Core", Log::EMERG, "Video module failed to initialise");
+    shutdown(1);
+  WSACleanup();
+  return 0;
+  }
+
+  success = osd->init((void*)&win);
+  if (success)
+  {
+    logger->log("Core", Log::INFO, "OSD module initialised");
+  }
+  else
+  {
+    logger->log("Core", Log::EMERG, "OSD module failed to initialise");
+    shutdown(1);
+  WSACleanup();
+  return 0;
+  }
+
+  success = audio->init(Audio::MPEG2_PES);
+  if (success)
+  {
+    logger->log("Core", Log::INFO, "Audio module initialised");
+  }
+  else
+  {
+    logger->log("Core", Log::EMERG, "Audio module failed to initialise");
+    shutdown(1);
+  WSACleanup();
+  return 0;
+  }
+
+  success = vdr->init(3024);
+  if (success)
+  {
+    logger->log("Core", Log::INFO, "VDR module initialised");
+  }
+  else
+  {
+    logger->log("Core", Log::EMERG, "VDR module failed to initialise");
+    shutdown(1);
+  WSACleanup();
+  return 0;
+  }
+
+  success = viewman->init();
+  if (success)
+  {
+    logger->log("Core", Log::INFO, "ViewMan module initialised");
+  }
+  else
+  {
+    logger->log("Core", Log::EMERG, "ViewMan module failed to initialise");
+    shutdown(1);
+  WSACleanup();
+  return 0;
+  }
+
+  success = command->init();
+  if (success)
+  {
+    logger->log("Core", Log::INFO, "Command module initialised");
+  }
+  else
+  {
+    logger->log("Core", Log::EMERG, "Command module failed to initialise");
+    shutdown(1);
+  WSACleanup();
+  return 0;
+  }
+
+  // Other init ------------------------------------------------------------------------------------------------------
+
+  logger->log("Core", Log::NOTICE, "Startup successful");
+
+  // Run main loop ---------------------------------------------------------------------------------------------------
+
+  // Ok, all major device components and other bits are loaded and ready
+
+  HANDLE commandthread;
+ commandthread= CreateThread(NULL, 0, commandthreadStart, NULL,0,
+    NULL);
+  MSG message;
+  message.message=WM_NULL;
+  bool run=true;
+  while(run && WaitForSingleObject(commandthread,0)==WAIT_TIMEOUT) {
+    if (PeekMessage(&message, NULL, 0,0,PM_REMOVE)!=0) {
+      if (TranslateAccelerator(win,acc,&message)==NULL) {
+        TranslateMessage(&message);
+        DispatchMessage(&message);
+        switch (message.message) {
+        case WM_QUIT:
+          run=false; //TODO post exit to command Messages
+        };
+      }
+    } else {
+      //Render
+      ((OsdWin*)osd)->Render();
+    }
+  }
+  // When that returns quit ------------------------------------------------------------------------------------------
+  WaitForSingleObject(commandthread,INFINITE);
+  shutdown(0);
+  WSACleanup();
+  return 0;
+
+}
+
+LONG FAR PASCAL WindowProc(HWND win, UINT msg, WPARAM wparam, LPARAM lparam)
+{
+   switch (msg) {
+   case WM_DESTROY: {
+     //TODO: call command
+     logger->log("Core", Log::NOTICE, "Window closed, shutting down...");
+       command->stop(); // FIXME this is probably not safe - use the messaging system / is that even safe?
+     ((RemoteWin*)Remote::getInstance())->Signal();
+     PostQuitMessage(0);
+  }break;
+  case WM_SIZE: {
+        int width = LOWORD(lparam);
+        int height = HIWORD(lparam);
+         //Call device
+        }
+        break;
+   case WM_PAINT:
+        RECT r;
+        PAINTSTRUCT ps;
+        if (GetUpdateRect(win, &r, FALSE)) {
+            BeginPaint(win, &ps);
+            //Call Painting Mechanism
+            EndPaint(win, &ps);
+        }
+        break;
+   case WM_KEYDOWN:
+     if (((RemoteWin*)remote)->ReceiveButtonVK(wparam)) {
+       return 0L; //We process that Key
+     } else {
+       return DefWindowProc(win, msg, wparam, lparam);
+     }
+
+     break;
+  case WM_APPCOMMAND:
+    if (((RemoteWin*)remote)->ReceiveButtonAP(GET_APPCOMMAND_LPARAM(lparam))){
+      return TRUE; //yes we process that message
+    } else {
+      return DefWindowProc(win, msg, wparam, lparam);
+    }
+
+    break;
+  case WM_COMMAND:
+    if (((RemoteWin*)remote)->ReceiveButtonAP(LOWORD(wparam))){
+      return 0; //yes we process that message
+    } else {
+      return DefWindowProc(win, msg, wparam, lparam);
+    }
+
+    break;
+    default:
+        return DefWindowProc(win, msg, wparam, lparam);
+    }
+    return 0L;
+}
+
+
+bool InitApp(HINSTANCE hinst,int cmdshow) {
+  WNDCLASS wcs;
+  DWORD flags;
+  wcs.style = CS_HREDRAW | CS_VREDRAW;
+    wcs.lpfnWndProc = WindowProc;
+    wcs.cbClsExtra = 0;
+    wcs.cbWndExtra = sizeof(DWORD);
+    wcs.hInstance = hinst;
+    wcs.hIcon = NULL;
+    wcs.hCursor = NULL;
+    wcs.hbrBackground = (HBRUSH)GetStockObject(WHITE_BRUSH);
+    wcs.lpszMenuName = NULL;
+    wcs.lpszClassName = "vomp";
+  acc=LoadAccelerators(hinst,MAKEINTRESOURCE(VOMPACCELERATOR));
+  if (!RegisterClass(&wcs))
+        return false;
+  flags =WS_VISIBLE | WS_POPUP | WS_CAPTION | WS_SYSMENU
+                 |WS_MINIMIZEBOX | WS_SIZEBOX |WS_MAXIMIZEBOX;
+  RECT wnted={0,0,720,576};
+  AdjustWindowRect(&wnted,flags ,false);
+  win=CreateWindow("vomp","vomp",flags, CW_USEDEFAULT,CW_USEDEFAULT,
+    wnted.right-wnted.left,wnted.bottom-wnted.top,NULL,NULL,hinst,NULL);
+  if (!win)
+        return FALSE;
+  ShowWindow(win,SW_SHOWNORMAL);
+    UpdateWindow(win);
+  return TRUE;
+}
+
+
+
+
+
+// -------------------------------------------------------------------------------------------------------------------
+
+void shutdown(int code)
+{
+  if (viewman)
+  {
+    viewman->shutdown();
+    delete viewman;
+    logger->log("Core", Log::NOTICE, "ViewMan module shut down");
+  }
+
+  if (command) // shut down command here in case views have posted messages
+  {
+    command->shutdown();
+    delete command;
+    logger->log("Core", Log::NOTICE, "Command module shut down");
+  }
+
+  if (vdr)
+  {
+    vdr->shutdown();
+    delete vdr;
+    logger->log("Core", Log::NOTICE, "VDR module shut down");
+  }
+
+  if (osd)
+  {
+    osd->shutdown();
+    delete osd;
+    logger->log("Core", Log::NOTICE, "OSD module shut down");
+  }
+
+  if (audio)
+  {
+    audio->shutdown();
+    delete audio;
+    logger->log("Core", Log::NOTICE, "Audio module shut down");
+  }
+
+  if (video)
+  {
+    video->shutdown();
+    delete video;
+    logger->log("Core", Log::NOTICE, "Video module shut down");
+  }
+
+  if (timers)
+  {
+    timers->shutdown();
+    delete timers;
+    logger->log("Core", Log::NOTICE, "Timers module shut down");
+  }
+
+  if (mtd)
+  {
+    mtd->shutdown();
+    delete mtd;
+    logger->log("Core", Log::NOTICE, "MTD module shut down");
+  }
+
+  if (led)
+  {
+    led->shutdown();
+    delete led;
+    logger->log("Core", Log::NOTICE, "LED module shut down");
+  }
+
+  if (remote)
+  {
+    remote->shutdown();
+    delete remote;
+    logger->log("Core", Log::NOTICE, "Remote module shut down");
+  }
+
+  if (logger)
+  {
+    logger->log("Core", Log::NOTICE, "Log module shutting down... bye!\n\n");
+    logger->shutdown();
+    delete logger;
+  }
+  ExitProcess(0);
+
+}
+
+// -------------------------------------------------------------------------------------------------------------------
+
+ULLONG ntohll(ULLONG a)
+{
+  return htonll(a);
+}
+
+ULLONG htonll(ULLONG a)
+{
+/*
+  #if BYTE_ORDER == BIG_ENDIAN
+    return a;
+  #else
+    ULLONG b = 0;
+
+    b = ((a << 56) & 0xFF00000000000000ULL)
+      | ((a << 40) & 0x00FF000000000000ULL)
+      | ((a << 24) & 0x0000FF0000000000ULL)
+      | ((a <<  8) & 0x000000FF00000000ULL)
+      | ((a >>  8) & 0x00000000FF000000ULL)
+      | ((a >> 24) & 0x0000000000FF0000ULL)
+      | ((a >> 40) & 0x000000000000FF00ULL)
+      | ((a >> 56) & 0x00000000000000FFULL) ;
+
+    return b;
+  #endif*///This macro switching does not work for windows, here is a implementation without
+  // using BYTE_ORDER
+  //#define ntohll(x) (((_int64)(ntohl((int)((x << 32) >> 32))) << 32) |
+                 //    (unsigned int)ntohl(((int)(x >> 32)))) //By Runner
+
+  return (((ULLONG)htonl((ULONG)((a<<32)>> 32))<<32)
+    |(ULONG)htonl(((ULONG) (a >> 32))));
+}
+#endif
\ No newline at end of file
index 361a489c539551a8ffc53b6b2a7e0c377840ad24..91805d6954710f8cf090a9609c2a904de0453090 100644 (file)
--- a/wjpeg.cc
+++ b/wjpeg.cc
@@ -106,7 +106,13 @@ void WJpeg::draw()
 
   free(buffer);
   logger->log("BJpeg", Log::DEBUG, "deleted buffer");
+#else
+  DWORD width,height;
+  width=height=1;
+  ((SurfaceWin*)surface)->drawJpeg(fileName+1,offsetX,offsetY,&width,&height);//This should went into the abstract base classes?
+  //Windows has a problem with the leading / fixme
 
+  setDimensions(width, height);
 #endif
 }