Update of /cvsroot/freevo/fred
In directory sc8-pr-cvs1.sourceforge.net:/tmp/cvs-serv16163

Modified Files:
        ChangeLog Makefile dvbdevice.cc misc.h op_filewriter.cc 
        op_filewriter.h op_generic.cc op_generic.h remux.cc remux.h 
Added Files:
        ringbuffer.cc ringbuffer.h 
Log Message:
- replaced remuxer with newer version derived from vdr project 
- added ringbuffer.cc that is needed by new remuxer
- some remuxer related changes in other files


Index: ChangeLog
===================================================================
RCS file: /cvsroot/freevo/fred/ChangeLog,v
retrieving revision 1.3
retrieving revision 1.4
diff -C2 -d -r1.3 -r1.4
*** ChangeLog   28 Mar 2005 15:04:33 -0000      1.3
--- ChangeLog   23 Apr 2005 16:10:11 -0000      1.4
***************
*** 1,2 ****
--- 1,11 ----
+ 2005-04-23  Soenke Schwardt  <[EMAIL PROTECTED]>
+ 
+       * op_filewriter.cc (set_pids): changed to match with new remuxer
+       
+       * op_filewriter.cc (flush): changed to match with new remuxer
+ 
+       * remux.cc: replaced remuxer with newer version derived from vdr
+       project - added ringbuffer.cc that is needed by new remuxer
+ 
  2005-03-28  Soenke Schwardt  <[EMAIL PROTECTED]>
  

Index: misc.h
===================================================================
RCS file: /cvsroot/freevo/fred/misc.h,v
retrieving revision 1.1.1.1
retrieving revision 1.2
diff -C2 -d -r1.1.1.1 -r1.2
*** misc.h      2 Mar 2005 17:57:48 -0000       1.1.1.1
--- misc.h      23 Apr 2005 16:10:11 -0000      1.2
***************
*** 53,56 ****
--- 53,57 ----
  const int LOG_DEBUG_RPCSERVER    = 1024;
  const int LOG_DEBUG_REMUX        = 2048;
+ const int LOG_DEBUG_RINGBUFFER   = 4096;
  
  #define printD(verbose, fmt, args...)                              \

Index: remux.cc
===================================================================
RCS file: /cvsroot/freevo/fred/remux.cc,v
retrieving revision 1.3
retrieving revision 1.4
diff -C2 -d -r1.3 -r1.4
*** remux.cc    28 Mar 2005 15:04:34 -0000      1.3
--- remux.cc    23 Apr 2005 16:10:12 -0000      1.4
***************
*** 2,7 ****
   * File: remux.cc
   *
-  * Author: S�nke Schwardt <[EMAIL PROTECTED]>
-  *
   * $Id$
   *
--- 2,5 ----
***************
*** 25,96 ****
   *
[...1830 lines suppressed...]
!   synced = false;
!   skipped = 0;
!   resultSkipped = 0;
  }
  
