summaryrefslogtreecommitdiff
path: root/server/streamer.h
blob: 6561bc2872418c2b8c20d41cc0c2d29388a37e0c (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
/*
 *  $Id: streamer.h,v 1.11 2009/06/19 06:32:45 schmirl Exp $
 */
 
#ifndef VDR_STREAMDEV_STREAMER_H
#define VDR_STREAMDEV_STREAMER_H

#include <vdr/thread.h>
#include <vdr/ringbuffer.h>
#include <vdr/tools.h>

class cTBSocket;
class cStreamdevStreamer;

#ifndef TS_SIZE
#define TS_SIZE 188
#endif

#define STREAMERBUFSIZE (20000 * TS_SIZE)
#define WRITERBUFSIZE (5000 * TS_SIZE)

// --- cStreamdevBuffer -------------------------------------------------------

class cStreamdevBuffer: public cRingBufferLinear {
public:
	// make public
	void WaitForPut(void) { cRingBuffer::WaitForPut(); }
	// Always write complete TS packets
	// (assumes Count is a multiple of TS_SIZE)
	int PutTS(const uchar *Data, int Count);
	cStreamdevBuffer(int Size, int Margin = 0, bool Statistics = false, const char *Description = NULL);
};

inline int cStreamdevBuffer::PutTS(const uchar *Data, int Count)
{
	int free = Free();
	if (free < Count)
		Count = free;

	Count -= Count % TS_SIZE;
	if (Count)
		Count = Put(Data, Count);
	else
		WaitForPut();
	return Count;
}

// --- cStreamdevWriter -------------------------------------------------------

class cStreamdevWriter: public cThread {
private:
	cStreamdevStreamer *m_Streamer;
	cTBSocket          *m_Socket;

protected:
	virtual void Action(void);

public:
	cStreamdevWriter(cTBSocket *Socket, cStreamdevStreamer *Streamer);
	virtual ~cStreamdevWriter();
};

// --- cStreamdevStreamer -----------------------------------------------------

class cStreamdevStreamer: public cThread {
private:
	cStreamdevWriter  *m_Writer;
	cStreamdevBuffer  *m_RingBuffer;
	cStreamdevBuffer  *m_SendBuffer;

protected:
	virtual void Action(void);

	bool IsRunning(void) const { return m_Writer; }

public:
	cStreamdevStreamer(const char *Name);
	virtual ~cStreamdevStreamer();

	virtual void Start(cTBSocket *Socket);
	virtual void Stop(void);
	bool Abort(void);

	void Activate(bool On);
	int Receive(uchar *Data, int Length) { return m_RingBuffer->PutTS(Data, Length); }
	void ReportOverflow(int Bytes) { m_RingBuffer->ReportOverflow(Bytes); }
	
	virtual int Put(const uchar *Data, int Count) { return m_SendBuffer->PutTS(Data, Count); }
	virtual uchar *Get(int &Count) { return m_SendBuffer->Get(Count); }
	virtual void Del(int Count) { m_SendBuffer->Del(Count); }

	virtual void Detach(void) {}
	virtual void Attach(void) {}
};

inline bool cStreamdevStreamer::Abort(void)
{
	return Active() && !m_Writer->Active();
}

#endif // VDR_STREAMDEV_STREAMER_H