summaryrefslogtreecommitdiff
path: root/tools/backgroundwriter.h
blob: 7119047edf3927e34339e29d7f7c7d6bffdf1ff8 (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
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
/*
 * backgroundwriter.h: Buffered socket/file writing thread
 *
 * See the main source file 'xineliboutput.c' for copyright information and
 * how to reach the author.
 *
 * $Id: backgroundwriter.h,v 1.4 2007-01-07 05:36:30 phintuka Exp $
 *
 */

#ifndef __BACKGROUNDWRITER_H
#define __BACKGROUNDWRITER_H

#include <stdint.h>

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

//
// cBackgroundWriterI
//  - generic interface for buffered output
//
class cBackgroundWriterI : public cThread 
{
  protected:
    cRingBufferLinear m_RingBuffer;

    volatile bool m_Active;
    int      m_fd;
    bool     m_IsSocket;

    uint64_t m_PutPos;
    uint64_t m_DiscardStart;
    uint64_t m_DiscardEnd;

    int      m_BufferOverflows;

  protected:
    virtual void Action(void) = 0;

  public:
    cBackgroundWriterI(int fd, int Size = KILOBYTE(512), int Margin = 0);
    virtual ~cBackgroundWriterI();

    // Add PES frame to buffer
    //
    // Return value:
    // Success:     Count   (all bytes pushed to queue)
    // Error:       0       (write error ; socket disconnected)
    // Buffer full: -Count  (no bytes will be pushed to queue)
    //
    virtual int Put(uint64_t StreamPos, const uchar *Data, int DataCount) = 0;
   
    int  Free(void);           // Return largest possible Put size
    void Clear(void);          // Drop all data (only complete frames) from buffer
    bool Flush(int TimeoutMs); // Flush buffer (wait for data to be sent)
};


//
// cTcpWriter
//  - xineliboutput TCP data steam 
//  - stream_tcp_header_t encapsulated PES frames
//
class cTcpWriter : public cBackgroundWriterI 
{
  protected:
    virtual void Action(void);

    int Put(const uchar *Header, int HeaderCount, 
	    const uchar *Data,   int DataCount);

  public:
    cTcpWriter(int fd, int Size = KILOBYTE(512));
    virtual ~cTcpWriter() {};

    virtual int Put(uint64_t StreamPos, const uchar *Data, int DataCount);
};


//
// cRawWriter
//  - Raw PES stream
//  - Used with HTTP
//
class cRawWriter : public cBackgroundWriterI 
{
  protected:
    virtual void Action(void);

  public:
    cRawWriter(int fd, int Size = KILOBYTE(512));
    virtual ~cRawWriter() {};

    virtual int Put(uint64_t StreamPos, const uchar *Data, int DataCount);
};


//
// cTsWriter
//  - Demux PES stream to PS
//
class cTsWriter : public cBackgroundWriterI 
{
  protected:
    virtual void Action(void);

  public:
    cTsWriter(int fd, int Size = KILOBYTE(512));
    virtual ~cTsWriter() {};

    virtual int Put(uint64_t StreamPos, const uchar *Data, int DataCount);
};


//
// cRtspMuxWriter
//  - RTSP multiplexed control+data
//  - Each encapsulated PES frame is written atomically to socket buffer
//  - Atomic control data can be written directly to socket 
//    from another thread to bypass buffer
//

class cRtspMuxWriter : public cBackgroundWriterI 
{
  protected:
    virtual void Action(void);

  public:
    cRtspMuxWriter(int fd, int Size = KILOBYTE(512));
    virtual ~cRtspMuxWriter() {};

    virtual int Put(uint64_t StreamPos, const uchar *Data, int DataCount);
};


//
// cRtspRemuxWriter
//  - RTSP multiplexed control+data
//  - Demux PES stream to independent ES streams
//  - encapsulate ES to RTP/AVP compatible frames
//  - Mux RTP/AVP ES streams to pipelined RTCP control connection
//  - Each encapsulated frame is written atomically to socket buffer
//  - Atomic control data can be written directly to socket 
//    from another thread to bypass buffer
//

class cRtspRemuxWriter : public cBackgroundWriterI 
{
  protected:
    virtual void Action(void);

  public:
    cRtspRemuxWriter(int fd, int Size = KILOBYTE(512));
    virtual ~cRtspRemuxWriter() {};

    virtual int Put(uint64_t StreamPos, const uchar *Data, int DataCount);
};


#endif