summaryrefslogtreecommitdiff
path: root/p2pvr/devices/tuner.h
blob: 11fbf07adc62119db11a5a6decab1a0611e9446a (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
#ifndef P2PVR_TUNER_H
#define P2PVR_TUNER_H

#include <dvb.h>
#include <boost/filesystem/path.hpp>
#include <fileUtils.h>
#include <poll.h>
#include "frontend.h"
#include <map>
#include <thread>
#include <mutex>
#include <boost/bind.hpp>
#include <boost/function.hpp>
#include <boost/tuple/tuple.hpp>
#include <options.h>
#include <fileUtils.h>
#include <logger.h>

namespace P2PVR {
namespace DVB {
namespace Frontends {
	class OFDM;
}

class DLL_PUBLIC TunerI : public Tuner {
	public:
		class IDataSender {
			public:
				IDataSender(AdHoc::FileUtils::FileHandle, const RawDataClientPrxPtr &);
				virtual ~IDataSender() = 0;

				virtual void NewData(const Data &) = 0;
				virtual bool IsFinished() = 0;
				uint64_t PacketsSent() const;
				int fileHandle() const;

			protected:
				uint64_t _packetsSent;
				const AdHoc::FileUtils::FileHandle fh;
				const RawDataClientPrxPtr client;
		};
		typedef std::shared_ptr<IDataSender> BackgroundClient;
		typedef std::map<int, BackgroundClient> BackgroundClients;

		TunerI(const boost::filesystem::path & deviceFrontend, FrontendPtr = FrontendPtr());
		~TunerI();

		void TuneTo(const DVBSI::DeliveryPtr &) override;
		int GetStatus() override;
		std::string GetDevice() override;

		void ScanAndSendNetworkInformation(const RawDataClientPrxPtr & client) override;
		void SendNetworkInformation(const RawDataClientPrxPtr & client) override;
		void SendBouquetAssociations(const RawDataClientPrxPtr & client) override;
		void SendServiceDescriptions(const RawDataClientPrxPtr & client) override;
		void SendProgramMap(Ice::Int pid, const RawDataClientPrxPtr & client) override;
		void SendProgramAssociationTable(const RawDataClientPrxPtr & client) override;
		void SendEventInformation(const RawDataClientPrxPtr & client) override;

		int StartSendingTS(const PacketIds & pids, const RawDataClientPrxPtr & client) override;
		int StartSendingSection(Ice::Int pid, const RawDataClientPrxPtr & client) override;
		void StopSending(int handle) override;

	protected:
		virtual int iopoll(struct pollfd *fds, nfds_t nfds, int timeout) const;
		virtual ssize_t ioread(int fd, void *buf, size_t count) const;
		virtual int ioselect(int nfds, fd_set *readfds, fd_set *writefds, fd_set *exceptfds, struct timeval *timeout) const;

	private:
		virtual AdHoc::FileUtils::FileHandle OpenDemux() const;
		uint64_t SendPID(int pid, const RawDataClientPrxPtr & client) const;
		virtual void RequestPID(int pid, int fd) const;
		virtual void RequestTS(const PacketIds &, int fd) const;
		uint64_t ReadDemuxAndSend(AdHoc::FileUtils::FileHandle fd, const RawDataClientPrxPtr & client) const;
		void startSenderThread();
		void senderThread();
		static void setBufferSize(int fd, unsigned long bytes);

		const boost::filesystem::path deviceFrontend;
		const boost::filesystem::path deviceRoot;
		AdHoc::FileUtils::FileHandle frontendFD;
		BackgroundClients backgroundClients;
		std::thread * backgroundThread;
		std::mutex lock;

		FrontendPtr frontend;
		static IceTray::Logging::LoggerPtr logger;

	public:
		class Options : public IceTray::Options {
			public:
				Options();

				ICETRAY_OPTIONS_DECLARE;

				int TuningTimeout;
				int LockTimeout;
				int DemuxReadTimeout;
				int DemuxTableBufferSize;
				int DemuxStreamBufferSize;
		};

	private:
		friend class Frontend;
		friend class Frontends::OFDM;
		IceTray::OptionsResolver<Options> options;
};
}
}

#endif