]> git.vomp.tv Git - vompclient.git/commitdiff
MVP/Windows convergence: Stream; DrainTarget
authorMark Calderbank <mark@vomp.tv>
Sat, 24 Jun 2006 12:23:20 +0000 (12:23 +0000)
committerMark Calderbank <mark@vomp.tv>
Sat, 24 Jun 2006 12:23:20 +0000 (12:23 +0000)
19 files changed:
afeed.cc
audio.h
audiomvp.cc
audiomvp.h
audiowin.cc
audiowin.h
defines.h
demuxer.cc
demuxer.h
draintarget.h
player.cc
stream.cc
stream.h
vfeed.cc
video.h
videomvp.cc
videomvp.h
videowin.cc
videowin.h

index 7bc8fbf081398e244687ab79c0e5fe42df4fea5c..5f864459cc288d4eac9df774407652e05300171f 100644 (file)
--- a/afeed.cc
+++ b/afeed.cc
@@ -60,7 +60,7 @@ void AFeed::stop()
 
 void AFeed::threadMethod()
 {
-  int alen;
+  bool alen;
 
   while(1)
   {
diff --git a/audio.h b/audio.h
index a240121bcc600f1705c2b18a7446bd4b34327ffc..0baaeb2236c8d5d8d00e19602e4cc509b46e710f 100644 (file)
--- a/audio.h
+++ b/audio.h
@@ -58,10 +58,6 @@ class Audio : public DrainTarget
     virtual int mute()=0;
     virtual int unMute()=0;
 
-#ifndef NEW_DEMUXER
-    virtual int write(UCHAR* buffer, ULONG length)=0;
-#endif
-
     int volumeUp();
     int volumeDown();
     int getVolume();
index f7a4ab4c705b6b62cd9ec932bf2f007c2d089f28..3ef84e1b8e7cb8c58d6aee0bebcc497118489416 100644 (file)
@@ -228,23 +228,20 @@ int AudioMVP::test()
 }
 #endif
 
-
-#ifdef NEW_DEMUXER
-
-UINT AudioMVP::DeliverMediaSample(MediaPacket packet, UCHAR* buffer, UINT *samplepos)
+void AudioMVP::PrepareMediaSample(const MediaPacketList& mplist,UINT samplepos)
 {
-  return 0;
+  packet = mplist.front();
 }
 
-void AudioMVP::ResetTimeOffsets()
+UINT AudioMVP::DeliverMediaSample(const UCHAR* buffer, UINT* samplepos)
 {
+  int written = ::write(fdAudio, buffer + packet.pos_buffer + *samplepos,
+                                 packet.length - *samplepos);
+  if (written == (int)(packet.length - *samplepos)) {*samplepos = 0; return 1;}
+  if (written > 0) *samplepos += written;
+  return 0;
 }
 
-#else
-
-int AudioMVP::write(UCHAR* buffer, ULONG length)
+void AudioMVP::ResetTimeOffsets()
 {
-  return ::write(fdAudio, buffer, length);
 }
-
-#endif
index 0178514d065339e03911ad0fed744c9e76cb6278..52c3b53589291db2632c257ac1a889ec6983dce9 100644 (file)
@@ -55,14 +55,11 @@ class AudioMVP : public Audio
     int mute();
     int unMute();
 
-#ifdef NEW_DEMUXER
-    //Writing Data to Audiodevice -- unused in MVP code so far
-    virtual UINT DeliverMediaSample(MediaPacket packet, UCHAR* buffer, UINT *samplepos);
+    //Writing Data to Audiodevice
+    virtual void PrepareMediaSample(const MediaPacketList&, UINT samplepos);
+    virtual UINT DeliverMediaSample(const UCHAR* buffer, UINT *samplepos);
     virtual long long SetStartOffset(long long curreftime, bool *rsync) { return 0; };
     virtual void ResetTimeOffsets();
-#else
-    int write(UCHAR* buffer, ULONG length);
-#endif
 
 #ifdef DEV
     int test();
@@ -72,6 +69,9 @@ class AudioMVP : public Audio
     int initAllParams();
     UCHAR streamType;
     int fdAudio;
+
+    MediaPacket packet;
+    UINT packetpos;
 };
 
 #endif
