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