! void cRemux::SetBrokenLink(uchar *Data, int Length)
  {
    if (Length > 9 && Data[0] == 0 && Data[1] == 0 && Data[2] == 1 && (Data[3] 
& 0xF0) == VIDEO_STREAM_S) {
!      for (int i = Data[8] + 9; i < Length - 7; i++) { // +9 to skip video 
packet header
!          if (Data[i] == 0 && Data[i + 1] == 0 && Data[i + 2] == 1 && Data[i + 
3] == 0xB8) {
!             if (!(Data[i + 7] & 0x40)) // set flag only if GOP is not closed
!                Data[i + 7] |= 0x20;
!             return;
!             }
!          }
!      printD( LOG_DEBUG_REMUX, "SetBrokenLink: no GOP header found in video 
packet\n");
!      }
!   else
!      printD( LOG_DEBUG_REMUX, "SetBrokenLink: no video packet in frame\n");
  }

--- NEW FILE: ringbuffer.h ---
/*
 * File: ringbuffer.h
 *
 * $Id: ringbuffer.h,v 1.1 2005/04/23 16:10:12 schwardt Exp $
 *
 * Copyright (C) 2005 S�nke Schwardt <[EMAIL PROTECTED]>
 *
 * This program 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, or (at your option)
 * any later version.
 *
 * This program 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 this program; if not, write to the Free Software
 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
 *
 * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
 *
 * The parts of this code that implement TS2PES and Remux have been
 * taken from VDR project. (http://www.cadsoft.de/people/kls/vdr/)
 *
 */

#ifndef __RINGBUFFER_H
#define __RINGBUFFER_H

/* #include "tools.h" */
#include <inttypes.h>
#include <time.h>

typedef unsigned char uchar;

class cRingBuffer {
private:
  int putTimeout;
  int getTimeout;
  int size;
  time_t lastOverflowReport;
  int overflowCount;
  int overflowBytes;
protected:
  int maxFill;//XXX
  int lastPercent;
  bool statistics;//XXX
  void UpdatePercentage(int Fill);
  void WaitForPut(void);
  void WaitForGet(void);
  void EnablePut(void);
  void EnableGet(void);
  virtual void Clear(void) = 0;
  virtual int Available(void) = 0;
  virtual int Free(void) { return Size() - Available() - 1; }
  int Size(void) { return size; }
public:
  cRingBuffer(int Size, bool Statistics = false);
  virtual ~cRingBuffer();
  void SetTimeouts(int PutTimeout, int GetTimeout);
  void ReportOverflow(int Bytes);
  };

class cRingBufferLinear : public cRingBuffer {
//#define DEBUGRINGBUFFERS
#ifdef DEBUGRINGBUFFERS
private:
  int lastHead, lastTail;
  int lastPut, lastGet;
  static cRingBufferLinear *RBLS[];
  static void AddDebugRBL(cRingBufferLinear *RBL);
  static void DelDebugRBL(cRingBufferLinear *RBL);
public:
  static void PrintDebugRBL(void);
#endif
private:
  int margin, head, tail;
  int gotten;
  uchar *buffer;
  char *description;
public:
  cRingBufferLinear(int Size, int Margin = 0, bool Statistics = false, const 
char *Description = NULL);
    ///< Creates a linear ring buffer.
    ///< The buffer will be able to hold at most Size-Margin-1 bytes of data, 
and will
    ///< be guaranteed to return at least Margin bytes in one consecutive block.
    ///< The optional Description is used for debugging only.
  virtual ~cRingBufferLinear();
  virtual int Available(void);
  virtual int Free(void) { return Size() - Available() - 1 - margin; }
  virtual void Clear(void);
    ///< Immediately clears the ring buffer.
/*   int Read(int FileHandle, int Max = 0); */
    ///< Reads at most Max bytes from FileHandle and stores them in the
    ///< ring buffer. If Max is 0, reads as many bytes as possible.
    ///< Only one actual read() call is done.
    ///< \return Returns the number of bytes actually read and stored, or
    ///< an error value from the actual read() call.
  int Put(const uchar *Data, int Count);
    ///< Puts at most Count bytes of Data into the ring buffer.
    ///< \return Returns the number of bytes actually stored.
  uchar *Get(int &Count);
    ///< Gets data from the ring buffer.
    ///< The data will remain in the buffer until a call to Del() deletes it.
    ///< \return Returns a pointer to the data, and stores the number of bytes
    ///< actually available in Count. If the returned pointer is NULL, Count 
has no meaning.
  void Del(int Count);
    ///< Deletes at most Count bytes from the ring buffer.
    ///< Count must be less or equal to the number that was returned by a 
previous
    ///< call to Get().
  };

enum eFrameType { ftUnknown, ftVideo, ftAudio, ftDolby };

class cFrame {
  friend class cRingBufferFrame;
private:
  cFrame *next;
  uchar *data;
  int count;
  eFrameType type;
  int index;
public:
  cFrame(const uchar *Data, int Count, eFrameType = ftUnknown, int Index = -1);
    ///< Creates a new cFrame object.
    ///< If Count is negative, the cFrame object will take ownership of the 
given
    ///< Data. Otherwise it will allocate Count bytes of memory and copy Data.
  ~cFrame();
  uchar *Data(void) const { return data; }
  int Count(void) const { return count; }
  eFrameType Type(void) const { return type; }
  int Index(void) const { return index; }
  };

class cRingBufferFrame : public cRingBuffer {
private:
  cFrame *head;
  int currentFill;
  void Delete(cFrame *Frame);
  void Lock(void) {}
  void Unlock(void) {}
public:
  cRingBufferFrame(int Size, bool Statistics = false);
  virtual ~cRingBufferFrame();
  virtual int Available(void);
  virtual void Clear(void);
    // Immediately clears the ring buffer.
  bool Put(cFrame *Frame);
    // Puts the Frame into the ring buffer.
    // Returns true if this was possible.
  cFrame *Get(void);
    // Gets the next frame from the ring buffer.
    // The actual data still remains in the buffer until Drop() is called.
  void Drop(cFrame *Frame);
    // Drops the Frame that has just been fetched with Get().
  };

#endif // __RINGBUFFER_H

Index: Makefile
===================================================================
RCS file: /cvsroot/freevo/fred/Makefile,v
retrieving revision 1.1.1.1
retrieving revision 1.2
diff -C2 -d -r1.1.1.1 -r1.2
*** Makefile    2 Mar 2005 17:57:46 -0000       1.1.1.1
--- Makefile    23 Apr 2005 16:10:11 -0000      1.2
***************
*** 5,9 ****
  
  OBJECTFILES= op_generic.o op_filewriter.o dvbdevice.o tuner.o filter.o 
options.o \
!            config.o rpcserver.o main.o cmdline.o scheduler.o remux.o
  SOURCEFILES=$(OBJECTFILES:.o=.cc)
  
--- 5,9 ----
  
  OBJECTFILES= op_generic.o op_filewriter.o dvbdevice.o tuner.o filter.o 
options.o \
!            config.o rpcserver.o main.o cmdline.o scheduler.o remux.o 
ringbuffer.o
  SOURCEFILES=$(OBJECTFILES:.o=.cc)
  

Index: op_generic.h
===================================================================
RCS file: /cvsroot/freevo/fred/op_generic.h,v
retrieving revision 1.1.1.1
retrieving revision 1.2
diff -C2 -d -r1.1.1.1 -r1.2
*** op_generic.h        2 Mar 2005 17:57:48 -0000       1.1.1.1
--- op_generic.h        23 Apr 2005 16:10:12 -0000      1.2
***************
*** 26,29 ****
--- 26,30 ----
  
  #include <string>
+ #include <vector>
  
  class OutputPlugin {
***************
*** 32,43 ****
    int chunksize;
    int pid_v;
!   int pid_a1;
!   int pid_a2;
!   int pid_d1;
!   int pid_d2;
    
    public:
    OutputPlugin( const std::string &uri, int chunksize );
!   virtual void set_pids( int Pid_V, int Pid_A1, int Pid_A2, int Pid_D1, int 
Pid_D2 );
    virtual void process_data( const std::string &data ) = 0;
    virtual void flush() = 0;  
--- 33,43 ----
    int chunksize;
    int pid_v;
!   std::vector<int> pids_a;
!   std::vector<int> pids_d;
!   std::vector<int> pids_s;
    
    public:
    OutputPlugin( const std::string &uri, int chunksize );
!   virtual void set_pids( int Pid_V, std::vector<int> Pids_A, std::vector<int> 
Pids_D, std::vector<int> Pids_S );
    virtual void process_data( const std::string &data ) = 0;
    virtual void flush() = 0;  

Index: dvbdevice.cc
===================================================================
RCS file: /cvsroot/freevo/fred/dvbdevice.cc,v
retrieving revision 1.1.1.1
retrieving revision 1.2
diff -C2 -d -r1.1.1.1 -r1.2
*** dvbdevice.cc        2 Mar 2005 17:57:47 -0000       1.1.1.1
--- dvbdevice.cc        23 Apr 2005 16:10:11 -0000      1.2
***************
*** 164,170 ****
        id2pid[ id ].push_back( bouquet_list[ib].channels[ic].pid_audio );
  
        plugin->set_pids( bouquet_list[ib].channels[ic].pid_video,
!                         bouquet_list[ib].channels[ic].pid_audio,
!                         0, 0, 0 );
  
        notfound = false;
--- 164,176 ----
        id2pid[ id ].push_back( bouquet_list[ib].channels[ic].pid_audio );
  
+       // add pids to output plugin
+       vector<int> pids_a;
+       vector<int> pids_empty;
+       pids_a.push_back( bouquet_list[ib].channels[ic].pid_audio );
+ 
        plugin->set_pids( bouquet_list[ib].channels[ic].pid_video,
!                         pids_a,
!                         pids_empty,
!                         pids_empty );
  
        notfound = false;

--- NEW FILE: ringbuffer.cc ---
/*
 * File: ringbuffer.cc
 *
 * $Id: ringbuffer.cc,v 1.1 2005/04/23 16:10:12 schwardt Exp $
 *
 * Copyright (C) 2005 S�nke Schwardt <[EMAIL PROTECTED]>
 *
 * This program 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, or (at your option)
 * any later version.
 *
 * This program 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 this program; if not, write to the Free Software
 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
 *
 * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
 *
 * The parts of this code that implement TS2PES and Remux have been
 * taken from VDR project. (http://www.cadsoft.de/people/kls/vdr/)
 *
 */

#include <stdlib.h>
#include <unistd.h>
#include <string.h>
// #include "tools.h"
#include "misc.h"
#include "ringbuffer.h"

// --- cRingBuffer -----------------------------------------------------------

#define OVERFLOWREPORTDELTA 5 // seconds between reports
#define PERCENTAGEDELTA     10
#define PERCENTAGETHRESHOLD 70

cRingBuffer::cRingBuffer(int Size, bool Statistics)
{
  size = Size;
  statistics = Statistics;
  maxFill = 0;
  lastPercent = 0;
  putTimeout = getTimeout = 0;
  lastOverflowReport = 0;
  overflowCount = overflowBytes = 0;
}

cRingBuffer::~cRingBuffer()
{
  if (statistics)
     printD( LOG_DEBUG_RINGBUFFER, "buffer stats: %d (%d%%) used", maxFill, 
maxFill * 100 / (size - 1));
}

void cRingBuffer::UpdatePercentage(int Fill)
{
  if (Fill > maxFill)
     maxFill = Fill;
  int percent = Fill * 100 / (Size() - 1) / PERCENTAGEDELTA * PERCENTAGEDELTA;
  if (percent != lastPercent) {
     if (percent >= PERCENTAGETHRESHOLD && percent > lastPercent || percent < 
PERCENTAGETHRESHOLD && lastPercent >= PERCENTAGETHRESHOLD) {
        printD( LOG_DEBUG_RINGBUFFER, "buffer usage: %d%%", percent);
        lastPercent = percent;
        }
     }
}

void cRingBuffer::WaitForPut(void)
{
}

void cRingBuffer::WaitForGet(void)
{
}

void cRingBuffer::EnablePut(void)
{
}

void cRingBuffer::EnableGet(void)
{
}

void cRingBuffer::SetTimeouts(int PutTimeout, int GetTimeout)
{
  putTimeout = PutTimeout;
  getTimeout = GetTimeout;
}

void cRingBuffer::ReportOverflow(int Bytes)
{
  overflowCount++;
  overflowBytes += Bytes;
  if (time(NULL) - lastOverflowReport > OVERFLOWREPORTDELTA) {
     printD( LOG_ERROR, "ERROR: %d ring buffer overflow%s (%d bytes dropped)", 
overflowCount, overflowCount > 1 ? "s" : "", overflowBytes);
     overflowCount = overflowBytes = 0;
     lastOverflowReport = time(NULL);
     }
}

// --- cRingBufferLinear -----------------------------------------------------

#ifdef DEBUGRINGBUFFERS
#define MAXRBLS 30
#define DEBUGRBLWIDTH 45

cRingBufferLinear *cRingBufferLinear::RBLS[MAXRBLS] = { NULL };

void cRingBufferLinear::AddDebugRBL(cRingBufferLinear *RBL)
{
  for (int i = 0; i < MAXRBLS; i++) {
      if (!RBLS[i]) {
         RBLS[i] = RBL;
         break;
         }
      }
}

void cRingBufferLinear::DelDebugRBL(cRingBufferLinear *RBL)
{
  for (int i = 0; i < MAXRBLS; i++) {
      if (RBLS[i] == RBL) {
         RBLS[i] = NULL;
         break;
         }
      }
}

void cRingBufferLinear::PrintDebugRBL(void)
{
  bool printed = false;
  for (int i = 0; i < MAXRBLS; i++) {
      cRingBufferLinear *p = RBLS[i];
      if (p) {
         printed = true;
         int lh = p->lastHead;
         int lt = p->lastTail;
         int h = lh * DEBUGRBLWIDTH / p->Size();
         int t = lt * DEBUGRBLWIDTH / p->Size();
         char buf[DEBUGRBLWIDTH + 10];
         memset(buf, '-', DEBUGRBLWIDTH);
         if (lt <= lh)
            memset(buf + t, '*', max(h - t, 1));
         else {
            memset(buf, '*', h);
            memset(buf + t, '*', DEBUGRBLWIDTH - t);
            }
         buf[t] = '<';
         buf[h] = '>';
         buf[DEBUGRBLWIDTH] = 0;
         printf("%2d %s %8d %8d %s\n", i, buf, p->lastPut, p->lastGet, 
p->description);
         }
      }
  if (printed)
     printf("\n");
  }
#endif

cRingBufferLinear::cRingBufferLinear(int Size, int Margin, bool Statistics, 
const char *Description)
:cRingBuffer(Size, Statistics)
{
  description = Description ? strdup(Description) : NULL;
  tail = head = margin = Margin;
  buffer = NULL;
  if (Size > 1) { // 'Size - 1' must not be 0!
     if (Margin <= Size / 2) {
        buffer = (unsigned char*)malloc( sizeof(unsigned char) * Size );
        if (!buffer)
           printD( LOG_ERROR, "ERROR: can't allocate ring buffer (size=%d)", 
Size);
        Clear();
        }
     else
        printD( LOG_ERROR, "ERROR: illegal margin for ring buffer (%d > %d)", 
Margin, Size / 2);
     }
  else
     printD( LOG_ERROR, "ERROR: illegal size for ring buffer (%d)", Size);
#ifdef DEBUGRINGBUFFERS
  lastHead = head;
  lastTail = tail;
  lastPut = lastGet = -1;
  AddDebugRBL(this);
#endif
}

cRingBufferLinear::~cRingBufferLinear()
{
#ifdef DEBUGRINGBUFFERS
  DelDebugRBL(this);
#endif
  free(buffer);
  free(description);
}

int cRingBufferLinear::Available(void)
{
  int diff = head - tail;
  return (diff >= 0) ? diff : Size() + diff - margin;
}

void cRingBufferLinear::Clear(void)
{
  tail = head;
#ifdef DEBUGRINGBUFFERS
  lastHead = head;
  lastTail = tail;
  lastPut = lastGet = -1;
#endif
  maxFill = 0;
  EnablePut();
}

// int cRingBufferLinear::Read(int FileHandle, int Max)
// {
//   int Tail = tail;
//   int diff = Tail - head;
//   int free = (diff > 0) ? diff - 1 : Size() - head;
//   if (Tail <= margin)
//      free--;
//   int Count = 0;
//   if (free > 0) {
//      if (0 < Max && Max < free)
//         free = Max;
//      Count = safe_read(FileHandle, buffer + head, free);
//      if (Count > 0) {
//         int Head = head + Count;
//         if (Head >= Size())
//            Head = margin;
//         head = Head;
//         if (statistics) {
//            int fill = head - Tail;
//            if (fill < 0)
//               fill = Size() + fill;
//            else if (fill >= Size())
//               fill = Size() - 1;
//            UpdatePercentage(fill);
//            }
//         }
//      }
// #ifdef DEBUGRINGBUFFERS
//   lastHead = head;
//   lastPut = Count;
// #endif
//   EnableGet();
//   if (free == 0)
//      WaitForPut();
//   return Count;
// }

int cRingBufferLinear::Put(const uchar *Data, int Count)
{
  if (Count > 0) {
     int Tail = tail;
     int rest = Size() - head;
     int diff = Tail - head;
     int free = ((Tail < margin) ? rest : (diff > 0) ? diff : Size() + diff - 
margin) - 1;
     if (statistics) {
        int fill = Size() - free - 1 + Count;
        if (fill >= Size())
           fill = Size() - 1;
        UpdatePercentage(fill);
        }
     if (free > 0) {
        if (free < Count)
           Count = free;
        if (Count >= rest) {
           memcpy(buffer + head, Data, rest);
           if (Count - rest)
              memcpy(buffer + margin, Data + rest, Count - rest);
           head = margin + Count - rest;
           }
        else {
           memcpy(buffer + head, Data, Count);
           head += Count;
           }
        }
     else
        Count = 0;
#ifdef DEBUGRINGBUFFERS
     lastHead = head;
     lastPut = Count;
#endif
     EnableGet();
     if (Count == 0)
        WaitForPut();
     }
  return Count;
}

uchar *cRingBufferLinear::Get(int &Count)
{
  uchar *p = NULL;
  int Head = head;
  int rest = Size() - tail;
  if (rest < margin && Head < tail) {
     int t = margin - rest;
     memcpy(buffer + t, buffer + tail, rest);
     tail = t;
     rest = Head - tail;
     }
  int diff = Head - tail;
  int cont = (diff >= 0) ? diff : Size() + diff - margin;
  if (cont > rest)
     cont = rest;
  if (cont >= margin) {
     p = buffer + tail;
     Count = gotten = cont;
     }
  if (!p)
     WaitForGet();
  return p;
}

void cRingBufferLinear::Del(int Count)
{
  if (Count > gotten) {
     printD( LOG_ERROR, "ERROR: invalid Count in cRingBufferLinear::Del: %d 
(limited to %d)", Count, gotten);
     Count = gotten;
     }
  if (Count > 0) {
     int Tail = tail;
     Tail += Count;
     gotten -= Count;
     if (Tail >= Size())
        Tail = margin;
     tail = Tail;
     EnablePut();
     }
#ifdef DEBUGRINGBUFFERS
  lastTail = tail;
  lastGet = Count;
#endif
}

// --- cFrame ----------------------------------------------------------------

cFrame::cFrame(const uchar *Data, int Count, eFrameType Type, int Index)
{
  count = abs(Count);
  type = Type;
  index = Index;
  if (Count < 0)
     data = (uchar *)Data;
  else {
     data = (unsigned char*)malloc( sizeof(unsigned char) * count );
     if (data)
        memcpy(data, Data, count);
     else
        printD( LOG_ERROR, "ERROR: can't allocate frame buffer (count=%d)", 
count);
     }
  next = NULL;
}

cFrame::~cFrame()
{
  free(data);
}

// --- cRingBufferFrame ------------------------------------------------------

cRingBufferFrame::cRingBufferFrame(int Size, bool Statistics)
:cRingBuffer(Size, Statistics)
{
  head = NULL;
  currentFill = 0;
}

cRingBufferFrame::~cRingBufferFrame()
{
  Clear();
}

void cRingBufferFrame::Clear(void)
{
  Lock();
  cFrame *p;
  while ((p = Get()) != NULL)
        Drop(p);
  Unlock();
  EnablePut();
  EnableGet();
}

bool cRingBufferFrame::Put(cFrame *Frame)
{
  if (Frame->Count() <= Free()) {
     Lock();
     if (head) {
        Frame->next = head->next;
        head->next = Frame;
        head = Frame;
        }
     else {
        head = Frame->next = Frame;
        }
     currentFill += Frame->Count();
     Unlock();
     EnableGet();
     return true;
     }
  return false;
}

cFrame *cRingBufferFrame::Get(void)
{
  Lock();
  cFrame *p = head ? head->next : NULL;
  Unlock();
  return p;
}

void cRingBufferFrame::Delete(cFrame *Frame)
{
  currentFill -= Frame->Count();
  delete Frame;
}

void cRingBufferFrame::Drop(cFrame *Frame)
{
  Lock();
  if (head) {
     if (Frame == head->next) {
        if (head->next != head) {
           head->next = Frame->next;
           Delete(Frame);
           }
        else {
           Delete(head);
           head = NULL;
           }
        }
     else
        printD( LOG_ERROR, "ERROR: attempt to drop wrong frame from ring 
buffer!");
     }
  Unlock();
  EnablePut();
}

int cRingBufferFrame::Available(void)
{
  Lock();
  int av = currentFill;
  Unlock();
  return av;
}

Index: op_generic.cc
===================================================================
RCS file: /cvsroot/freevo/fred/op_generic.cc,v
retrieving revision 1.1.1.1
retrieving revision 1.2
diff -C2 -d -r1.1.1.1 -r1.2
*** op_generic.cc       2 Mar 2005 17:57:48 -0000       1.1.1.1
--- op_generic.cc       23 Apr 2005 16:10:12 -0000      1.2
***************
*** 26,41 ****
  
  OutputPlugin::OutputPlugin( const std::string &uri, int chunksize ) :
!   uri(uri), chunksize(chunksize), pid_v(0), pid_a1(0), pid_a2(0), pid_d1(0), 
pid_d2(0)
  {
    ;
  }
  
! void OutputPlugin::set_pids( int Pid_V, int Pid_A1, int Pid_A2, int Pid_D1, 
int Pid_D2 ) {
    pid_v  = Pid_V;
!   pid_a1 = Pid_A1;
!   pid_a2 = Pid_A2;
!   pid_d1 = Pid_D1;
!   pid_d2 = Pid_D2;
!   printD( LOG_DEBUG_OUTPUTPLUGIN, "setting pids: v=%d  a1=%d  a2=%d  d1=%d  
d2=%d\n",
!         pid_v, pid_a1, pid_a2, pid_d1, pid_d2 );
  }
--- 26,42 ----
  
  OutputPlugin::OutputPlugin( const std::string &uri, int chunksize ) :
!   uri(uri), chunksize(chunksize), pid_v(0)
  {
    ;
  }
  
! void OutputPlugin::set_pids( int Pid_V, std::vector<int> Pids_A, 
!                            std::vector<int> Pids_D, std::vector<int> Pids_S ) 
{
    pid_v  = Pid_V;
!   pids_a = Pids_A;
!   pids_d = Pids_D;
!   pids_s = Pids_S;
!   // TODO FIXME  fix debug output
!   //   printD( LOG_DEBUG_OUTPUTPLUGIN, "setting pids: v=%d  a1=%d  a2=%d  
d1=%d  d2=%d\n",
!   //    pid_v, pid_a1, pid_a2, pid_d1, pid_d2 );
  }

Index: op_filewriter.cc
===================================================================
RCS file: /cvsroot/freevo/fred/op_filewriter.cc,v
retrieving revision 1.1.1.1
retrieving revision 1.2
diff -C2 -d -r1.1.1.1 -r1.2
*** op_filewriter.cc    2 Mar 2005 17:57:48 -0000       1.1.1.1
--- op_filewriter.cc    23 Apr 2005 16:10:11 -0000      1.2
***************
*** 52,64 ****
  
  
! void OutputPluginFilewriter::set_pids( int Pid_V, int Pid_A1, int Pid_A2, int 
Pid_D1, int Pid_D2 ) {
    // call super class
!   OutputPlugin::set_pids( Pid_V, Pid_A1, Pid_A2, Pid_D1, Pid_D2 );
!   // TODO FIXME check if pids are the same as previous debug line in 
OutputPlugin::set_pids
!   printD( LOG_DEBUG_OUTPUTPLUGIN, "pids: v=%d  a1=%d  a2=%d  d1=%d  d2=%d\n",
!         pid_v, pid_a1, pid_a2, pid_d1, pid_d2 );
  
    if (file_type == FT_MPEG) {
!     remux = new Remux( pid_v, pid_a1, pid_a2, pid_d1, pid_d2 );
      if (!remux) {
        printD( LOG_ERROR, "ERROR: couldn't allocate memory for remuxer\n");
--- 52,98 ----
  
  
! void OutputPluginFilewriter::set_pids( int Pid_V, std::vector<int> Pids_A,
!                                      std::vector<int> Pids_D, 
std::vector<int> Pids_S ) {
!   // FIXME TODO
!   //   cRemux(VPid, APids, Setup.UseDolbyDigital ? DPids : NULL, SPids, true);
! 
    // call super class
!   OutputPlugin::set_pids( Pid_V, Pids_A, Pids_D, Pids_S );
  
    if (file_type == FT_MPEG) {
!     int* p_a = NULL;
!     int* p_d = NULL;
!     int* p_s = NULL;
! 
!     if (pids_a.size()) {
!       p_a = new int[ pids_a.size() + 1 ];
!       for(unsigned int i = 0; i < pids_a.size(); ++i) {
!       p_a[i] = pids_a[i];
!       }
!       p_a[pids_a.size()] = 0;
!     }
! 
!     if (pids_d.size()) {
!       p_d = new int[ pids_d.size() + 1 ];
!       for(unsigned int i = 0; i < pids_d.size(); ++i) {
!       p_d[i] = pids_d[i];
!       }
!       p_d[pids_d.size()] = 0;
!     }
! 
!     if (pids_s.size()) {
!       p_s = new int[ pids_s.size() + 1 ];
!       for(unsigned int i = 0; i < pids_s.size(); ++i) {
!       p_s[i] = pids_s[i];
!       }
!       p_s[pids_s.size()] = 0;
!     }
! 
!     remux = new cRemux( pid_v, p_a, p_d, p_s, false );
! 
!     if (p_a) {
!       delete[] p_a;
!     }
! 
      if (!remux) {
        printD( LOG_ERROR, "ERROR: couldn't allocate memory for remuxer\n");
***************
*** 81,143 ****
  
  void OutputPluginFilewriter::flush() {
!   static Remux::PictureType picture_type = Remux::NO_PICTURE;
! 
!   if (file_type == FT_MPEG) {
!     int count;
!     int bufoutlen;
!     const char *bufout;
!     if (buffer_in.size()) {
!       do {
!       // TODO FIXME enlarge "count"
!       count  = buffer_in.size() > 188 ? 188 : buffer_in.size();
!       bufoutlen = 0;
! 
!       // IN: buffer_in: input buffer
!       //     count: number of bytes in buffer_in
!       //     bufoutlen: unused
!       //     pictureType: unused
!       bufout = (char*)remux->Process( (unsigned char*)buffer_in.c_str(), 
count, bufoutlen, picture_type);
!       // OUT: buffer_in: nothing changed
!       //      count: number of processed bytes of buffer_in (if count>0 
cutoff count bytes from buffer_in)
!       //      bufout: pointer to output buffer with converted data
!       //      bufoutlen: if bufout != NULL then bufoutlen specifies size of 
bufout
!       //      pictureType: type of current frame
  
!       //      printD( LOG_DEBUG_OUTPUTPLUGIN, "IN: count=%08d  OUT: 
count=%08d  bufoutlen=%08d  bufout=%p  pt=%d\n",
!       //              buffer_in.size(), count, bufoutlen, bufout, 
(int)picture_type );
  
!       if (count) {
!         buffer_in.erase(0, count);
!       }
  
!       // if bufout == NULL ==> not enough data in buffer_in or trash at top 
of buffer_in
!       if (bufout) {
!         // enough data present
!         if (picture_type != Remux::NO_PICTURE) {
!           // processed buffer contained a I/P/B-Frame
!           // printD( LOG_DEBUG_OUTPUTPLUGIN, "Frametype %d at filepos %d\n", 
picture_type, file_size_total);
!         }
!         // append data to output buffer
!         buffer_out.append( string(bufout, bufoutlen) );
!       }
  
!       } while ( (bufout) || (count) );
      }
  
!     // TODO FIXME das hier wegr�umen
!     // Count == bufferIn.length()
!     // uchar *bufferOUT = remux->Process(bufferIN, Count, bufferOUTlength, 
&pictureType);
!     // Count == Anzahl der bearbeiteten Bytes von bufferIN ==> diese Anzahl 
vorne abschneiden
! 
!     // wenn (bufferOUT != NULL)
!     // dann
!     //      1) wenn (pictureType != NO_PICTURE) ==> INDEX SCHREIBEN ==> 
pictureType + aktuelle FileLength
!     //      2) Daten ins File schreiben
!     //      3) Dateigr��e erh�hen
  
!     // wenn (bufferOUT == NULL) && (Count==0) ==> NOT ENOUGH DATA
!     // wenn (bufferOUT == NULL) && (Count > 0) ==> skip that amount of data 
from bufferIN
    }
  
    // flush data to disk if file is open
    if (buffer_out.size() > 0) {
--- 115,164 ----
  
  void OutputPluginFilewriter::flush() {
!   unsigned char picture_type = NO_PICTURE;
  
!   // if output format IS NOT MPEG ==> TS
!   if (file_type != FT_MPEG) {
  
!     // copy in buffer to outbuffer
!     buffer_out = buffer_in;
!     buffer_in.clear();
  
!   } else {
!     // if output format is MPEG
  
!     // add new data to remuxer
!     if (buffer_in.size()) {
!       int count = remux->Put( (const unsigned char*)buffer_in.c_str(), 
buffer_in.size() );
!       if (count) {
!       buffer_in.erase(0, count);
!       }
      }
  
!     while(1) {
!       int count;
!       // get
!       unsigned char *p = remux->Get(count, &picture_type);
  
!       // if bufout == NULL ==> not enough data in buffer_in or trash at top 
of buffer_in
!       if (p) {
!       // enough data present
!       if (picture_type != NO_PICTURE) {
!         // TODO FIXME
!         // processed buffer contained a I/P/B-Frame
!         //      if (index && pictureType != NO_PICTURE)
!         //        index->Write(pictureType, fileName->Number(), fileSize);
!         //    fileSize += Count;
!         // printD( LOG_DEBUG_OUTPUTPLUGIN, "Frametype %d at filepos %d\n", 
picture_type, file_size_total);
!       }
!       // append data to output buffer
!       buffer_out.append( (char*)p, count );
!       remux->Del(count);
!       } else {
!       break;
!       }
!     }
    }
  
+ 
    // flush data to disk if file is open
    if (buffer_out.size() > 0) {

Index: remux.h
===================================================================
RCS file: /cvsroot/freevo/fred/remux.h,v
retrieving revision 1.1.1.1
retrieving revision 1.2
diff -C2 -d -r1.1.1.1 -r1.2
*** remux.h     2 Mar 2005 17:57:49 -0000       1.1.1.1
--- remux.h     23 Apr 2005 16:10:12 -0000      1.2
***************
*** 1,6 ****
  /*
!  * File: remux.cc
!  *
!  * Author: S�nke Schwardt <[EMAIL PROTECTED]>
   *
   * $Id$
--- 1,4 ----
  /*
!  * File: remux.h
   *
   * $Id$
***************
*** 25,29 ****
   *
   * The parts of this code that implement TS2PES and Remux have been
!  * taken from VDR project and were rewritten to suit FRED's needs.
   *
   */
--- 23,27 ----
   *
   * The parts of this code that implement TS2PES and Remux have been
!  * taken from VDR project. (http://www.cadsoft.de/people/kls/vdr/)
   *
   */
***************
*** 32,75 ****
  #define __REMUX_H
  
! #include <time.h> //XXX TODO FIXME: DVB/linux/dvb/dmx.h should include 
<time.h> itself!!!
! // #include <linux/dvb/dmx.h>  // TODO FIXME dmx.h ist schon im aktuellen 
Verzeichnis
! // #include "tools.h"  // TODO FIXME brauche ich das �berhaupt?
  
  // Picture types:
! /* #define NO_PICTURE 0 */
! /* #define I_FRAME    1 */
! /* #define P_FRAME    2 */
! /* #define B_FRAME    3 */
! 
! // The minimum amount of video data necessary to identify frames:
! #define MINVIDEODATA (16*1024) // just a safe guess (max. size of any frame 
block, plus some safety)
! 
! #define RESULTBUFFERSIZE (MINVIDEODATA * 4)
  
! class TS2PES;
  
! class Remux {
! public:
!   enum PictureType { NO_PICTURE, I_FRAME, P_FRAME, B_FRAME };
  
!   Remux(int VPid, int APid1, int APid2, int DPid1, int DPid2, bool 
ExitOnFailure = false);
!   ~Remux();
!   unsigned char *Process(const unsigned char *Data, int &Count, int &Result, 
PictureType &pictureType);
!   static void SetBrokenLink(unsigned char *Data, int Length);
  
  private:
    bool exitOnFailure;
    bool synced;
    int skipped;
!   int vPid, aPid1, aPid2, dPid1, dPid2;
!   TS2PES *vTS2PES, *aTS2PES1, *aTS2PES2, *dTS2PES1, *dTS2PES2;
!   unsigned char resultBuffer[RESULTBUFFERSIZE];
!   int resultCount;
!   int resultDelivered;
!   int GetPid(const unsigned char *Data);
!   int GetPacketLength(const unsigned char *Data, int Count, int Offset);
!   int ScanVideoPacket(const unsigned char *Data, int Count, int Offset, 
PictureType &PictureType);
! };
! 
  
  #endif // __REMUX_H
--- 30,93 ----
  #define __REMUX_H
  
! #include <time.h> //XXX FIXME: DVB/linux/dvb/dmx.h should include <time.h> 
itself!!!
! // #include <linux/dvb/dmx.h>
! #include "ringbuffer.h"
! // #include "tools.h"
  
  // Picture types:
! #define NO_PICTURE 0
! #define I_FRAME    1
! #define P_FRAME    2
! #define B_FRAME    3
  
! #define MAXTRACKS 64
! #define MAXAPIDS 32
! #define MAXDPIDS 16
! #define MAXSPIDS 8
  
! #define MALLOC(type, size)  (type *)malloc(sizeof(type) * (size))
  
! class cTS2PES;
  
+ class cRemux {
  private:
    bool exitOnFailure;
+   bool isRadio;
+   int numUPTerrors;
    bool synced;
    int skipped;
!   cTS2PES *ts2pes[MAXTRACKS];
!   int numTracks;
!   cRingBufferLinear *resultBuffer;
!   int resultSkipped;
!   int GetPid(const uchar *Data);
!   int GetPacketLength(const uchar *Data, int Count, int Offset);
!   int ScanVideoPacket(const uchar *Data, int Count, int Offset, uchar 
&PictureType);
! public:
!   cRemux(int VPid, const int *APids, const int *DPids, const int *SPids, bool 
ExitOnFailure = false);
!        ///< Creates a new remuxer for the given PIDs. VPid is the video PID, 
while
!        ///< APids, DPids and SPids are pointers to zero terminated lists of 
audio,
!        ///< dolby and subtitle PIDs (the pointers may be NULL if there is no 
such
!        ///< PID). If ExitOnFailure is true, the remuxer will initiate an 
"emergency
!        ///< exit" in case of problems with the data stream.
!   ~cRemux();
!   int Put(const uchar *Data, int Count);
!        ///< Puts at most Count bytes of Data into the remuxer.
!        ///< \return Returns the number of bytes actually consumed from Data.
!   uchar *Get(int &Count, uchar *PictureType = NULL);
!        ///< Gets all currently available data from the remuxer.
!        ///< \return Count contains the number of bytes the result points to, 
and
!        ///< PictureType (if not NULL) will contain one of NO_PICTURE, 
I_FRAME, P_FRAME
!        ///< or B_FRAME.
!   void Del(int Count);
!        ///< Deletes Count bytes from the remuxer. Count must be the number 
returned
!        ///< from a previous call to Get(). Several calls to Del() with 
fractions of
!        ///< a previously returned Count may be made, but the total sum of all 
Count
!        ///< values must be exactly what the previous Get() has returned.
!   void Clear(void);
!        ///< Clears the remuxer of all data it might still contain, keeping 
the PID
!        ///< settings as they are.
!   static void SetBrokenLink(uchar *Data, int Length);
!   };
  
  #endif // __REMUX_H

Index: op_filewriter.h
===================================================================
RCS file: /cvsroot/freevo/fred/op_filewriter.h,v
retrieving revision 1.1.1.1
retrieving revision 1.2
diff -C2 -d -r1.1.1.1 -r1.2
*** op_filewriter.h     2 Mar 2005 17:57:48 -0000       1.1.1.1
--- op_filewriter.h     23 Apr 2005 16:10:11 -0000      1.2
***************
*** 25,28 ****
--- 25,29 ----
  #define __OP_FILEWRITER_H_
  
+ #include <vector>
  #include <string>
  #include "op_generic.h"
***************
*** 34,38 ****
  
    OutputPluginFilewriter( const std::string &uri, int chunksize, FileType 
ftype  );
!   virtual void set_pids( int Pid_V, int Pid_A1, int Pid_A2, int Pid_D1, int 
Pid_D2 );
    void process_data( const std::string &data );
    void flush();  
--- 35,40 ----
  
    OutputPluginFilewriter( const std::string &uri, int chunksize, FileType 
ftype  );
!   virtual void set_pids( int Pid_V, std::vector<int> Pids_A, 
!                        std::vector<int> Pids_D, std::vector<int> Pids_S );
    void process_data( const std::string &data );
    void flush();  
***************
*** 49,53 ****
    FileType file_type;      // type of output file 
  
!   Remux *remux;
  
    std::string buffer_in;   // buffer for caching data
--- 51,55 ----
    FileType file_type;      // type of output file 
  
!   cRemux *remux;
  
    std::string buffer_in;   // buffer for caching data



-------------------------------------------------------
SF email is sponsored by - The IT Product Guide
Read honest & candid reviews on hundreds of IT Products from real users.
Discover which products truly live up to the hype. Start reading now.
http://ads.osdn.com/?ad_id=6595&alloc_id=14396&op=click
_______________________________________________
Freevo-cvslog mailing list
[email protected]
https://lists.sourceforge.net/lists/listinfo/freevo-cvslog

Reply via email to