index 189731b28c1573187914fd41f7cdb1ffb961a48e..097247fbab1c4fff998b3ec7d1695ca26baa523f 100644 (file)
@@ -145,8 +145,23 @@ int AudioWin::unMute()
   return 1;\r
 }\r
 \r
-UINT AudioWin::DeliverMediaSample(MediaPacket packet,\r
-     UCHAR* buffer,\r
+void AudioWin::PrepareMediaSample(const MediaPacketList& mplist,UINT samplepos)\r
+{\r
+  mediapacket = mplist.front();\r
+}\r
+\r
+UINT AudioWin::DeliverMediaSample(const UCHAR* buffer, UINT *samplepos)\r
+{\r
+  DeliverMediaPacket(mediapacket, buffer, samplepos);\r
+  if (*samplepos == mediapacket.length) {\r
+    *samplepos = 0;\r
+    return 1;\r
+  }\r
+  else return 0;\r
+}\r
+\r
+UINT AudioWin::DeliverMediaPacket(MediaPacket packet,\r
+     const UCHAR* buffer,\r
      UINT *samplepos)\r
 {\r
   /*First Check, if we have an audio sample*/\r
index 52690b55a782fc20b3511be3d8cc72ca8d83806c..b297519f77d0f8d115d1d0f6d646c2cd8a74ca00 100644 (file)
@@ -49,7 +49,12 @@ class AudioWin : public Audio
     int write(char *buf, int len);\r
 \r
     // Writing Data to Audiodevice\r
-    virtual UINT DeliverMediaSample(MediaPacket packet, UCHAR* buffer, UINT *samplepos);\r
+    virtual void PrepareMediaSample(const MediaPacketList&, UINT samplepos);\r
+    virtual UINT DeliverMediaSample(const UCHAR* buffer, UINT *samplepos);\r
+    UINT DeliverMediaPacket(MediaPacket packet, const UCHAR* buffer, UINT *samplepos);\r
+  private:\r
+    MediaPacket mediapacket;\r
+  public:\r
     virtual long long SetStartOffset(long long curreftime, bool *rsync);\r
   virtual void ResetTimeOffsets();\r
 \r
index d3c1f0ddbab45329751ad23694bdd11647d1318f..a1a7d7d0408c7ccf5eea17b4438a8f370faa396f 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;
index 8e97ec65591d027f99d514f9913254a3a56ac823..90db8146ff6f9602503617d3eef5dba9ad141ece 100644 (file)
@@ -145,12 +145,12 @@ void Demuxer::setAspectRatio(enum AspectRatio ar)
     arcnt = 0;
 }
 
-int Demuxer::writeAudio()
+bool Demuxer::writeAudio()
 {
   return audiostream.drain();
 }
 
-int Demuxer::writeVideo()
+bool Demuxer::writeVideo()
 {
   return videostream.drain();
 }
index 7e0f88dbfafcab3fe878396fb1420e4109d26931..c4c93927289c7d6fbc1a4d678c051c4cc8bf440d 100644 (file)
--- a/demuxer.h
+++ b/demuxer.h
@@ -73,8 +73,8 @@ protected:
     void seek();
     void setVideoStream(int id);
     void setAudioStream(int id);
-    int writeAudio();
-    int writeVideo();
+    bool writeAudio();
+    bool writeVideo();
 
     virtual int scan(UCHAR* buf, int len) = 0;
     virtual int findVideoPTS(UCHAR* buf, int len, ULLONG* dest) = 0;
index 380979b83ebccefeb7bf1419d44ebec2cfbba634..74d5862bc72bbbc2cd776ebf0e908adf4fe27625 100644 (file)
 #include "defines.h"
 #include <list>
 
-
-#ifdef NEW_DEMUXER
-
 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
+  // The fields below are not needed by the MVP
+#ifdef WIN32
+  ULLONG recording_byte_pos; //position in recording
+  ULLONG pts;
   long long presentation_time;/* in 100 ns units*/
   bool synched;
   bool disconti;
+#endif
 };
 
 using namespace std;
