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
|
#include "remux/ts2ps.h"
#include "remux/ts2pes.h"
#include "remux/ts2es.h"
#include "remux/extern.h"
#include <vdr/ringbuffer.h>
#include "server/recstreamer.h"
#include "server/connection.h"
#include "common.h"
using namespace Streamdev;
// --- cStreamdevRecStreamer -------------------------------------------------
cStreamdevRecStreamer::cStreamdevRecStreamer(cRecording *Rec, const cServerConnection *Connection, std::string pos):
cStreamdevStreamer("streamdev-recstreaming", Connection),
m_RecPlayer(Rec),
m_From(0L)
{
Dprintf("New rec streamer\n");
m_To = (int64_t) m_RecPlayer.getLengthBytes() - 1;
m_Pos = pos;
}
cStreamdevRecStreamer::~cStreamdevRecStreamer()
{
Dprintf("Desctructing rec streamer\n");
Stop();
}
int64_t cStreamdevRecStreamer::SetRange(int64_t &From, int64_t &To)
{
int64_t l = (int64_t) m_RecPlayer.getLengthBytes();
if (From < 0L) {
From += l;
if (From < 0L)
From = 0L;
To = l - 1;
}
else {
if (To < 0L)
To += l;
else if (To >= l)
To = l - 1;
if (From > To) {
// invalid range - return whole content
From = 0L;
To = l - 1;
}
}
m_From = From;
m_To = To;
return m_To - m_From + 1;
}
int32_t cStreamdevRecStreamer::getIFrameBeforeFrame(int32_t frame)
{
uint32_t iframe, len;
uint64_t pos;
m_RecPlayer.getNextIFrame(frame + 1, 0, &pos, &iframe, &len);
Dprintf("pos: frame %i -> start at iFrame %i\n", frame, iframe);
return iframe;
}
int64_t cStreamdevRecStreamer::GetFromByPos()
{
if (m_Pos.empty()) return 0;
std::string pos = m_Pos;
// cut prefix (if any)
if (pos.find('_') != std::string::npos) {
pos = pos.substr(pos.find('_') + 1);
}
// resume file
if (pos == "resume") {
int frame = getIFrameBeforeFrame(m_RecPlayer.frameFromResume());
Dprintf("pos: frame from resume: %i\n", frame);
return m_RecPlayer.positionFromFrameNumber(frame);
}
// mark
if (pos.find("mark.") == 0) {
int index = atoi(pos.substr(5).c_str());
int frame = getIFrameBeforeFrame(m_RecPlayer.frameFromMark(index));
Dprintf("pos: mark %i - frame %i\n", index, frame);
return m_RecPlayer.positionFromFrameNumber(frame);
}
// time
if (pos.find("time.") == 0) {
int seconds = atoi(pos.substr(5).c_str());
int frame = getIFrameBeforeFrame(m_RecPlayer.frameFromSeconds(seconds));
Dprintf("pos: %i seconds - frame %i\n", seconds, frame);
return m_RecPlayer.positionFromFrameNumber(frame);
}
// frame number
if (pos.find("frame.") == 0) {
int frame = getIFrameBeforeFrame(atoi(pos.substr(6).c_str()));
Dprintf("pos: frame %i\n", frame);
return m_RecPlayer.positionFromFrameNumber(frame);
}
// default: byte index or percent
// as "%" is the url escape character, interpret <100 as percent
// if (pos.find("%") != std::string::npos) {
// int percent = atoi(pos.substr(0, pos.find("%")).c_str());
int64_t number = atol(pos.c_str());
if (number < 100) {
Dprintf("pos: %lld percent\n", (long long)number);
int64_t offset = m_RecPlayer.getLengthBytes() * number / 100;
return offset;
}
return number;
}
uchar* cStreamdevRecStreamer::GetFromReceiver(int &Count)
{
if (m_From <= m_To) {
Count = (int) m_RecPlayer.getBlock(m_Buffer, m_From, sizeof(m_Buffer));
return m_Buffer;
}
return NULL;
}
cString cStreamdevRecStreamer::ToText() const
{
return "REPLAY";
}
|