File: transfer.c

package info (click to toggle)
w-scan-cpp 0~20230121-1
  • links: PTS, VCS
  • area: main
  • in suites: bookworm
  • size: 8,008 kB
  • sloc: ansic: 69,193; cpp: 9,599; makefile: 1,149; perl: 862; python: 74; sh: 70
file content (83 lines) | stat: -rw-r--r-- 2,297 bytes parent folder | download | duplicates (3)
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
/*
 * transfer.c: Transfer mode
 *
 * See the main source file 'vdr.c' for copyright information and
 * how to reach the author.
 *
 * $Id: transfer.c 5.1 2022/12/05 14:45:51 kls Exp $
 */

#include "transfer.h"

// --- cTransfer -------------------------------------------------------------

cTransfer::cTransfer(const cChannel *Channel)
:cReceiver(Channel, TRANSFERPRIORITY)
{
  lastErrorReport = 0;
  numLostPackets = 0;
  patPmtGenerator.SetChannel(Channel);
}

cTransfer::~cTransfer()
{
  cReceiver::Detach();
  cPlayer::Detach();
}

void cTransfer::Activate(bool On)
{
  if (On) {
     PlayTs(patPmtGenerator.GetPat(), TS_SIZE);
     int Index = 0;
     while (uchar *pmt = patPmtGenerator.GetPmt(Index))
           PlayTs(pmt, TS_SIZE);
     }
  else
     cPlayer::Detach();
}

#define MAXRETRIES    20 // max. number of retries for a single TS packet
#define RETRYWAIT      5 // time (in ms) between two retries
#define ERRORDELTA    60 // seconds before reporting lost TS packets again

void cTransfer::Receive(const uchar *Data, int Length)
{
  if (cPlayer::IsAttached()) {
     // Transfer Mode means "live tv", so there's no point in doing any additional
     // buffering here. The TS packets *must* get through here! However, every
     // now and then there may be conditions where the packet just can't be
     // handled when offered the first time, so that's why we try several times:
     for (int i = 0; i < MAXRETRIES; i++) {
         if (PlayTs(Data, Length) > 0)
            return;
         cCondWait::SleepMs(RETRYWAIT);
         }
     DeviceClear();
     numLostPackets++;
     if (time(NULL) - lastErrorReport > ERRORDELTA) {
        esyslog("ERROR: %d TS packet(s) not accepted in Transfer Mode", numLostPackets);
        numLostPackets = 0;
        lastErrorReport = time(NULL);
        }
     }
}

// --- cTransferControl ------------------------------------------------------

cDevice *cTransferControl::receiverDevice = NULL;

cTransferControl::cTransferControl(cDevice *ReceiverDevice, const cChannel *Channel)
:cControl(NULL, true)
{
  transfer = new cTransfer(Channel);
  SetPlayer(transfer);
  ReceiverDevice->AttachReceiver(transfer);
  receiverDevice = ReceiverDevice;
}

cTransferControl::~cTransferControl()
{
  receiverDevice = NULL;
  delete transfer;
}