-
 typedef list<MediaPacket> MediaPacketList;
 
-#endif
-
 class DrainTarget
 {
   public:
     DrainTarget();
     virtual ~DrainTarget();
 
-#ifdef NEW_DEMUXER
-
-    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;
     virtual void ResetTimeOffsets()=0;
 
-#else
-    virtual int write(UCHAR* buffer, ULONG length)=0;
-#endif
-
+// The following two functions are used by the Stream
+// to deliver media packets to the front end (DrainTarget).
+//
+// First, the Stream calls PrepareMediaSample, which gives the front end
+// read-only access to the Stream's MediaPacketList. PrepareMediaSample should
+// examine the list to determine how much it wishes to consume, and
+// should copy any data it requires from the MediaPacket objects into
+// local storage.
+// This function call takes place under a mutex lock to ensure integrity
+// of the list structure. It should be fast and must not contain any
+// cancellation points, such as I/O calls for logging.
+//
+// Second, the Stream releases the mutex and calls DeliverMediaSample.
+// This function delivers data from the Stream buffer to the presentation
+// device and returns information to the Stream regarding how many MediaPackets
+// were consumed. Any data copied from the MediaPackets objects during
+// PrepareMediaSample is guaranteed by the Stream still to be valid
+// during the following DeliverMediaSample call.
+
+    // samplepos is equal to the number of bytes from the first MediaPacket
+    // in the list that have already been consumed in a previous call.
+    virtual void PrepareMediaSample(const MediaPacketList&, UINT samplepos)=0;
+
+    // The Stream guarantees that the value of *samplepos passed to
+    // DeliverMediaSample will be equal to the value of samplepos passed to
+    // PrepareMediaSample in the previous call.
+    // This function should consume data from the buffer according to the
+    // decisions made in PrepareMediaSample. Its return value and *samplepos
+    // tell the Stream how much data it consumed.
+    // If DeliverMediaSample returns X, the Stream will remove packets 0 to X-1
+    // (inclusive) from the list before the next call.
+    // DeliverMediaSample must also set *samplepos equal to the number of bytes
+    // processed from packet X (usually zero).
+    virtual UINT DeliverMediaSample(const UCHAR* buffer, UINT *samplepos)=0;
 };
 
-
-
-
 #endif
-
index bdacba5e725b909840c4a06b5c4a1a5399ee0c06..7477586590d3c62c7a6bd94f79ac82bc3a5fe7fc 100644 (file)
--- a/player.cc
+++ b/player.cc
@@ -293,6 +293,8 @@ int Player::playInt(bool* doUnlock)
   else // do prebuffering
   {
     logger->log("Player", Log::DEBUG, "Prebuffering...");
+//    afeed.start();
+//    vfeed.start();
     preBuffering = true;
   }
 
index 6a4531e5ed0b9930f176eba04fafdadaa4a4e2ef..21b847a93ca93766ccb2e0db115cb879296c4227 100644 (file)
--- a/stream.cc
+++ b/stream.cc
@@ -1,5 +1,5 @@
 /*
-    Copyright 2005 Mark Calderbank
+    Copyright 2005-2006 Mark Calderbank
 
     This file is part of VOMP.
 
 */
 
 #include "stream.h"
+#include "log.h"
 
 Stream::Stream()
 {
   initted = 0;
-  draintarget=NULL;
-#ifdef NEW_DEMUXER
-  cur_packet_pos=0;
-#endif
+  draintarget = NULL;
+  cur_packet_pos = 0;
 }
 
 Stream::~Stream()
@@ -36,16 +35,14 @@ Stream::~Stream()
 
 void Stream::shutdown()
 {
-  if (initted) {
-         free(outbuf);
-#ifdef NEW_DEMUXER
+  if (initted)
+  {
+    free(outbuf);
 #ifdef WIN32
-  CloseHandle(mutex);
-#endif
+    CloseHandle(mutex);
 #endif
   }
   initted = 0;
-
 }
 
 int Stream::init(DrainTarget* tdt, int bufsize)
@@ -54,82 +51,31 @@ int Stream::init(DrainTarget* tdt, int bufsize)
   if (!outbuf) return 0;
   draintarget = tdt;
   bufferSize = bufsize;
-  bufferHead = 0;
-  bufferTail = 0;
-  bufferMark = -1;
   initted = 1;
-#ifdef NEW_DEMUXER
 #ifndef WIN32
   pthread_mutex_init(&mutex, NULL);
 #else
   mutex=CreateMutex(NULL,FALSE,NULL);
-#endif
 #endif
   return 1;
 }
 
 void Stream::flush()
 {
-#ifdef NEW_DEMUXER
   lock();
   mediapackets.clear();
   unLock();
   if (draintarget) draintarget->ResetTimeOffsets();
-#endif
-  bufferHead = 0;
-  bufferTail = 0;
-  bufferMark = -1;
 }
 
-#ifndef NEW_DEMUXER
-int Stream::put(UCHAR* inbuf, int len)
+int Stream::put(const UCHAR* inbuf, int len)
 {
   int ret = 0;
-  int tail = bufferTail;
-  int head = bufferHead;
-  if (tail == 0) tail = bufferSize;
-
-  if (head < tail)
-  {
-    // The free space is in one continuous chunk.
-    if (len < tail - head)
-    {
-      memcpy(outbuf + head, inbuf, len);
-      bufferHead += len;
-      ret = len;
-    }
-  }
-  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;
-    ret = len;
-  }
-  else if (len < tail)
-  {
-    bufferMark = head;
-    memcpy(outbuf, inbuf, len);
-    bufferHead = len;
-    ret = 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.length = len;
+  newPacket.pos_buffer = 0;
+#ifdef WIN32
   newPacket.synched=false;
   newPacket.disconti=false;
   newPacket.pts=0;
@@ -146,142 +92,66 @@ int Stream::put(UCHAR* inbuf, int len)
     newPacket.presentation_time=(ULLONG)(newPacket.pts*10000LL/90LL);
     newPacket.presentation_time-=draintarget->SetStartOffset(newPacket.presentation_time,&newPacket.disconti);
   }
+#endif
 
-  if (head < tail)
+  lock();
+  int front, back;
+  if (mediapackets.empty())
   {
-    // 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;
-         lock();
-      mediapackets.push_front(newPacket);
-         unLock();
-    }
+    back = 0; front = bufferSize;
   }
-  else if (len <= bufferSize - head)
+  else
   {
-    // 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;
-       lock();
-    mediapackets.push_front(newPacket);
-       unLock();
+    front = mediapackets.front().pos_buffer;
+    back = mediapackets.back().pos_buffer + mediapackets.back().length;
+    if (back == bufferSize) back = 0;
+  }
+  unLock();
 
+  if (back <= front)
+  {
+    // The free space (if any) is in one continuous chunk.
+    if (len <= front - back) ret = len; // Is there enough of it?
+  }
+  else if (len <= bufferSize - back)
+  {
+    // There is enough space at the end of the buffer
     ret = len;
   }
-  else if (len < tail)
+  else if (len <= front)
   {
-    bufferMark = head;
-    memcpy(outbuf, inbuf, len);
-    bufferHead = len;
+    // There is enough space at the start of the buffer
+    back = 0;
     ret = len;
-    newPacket.pos_buffer=0;
-       lock();
-    mediapackets.push_front(newPacket);
-       unLock();
   }
-  return ret;
-}
-#endif
-
-#ifndef NEW_DEMUXER
-
-int Stream::drain()
-{
-  int ret = 0;
-  int head = bufferHead;
-  int tail = bufferTail;
-  int mark = bufferMark;
-  int written;
 
-  if (mark == -1 && tail > head) mark = bufferSize;
-
-  if (mark >= 0)
+  if (ret) // Nonzero if we managed to find room for the packet
   {
-    // Drain up to the marker.
-#ifndef WIN32
-    written = draintarget->write(outbuf + tail, (mark - tail));
-#else
-    written=mark-tail;
-    MILLISLEEP(1);
-#endif
-    if (written < 0) return ret;
-    ret += written;
-    if (written == (mark - tail))
-    {
-      bufferMark = -1;
-      bufferTail = tail = 0;
-    }
-    else
-    {
-      bufferTail += written;
-      return ret;
-    }
+    memcpy(outbuf + back, inbuf, len);
+    newPacket.pos_buffer = back;
+    lock();
+    mediapackets.push_back(newPacket);
+    unLock();
   }
-
-  if (tail == head) return ret; // Empty
-#ifndef WIN32
-  written = draintarget->write(outbuf + tail, (head - tail));
-#else
-  written=(head - tail);
-  MILLISLEEP(1);
-#endif
-  if (written < 0) return ret;
-  ret += written;
-  bufferTail = tail + written;
   return ret;
 }
 
-#else
-
-int Stream::drain()
+bool Stream::drain()
 {
-  int ret = 0;
-  int written=1;
-//  draintarget=dt; // this is now set in init, is this ok?
-
-
-
-  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;
+  bool ret = false;
   lock();
-  MediaPacket cur_mp=mediapackets.back();
-  unLock();
-  written=0;
-  written=draintarget->DeliverMediaSample(cur_mp,outbuf,&cur_packet_pos);
-
-  ret+=written;
-
-  if (cur_packet_pos==cur_mp.length) {
-    cur_packet_pos=0;
-       lock();
-    mediapackets.pop_back();
-       unLock();
-    if ((((ULONG)tail)+cur_mp.length) < ((ULONG)mark)) {
-      bufferTail=tail+cur_mp.length;
-    } else {
-      bufferTail=0;
-      bufferMark=-1;
-    }
-
+  UINT listlength = mediapackets.size();
+  if (listlength != 0)
+  {
+    draintarget->PrepareMediaSample(mediapackets, cur_packet_pos);
+    unLock();
+    UINT consumed = draintarget->DeliverMediaSample(outbuf, &cur_packet_pos);
+    lock();
+    if (consumed != 0) ret = true;
+    if (consumed > listlength) consumed = listlength;
+    while (consumed--) mediapackets.pop_front();
   }
-
+  unLock();
   return ret;
 }
 
@@ -289,7 +159,7 @@ void Stream::lock()
 {
 #ifndef WIN32
   pthread_mutex_lock(&mutex);
-  logger->log("Player", Log::DEBUG, "LOCKED");
+  //logger->log("Player", Log::DEBUG, "LOCKED");
 
 #else
    WaitForSingleObject(mutex, INFINITE );
@@ -299,11 +169,9 @@ void Stream::lock()
 void Stream::unLock()
 {
 #ifndef WIN32
-  logger->log("Player", Log::DEBUG, "UNLOCKING");
+  //logger->log("Player", Log::DEBUG, "UNLOCKING");
   pthread_mutex_unlock(&mutex);
 #else
    ReleaseMutex(mutex);
 #endif
 }
-
-#endif
index 507855b2a7e80ebcc8521989801b124e95ce72e9..d9633308426389c1a6617437db7f29b8725e7396 100644 (file)
--- a/stream.h
+++ b/stream.h
 #ifndef STREAM_H
 #define STREAM_H
 
+#ifndef WIN32
+#include <pthread.h>
+#endif
+
 #include <stdlib.h>
 #ifndef WIN32
 #include <unistd.h>
@@ -32,8 +36,6 @@
 #include "defines.h"
 #include "draintarget.h"
 
-
-
 class Stream
 {
   public:
@@ -42,11 +44,10 @@ class Stream
     int init(DrainTarget* tdt, int bufsize);
     void shutdown();
     void flush();
-    int put(UCHAR* inbuf, int len);
-    int drain();
+    int put(const UCHAR* inbuf, int len);
+    bool drain();
 
   private:
-#ifdef NEW_DEMUXER
     MediaPacketList mediapackets;
     UINT cur_packet_pos;
 #ifndef WIN32
@@ -56,15 +57,11 @@ class Stream
 #endif
        void lock();
        void unLock();
-#endif
 
     DrainTarget* draintarget;
     int initted;
     UCHAR* outbuf;
     int bufferSize;
-    volatile int bufferHead;
-    volatile int bufferTail;
-    volatile int bufferMark;
 };
 
 #endif
index 4fd465709a5c89fe461981a1551a5e0acad0fb75..0255b9878f81b837689435c9f3590c3539ea6adf 100644 (file)
--- a/vfeed.cc
+++ b/vfeed.cc
@@ -53,7 +53,7 @@ void VFeed::release()
 
 void VFeed::threadMethod()
 {
-  int vlen;
+  bool vlen;
 
   threadWaitForSignal(); // Don't feed video until audio has started
 
diff --git a/video.h b/video.h
index 660e3e95d3206bb302d766cfde81f05f79a9a28b..026aee2645a104f664247b0ddbc655a7a19dee1b 100644 (file)
--- a/video.h
+++ b/video.h
@@ -65,10 +65,6 @@ class Video: public DrainTarget
     virtual ULONG timecodeToFrameNumber(ULLONG timecode)=0;
     virtual ULLONG getCurrentTimestamp()=0;
 
-#ifndef NEW_DEMUXER
-    virtual int write(UCHAR* buffer, ULONG length)=0;
-#endif
-
     virtual void turnVideoOn(){};
     virtual void turnVideoOff(){};
     virtual ULLONG frameNumberToTimecode(ULONG timecode) { return 0; };
index 43e84a72846993123dc5325239ccb82316ac69e2..279a1344d00e0ee3fbede4baefcd6956d206fad1 100644 (file)
@@ -366,25 +366,35 @@ int VideoMVP::test2()
 }
 #endif
 
-
-
-#ifdef NEW_DEMUXER
-
-UINT VideoMVP::DeliverMediaSample(MediaPacket packet, UCHAR* buffer, UINT *samplepos)
-{
-  return 0;
+void VideoMVP::PrepareMediaSample(const MediaPacketList& mplist,UINT samplepos)
+{
+  MediaPacketList::const_iterator iter = mplist.begin();
+  deliver_start = iter->pos_buffer + samplepos;
+  mediapacket_len[0] = deliver_length = iter->length;
+  deliver_count = 1;
+  while (++iter != mplist.end() &&
+           iter->pos_buffer == deliver_start + deliver_length)
+  {
+    deliver_length += iter->length;
+    mediapacket_len[deliver_count] = iter->length;
+    ++deliver_count;
+    if (deliver_length >= WRITE_LENGTH ||
+        deliver_count == WRITE_PACKETS) break;
+  }
 }
 
-void VideoMVP::ResetTimeOffsets()
+UINT VideoMVP::DeliverMediaSample(const UCHAR* buffer, UINT* samplepos)
 {
+  int written = ::write(fdVideo, buffer + deliver_start, deliver_length);
+  if (written == (int)deliver_length) { *samplepos = 0; return deliver_count;}
+  if (written <= 0) return 0;
+  // Handle a partial write. Is this possible? Should we bother?
+  UINT i = 0;
+  while ((written -= mediapacket_len[i]) >= 0) i++;
+  *samplepos = mediapacket_len[i] + written;
+  return i;
 }
 
-#else
-
-int VideoMVP::write(UCHAR* buffer, ULONG length)
+void VideoMVP::ResetTimeOffsets()
 {
-  return ::write(fdVideo, buffer, length);
 }
-
-#endif
-
index 3f626d20579ee4afeb3cfa53f74aa64a12573189..b8db9c6ea55de6ddf1f70fe322efcdf22c23a71e 100644 (file)
@@ -36,6 +36,9 @@
 #include "video.h"
 #include "stb.h"
 
+#define WRITE_LENGTH (32*1024) // Consume up to 32K at a time from Stream
+#define WRITE_PACKETS 16       // But no more than 16 packets
+
 class VideoMVP : public Video
 {
   public:
@@ -68,14 +71,12 @@ class VideoMVP : public Video
     ULONG timecodeToFrameNumber(ULLONG timecode);
     ULLONG getCurrentTimestamp();
 
-#ifdef NEW_DEMUXER
-    //Writing Data to Videodevice
-    virtual UINT DeliverMediaSample(MediaPacket packet, UCHAR* buffer, UINT *samplepos);
-    virtual long long SetStartOffset(long long curreftime, bool *rsync) { return 0; };
+    // Writing Data to Videodevice
+    virtual void PrepareMediaSample(const MediaPacketList&, UINT samplepos);
+    virtual UINT DeliverMediaSample(const UCHAR* buffer, UINT* samplepos);
+    virtual long long SetStartOffset(long long curreftime, bool *rsync)
+    { return 0; };
     virtual void ResetTimeOffsets();
-#else
-    int write(UCHAR* buffer, ULONG length);
-#endif
 
 #ifdef DEV
     int test();
@@ -85,6 +86,9 @@ class VideoMVP : public Video
   private:
     int checkSCART();
     void setLetterboxBorder(char* border);
+
+    UINT deliver_start, deliver_length, deliver_count;
+    UINT mediapacket_len[WRITE_PACKETS];
 };
 
 #endif
index d02988670c477809d62ded38b6aa9913012bb34d..35ddff6fe42bcb68d17e07de1722a4fc37a64c56 100644 (file)
@@ -453,9 +453,24 @@ void VideoWin::CleanupDS()
 \r
 }\r
 \r
+void VideoWin::PrepareMediaSample(const MediaPacketList& mplist,\r
+     UINT samplepos)\r
+{\r
+  mediapacket = mplist.front();\r
+}\r
+\r
+UINT VideoWin::DeliverMediaSample(const UCHAR* buffer, UINT *samplepos)\r
+{\r
+  DeliverMediaPacket(mediapacket, buffer, samplepos);\r
+  if (*samplepos == mediapacket.length) {\r
+    *samplepos = 0;\r
+    return 1;\r
+  }\r
+  else return 0;\r
+}\r
 \r
-UINT VideoWin::DeliverMediaSample(MediaPacket packet,\r
-     UCHAR* buffer,\r
+UINT VideoWin::DeliverMediaPacket(MediaPacket packet,\r
+     const UCHAR* buffer,\r
      UINT *samplepos)\r
 {\r
   /*First Check, if we have an audio sample*/\r
index 5176d6abb22d4f204d3ed1da0c0acbe935079dc7..23f558f64d407271dbfbaf3a8968fd24d1240c3c 100644 (file)
@@ -73,7 +73,12 @@ class VideoWin : public Video
     ULLONG getCurrentTimestamp();\r
 \r
     //Writing Data to Videodevice\r
-    virtual UINT DeliverMediaSample(MediaPacket packet, UCHAR* buffer, UINT *samplepos);\r
+    virtual void PrepareMediaSample(const MediaPacketList&, UINT samplepos);\r
+    virtual UINT DeliverMediaSample(const UCHAR* buffer, UINT *samplepos);\r
+    UINT DeliverMediaPacket(MediaPacket packet, const UCHAR* buffer, UINT *samplepos);\r
+  private:\r
+    MediaPacket mediapacket;\r
+  public:\r
 \r
     int getCurrentAudioMediaSample(IMediaSample** ms);\r
     int DeliverAudioMediaSample();\r