mirror of
https://projects.vdr-developer.org/git/vdr-plugin-streamdev.git
synced 2023-10-10 19:16:51 +02:00
- resurrected clients "Suspend Server" menu item as its mainmenu entry
- dropped unused code for remote timers/recordings on client side - dropped unused files client/{assembler,menu,remote}.[hc] - dropped unused files in libdvbmpeg (reported by tobi)
This commit is contained in:
parent
f51d6eb2df
commit
89735cbd95
6
Makefile
6
Makefile
@ -1,7 +1,7 @@
|
|||||||
#
|
#
|
||||||
# Makefile for a Video Disk Recorder plugin
|
# Makefile for a Video Disk Recorder plugin
|
||||||
#
|
#
|
||||||
# $Id: Makefile,v 1.13 2008/04/07 14:27:27 schmirl Exp $
|
# $Id: Makefile,v 1.14 2008/04/07 14:40:39 schmirl Exp $
|
||||||
|
|
||||||
# The official name of this plugin.
|
# The official name of this plugin.
|
||||||
# This name will be used in the '-P...' option of VDR to load the plugin.
|
# This name will be used in the '-P...' option of VDR to load the plugin.
|
||||||
@ -52,7 +52,7 @@ COMMONOBJS = common.o i18n.o \
|
|||||||
CLIENTOBJS = $(PLUGIN)-client.o \
|
CLIENTOBJS = $(PLUGIN)-client.o \
|
||||||
\
|
\
|
||||||
client/socket.o client/device.o client/setup.o \
|
client/socket.o client/device.o client/setup.o \
|
||||||
client/remote.o client/assembler.o client/filter.o
|
client/filter.o
|
||||||
|
|
||||||
|
|
||||||
SERVEROBJS = $(PLUGIN)-server.o \
|
SERVEROBJS = $(PLUGIN)-server.o \
|
||||||
@ -98,7 +98,7 @@ endif
|
|||||||
|
|
||||||
### Targets:
|
### Targets:
|
||||||
|
|
||||||
libdvbmpeg/libdvbmpegtools.a: libdvbmpeg/*.c libdvbmpeg/*.cc libdvbmpeg/*.h libdvbmpeg/*.hh
|
libdvbmpeg/libdvbmpegtools.a: libdvbmpeg/*.c libdvbmpeg/*.h
|
||||||
$(MAKE) -C ./libdvbmpeg libdvbmpegtools.a
|
$(MAKE) -C ./libdvbmpeg libdvbmpegtools.a
|
||||||
|
|
||||||
libvdr-$(PLUGIN)-client.so: $(CLIENTOBJS) $(COMMONOBJS) libdvbmpeg/libdvbmpegtools.a
|
libvdr-$(PLUGIN)-client.so: $(CLIENTOBJS) $(COMMONOBJS) libdvbmpeg/libdvbmpegtools.a
|
||||||
|
@ -1,114 +0,0 @@
|
|||||||
/*
|
|
||||||
* $Id: assembler.c,v 1.3 2008/04/07 14:27:28 schmirl Exp $
|
|
||||||
*/
|
|
||||||
|
|
||||||
#include "client/assembler.h"
|
|
||||||
#include "common.h"
|
|
||||||
|
|
||||||
#include "tools/socket.h"
|
|
||||||
#include "tools/select.h"
|
|
||||||
|
|
||||||
#include <vdr/tools.h>
|
|
||||||
#include <vdr/device.h>
|
|
||||||
#include <vdr/ringbuffer.h>
|
|
||||||
|
|
||||||
#include <unistd.h>
|
|
||||||
|
|
||||||
cStreamdevAssembler::cStreamdevAssembler(cTBSocket *Socket)
|
|
||||||
:cThread("Streamdev: UDP-TS Assembler")
|
|
||||||
{
|
|
||||||
m_Socket = Socket;
|
|
||||||
if (pipe(m_Pipe) != 0) {
|
|
||||||
esyslog("streamdev-client: Couldn't open assembler pipe: %m");
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
fcntl(m_Pipe[0], F_SETFL, O_NONBLOCK);
|
|
||||||
fcntl(m_Pipe[1], F_SETFL, O_NONBLOCK);
|
|
||||||
m_Mutex.Lock();
|
|
||||||
Start();
|
|
||||||
}
|
|
||||||
|
|
||||||
cStreamdevAssembler::~cStreamdevAssembler() {
|
|
||||||
if (m_Active) {
|
|
||||||
m_Active = false;
|
|
||||||
/* WakeUp();*/
|
|
||||||
Cancel(3);
|
|
||||||
}
|
|
||||||
close(m_Pipe[0]);
|
|
||||||
close(m_Pipe[1]);
|
|
||||||
}
|
|
||||||
|
|
||||||
void cStreamdevAssembler::Action(void) {
|
|
||||||
cTBSelect sel;
|
|
||||||
uchar buffer[2048];
|
|
||||||
bool fillup = true;
|
|
||||||
|
|
||||||
const int rbsize = TS_SIZE * 5600;
|
|
||||||
const int rbmargin = TS_SIZE * 2;
|
|
||||||
const int rbminfill = rbmargin * 50;
|
|
||||||
cRingBufferLinear ringbuf(rbsize, rbmargin, true);
|
|
||||||
|
|
||||||
m_Mutex.Lock();
|
|
||||||
|
|
||||||
m_Active = true;
|
|
||||||
while (m_Active) {
|
|
||||||
sel.Clear();
|
|
||||||
|
|
||||||
if (ringbuf.Available() < rbsize * 80 / 100)
|
|
||||||
sel.Add(*m_Socket, false);
|
|
||||||
if (ringbuf.Available() > rbminfill) {
|
|
||||||
if (fillup) {
|
|
||||||
Dprintf("giving signal\n");
|
|
||||||
m_WaitFill.Broadcast();
|
|
||||||
m_Mutex.Unlock();
|
|
||||||
fillup = false;
|
|
||||||
}
|
|
||||||
sel.Add(m_Pipe[1], true);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (sel.Select(1500) < 0) {
|
|
||||||
if (!m_Active) // Exit was requested
|
|
||||||
break;
|
|
||||||
esyslog("streamdev-client: Fatal error: %m");
|
|
||||||
Dprintf("streamdev-client: select failed (%m)\n");
|
|
||||||
m_Active = false;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (sel.CanRead(*m_Socket)) {
|
|
||||||
int b;
|
|
||||||
if ((b = m_Socket->Read(buffer, sizeof(buffer))) < 0) {
|
|
||||||
esyslog("streamdev-client: Couldn't read from server: %m");
|
|
||||||
Dprintf("streamdev-client: read failed (%m)\n");
|
|
||||||
m_Active = false;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
if (b == 0)
|
|
||||||
m_Active = false;
|
|
||||||
else
|
|
||||||
ringbuf.Put(buffer, b);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (sel.CanWrite(m_Pipe[1])) {
|
|
||||||
int recvd;
|
|
||||||
const uchar *block = ringbuf.Get(recvd);
|
|
||||||
if (block && recvd > 0) {
|
|
||||||
int result;
|
|
||||||
if (recvd > ringbuf.Available() - rbminfill)
|
|
||||||
recvd = ringbuf.Available() - rbminfill;
|
|
||||||
if ((result = write(m_Pipe[1], block, recvd)) == -1) {
|
|
||||||
esyslog("streamdev-client: Couldn't write to VDR: %m"); // TODO
|
|
||||||
Dprintf("streamdev-client: write failed (%m)\n");
|
|
||||||
m_Active = false;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
ringbuf.Del(result);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void cStreamdevAssembler::WaitForFill(void) {
|
|
||||||
m_WaitFill.Wait(m_Mutex);
|
|
||||||
m_Mutex.Unlock();
|
|
||||||
}
|
|
@ -1,32 +0,0 @@
|
|||||||
/*
|
|
||||||
* $Id: assembler.h,v 1.1 2004/12/30 22:44:04 lordjaxom Exp $
|
|
||||||
*/
|
|
||||||
|
|
||||||
#ifndef VDR_STREAMDEV_ASSEMBLER_H
|
|
||||||
#define VDR_STREAMDEV_ASSEMBLER_H
|
|
||||||
|
|
||||||
#include <vdr/config.h>
|
|
||||||
#include <vdr/thread.h>
|
|
||||||
|
|
||||||
class cTBSocket;
|
|
||||||
|
|
||||||
class cStreamdevAssembler: public cThread {
|
|
||||||
private:
|
|
||||||
cTBSocket *m_Socket;
|
|
||||||
cMutex m_Mutex;
|
|
||||||
cCondVar m_WaitFill;
|
|
||||||
int m_Pipe[2];
|
|
||||||
bool m_Active;
|
|
||||||
protected:
|
|
||||||
virtual void Action(void);
|
|
||||||
|
|
||||||
public:
|
|
||||||
cStreamdevAssembler(cTBSocket *Socket);
|
|
||||||
virtual ~cStreamdevAssembler();
|
|
||||||
|
|
||||||
int ReadPipe(void) const { return m_Pipe[0]; }
|
|
||||||
void WaitForFill(void);
|
|
||||||
};
|
|
||||||
|
|
||||||
#endif // VDR_STREAMDEV_ASSEMBLER_H
|
|
||||||
|
|
@ -1,10 +1,9 @@
|
|||||||
/*
|
/*
|
||||||
* $Id: device.c,v 1.16 2008/04/07 14:27:28 schmirl Exp $
|
* $Id: device.c,v 1.17 2008/04/07 14:40:39 schmirl Exp $
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include "client/device.h"
|
#include "client/device.h"
|
||||||
#include "client/setup.h"
|
#include "client/setup.h"
|
||||||
#include "client/assembler.h"
|
|
||||||
#include "client/filter.h"
|
#include "client/filter.h"
|
||||||
|
|
||||||
#include "tools/select.h"
|
#include "tools/select.h"
|
||||||
@ -26,11 +25,9 @@ cStreamdevDevice *cStreamdevDevice::m_Device = NULL;
|
|||||||
cStreamdevDevice::cStreamdevDevice(void) {
|
cStreamdevDevice::cStreamdevDevice(void) {
|
||||||
m_Channel = NULL;
|
m_Channel = NULL;
|
||||||
m_TSBuffer = NULL;
|
m_TSBuffer = NULL;
|
||||||
m_Assembler = NULL;
|
|
||||||
|
|
||||||
m_Filters = new cStreamdevFilters;
|
m_Filters = new cStreamdevFilters;
|
||||||
StartSectionHandler();
|
StartSectionHandler();
|
||||||
cSchedules::Read();
|
|
||||||
|
|
||||||
m_Device = this;
|
m_Device = this;
|
||||||
m_Pids = 0;
|
m_Pids = 0;
|
||||||
@ -54,7 +51,6 @@ cStreamdevDevice::~cStreamdevDevice() {
|
|||||||
|
|
||||||
DELETENULL(m_Filters);
|
DELETENULL(m_Filters);
|
||||||
DELETENULL(m_TSBuffer);
|
DELETENULL(m_TSBuffer);
|
||||||
delete m_Assembler;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
bool cStreamdevDevice::ProvidesSource(int Source) const {
|
bool cStreamdevDevice::ProvidesSource(int Source) const {
|
||||||
@ -283,7 +279,6 @@ bool cStreamdevDevice::ReInit(void) {
|
|||||||
ClientSocket.Reset();
|
ClientSocket.Reset();
|
||||||
if (m_Device != NULL) {
|
if (m_Device != NULL) {
|
||||||
//DELETENULL(m_Device->m_TSBuffer);
|
//DELETENULL(m_Device->m_TSBuffer);
|
||||||
DELETENULL(m_Device->m_Assembler);
|
|
||||||
m_Device->Unlock();
|
m_Device->Unlock();
|
||||||
}
|
}
|
||||||
return StreamdevClientSetup.StartClient ? Init() : true;
|
return StreamdevClientSetup.StartClient ? Init() : true;
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
* $Id: device.h,v 1.6 2008/04/07 14:27:28 schmirl Exp $
|
* $Id: device.h,v 1.7 2008/04/07 14:40:39 schmirl Exp $
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#ifndef VDR_STREAMDEV_DEVICE_H
|
#ifndef VDR_STREAMDEV_DEVICE_H
|
||||||
@ -8,7 +8,6 @@
|
|||||||
#include <vdr/device.h>
|
#include <vdr/device.h>
|
||||||
|
|
||||||
#include "client/socket.h"
|
#include "client/socket.h"
|
||||||
#include "client/assembler.h"
|
|
||||||
#include "client/filter.h"
|
#include "client/filter.h"
|
||||||
|
|
||||||
class cTBString;
|
class cTBString;
|
||||||
@ -21,7 +20,6 @@ class cStreamdevDevice: public cDevice {
|
|||||||
private:
|
private:
|
||||||
const cChannel *m_Channel;
|
const cChannel *m_Channel;
|
||||||
cTSBuffer *m_TSBuffer;
|
cTSBuffer *m_TSBuffer;
|
||||||
cStreamdevAssembler *m_Assembler;
|
|
||||||
cStreamdevFilters *m_Filters;
|
cStreamdevFilters *m_Filters;
|
||||||
int m_Pids;
|
int m_Pids;
|
||||||
bool m_DvrClosed;
|
bool m_DvrClosed;
|
||||||
|
802
client/menu.c
802
client/menu.c
@ -1,802 +0,0 @@
|
|||||||
/*
|
|
||||||
* $Id: menu.c,v 1.5 2008/04/07 14:27:28 schmirl Exp $
|
|
||||||
*/
|
|
||||||
|
|
||||||
#include <vdr/menuitems.h>
|
|
||||||
#include <vdr/interface.h>
|
|
||||||
|
|
||||||
#include "client/menu.h"
|
|
||||||
#include "client/socket.h"
|
|
||||||
#include "i18n.h"
|
|
||||||
|
|
||||||
#define CHNUMWIDTH (numdigits(Channels.MaxNumber()) + 1)
|
|
||||||
|
|
||||||
// --- cMenuText -------------------------------------------------------------
|
|
||||||
|
|
||||||
class cMenuText : public cOsdMenu {
|
|
||||||
public:
|
|
||||||
cMenuText(const char *Title, const char *Text, eDvbFont Font = fontOsd);
|
|
||||||
virtual eOSState ProcessKey(eKeys Key);
|
|
||||||
};
|
|
||||||
|
|
||||||
// --- cStreamdevMenu --------------------------------------------------------
|
|
||||||
|
|
||||||
cStreamdevMenu::cStreamdevMenu(void):
|
|
||||||
cOsdMenu(tr("Streaming Control")) {
|
|
||||||
SetHasHotkeys();
|
|
||||||
Add(new cOsdItem(hk(tr("Remote Schedule")), (eOSState)subSchedule));
|
|
||||||
Add(new cOsdItem(hk(tr("Remote Timers")), (eOSState)subTimers));
|
|
||||||
Add(new cOsdItem(hk(tr("Remote Recordings")), (eOSState)subRecordings));
|
|
||||||
Add(new cOsdItem(hk(tr("Suspend Server")), (eOSState)subSuspend));
|
|
||||||
Add(new cOsdItem(hk(tr("Synchronize EPG")), (eOSState)subSyncEPG));
|
|
||||||
}
|
|
||||||
|
|
||||||
cStreamdevMenu::~cStreamdevMenu() {
|
|
||||||
}
|
|
||||||
|
|
||||||
eOSState cStreamdevMenu::ProcessKey(eKeys Key) {
|
|
||||||
eOSState state = cOsdMenu::ProcessKey(Key);
|
|
||||||
switch (state) {
|
|
||||||
case subSchedule: return AddSubMenu(new cStreamdevMenuSchedule);
|
|
||||||
case subTimers: return AddSubMenu(new cStreamdevMenuTimers);
|
|
||||||
case subRecordings: return AddSubMenu(new cStreamdevMenuRecordings);
|
|
||||||
case subSuspend: SuspendServer(); return osEnd;
|
|
||||||
case subSyncEPG: ClientSocket.SynchronizeEPG(); return osEnd;
|
|
||||||
default: return state;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void cStreamdevMenu::SuspendServer(void) {
|
|
||||||
if (ClientSocket.SuspendServer())
|
|
||||||
INFO(tr("Server is suspended"));
|
|
||||||
else
|
|
||||||
ERROR(tr("Couldn't suspend Server!"));
|
|
||||||
}
|
|
||||||
|
|
||||||
// --- cStreamdevMenuEditTimer -----------------------------------------------
|
|
||||||
|
|
||||||
class cStreamdevMenuEditTimer : public cOsdMenu {
|
|
||||||
private:
|
|
||||||
int m_Channel;
|
|
||||||
bool m_AddIfConfirmed;
|
|
||||||
cRemoteTimer *m_Timer;
|
|
||||||
cRemoteTimer m_Data;
|
|
||||||
cMenuEditDateItem *m_FirstDay;
|
|
||||||
|
|
||||||
protected:
|
|
||||||
void SetFirstDayItem(void);
|
|
||||||
|
|
||||||
public:
|
|
||||||
cStreamdevMenuEditTimer(cRemoteTimer *Timer, bool New = false);
|
|
||||||
virtual ~cStreamdevMenuEditTimer();
|
|
||||||
|
|
||||||
virtual eOSState ProcessKey(eKeys Key);
|
|
||||||
};
|
|
||||||
|
|
||||||
cStreamdevMenuEditTimer::cStreamdevMenuEditTimer(cRemoteTimer *Timer, bool New):
|
|
||||||
cOsdMenu(tr("Edit remote timer"), 12) {
|
|
||||||
m_FirstDay = NULL;
|
|
||||||
m_Timer = Timer;
|
|
||||||
m_AddIfConfirmed = New;
|
|
||||||
|
|
||||||
if (m_Timer) {
|
|
||||||
m_Data = *m_Timer;
|
|
||||||
if (New)
|
|
||||||
m_Data.m_Active = 1;
|
|
||||||
m_Channel = m_Data.Channel()->Number();
|
|
||||||
Add(new cMenuEditBitItem( tr("Active"), &m_Data.m_Active, tfActive));
|
|
||||||
Add(new cMenuEditChanItem(tr("Channel"), &m_Channel));
|
|
||||||
Add(new cMenuEditDayItem( tr("Day"), &m_Data.m_Day));
|
|
||||||
Add(new cMenuEditTimeItem(tr("Start"), &m_Data.m_Start));
|
|
||||||
Add(new cMenuEditTimeItem(tr("Stop"), &m_Data.m_Stop));
|
|
||||||
Add(new cMenuEditBitItem( tr("VPS"), &m_Data.m_Active, tfVps));
|
|
||||||
Add(new cMenuEditIntItem( tr("Priority"), &m_Data.m_Priority, 0,
|
|
||||||
MAXPRIORITY));
|
|
||||||
Add(new cMenuEditIntItem( tr("Lifetime"), &m_Data.m_Lifetime, 0,
|
|
||||||
MAXLIFETIME));
|
|
||||||
Add(new cMenuEditStrItem( tr("File"), m_Data.m_File,
|
|
||||||
sizeof(m_Data.m_File), tr(FileNameChars)));
|
|
||||||
SetFirstDayItem();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
cStreamdevMenuEditTimer::~cStreamdevMenuEditTimer() {
|
|
||||||
if (m_Timer && m_AddIfConfirmed) {
|
|
||||||
Dprintf("SOMETHING GETS DELETED\n");
|
|
||||||
delete m_Timer; // apparently it wasn't confirmed
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void cStreamdevMenuEditTimer::SetFirstDayItem(void) {
|
|
||||||
if (!m_FirstDay && !m_Data.IsSingleEvent()) {
|
|
||||||
Add(m_FirstDay = new cMenuEditDateItem(tr("First day"),&m_Data.m_FirstDay));
|
|
||||||
Display();
|
|
||||||
} else if (m_FirstDay && m_Data.IsSingleEvent()) {
|
|
||||||
Del(m_FirstDay->Index());
|
|
||||||
m_FirstDay = NULL;
|
|
||||||
m_Data.m_FirstDay = 0;
|
|
||||||
Display();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
eOSState cStreamdevMenuEditTimer::ProcessKey(eKeys Key) {
|
|
||||||
eOSState state = cOsdMenu::ProcessKey(Key);
|
|
||||||
|
|
||||||
if (state == osUnknown) {
|
|
||||||
switch (Key) {
|
|
||||||
case kOk:
|
|
||||||
{
|
|
||||||
cChannel *ch = Channels.GetByNumber(m_Channel);
|
|
||||||
if (ch)
|
|
||||||
m_Data.m_Channel = ch;
|
|
||||||
else {
|
|
||||||
ERROR(tr("*** Invalid Channel ***"));
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
if (!*m_Data.m_File)
|
|
||||||
strcpy(m_Data.m_File, m_Data.Channel()->Name());
|
|
||||||
if (m_Timer) {
|
|
||||||
bool success = true;
|
|
||||||
if (m_Data != *m_Timer) {
|
|
||||||
// Timer has changed
|
|
||||||
if ((success = ClientSocket.SaveTimer(m_Timer, m_Data))) {
|
|
||||||
*m_Timer = m_Data;
|
|
||||||
if (m_Timer->m_Active)
|
|
||||||
m_Timer->m_Active = 1;
|
|
||||||
// allows external programs to mark active timers with
|
|
||||||
// values > 1 and recognize if the user has modified them
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (success) {
|
|
||||||
if (m_AddIfConfirmed)
|
|
||||||
RemoteTimers.Add(m_Timer);
|
|
||||||
isyslog("timer %d %s (%s)", m_Timer->Index() + 1,
|
|
||||||
m_AddIfConfirmed ? "added" : "modified",
|
|
||||||
m_Timer->m_Active ? "active" : "inactive");
|
|
||||||
m_AddIfConfirmed = false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return osBack;
|
|
||||||
|
|
||||||
case kRed:
|
|
||||||
case kGreen:
|
|
||||||
case kYellow:
|
|
||||||
case kBlue: return osContinue;
|
|
||||||
default: break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (Key != kNone)
|
|
||||||
SetFirstDayItem();
|
|
||||||
return state;
|
|
||||||
}
|
|
||||||
|
|
||||||
// --- cMenuWhatsOnItem ------------------------------------------------------
|
|
||||||
|
|
||||||
class cMenuWhatsOnItem : public cOsdItem {
|
|
||||||
public:
|
|
||||||
const cEvent *event;
|
|
||||||
const cChannel *channel;
|
|
||||||
cMenuWhatsOnItem(const cEvent *Event, cChannel *Channel); //, bool Now = false);
|
|
||||||
};
|
|
||||||
|
|
||||||
// --- cMenuEvent ------------------------------------------------------------
|
|
||||||
|
|
||||||
class cMenuEvent : public cOsdMenu {
|
|
||||||
private:
|
|
||||||
const cEvent *event;
|
|
||||||
public:
|
|
||||||
cMenuEvent(const cEvent *Event, bool CanSwitch = false);
|
|
||||||
virtual void Display(void);
|
|
||||||
virtual eOSState ProcessKey(eKeys Key);
|
|
||||||
};
|
|
||||||
|
|
||||||
// --- cStreamdevMenuWhatsOn -------------------------------------------------
|
|
||||||
|
|
||||||
int cStreamdevMenuWhatsOn::m_CurrentChannel = 0;
|
|
||||||
const cEvent *cStreamdevMenuWhatsOn::m_ScheduleEventInfo = NULL;
|
|
||||||
|
|
||||||
cStreamdevMenuWhatsOn::cStreamdevMenuWhatsOn(const cSchedules *Schedules,
|
|
||||||
bool Now, int CurrentChannel):
|
|
||||||
cOsdMenu(Now ? tr("What's on now?") : tr("What's on next?"), CHNUMWIDTH,
|
|
||||||
7, 6) {
|
|
||||||
for (cChannel *Channel = Channels.First(); Channel;
|
|
||||||
Channel = Channels.Next(Channel)) {
|
|
||||||
if (!Channel->GroupSep()) {
|
|
||||||
const cSchedule *Schedule
|
|
||||||
= Schedules->GetSchedule(Channel->GetChannelID());
|
|
||||||
if (Schedule) {
|
|
||||||
const cEvent *Event = Now ? Schedule->GetPresentEvent()
|
|
||||||
: Schedule->GetFollowingEvent();
|
|
||||||
if (Event)
|
|
||||||
Add(new cMenuWhatsOnItem(Event, Channel),
|
|
||||||
Channel->Number() == CurrentChannel);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
m_CurrentChannel = CurrentChannel;
|
|
||||||
SetHelp(Count() ? tr("Record") : NULL, Now ? tr("Next") : tr("Now"),
|
|
||||||
tr("Schedule"), tr("Switch"));
|
|
||||||
}
|
|
||||||
|
|
||||||
const cEvent *cStreamdevMenuWhatsOn::ScheduleEventInfo(void) {
|
|
||||||
const cEvent *ei = m_ScheduleEventInfo;
|
|
||||||
m_ScheduleEventInfo = NULL;
|
|
||||||
return ei;
|
|
||||||
}
|
|
||||||
|
|
||||||
eOSState cStreamdevMenuWhatsOn::Switch(void) {
|
|
||||||
cMenuWhatsOnItem *item = (cMenuWhatsOnItem*)Get(Current());
|
|
||||||
if (item) {
|
|
||||||
cChannel *channel
|
|
||||||
= Channels.GetByChannelID(item->event->ChannelID(), true);
|
|
||||||
if (channel && cDevice::PrimaryDevice()->SwitchChannel(channel, true))
|
|
||||||
return osEnd;
|
|
||||||
}
|
|
||||||
ERROR(tr("Can't switch channel!"));
|
|
||||||
return osContinue;
|
|
||||||
}
|
|
||||||
|
|
||||||
eOSState cStreamdevMenuWhatsOn::Record(void) {
|
|
||||||
cMenuWhatsOnItem *item = (cMenuWhatsOnItem*)Get(Current());
|
|
||||||
if (item) {
|
|
||||||
cRemoteTimer *timer
|
|
||||||
= new cRemoteTimer(item->event);
|
|
||||||
return AddSubMenu(new cStreamdevMenuEditTimer(timer));
|
|
||||||
// Load remote timers and see if timer exists before editing
|
|
||||||
}
|
|
||||||
return osContinue;
|
|
||||||
}
|
|
||||||
|
|
||||||
eOSState cStreamdevMenuWhatsOn::ProcessKey(eKeys Key) {
|
|
||||||
eOSState state = cOsdMenu::ProcessKey(Key);
|
|
||||||
if (state == osUnknown) {
|
|
||||||
switch (Key) {
|
|
||||||
case kRecord:
|
|
||||||
case kRed:
|
|
||||||
return Record();
|
|
||||||
|
|
||||||
case kYellow:
|
|
||||||
state = osBack;
|
|
||||||
case kGreen:
|
|
||||||
{
|
|
||||||
cMenuWhatsOnItem *mi = (cMenuWhatsOnItem*)Get(Current());
|
|
||||||
if (mi) {
|
|
||||||
m_ScheduleEventInfo = mi->event;
|
|
||||||
m_CurrentChannel = mi->channel->Number();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
|
|
||||||
case kBlue:
|
|
||||||
return Switch();
|
|
||||||
|
|
||||||
case kOk:
|
|
||||||
if (Count())
|
|
||||||
return AddSubMenu(new cMenuEvent(
|
|
||||||
((cMenuWhatsOnItem*)Get(Current()))->event, true));
|
|
||||||
break;
|
|
||||||
|
|
||||||
default:
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return state;
|
|
||||||
}
|
|
||||||
|
|
||||||
// --- cMenuScheduleItem -----------------------------------------------------
|
|
||||||
|
|
||||||
class cMenuScheduleItem : public cOsdItem {
|
|
||||||
public:
|
|
||||||
const cEvent *event;
|
|
||||||
cMenuScheduleItem(const cEvent *Event);
|
|
||||||
};
|
|
||||||
|
|
||||||
// --- cStreamdevMenuSchedule ------------------------------------------------
|
|
||||||
|
|
||||||
cStreamdevMenuSchedule::cStreamdevMenuSchedule(void):
|
|
||||||
cOsdMenu("", 7, 6, 4)
|
|
||||||
{
|
|
||||||
m_Now = false;
|
|
||||||
m_Next = false;
|
|
||||||
m_OtherChannel = -1;
|
|
||||||
m_Schedules = NULL;
|
|
||||||
|
|
||||||
cChannel *channel = Channels.GetByNumber(cDevice::CurrentChannel());
|
|
||||||
if (channel) {
|
|
||||||
m_Schedules = cSchedules::Schedules(m_Lock);
|
|
||||||
PrepareSchedule(channel);
|
|
||||||
SetHelp(Count() ? tr("Record") : NULL, tr("Now"), tr("Next"));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
cStreamdevMenuSchedule::~cStreamdevMenuSchedule() {
|
|
||||||
}
|
|
||||||
|
|
||||||
void cStreamdevMenuSchedule::PrepareSchedule(cChannel *Channel) {
|
|
||||||
Clear();
|
|
||||||
char *buffer = NULL;
|
|
||||||
asprintf(&buffer, tr("Schedule - %s"), Channel->Name());
|
|
||||||
SetTitle(buffer);
|
|
||||||
free(buffer);
|
|
||||||
if (m_Schedules) {
|
|
||||||
const cSchedule *Schedule = m_Schedules->GetSchedule(Channel->GetChannelID());
|
|
||||||
if (Schedule) {
|
|
||||||
const cEvent *PresentEvent = Schedule->GetPresentEvent(Channel->Number() == cDevice::CurrentChannel());
|
|
||||||
time_t now = time(NULL) - Setup.EPGLinger * 60;
|
|
||||||
for (const cEvent *Event = Schedule->Events()->First(); Event; Event = Schedule->Events()->Next(Event)) {
|
|
||||||
if (Event->EndTime() > now || Event == PresentEvent)
|
|
||||||
Add(new cMenuScheduleItem(Event), Event == PresentEvent);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
eOSState cStreamdevMenuSchedule::Switch(void) {
|
|
||||||
if (m_OtherChannel) {
|
|
||||||
if (Channels.SwitchTo(m_OtherChannel))
|
|
||||||
return osEnd;
|
|
||||||
}
|
|
||||||
ERROR(tr("Can't switch channel!"));
|
|
||||||
return osContinue;
|
|
||||||
}
|
|
||||||
|
|
||||||
eOSState cStreamdevMenuSchedule::Record(void) {
|
|
||||||
cMenuScheduleItem *item = (cMenuScheduleItem*)Get(Current());
|
|
||||||
if (item) {
|
|
||||||
cRemoteTimer *timer
|
|
||||||
= new cRemoteTimer(item->event);
|
|
||||||
return AddSubMenu(new cStreamdevMenuEditTimer(timer));
|
|
||||||
// Load remote timers and see if timer exists before editing
|
|
||||||
}
|
|
||||||
return osContinue;
|
|
||||||
}
|
|
||||||
|
|
||||||
eOSState cStreamdevMenuSchedule::ProcessKey(eKeys Key) {
|
|
||||||
eOSState state = cOsdMenu::ProcessKey(Key);
|
|
||||||
if (state == osUnknown) {
|
|
||||||
switch (Key) {
|
|
||||||
case kRecord:
|
|
||||||
case kRed:
|
|
||||||
return Record();
|
|
||||||
|
|
||||||
case kGreen:
|
|
||||||
if (m_Schedules) {
|
|
||||||
if (!m_Now && !m_Next) {
|
|
||||||
int channelnr = 0;
|
|
||||||
if (Count()) {
|
|
||||||
cChannel *channel
|
|
||||||
= Channels.GetByChannelID(
|
|
||||||
((cMenuScheduleItem*)Get(Current()))->event->ChannelID(), true);
|
|
||||||
if (channel)
|
|
||||||
channelnr = channel->Number();
|
|
||||||
}
|
|
||||||
m_Now = true;
|
|
||||||
return AddSubMenu(new cStreamdevMenuWhatsOn(m_Schedules, true,
|
|
||||||
channelnr));
|
|
||||||
}
|
|
||||||
m_Now = !m_Now;
|
|
||||||
m_Next = !m_Next;
|
|
||||||
return AddSubMenu(new cStreamdevMenuWhatsOn(m_Schedules, m_Now,
|
|
||||||
cStreamdevMenuWhatsOn::CurrentChannel()));
|
|
||||||
}
|
|
||||||
|
|
||||||
case kYellow:
|
|
||||||
if (m_Schedules)
|
|
||||||
return AddSubMenu(new cStreamdevMenuWhatsOn(m_Schedules, false,
|
|
||||||
cStreamdevMenuWhatsOn::CurrentChannel()));
|
|
||||||
break;
|
|
||||||
|
|
||||||
case kBlue:
|
|
||||||
if (Count())
|
|
||||||
return Switch();
|
|
||||||
break;
|
|
||||||
|
|
||||||
case kOk:
|
|
||||||
if (Count())
|
|
||||||
return AddSubMenu(new cMenuEvent(
|
|
||||||
((cMenuScheduleItem*)Get(Current()))->event, m_OtherChannel));
|
|
||||||
break;
|
|
||||||
|
|
||||||
default:
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
} else if (!HasSubMenu()) {
|
|
||||||
m_Now = false;
|
|
||||||
m_Next = false;
|
|
||||||
const cEvent *ei
|
|
||||||
= cStreamdevMenuWhatsOn::ScheduleEventInfo();
|
|
||||||
if (ei) {
|
|
||||||
cChannel *channel
|
|
||||||
= Channels.GetByChannelID(ei->ChannelID(), true);
|
|
||||||
if (channel) {
|
|
||||||
PrepareSchedule(channel);
|
|
||||||
if (channel->Number() != cDevice::CurrentChannel()) {
|
|
||||||
m_OtherChannel = channel->Number();
|
|
||||||
SetHelp(Count() ? tr("Record") : NULL, tr("Now"), tr("Next"),
|
|
||||||
tr("Switch"));
|
|
||||||
}
|
|
||||||
Display();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return state;
|
|
||||||
}
|
|
||||||
|
|
||||||
// --- cStreamdevMenuRecordingItem -------------------------------------------
|
|
||||||
|
|
||||||
class cStreamdevMenuRecordingItem: public cOsdItem {
|
|
||||||
private:
|
|
||||||
int m_Total;
|
|
||||||
int m_New;
|
|
||||||
char *m_FileName;
|
|
||||||
char *m_Name;
|
|
||||||
|
|
||||||
public:
|
|
||||||
cStreamdevMenuRecordingItem(cRemoteRecording *Recording, int Level);
|
|
||||||
virtual ~cStreamdevMenuRecordingItem();
|
|
||||||
|
|
||||||
void IncrementCounter(bool New);
|
|
||||||
const char *Name(void) const { return m_Name; }
|
|
||||||
const char *FileName(void) const { return m_FileName; }
|
|
||||||
bool IsDirectory(void) const { return m_Name != NULL; }
|
|
||||||
};
|
|
||||||
|
|
||||||
cStreamdevMenuRecordingItem::cStreamdevMenuRecordingItem(
|
|
||||||
cRemoteRecording *Recording, int Level) {
|
|
||||||
m_FileName = strdup(Recording->Name());
|
|
||||||
m_Name = NULL;
|
|
||||||
m_Total = m_New = 0;
|
|
||||||
SetText(Recording->Title('\t', true, Level));
|
|
||||||
if (*Text() == '\t')
|
|
||||||
m_Name = strdup(Text() + 2);
|
|
||||||
}
|
|
||||||
|
|
||||||
cStreamdevMenuRecordingItem::~cStreamdevMenuRecordingItem() {
|
|
||||||
}
|
|
||||||
|
|
||||||
void cStreamdevMenuRecordingItem::IncrementCounter(bool New) {
|
|
||||||
++m_Total;
|
|
||||||
if (New) ++m_New;
|
|
||||||
char *buffer = NULL;
|
|
||||||
asprintf(&buffer, "%d\t%d\t%s", m_Total, m_New, m_Name);
|
|
||||||
SetText(buffer, false);
|
|
||||||
}
|
|
||||||
|
|
||||||
// --- cStreamdevMenuRecordings ----------------------------------------------
|
|
||||||
|
|
||||||
cRemoteRecordings cStreamdevMenuRecordings::Recordings;
|
|
||||||
int cStreamdevMenuRecordings::HelpKeys = -1;
|
|
||||||
|
|
||||||
cStreamdevMenuRecordings::cStreamdevMenuRecordings(const char *Base, int Level,
|
|
||||||
bool OpenSubMenus):
|
|
||||||
cOsdMenu(Base ? Base : tr("Remote Recordings"), 6, 6) {
|
|
||||||
m_Base = Base ? strdup(Base) : NULL;
|
|
||||||
m_Level = Setup.RecordingDirs ? Level : -1;
|
|
||||||
|
|
||||||
Display(); // this keeps the higher level menus from showing up briefly when
|
|
||||||
// pressing 'Back' during replay
|
|
||||||
|
|
||||||
if (!Base) {
|
|
||||||
STATUS(tr("Fetching recordings..."));
|
|
||||||
FLUSH();
|
|
||||||
}
|
|
||||||
|
|
||||||
if (Base || Recordings.Load()) {
|
|
||||||
cStreamdevMenuRecordingItem *LastItem = NULL;
|
|
||||||
char *LastItemText = NULL;
|
|
||||||
for (cRemoteRecording *r = Recordings.First(); r; r = Recordings.Next(r)) {
|
|
||||||
if (!Base || (strstr(r->Name(), Base) == r->Name()
|
|
||||||
&& r->Name()[strlen(Base)] == '~')) {
|
|
||||||
cStreamdevMenuRecordingItem *Item = new cStreamdevMenuRecordingItem(r,
|
|
||||||
m_Level);
|
|
||||||
if (*Item->Text() && (!LastItem || strcmp(Item->Text(), LastItemText)
|
|
||||||
!= 0)) {
|
|
||||||
Add(Item);
|
|
||||||
LastItem = Item;
|
|
||||||
free(LastItemText);
|
|
||||||
LastItemText = strdup(LastItem->Text());
|
|
||||||
} else
|
|
||||||
delete Item;
|
|
||||||
|
|
||||||
if (LastItem) {
|
|
||||||
if (LastItem->IsDirectory())
|
|
||||||
LastItem->IncrementCounter(r->IsNew());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
free(LastItemText);
|
|
||||||
if (Current() < 0)
|
|
||||||
SetCurrent(First());
|
|
||||||
else if (OpenSubMenus && Open(true))
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
STATUS(NULL);
|
|
||||||
FLUSH();
|
|
||||||
|
|
||||||
SetHelpKeys();
|
|
||||||
}
|
|
||||||
|
|
||||||
cStreamdevMenuRecordings::~cStreamdevMenuRecordings() {
|
|
||||||
if (m_Base != NULL) free(m_Base);
|
|
||||||
HelpKeys = -1;
|
|
||||||
}
|
|
||||||
|
|
||||||
void cStreamdevMenuRecordings::SetHelpKeys(void) {
|
|
||||||
cStreamdevMenuRecordingItem *ri =(cStreamdevMenuRecordingItem*)Get(Current());
|
|
||||||
int NewHelpKeys = HelpKeys;
|
|
||||||
if (ri) {
|
|
||||||
if (ri->IsDirectory())
|
|
||||||
NewHelpKeys = 1;
|
|
||||||
else {
|
|
||||||
NewHelpKeys = 2;
|
|
||||||
cRemoteRecording *recording = GetRecording(ri);
|
|
||||||
if (recording && recording->Summary())
|
|
||||||
NewHelpKeys = 3;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (NewHelpKeys != HelpKeys) {
|
|
||||||
switch (NewHelpKeys) {
|
|
||||||
case 0: SetHelp(NULL); break;
|
|
||||||
case 1: SetHelp(tr("Open")); break;
|
|
||||||
case 2:
|
|
||||||
case 3: SetHelp(NULL, NULL, tr("Delete"), NewHelpKeys == 3 ? tr("Summary") : NULL);
|
|
||||||
//SetHelp(tr("Play"), tr("Rewind"), tr("Delete"), NewHelpKeys == 3 ? tr("Summary") : NULL); XXX
|
|
||||||
}
|
|
||||||
HelpKeys = NewHelpKeys;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
cRemoteRecording *cStreamdevMenuRecordings::GetRecording(
|
|
||||||
cStreamdevMenuRecordingItem *Item) {
|
|
||||||
Dprintf("looking for %s\n", Item->FileName());
|
|
||||||
cRemoteRecording *recording = Recordings.GetByName(Item->FileName());
|
|
||||||
if (!recording)
|
|
||||||
ERROR(tr("Error while accessing recording!"));
|
|
||||||
return recording;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool cStreamdevMenuRecordings::Open(bool OpenSubMenus) {
|
|
||||||
cStreamdevMenuRecordingItem *ri
|
|
||||||
= (cStreamdevMenuRecordingItem*)Get(Current());
|
|
||||||
|
|
||||||
if (ri && ri->IsDirectory()) {
|
|
||||||
const char *t = ri->Name();
|
|
||||||
char *buffer = NULL;
|
|
||||||
if (m_Base) {
|
|
||||||
asprintf(&buffer, "%s~%s", m_Base, t);
|
|
||||||
t = buffer;
|
|
||||||
}
|
|
||||||
AddSubMenu(new cStreamdevMenuRecordings(t, m_Level + 1, OpenSubMenus));
|
|
||||||
if (buffer != NULL) free(buffer);
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
eOSState cStreamdevMenuRecordings::Select(void) {
|
|
||||||
cStreamdevMenuRecordingItem *ri
|
|
||||||
= (cStreamdevMenuRecordingItem*)Get(Current());
|
|
||||||
|
|
||||||
if (ri) {
|
|
||||||
if (ri->IsDirectory())
|
|
||||||
Open();
|
|
||||||
/*else {
|
|
||||||
cControl::Launch(new cStreamdevPlayerControl(ri->FileName()));
|
|
||||||
return osEnd;
|
|
||||||
} XXX */
|
|
||||||
}
|
|
||||||
return osContinue;
|
|
||||||
}
|
|
||||||
|
|
||||||
eOSState cStreamdevMenuRecordings::Delete(void) {
|
|
||||||
if (HasSubMenu() || Count() == 0)
|
|
||||||
return osContinue;
|
|
||||||
cStreamdevMenuRecordingItem *ri
|
|
||||||
= (cStreamdevMenuRecordingItem*)Get(Current());
|
|
||||||
if (ri && !ri->IsDirectory()) {
|
|
||||||
if (Interface->Confirm(tr("Delete recording?"))) {
|
|
||||||
cRemoteRecording *recording = GetRecording(ri);
|
|
||||||
if (recording) {
|
|
||||||
if (ClientSocket.DeleteRecording(recording)) {
|
|
||||||
cOsdMenu::Del(Current());
|
|
||||||
Recordings.Del(recording);
|
|
||||||
Display();
|
|
||||||
if (!Count())
|
|
||||||
return osBack;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return osContinue;
|
|
||||||
}
|
|
||||||
|
|
||||||
eOSState cStreamdevMenuRecordings::Summary(void) {
|
|
||||||
if (HasSubMenu() || Count() == 0)
|
|
||||||
return osContinue;
|
|
||||||
cStreamdevMenuRecordingItem *ri=(cStreamdevMenuRecordingItem *)Get(Current());
|
|
||||||
if (ri && !ri->IsDirectory()) {
|
|
||||||
cRemoteRecording *recording = GetRecording(ri);
|
|
||||||
if (recording && recording->Summary() && *recording->Summary())
|
|
||||||
return AddSubMenu(new cMenuText(tr("Summary"), recording->Summary()));
|
|
||||||
}
|
|
||||||
return osContinue;
|
|
||||||
}
|
|
||||||
|
|
||||||
eOSState cStreamdevMenuRecordings::ProcessKey(eKeys Key) {
|
|
||||||
bool HadSubMenu = HasSubMenu();
|
|
||||||
eOSState state = cOsdMenu::ProcessKey(Key);
|
|
||||||
|
|
||||||
if (state == osUnknown) {
|
|
||||||
switch (Key) {
|
|
||||||
case kOk:
|
|
||||||
case kRed: return Select();
|
|
||||||
case kYellow: return Delete();
|
|
||||||
case kBlue: return Summary();
|
|
||||||
default: break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (Key == kYellow && HadSubMenu && !HasSubMenu()) {
|
|
||||||
cOsdMenu::Del(Current());
|
|
||||||
if (!Count())
|
|
||||||
return osBack;
|
|
||||||
Display();
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!HasSubMenu() && Key != kNone)
|
|
||||||
SetHelpKeys();
|
|
||||||
return state;
|
|
||||||
}
|
|
||||||
|
|
||||||
// --- cStreamdevMenuTimerItem -----------------------------------------------
|
|
||||||
|
|
||||||
class cStreamdevMenuTimerItem: public cOsdItem {
|
|
||||||
private:
|
|
||||||
cRemoteTimer *m_Timer;
|
|
||||||
|
|
||||||
public:
|
|
||||||
cStreamdevMenuTimerItem(cRemoteTimer *Timer);
|
|
||||||
virtual ~cStreamdevMenuTimerItem();
|
|
||||||
|
|
||||||
virtual void Set(void);
|
|
||||||
|
|
||||||
cRemoteTimer *Timer(void) const { return m_Timer; }
|
|
||||||
};
|
|
||||||
|
|
||||||
cStreamdevMenuTimerItem::cStreamdevMenuTimerItem(cRemoteTimer *Timer) {
|
|
||||||
m_Timer = Timer;
|
|
||||||
Set();
|
|
||||||
}
|
|
||||||
|
|
||||||
cStreamdevMenuTimerItem::~cStreamdevMenuTimerItem() {
|
|
||||||
}
|
|
||||||
|
|
||||||
void cStreamdevMenuTimerItem::Set(void) {
|
|
||||||
char *buffer = NULL;
|
|
||||||
asprintf(&buffer, "%c\t%d\t%s\t%02d:%02d\t%02d:%02d\t%s",
|
|
||||||
!m_Timer->Active() ? ' ' :
|
|
||||||
m_Timer->FirstDay() ? '!' :
|
|
||||||
/*m_Timer->Recording() ? '#' :*/ '>',
|
|
||||||
m_Timer->Channel()->Number(),
|
|
||||||
m_Timer->PrintDay(m_Timer->Day()),
|
|
||||||
m_Timer->Start() / 100,
|
|
||||||
m_Timer->Start() % 100,
|
|
||||||
m_Timer->Stop() / 100,
|
|
||||||
m_Timer->Stop() % 100,
|
|
||||||
m_Timer->File());
|
|
||||||
SetText(buffer, false);
|
|
||||||
}
|
|
||||||
|
|
||||||
// --- cStreamdevMenuTimers --------------------------------------------------
|
|
||||||
|
|
||||||
cStreamdevMenuTimers::cStreamdevMenuTimers(void):
|
|
||||||
cOsdMenu(tr("Remote Timers"), 2, CHNUMWIDTH, 10, 6, 6) {
|
|
||||||
Refresh();
|
|
||||||
SetHelp(tr("Edit"), tr("New"), tr("Delete"), tr("On/Off"));
|
|
||||||
}
|
|
||||||
|
|
||||||
cStreamdevMenuTimers::~cStreamdevMenuTimers() {
|
|
||||||
}
|
|
||||||
|
|
||||||
eOSState cStreamdevMenuTimers::ProcessKey(eKeys Key) {
|
|
||||||
int timerNum = HasSubMenu() ? Count() : -1;
|
|
||||||
eOSState state = cOsdMenu::ProcessKey(Key);
|
|
||||||
|
|
||||||
if (state == osUnknown) {
|
|
||||||
switch (Key) {
|
|
||||||
case kOk: return Summary();
|
|
||||||
case kRed: return Edit();
|
|
||||||
case kGreen: return New();
|
|
||||||
case kYellow: return Delete();
|
|
||||||
case kBlue: OnOff(); break;
|
|
||||||
default: break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (timerNum >= 0 && !HasSubMenu()) {
|
|
||||||
Refresh();
|
|
||||||
Display();
|
|
||||||
}
|
|
||||||
return state;
|
|
||||||
}
|
|
||||||
|
|
||||||
eOSState cStreamdevMenuTimers::Edit(void) {
|
|
||||||
if (HasSubMenu() || Count() == 0)
|
|
||||||
return osContinue;
|
|
||||||
isyslog("Streamdev: Editing remote timer %d", CurrentTimer()->Index() + 1);
|
|
||||||
return AddSubMenu(new cStreamdevMenuEditTimer(CurrentTimer()));
|
|
||||||
}
|
|
||||||
|
|
||||||
eOSState cStreamdevMenuTimers::New(void) {
|
|
||||||
if (HasSubMenu())
|
|
||||||
return osContinue;
|
|
||||||
return AddSubMenu(new cStreamdevMenuEditTimer(new cRemoteTimer, true));
|
|
||||||
}
|
|
||||||
|
|
||||||
eOSState cStreamdevMenuTimers::Delete(void) {
|
|
||||||
cRemoteTimer *ti = CurrentTimer();
|
|
||||||
if (ti) {
|
|
||||||
if (Interface->Confirm(tr("Delete timer?"))) {
|
|
||||||
int idx = ti->Index();
|
|
||||||
if (ClientSocket.DeleteTimer(ti)) {
|
|
||||||
RemoteTimers.Del(ti);
|
|
||||||
cOsdMenu::Del(Current());
|
|
||||||
isyslog("Streamdev: Remote timer %d deleted", idx + 1);
|
|
||||||
}
|
|
||||||
Refresh();
|
|
||||||
Display();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return osContinue;
|
|
||||||
}
|
|
||||||
|
|
||||||
eOSState cStreamdevMenuTimers::OnOff(void) {
|
|
||||||
cRemoteTimer *timer = CurrentTimer();
|
|
||||||
if (timer) {
|
|
||||||
cRemoteTimer data = *timer;
|
|
||||||
data.OnOff();
|
|
||||||
if (data.FirstDay())
|
|
||||||
isyslog("Streamdev: Remote timer %d first day set to %s",
|
|
||||||
data.Index() + 1, data.PrintFirstDay());
|
|
||||||
else
|
|
||||||
isyslog("Streamdev: Remote timer %d %sactivated", data.Index() + 1,
|
|
||||||
data.Active() ? "" : "de");
|
|
||||||
|
|
||||||
if (ClientSocket.SaveTimer(timer, data)) {
|
|
||||||
*timer = data;
|
|
||||||
RefreshCurrent();
|
|
||||||
DisplayCurrent(true);
|
|
||||||
} else {
|
|
||||||
Refresh();
|
|
||||||
Display();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return osContinue;
|
|
||||||
}
|
|
||||||
|
|
||||||
eOSState cStreamdevMenuTimers::Summary(void) {
|
|
||||||
if (HasSubMenu() || Count() == 0)
|
|
||||||
return osContinue;
|
|
||||||
|
|
||||||
cRemoteTimer *ti = CurrentTimer();
|
|
||||||
if (ti && ti->Summary() != "")
|
|
||||||
return AddSubMenu(new cMenuText(tr("Summary"), ti->Summary().c_str()));
|
|
||||||
|
|
||||||
return osContinue;
|
|
||||||
}
|
|
||||||
|
|
||||||
cRemoteTimer *cStreamdevMenuTimers::CurrentTimer(void) {
|
|
||||||
cStreamdevMenuTimerItem *item = (cStreamdevMenuTimerItem*)Get(Current());
|
|
||||||
return item ? item->Timer() : NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
void cStreamdevMenuTimers::Refresh(void) {
|
|
||||||
Clear();
|
|
||||||
if (RemoteTimers.Load()) {
|
|
||||||
for (cRemoteTimer *t = RemoteTimers.First(); t; t = RemoteTimers.Next(t)) {
|
|
||||||
Add(new cStreamdevMenuTimerItem(t));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
132
client/menu.h
132
client/menu.h
@ -1,132 +0,0 @@
|
|||||||
/*
|
|
||||||
* $Id: menu.h,v 1.2 2008/04/07 14:27:28 schmirl Exp $
|
|
||||||
*/
|
|
||||||
|
|
||||||
#ifndef VDR_STREAMDEV_MENU_H
|
|
||||||
#define VDR_STREAMDEV_MENU_H
|
|
||||||
|
|
||||||
#include <vdr/osd.h>
|
|
||||||
|
|
||||||
#include "client/remote.h"
|
|
||||||
|
|
||||||
class cStreamdevMenuRecordingItem;
|
|
||||||
|
|
||||||
// --- cStreamdevMenu --------------------------------------------------------
|
|
||||||
|
|
||||||
class cStreamdevMenu: public cOsdMenu {
|
|
||||||
private:
|
|
||||||
enum eSubmenus {
|
|
||||||
sub_Start = os_User,
|
|
||||||
subSchedule,
|
|
||||||
subTimers,
|
|
||||||
subRecordings,
|
|
||||||
subSuspend,
|
|
||||||
subSyncEPG
|
|
||||||
};
|
|
||||||
|
|
||||||
protected:
|
|
||||||
void SuspendServer(void);
|
|
||||||
|
|
||||||
public:
|
|
||||||
cStreamdevMenu(void);
|
|
||||||
virtual ~cStreamdevMenu(void);
|
|
||||||
|
|
||||||
virtual eOSState ProcessKey(eKeys Key);
|
|
||||||
};
|
|
||||||
|
|
||||||
// --- cStreamdevMenuSchedule ------------------------------------------------
|
|
||||||
|
|
||||||
class cStreamdevMenuSchedule: public cOsdMenu {
|
|
||||||
private:
|
|
||||||
bool m_Now;
|
|
||||||
bool m_Next;
|
|
||||||
int m_OtherChannel;
|
|
||||||
const cSchedules *m_Schedules;
|
|
||||||
cSchedulesLock m_Lock;
|
|
||||||
|
|
||||||
protected:
|
|
||||||
void PrepareSchedule(cChannel *Channel);
|
|
||||||
|
|
||||||
eOSState Switch(void);
|
|
||||||
eOSState Record(void);
|
|
||||||
|
|
||||||
public:
|
|
||||||
cStreamdevMenuSchedule(void);
|
|
||||||
virtual ~cStreamdevMenuSchedule(void);
|
|
||||||
|
|
||||||
virtual eOSState ProcessKey(eKeys Key);
|
|
||||||
};
|
|
||||||
|
|
||||||
// --- cStreamdevMenuWhatsOn -------------------------------------------------
|
|
||||||
|
|
||||||
class cStreamdevMenuWhatsOn: public cOsdMenu {
|
|
||||||
private:
|
|
||||||
static int m_CurrentChannel;
|
|
||||||
static const cEvent *m_ScheduleEventInfo;
|
|
||||||
|
|
||||||
protected:
|
|
||||||
eOSState Switch(void);
|
|
||||||
eOSState Record(void);
|
|
||||||
|
|
||||||
public:
|
|
||||||
cStreamdevMenuWhatsOn(const cSchedules *Schedules, bool Now,
|
|
||||||
int CurrentChannel);
|
|
||||||
|
|
||||||
static int CurrentChannel(void) { return m_CurrentChannel; }
|
|
||||||
static void SetCurrentChannel(int Channel) { m_CurrentChannel = Channel; }
|
|
||||||
static const cEvent *ScheduleEventInfo(void);
|
|
||||||
|
|
||||||
virtual eOSState ProcessKey(eKeys Key);
|
|
||||||
};
|
|
||||||
|
|
||||||
// --- cStreamdevMenuRecordings ----------------------------------------------
|
|
||||||
|
|
||||||
class cStreamdevMenuRecordings: public cOsdMenu {
|
|
||||||
private:
|
|
||||||
char *m_Base;
|
|
||||||
int m_Level;
|
|
||||||
|
|
||||||
static int HelpKeys;
|
|
||||||
static cRemoteRecordings Recordings;
|
|
||||||
|
|
||||||
protected:
|
|
||||||
bool Open(bool OpenSubMenus = false);
|
|
||||||
void SetHelpKeys();
|
|
||||||
cRemoteRecording *cStreamdevMenuRecordings::GetRecording(
|
|
||||||
cStreamdevMenuRecordingItem *Item);
|
|
||||||
|
|
||||||
eOSState Select(void);
|
|
||||||
eOSState Delete(void);
|
|
||||||
eOSState Summary(void);
|
|
||||||
|
|
||||||
public:
|
|
||||||
cStreamdevMenuRecordings(const char *Base = NULL, int Level = 0,
|
|
||||||
bool OpenSubMenus = false);
|
|
||||||
virtual ~cStreamdevMenuRecordings();
|
|
||||||
|
|
||||||
virtual eOSState ProcessKey(eKeys Key);
|
|
||||||
};
|
|
||||||
|
|
||||||
// --- cStreamdevMenuTimers --------------------------------------------------
|
|
||||||
|
|
||||||
class cStreamdevMenuTimers: public cOsdMenu {
|
|
||||||
protected:
|
|
||||||
eOSState Edit(void);
|
|
||||||
eOSState New(void);
|
|
||||||
eOSState Delete(void);
|
|
||||||
eOSState OnOff(void);
|
|
||||||
eOSState Summary(void);
|
|
||||||
|
|
||||||
cRemoteTimer *CurrentTimer(void);
|
|
||||||
|
|
||||||
void Refresh(void);
|
|
||||||
|
|
||||||
public:
|
|
||||||
cStreamdevMenuTimers(void);
|
|
||||||
virtual ~cStreamdevMenuTimers();
|
|
||||||
|
|
||||||
virtual eOSState ProcessKey(eKeys Key);
|
|
||||||
};
|
|
||||||
|
|
||||||
#endif // VDR_STREAMDEV_MENU_H
|
|
||||||
|
|
465
client/remote.c
465
client/remote.c
@ -1,465 +0,0 @@
|
|||||||
/*
|
|
||||||
* $Id: remote.c,v 1.5 2008/04/07 14:27:28 schmirl Exp $
|
|
||||||
*/
|
|
||||||
|
|
||||||
#include <ctype.h>
|
|
||||||
|
|
||||||
#include "client/remote.h"
|
|
||||||
#include "client/device.h"
|
|
||||||
#include "common.h"
|
|
||||||
|
|
||||||
cRemoteTimers RemoteTimers;
|
|
||||||
|
|
||||||
// --- cRemoteRecording ------------------------------------------------------
|
|
||||||
|
|
||||||
cRemoteRecording::cRemoteRecording(const char *Text) {
|
|
||||||
m_IsValid = false;
|
|
||||||
m_Index = -1;
|
|
||||||
m_IsNew = false;
|
|
||||||
m_TitleBuffer = NULL;
|
|
||||||
|
|
||||||
char *ptr;
|
|
||||||
char *timestr;
|
|
||||||
int idx;
|
|
||||||
|
|
||||||
Dprintf("text: %s\n", Text);
|
|
||||||
|
|
||||||
m_Index = strtoul(Text, &ptr, 10);
|
|
||||||
Dprintf("index: %d\n", m_Index);
|
|
||||||
if (*ptr == '\0' || *++ptr == '\0' ) return;
|
|
||||||
timestr = ptr;
|
|
||||||
while (*ptr != '\0' && !isspace(*ptr)) ++ptr;
|
|
||||||
if (*ptr == '\0' || *++ptr == '\0') return;
|
|
||||||
while (*ptr != '\0' && *ptr != '*' && !isspace(*ptr)) ++ptr;
|
|
||||||
if (*ptr == '*') m_IsNew = true;
|
|
||||||
Dprintf("new: %d\n", m_IsNew);
|
|
||||||
*(ptr++) = '\0';
|
|
||||||
m_StartTime = timestr;
|
|
||||||
idx = -1;
|
|
||||||
while ((idx = m_StartTime.find(' ', idx + 1)) != -1) m_StartTime[idx] = '\t';
|
|
||||||
Dprintf("m_Start: %s\n", m_StartTime.c_str());
|
|
||||||
if (*ptr == 0) return;
|
|
||||||
if (isspace(*ptr)) ++ptr;
|
|
||||||
if (*ptr == 0) return;
|
|
||||||
m_Name = ptr;
|
|
||||||
Dprintf("file: %s\n", m_Name.c_str());
|
|
||||||
m_IsValid = true;
|
|
||||||
}
|
|
||||||
|
|
||||||
cRemoteRecording::~cRemoteRecording(void) {
|
|
||||||
}
|
|
||||||
|
|
||||||
bool cRemoteRecording::operator==(const cRemoteRecording &Recording) {
|
|
||||||
return m_IsValid == Recording.m_IsValid
|
|
||||||
&& m_Index == Recording.m_Index
|
|
||||||
&& m_StartTime == Recording.m_StartTime
|
|
||||||
&& m_Name == Recording.m_Name;
|
|
||||||
}
|
|
||||||
|
|
||||||
void cRemoteRecording::ParseInfo(const char *Text) {
|
|
||||||
m_Summary = strreplace(strdup(Text), '|', '\n');
|
|
||||||
}
|
|
||||||
|
|
||||||
const char *cRemoteRecording::Title(char Delimiter, bool NewIndicator,
|
|
||||||
int Level) {
|
|
||||||
char New = NewIndicator && IsNew() ? '*' : ' ';
|
|
||||||
|
|
||||||
if (m_TitleBuffer != NULL) {
|
|
||||||
free(m_TitleBuffer);
|
|
||||||
m_TitleBuffer = NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (Level < 0 || Level == HierarchyLevels()) {
|
|
||||||
char *s;
|
|
||||||
const char *t;
|
|
||||||
if (Level > 0 && (t = strrchr(m_Name.c_str(), '~')) != NULL)
|
|
||||||
t++;
|
|
||||||
else
|
|
||||||
t = m_Name.c_str();
|
|
||||||
|
|
||||||
asprintf(&m_TitleBuffer, "%s%c%c%s", m_StartTime.c_str(), New, Delimiter, t);
|
|
||||||
// let's not display a trailing '~':
|
|
||||||
stripspace(m_TitleBuffer);
|
|
||||||
s = &m_TitleBuffer[strlen(m_TitleBuffer) - 1];
|
|
||||||
if (*s == '~')
|
|
||||||
*s = 0;
|
|
||||||
} else if (Level < HierarchyLevels()) {
|
|
||||||
const char *s = m_Name.c_str();
|
|
||||||
const char *p = s;
|
|
||||||
while (*++s) {
|
|
||||||
if (*s == '~') {
|
|
||||||
if (Level--)
|
|
||||||
p = s + 1;
|
|
||||||
else
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
m_TitleBuffer = MALLOC(char, s - p + 3);
|
|
||||||
*m_TitleBuffer = Delimiter;
|
|
||||||
*(m_TitleBuffer + 1) = Delimiter;
|
|
||||||
strn0cpy(m_TitleBuffer + 2, p, s - p + 1);
|
|
||||||
} else
|
|
||||||
return "";
|
|
||||||
return m_TitleBuffer;
|
|
||||||
}
|
|
||||||
|
|
||||||
int cRemoteRecording::HierarchyLevels(void)
|
|
||||||
{
|
|
||||||
const char *s = m_Name.c_str();
|
|
||||||
int level = 0;
|
|
||||||
while (*++s) {
|
|
||||||
if (*s == '~') ++level;
|
|
||||||
}
|
|
||||||
return level;
|
|
||||||
}
|
|
||||||
|
|
||||||
// --- cRemoteRecordings -----------------------------------------------------
|
|
||||||
|
|
||||||
bool cRemoteRecordings::Load(void) {
|
|
||||||
Clear();
|
|
||||||
return ClientSocket.LoadRecordings(*this);
|
|
||||||
}
|
|
||||||
|
|
||||||
cRemoteRecording *cRemoteRecordings::GetByName(const char *Name) {
|
|
||||||
for (cRemoteRecording *r = First(); r; r = Next(r))
|
|
||||||
if (strcmp(r->Name(), Name) == 0)
|
|
||||||
return r;
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
// --- cRemoteTimer ----------------------------------------------------------
|
|
||||||
|
|
||||||
cRemoteTimer::cRemoteTimer(const char *Text) {
|
|
||||||
m_IsValid = false;
|
|
||||||
m_Index = -1;
|
|
||||||
m_Active = -1;
|
|
||||||
m_Day = -1;
|
|
||||||
m_Start = -1;
|
|
||||||
m_Stop = -1;
|
|
||||||
m_StartTime = 0;
|
|
||||||
m_StopTime = 0;
|
|
||||||
m_Priority = -1;
|
|
||||||
m_Lifetime = -1;
|
|
||||||
m_File[0] = '\0';
|
|
||||||
m_FirstDay = 0;
|
|
||||||
m_Buffer = NULL;
|
|
||||||
m_Channel = NULL;
|
|
||||||
|
|
||||||
char *tmpbuf;
|
|
||||||
char *ptr;
|
|
||||||
|
|
||||||
Dprintf("text: %s\n", Text);
|
|
||||||
|
|
||||||
m_Index = strtoul(Text, &ptr, 10);
|
|
||||||
Dprintf("index: %d\n", m_Index);
|
|
||||||
if (*ptr == '\0' || *++ptr == '\0') return;
|
|
||||||
m_Active = strtoul(ptr, &ptr, 10);
|
|
||||||
Dprintf("m_Active: %d\n", m_Active);
|
|
||||||
if (*ptr == '\0' || *++ptr == '\0') return;
|
|
||||||
|
|
||||||
tmpbuf = ptr;
|
|
||||||
while (*ptr != '\0' && *ptr != ':') ++ptr;
|
|
||||||
if (*ptr == '\0') return;
|
|
||||||
*(ptr++)= '\0';
|
|
||||||
if (isnumber(tmpbuf))
|
|
||||||
m_Channel = Channels.GetByNumber(strtoul(tmpbuf, NULL, 10));
|
|
||||||
else
|
|
||||||
m_Channel = Channels.GetByChannelID(tChannelID::FromString(tmpbuf));
|
|
||||||
Dprintf("channel no.: %d\n", m_Channel->Number());
|
|
||||||
|
|
||||||
tmpbuf = ptr;
|
|
||||||
while (*ptr != '\0' && *ptr != ':') ++ptr;
|
|
||||||
if (*ptr == '\0') return;
|
|
||||||
*(ptr++) = '\0';
|
|
||||||
m_Day = ParseDay(tmpbuf, &m_FirstDay);
|
|
||||||
Dprintf("Day: %d\n", m_Day);
|
|
||||||
m_Start = strtoul(ptr, &ptr, 10);
|
|
||||||
Dprintf("Start: %d\n", m_Start);
|
|
||||||
if (*ptr == '\0' || *++ptr == '\0') return;
|
|
||||||
m_Stop = strtoul(ptr, &ptr, 10);
|
|
||||||
Dprintf("Stop: %d\n", m_Stop);
|
|
||||||
if (*ptr == '\0' || *++ptr == '\0') return;
|
|
||||||
m_Priority = strtoul(ptr, &ptr, 10);
|
|
||||||
Dprintf("Prio: %d\n", m_Priority);
|
|
||||||
if (*ptr == '\0' || *++ptr == '\0') return;
|
|
||||||
m_Lifetime = strtoul(ptr, &ptr, 10);
|
|
||||||
Dprintf("Lifetime: %d\n", m_Lifetime);
|
|
||||||
if (*ptr == '\0' || *++ptr == '\0') return;
|
|
||||||
tmpbuf = ptr;
|
|
||||||
while (*ptr != '\0' && *ptr != ':') ++ptr;
|
|
||||||
if (*ptr == '\0') return;
|
|
||||||
*(ptr++) = '\0';
|
|
||||||
strncpy(m_File, tmpbuf, MaxFileName);
|
|
||||||
Dprintf("file: %s\n", m_File);
|
|
||||||
if (*ptr != '\0') m_Summary = ptr;
|
|
||||||
Dprintf("summary: %s\n", m_Summary.c_str());
|
|
||||||
m_IsValid = true;
|
|
||||||
}
|
|
||||||
|
|
||||||
cRemoteTimer::cRemoteTimer(const cEvent *Event) {
|
|
||||||
time_t tstart = Event->StartTime();
|
|
||||||
time_t tstop = tstart + Event->Duration() + Setup.MarginStop * 60;
|
|
||||||
tstart -= Setup.MarginStart * 60;
|
|
||||||
struct tm tm_r;
|
|
||||||
struct tm *time = localtime_r(&tstart, &tm_r);
|
|
||||||
const char *title = Event->Title();
|
|
||||||
cChannel *channel = Channels.GetByChannelID(Event->ChannelID(), true);
|
|
||||||
|
|
||||||
m_IsValid = true;
|
|
||||||
m_Index = -1;
|
|
||||||
m_Active = true;
|
|
||||||
m_Day = time->tm_mday;
|
|
||||||
m_Start = time->tm_hour * 100 + time->tm_min;
|
|
||||||
time = localtime_r(&tstop, &tm_r);
|
|
||||||
m_Stop = time->tm_hour * 100 + time->tm_min;
|
|
||||||
m_StartTime = 0;
|
|
||||||
m_StopTime = 0;
|
|
||||||
if (m_Stop >= 2400) m_Stop -= 2400;
|
|
||||||
m_Priority = Setup.DefaultPriority;
|
|
||||||
m_Lifetime = Setup.DefaultLifetime;
|
|
||||||
m_File[0] = '\0';
|
|
||||||
if (!isempty(title))
|
|
||||||
strn0cpy(m_File, title, sizeof(m_File));
|
|
||||||
m_FirstDay = 0;
|
|
||||||
m_Channel = channel;
|
|
||||||
}
|
|
||||||
|
|
||||||
cRemoteTimer::cRemoteTimer(void) {
|
|
||||||
time_t t = time(NULL);
|
|
||||||
struct tm tm_r;
|
|
||||||
struct tm *now = localtime_r(&t, &tm_r);
|
|
||||||
|
|
||||||
m_IsValid = true;
|
|
||||||
m_Index = -1;
|
|
||||||
m_Active = -1;
|
|
||||||
m_Day = now->tm_mday;
|
|
||||||
m_Start = now->tm_hour * 100 + now->tm_min;
|
|
||||||
m_Stop = now->tm_hour * 60 + now->tm_min + Setup.InstantRecordTime;
|
|
||||||
m_Stop = (m_Stop / 60) * 100 + (m_Stop % 60);
|
|
||||||
if (m_Stop >= 2400) m_Stop -= 2400;
|
|
||||||
m_StartTime = 0;
|
|
||||||
m_StopTime = 0;
|
|
||||||
m_Priority = Setup.DefaultPriority;
|
|
||||||
m_Lifetime = Setup.DefaultLifetime;
|
|
||||||
m_File[0] = '\0';
|
|
||||||
m_FirstDay = 0;
|
|
||||||
m_Buffer = NULL;
|
|
||||||
m_Channel = Channels.GetByNumber(cDevice::CurrentChannel());
|
|
||||||
}
|
|
||||||
|
|
||||||
cRemoteTimer::~cRemoteTimer() {
|
|
||||||
if (m_Buffer != NULL) free(m_Buffer);
|
|
||||||
}
|
|
||||||
|
|
||||||
cRemoteTimer &cRemoteTimer::operator=(const cRemoteTimer &Timer) {
|
|
||||||
Dprintf("\n\n\n\nOPÜERATHVBDÖLJVG\n\n\n");
|
|
||||||
m_IsValid = Timer.m_IsValid;
|
|
||||||
m_Index = Timer.m_Index;
|
|
||||||
m_Active = Timer.m_Active;
|
|
||||||
m_Day = Timer.m_Day;
|
|
||||||
m_Start = Timer.m_Start;
|
|
||||||
m_Stop = Timer.m_Stop;
|
|
||||||
m_Priority = Timer.m_Priority;
|
|
||||||
m_Lifetime = Timer.m_Lifetime;
|
|
||||||
m_FirstDay = Timer.m_FirstDay;
|
|
||||||
m_Channel = Timer.m_Channel;
|
|
||||||
m_Summary = Timer.m_Summary;
|
|
||||||
return *this;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool cRemoteTimer::operator==(const cRemoteTimer &Timer) {
|
|
||||||
return m_IsValid == Timer.m_IsValid
|
|
||||||
&& m_Index == Timer.m_Index
|
|
||||||
&& m_Active == Timer.m_Active
|
|
||||||
&& m_Day == Timer.m_Day
|
|
||||||
&& m_Start == Timer.m_Start
|
|
||||||
&& m_Stop == Timer.m_Stop
|
|
||||||
&& m_Priority == Timer.m_Priority
|
|
||||||
&& m_Lifetime == Timer.m_Lifetime
|
|
||||||
&& m_FirstDay == Timer.m_FirstDay
|
|
||||||
&& m_Channel == Timer.m_Channel
|
|
||||||
&& strcmp(m_File, Timer.m_File) == 0
|
|
||||||
&& m_Summary == Timer.m_Summary;
|
|
||||||
}
|
|
||||||
|
|
||||||
int cRemoteTimer::ParseDay(const char *s, time_t *FirstDay) {
|
|
||||||
char *tail;
|
|
||||||
int d = strtol(s, &tail, 10);
|
|
||||||
if (FirstDay)
|
|
||||||
*FirstDay = 0;
|
|
||||||
if (tail && *tail) {
|
|
||||||
d = 0;
|
|
||||||
if (tail == s) {
|
|
||||||
const char *first = strchr(s, '@');
|
|
||||||
int l = first ? first - s : strlen(s);
|
|
||||||
if (l == 7) {
|
|
||||||
for (const char *p = s + 6; p >= s; p--) {
|
|
||||||
d <<= 1;
|
|
||||||
d |= (*p != '-');
|
|
||||||
}
|
|
||||||
d |= 0x80000000;
|
|
||||||
}
|
|
||||||
if (FirstDay && first) {
|
|
||||||
++first;
|
|
||||||
if (strlen(first) == 10) {
|
|
||||||
struct tm tm_r;
|
|
||||||
if (3 == sscanf(first, "%d-%d-%d", &tm_r.tm_year, &tm_r.tm_mon, &tm_r.tm_mday)) {
|
|
||||||
tm_r.tm_year -= 1900;
|
|
||||||
tm_r.tm_mon--;
|
|
||||||
tm_r.tm_hour = tm_r.tm_min = tm_r.tm_sec = 0;
|
|
||||||
tm_r.tm_isdst = -1; // makes sure mktime() will determine the correct DST setting
|
|
||||||
*FirstDay = mktime(&tm_r);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else
|
|
||||||
d = 0;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else if (d < 1 || d > 31)
|
|
||||||
d = 0;
|
|
||||||
return d;
|
|
||||||
}
|
|
||||||
|
|
||||||
const char *cRemoteTimer::PrintDay(int d, time_t FirstDay) {
|
|
||||||
#define DAYBUFFERSIZE 32
|
|
||||||
static char buffer[DAYBUFFERSIZE];
|
|
||||||
if ((d & 0x80000000) != 0) {
|
|
||||||
char *b = buffer;
|
|
||||||
const char *w = tr("MTWTFSS");
|
|
||||||
while (*w) {
|
|
||||||
*b++ = (d & 1) ? *w : '-';
|
|
||||||
d >>= 1;
|
|
||||||
w++;
|
|
||||||
}
|
|
||||||
if (FirstDay) {
|
|
||||||
struct tm tm_r;
|
|
||||||
localtime_r(&FirstDay, &tm_r);
|
|
||||||
b += strftime(b, DAYBUFFERSIZE - (b - buffer), "@%Y-%m-%d", &tm_r);
|
|
||||||
}
|
|
||||||
*b = 0;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
sprintf(buffer, "%d", d);
|
|
||||||
return buffer;
|
|
||||||
}
|
|
||||||
|
|
||||||
const char *cRemoteTimer::PrintFirstDay(void) const {
|
|
||||||
if (m_FirstDay) {
|
|
||||||
const char *s = PrintDay(m_Day, m_FirstDay);
|
|
||||||
if (strlen(s) == 18)
|
|
||||||
return s + 8;
|
|
||||||
}
|
|
||||||
return ""; // not NULL, so the caller can always use the result
|
|
||||||
}
|
|
||||||
|
|
||||||
void cRemoteTimer::OnOff(void) {
|
|
||||||
if (IsSingleEvent())
|
|
||||||
m_Active = !m_Active;
|
|
||||||
else if (m_FirstDay) {
|
|
||||||
m_FirstDay = 0;
|
|
||||||
m_Active = false;
|
|
||||||
}
|
|
||||||
else if (m_Active)
|
|
||||||
Skip();
|
|
||||||
else
|
|
||||||
m_Active = true;
|
|
||||||
Matches(); // refresh m_Start and end time
|
|
||||||
}
|
|
||||||
|
|
||||||
time_t cRemoteTimer::SetTime(time_t t, int SecondsFromMidnight) {
|
|
||||||
struct tm tm_r;
|
|
||||||
tm tm = *localtime_r(&t, &tm_r);
|
|
||||||
tm.tm_hour = SecondsFromMidnight / 3600;
|
|
||||||
tm.tm_min = (SecondsFromMidnight % 3600) / 60;
|
|
||||||
tm.tm_sec = SecondsFromMidnight % 60;
|
|
||||||
tm.tm_isdst = -1; // makes sure mktime() will determine the correct DST setting
|
|
||||||
return mktime(&tm);
|
|
||||||
}
|
|
||||||
|
|
||||||
bool cRemoteTimer::Matches(time_t t) {
|
|
||||||
m_StartTime = m_StopTime = 0;
|
|
||||||
if (t == 0)
|
|
||||||
t = time(NULL);
|
|
||||||
|
|
||||||
int begin = TimeToInt(m_Start); // seconds from midnight
|
|
||||||
int length = TimeToInt(m_Stop) - begin;
|
|
||||||
if (length < 0)
|
|
||||||
length += SECSINDAY;
|
|
||||||
|
|
||||||
int DaysToCheck = IsSingleEvent() ? 61 : 7; // 61 to handle months with 31/30/31
|
|
||||||
for (int i = -1; i <= DaysToCheck; i++) {
|
|
||||||
time_t t0 = IncDay(t, i);
|
|
||||||
if (DayMatches(t0)) {
|
|
||||||
time_t a = SetTime(t0, begin);
|
|
||||||
time_t b = a + length;
|
|
||||||
if ((!m_FirstDay || a >= m_FirstDay) && t <= b) {
|
|
||||||
m_StartTime = a;
|
|
||||||
m_StopTime = b;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (!m_StartTime)
|
|
||||||
m_StartTime = m_FirstDay; // just to have something that's more than a week in the future
|
|
||||||
else if (t > m_StartTime || t > m_FirstDay + SECSINDAY + 3600) // +3600 in case of DST change
|
|
||||||
m_FirstDay = 0;
|
|
||||||
return m_Active && m_StartTime <= t && t < m_StopTime; // must m_Stop *before* m_StopTime to allow adjacent timers
|
|
||||||
}
|
|
||||||
|
|
||||||
bool cRemoteTimer::DayMatches(time_t t) {
|
|
||||||
return IsSingleEvent()
|
|
||||||
? GetMDay(t) == m_Day
|
|
||||||
: (m_Day & (1 << GetWDay(t))) != 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
int cRemoteTimer::GetMDay(time_t t)
|
|
||||||
{
|
|
||||||
struct tm tm_r;
|
|
||||||
return localtime_r(&t, &tm_r)->tm_mday;
|
|
||||||
}
|
|
||||||
|
|
||||||
int cRemoteTimer::GetWDay(time_t t)
|
|
||||||
{
|
|
||||||
struct tm tm_r;
|
|
||||||
int weekday = localtime_r(&t, &tm_r)->tm_wday;
|
|
||||||
return weekday == 0 ? 6 : weekday - 1; // we start with monday==0!
|
|
||||||
}
|
|
||||||
|
|
||||||
time_t cRemoteTimer::IncDay(time_t t, int Days) {
|
|
||||||
struct tm tm_r;
|
|
||||||
tm tm = *localtime_r(&t, &tm_r);
|
|
||||||
tm.tm_mday += Days; // now tm_mday may be out of its valid range
|
|
||||||
int h = tm.tm_hour; // save original hour to compensate for DST change
|
|
||||||
tm.tm_isdst = -1; // makes sure mktime() will determine the correct DST setting
|
|
||||||
t = mktime(&tm); // normalize all values
|
|
||||||
tm.tm_hour = h; // compensate for DST change
|
|
||||||
return mktime(&tm); // calculate final result
|
|
||||||
}
|
|
||||||
|
|
||||||
const char *cRemoteTimer::ToText(void) {
|
|
||||||
char *summary = NULL;
|
|
||||||
|
|
||||||
if (m_Buffer != NULL) free(m_Buffer);
|
|
||||||
|
|
||||||
strreplace(m_File, ':', '|');
|
|
||||||
if (m_Summary != "")
|
|
||||||
summary = strreplace(strdup(m_Summary.c_str()), ':', '|');
|
|
||||||
|
|
||||||
asprintf(&m_Buffer, "%d:%s:%s:%04d:%04d:%d:%d:%s:%s", m_Active,
|
|
||||||
(const char*)Channel()->GetChannelID().ToString(), PrintDay(m_Day, m_FirstDay),
|
|
||||||
m_Start, m_Stop, m_Priority, m_Lifetime, m_File, summary ? summary : "");
|
|
||||||
|
|
||||||
if (summary != NULL)
|
|
||||||
free(summary);
|
|
||||||
strreplace(m_File, '|', ':');
|
|
||||||
return m_Buffer;
|
|
||||||
}
|
|
||||||
|
|
||||||
// --- cRemoteTimers ---------------------------------------------------------
|
|
||||||
|
|
||||||
bool cRemoteTimers::Load(void) {
|
|
||||||
Clear();
|
|
||||||
return ClientSocket.LoadTimers(*this);
|
|
||||||
}
|
|
||||||
|
|
123
client/remote.h
123
client/remote.h
@ -1,123 +0,0 @@
|
|||||||
/*
|
|
||||||
* $Id: remote.h,v 1.3 2008/04/07 14:27:28 schmirl Exp $
|
|
||||||
*/
|
|
||||||
|
|
||||||
#ifndef VDR_STREAMDEV_REMOTE_H
|
|
||||||
#define VDR_STREAMDEV_REMOTE_H
|
|
||||||
|
|
||||||
#include <vdr/config.h>
|
|
||||||
#include <string>
|
|
||||||
|
|
||||||
class cEvent;
|
|
||||||
class cChannel;
|
|
||||||
|
|
||||||
class cRemoteRecording: public cListObject {
|
|
||||||
private:
|
|
||||||
bool m_IsValid;
|
|
||||||
int m_Index;
|
|
||||||
bool m_IsNew;
|
|
||||||
char *m_TitleBuffer;
|
|
||||||
std::string m_StartTime;
|
|
||||||
std::string m_Name;
|
|
||||||
std::string m_Summary;
|
|
||||||
|
|
||||||
public:
|
|
||||||
cRemoteRecording(const char *Text);
|
|
||||||
~cRemoteRecording();
|
|
||||||
|
|
||||||
bool operator==(const cRemoteRecording &Recording);
|
|
||||||
bool operator!=(const cRemoteRecording &Recording);
|
|
||||||
|
|
||||||
void ParseInfo(const char *Text);
|
|
||||||
|
|
||||||
bool IsValid(void) const { return m_IsValid; }
|
|
||||||
int Index(void) const { return m_Index; }
|
|
||||||
const char *StartTime(void) const { return m_StartTime.c_str(); }
|
|
||||||
bool IsNew(void) const { return m_IsNew; }
|
|
||||||
const char *Name(void) const { return m_Name.c_str(); }
|
|
||||||
const char *Summary(void) const { return m_Summary.c_str(); }
|
|
||||||
const char *Title(char Delimiter, bool NewIndicator, int Level);
|
|
||||||
int HierarchyLevels(void);
|
|
||||||
};
|
|
||||||
|
|
||||||
inline bool cRemoteRecording::operator!=(const cRemoteRecording &Recording) {
|
|
||||||
return !operator==(Recording);
|
|
||||||
}
|
|
||||||
|
|
||||||
class cRemoteRecordings: public cList<cRemoteRecording> {
|
|
||||||
public:
|
|
||||||
bool Load(void);
|
|
||||||
cRemoteRecording *GetByName(const char *Name);
|
|
||||||
};
|
|
||||||
|
|
||||||
class cRemoteTimer: public cListObject {
|
|
||||||
friend class cStreamdevMenuEditTimer;
|
|
||||||
|
|
||||||
private:
|
|
||||||
bool m_IsValid;
|
|
||||||
int m_Index;
|
|
||||||
int m_Active;
|
|
||||||
int m_Day;
|
|
||||||
int m_Start;
|
|
||||||
int m_Stop;
|
|
||||||
time_t m_StartTime;
|
|
||||||
time_t m_StopTime;
|
|
||||||
int m_Priority;
|
|
||||||
int m_Lifetime;
|
|
||||||
char m_File[MaxFileName];
|
|
||||||
time_t m_FirstDay;
|
|
||||||
std::string m_Summary;
|
|
||||||
char *m_Buffer;
|
|
||||||
const cChannel *m_Channel;
|
|
||||||
|
|
||||||
public:
|
|
||||||
cRemoteTimer(const char *Text);
|
|
||||||
cRemoteTimer(const cEvent *Event);
|
|
||||||
cRemoteTimer(void);
|
|
||||||
~cRemoteTimer();
|
|
||||||
|
|
||||||
cRemoteTimer &operator=(const cRemoteTimer &Timer);
|
|
||||||
bool operator==(const cRemoteTimer &Timer);
|
|
||||||
bool operator!=(const cRemoteTimer &Timer) { return !operator==(Timer); }
|
|
||||||
|
|
||||||
static int ParseDay(const char *s, time_t *FirstDay);
|
|
||||||
static const char *PrintDay(int d, time_t FirstDay = 0);
|
|
||||||
static time_t SetTime(time_t t, int SecondsFromMidnight);
|
|
||||||
static time_t IncDay(time_t t, int Days);
|
|
||||||
static int TimeToInt(int t) { return (t / 100 * 60 + t % 100) * 60; }
|
|
||||||
|
|
||||||
const char *PrintFirstDay(void) const;
|
|
||||||
void OnOff(void);
|
|
||||||
bool IsSingleEvent(void) const { return (m_Day & 0x80000000) == 0; }
|
|
||||||
void Skip(void) { m_FirstDay = IncDay(SetTime(StartTime(), 0), 1); }
|
|
||||||
bool Matches(time_t t = 0);
|
|
||||||
bool DayMatches(time_t t = 0);
|
|
||||||
int GetMDay(time_t t);
|
|
||||||
int GetWDay(time_t t);
|
|
||||||
|
|
||||||
bool IsValid(void) const { return m_IsValid; }
|
|
||||||
int Index(void) const { return m_Index; }
|
|
||||||
int Active(void) const { return m_Active; }
|
|
||||||
int Day(void) const { return m_Day; }
|
|
||||||
int Start(void) const { return m_Start; }
|
|
||||||
int Stop(void) const { return m_Stop; }
|
|
||||||
time_t StartTime(void) { if (!m_StartTime) Matches(); return m_StartTime; }
|
|
||||||
time_t StopTime(void) { if (!m_StopTime) Matches(); return m_StopTime; }
|
|
||||||
int Priority(void) const { return m_Priority; }
|
|
||||||
int Lifetime(void) const { return m_Lifetime; }
|
|
||||||
const char *File(void) const { return m_File; }
|
|
||||||
time_t FirstDay(void) const { return m_FirstDay; }
|
|
||||||
const std::string &Summary(void) const { return m_Summary; }
|
|
||||||
const cChannel *Channel(void) const { return m_Channel; }
|
|
||||||
|
|
||||||
const char *ToText(void);
|
|
||||||
};
|
|
||||||
|
|
||||||
class cRemoteTimers: public cList<cRemoteTimer> {
|
|
||||||
public:
|
|
||||||
bool Load(void);
|
|
||||||
};
|
|
||||||
|
|
||||||
extern cRemoteTimers RemoteTimers;
|
|
||||||
|
|
||||||
#endif // VDR_STREAMDEV_REMOTE_H
|
|
@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
* $Id: setup.c,v 1.3 2008/04/07 14:27:28 schmirl Exp $
|
* $Id: setup.c,v 1.4 2008/04/07 14:40:40 schmirl Exp $
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include <vdr/menuitems.h>
|
#include <vdr/menuitems.h>
|
||||||
@ -52,7 +52,7 @@ void cStreamdevClientMenuSetupPage::Store(void) {
|
|||||||
if (m_NewSetup.StartClient)
|
if (m_NewSetup.StartClient)
|
||||||
cStreamdevDevice::Init();
|
cStreamdevDevice::Init();
|
||||||
else
|
else
|
||||||
INFO(tr("Please restart VDR to activate changes"));
|
Skins.Message(mtInfo, tr("Please restart VDR to activate changes"));
|
||||||
}
|
}
|
||||||
|
|
||||||
SetupStore("StartClient", m_NewSetup.StartClient);
|
SetupStore("StartClient", m_NewSetup.StartClient);
|
||||||
|
230
client/socket.c
230
client/socket.c
@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
* $Id: socket.c,v 1.10 2008/04/07 14:27:28 schmirl Exp $
|
* $Id: socket.c,v 1.11 2008/04/07 14:40:40 schmirl Exp $
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include <tools/select.h>
|
#include <tools/select.h>
|
||||||
@ -13,7 +13,6 @@
|
|||||||
|
|
||||||
#include "client/socket.h"
|
#include "client/socket.h"
|
||||||
#include "client/setup.h"
|
#include "client/setup.h"
|
||||||
#include "client/remote.h"
|
|
||||||
#include "common.h"
|
#include "common.h"
|
||||||
#include "i18n.h"
|
#include "i18n.h"
|
||||||
|
|
||||||
@ -362,128 +361,6 @@ bool cClientSocket::Quit(void) {
|
|||||||
return res;
|
return res;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool cClientSocket::LoadRecordings(cRemoteRecordings &Recordings) {
|
|
||||||
bool res;
|
|
||||||
|
|
||||||
if (!CheckConnection()) return false;
|
|
||||||
|
|
||||||
CMD_LOCK;
|
|
||||||
|
|
||||||
if (!Command("LSTR"))
|
|
||||||
return false;
|
|
||||||
|
|
||||||
std::string buffer;
|
|
||||||
while ((res = Expect(250, &buffer))) {
|
|
||||||
cRemoteRecording *rec = new cRemoteRecording(buffer.c_str() + 4);
|
|
||||||
Dprintf("recording valid: %d\n", rec->IsValid());
|
|
||||||
if (rec->IsValid())
|
|
||||||
Recordings.Add(rec);
|
|
||||||
else
|
|
||||||
delete rec;
|
|
||||||
if (buffer[3] == ' ') break;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!res && buffer.substr(0, 3) != "550") {
|
|
||||||
if (errno == 0)
|
|
||||||
esyslog("ERROR: Streamdev: Couldn't fetch recordings from %s:%d",
|
|
||||||
RemoteIp().c_str(), RemotePort());
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
for (cRemoteRecording *r = Recordings.First(); r; r = Recordings.Next(r)) {
|
|
||||||
std::string command = (std::string)"LSTR " + (const char*)itoa(r->Index());
|
|
||||||
if (!Command(command))
|
|
||||||
return false;
|
|
||||||
|
|
||||||
if (Expect(250, &buffer))
|
|
||||||
r->ParseInfo(buffer.c_str() + 4);
|
|
||||||
else if (buffer.substr(0, 3) != "550") {
|
|
||||||
if (errno == 0)
|
|
||||||
esyslog("ERROR: Streamdev: Couldn't fetch details for recording from %s:%d",
|
|
||||||
RemoteIp().c_str(), RemotePort());
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
Dprintf("recording complete: %d\n", r->Index());
|
|
||||||
}
|
|
||||||
return res;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool cClientSocket::StartReplay(const char *Filename) {
|
|
||||||
if (!CheckConnection()) return false;
|
|
||||||
|
|
||||||
CMD_LOCK;
|
|
||||||
|
|
||||||
std::string command = (std::string)"PLAY " + Filename;
|
|
||||||
if (!Command(command, 220)) {
|
|
||||||
if (errno == 0)
|
|
||||||
esyslog("ERROR: Streamdev: Couldn't replay \"%s\" from %s:%d",
|
|
||||||
Filename, RemoteIp().c_str(), RemotePort());
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool cClientSocket::AbortReplay(void) {
|
|
||||||
if (!CheckConnection()) return false;
|
|
||||||
|
|
||||||
CMD_LOCK;
|
|
||||||
|
|
||||||
if (m_DataSockets[siReplay] != NULL) {
|
|
||||||
std::string command = (std::string)"ABRT " + (const char*)itoa(siReplay);
|
|
||||||
if (!Command(command, 220)) {
|
|
||||||
if (errno == 0)
|
|
||||||
esyslog("ERROR: Streamdev: Couldn't cleanly close data connection");
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
DELETENULL(m_DataSockets[siReplay]);
|
|
||||||
}
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool cClientSocket::DeleteRecording(cRemoteRecording *Recording) {
|
|
||||||
bool res;
|
|
||||||
cRemoteRecording *rec = NULL;
|
|
||||||
|
|
||||||
if (!CheckConnection())
|
|
||||||
return false;
|
|
||||||
|
|
||||||
CMD_LOCK;
|
|
||||||
|
|
||||||
if (!Command("LSTR"))
|
|
||||||
return false;
|
|
||||||
|
|
||||||
std::string buffer;
|
|
||||||
while ((res = Expect(250, &buffer))) {
|
|
||||||
if (rec == NULL) {
|
|
||||||
rec = new cRemoteRecording(buffer.c_str() + 4);
|
|
||||||
if (!rec->IsValid() || rec->Index() != Recording->Index())
|
|
||||||
DELETENULL(rec);
|
|
||||||
}
|
|
||||||
if (buffer[3] == ' ') break;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!res && buffer.substr(0, 3) != "550") {
|
|
||||||
if (errno == 0)
|
|
||||||
esyslog("ERROR: Streamdev: Couldn't fetch recordings from %s:%d",
|
|
||||||
RemoteIp().c_str(), RemotePort());
|
|
||||||
if (rec != NULL) delete rec;
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (rec == NULL || *rec != *Recording) {
|
|
||||||
ERROR(tr("Recordings not in sync! Try again..."));
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
std::string command = (std::string)"DELR " + (const char*)itoa(Recording->Index());
|
|
||||||
if (!Command(command, 250)) {
|
|
||||||
ERROR(tr("Couldn't delete recording! Try again..."));
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool cClientSocket::SuspendServer(void) {
|
bool cClientSocket::SuspendServer(void) {
|
||||||
if (!CheckConnection()) return false;
|
if (!CheckConnection()) return false;
|
||||||
|
|
||||||
@ -496,108 +373,3 @@ bool cClientSocket::SuspendServer(void) {
|
|||||||
}
|
}
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool cClientSocket::LoadTimers(cRemoteTimers &Timers) {
|
|
||||||
if (!CheckConnection()) return false;
|
|
||||||
|
|
||||||
CMD_LOCK;
|
|
||||||
|
|
||||||
if (!Command("LSTT"))
|
|
||||||
return false;
|
|
||||||
|
|
||||||
bool res;
|
|
||||||
std::string buffer;
|
|
||||||
while ((res = Expect(250, &buffer))) {
|
|
||||||
cRemoteTimer *timer = new cRemoteTimer(buffer.c_str() + 4);
|
|
||||||
Dprintf("timer valid: %d\n", timer->IsValid());
|
|
||||||
if (timer->IsValid())
|
|
||||||
Timers.Add(timer);
|
|
||||||
if (buffer[3] == ' ') break;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!res && buffer.substr(0, 3) != "550") {
|
|
||||||
if (errno == 0)
|
|
||||||
esyslog("ERROR: Streamdev: Couldn't fetch recordings from %s:%d",
|
|
||||||
RemoteIp().c_str(), RemotePort());
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
return res;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool cClientSocket::SaveTimer(cRemoteTimer *Old, cRemoteTimer &New) {
|
|
||||||
if (!CheckConnection()) return false;
|
|
||||||
|
|
||||||
CMD_LOCK;
|
|
||||||
|
|
||||||
if (New.Index() == -1) { // New timer
|
|
||||||
std::string command = (std::string)"NEWT " + (const char*)New.ToText();
|
|
||||||
if (!Command(command, 250)) {
|
|
||||||
ERROR(tr("Couldn't save timer! Try again..."));
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
} else { // Modified timer
|
|
||||||
std::string command = (std::string)"LSTT " + (const char*)itoa(New.Index());
|
|
||||||
if (!Command(command))
|
|
||||||
return false;
|
|
||||||
|
|
||||||
std::string buffer;
|
|
||||||
if (!Expect(250, &buffer)) {
|
|
||||||
if (errno == 0)
|
|
||||||
ERROR(tr("Timers not in sync! Try again..."));
|
|
||||||
else
|
|
||||||
ERROR(tr("Server error! Try again..."));
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
cRemoteTimer oldstate(buffer.c_str() + 4);
|
|
||||||
if (oldstate != *Old) {
|
|
||||||
/*Dprintf("old timer: %d,%d,%d,%d,%d,%d,%s,%d,%s,%d\n", oldstate.m_Index,
|
|
||||||
oldstate.m_Active,oldstate.m_Day,oldstate.m_Start,oldstate.m_StartTime,oldstate.m_Priority,oldstate.m_File,oldstate.m_FirstDay,(const char*)oldstate.m_Summary,oldstate.m_Channel->Number());
|
|
||||||
Dprintf("new timer: %d,%d,%d,%d,%d,%d,%s,%d,%s,%d\n", Old->m_Index,
|
|
||||||
Old->m_Active,Old->m_Day,Old->m_Start,Old->m_StartTime,Old->m_Priority,Old->m_File,Old->m_FirstDay,(const char*)Old->m_Summary,Old->m_Channel->Number());*/
|
|
||||||
ERROR(tr("Timers not in sync! Try again..."));
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
command = (std::string)"MODT " + (const char*)itoa(New.Index()) + " "
|
|
||||||
+ (const char*)New.ToText();
|
|
||||||
if (!Command(command, 250)) {
|
|
||||||
ERROR(tr("Couldn't save timer! Try again..."));
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool cClientSocket::DeleteTimer(cRemoteTimer *Timer) {
|
|
||||||
if (!CheckConnection()) return false;
|
|
||||||
|
|
||||||
CMD_LOCK;
|
|
||||||
|
|
||||||
std::string command = (std::string)"LSTT " + (const char*)itoa(Timer->Index());
|
|
||||||
if (!Command(command))
|
|
||||||
return false;
|
|
||||||
|
|
||||||
std::string buffer;
|
|
||||||
if (!Expect(250, &buffer)) {
|
|
||||||
if (errno == 0)
|
|
||||||
ERROR(tr("Timers not in sync! Try again..."));
|
|
||||||
else
|
|
||||||
ERROR(tr("Server error! Try again..."));
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
cRemoteTimer oldstate(buffer.c_str() + 4);
|
|
||||||
if (oldstate != *Timer) {
|
|
||||||
ERROR(tr("Timers not in sync! Try again..."));
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
command = (std::string)"DELT " + (const char*)itoa(Timer->Index());
|
|
||||||
if (!Command(command, 250)) {
|
|
||||||
ERROR(tr("Couldn't delete timer! Try again..."));
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
* $Id: socket.h,v 1.5 2008/04/07 14:27:28 schmirl Exp $
|
* $Id: socket.h,v 1.6 2008/04/07 14:40:40 schmirl Exp $
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#ifndef VDR_STREAMDEV_CLIENT_CONNECTION_H
|
#ifndef VDR_STREAMDEV_CLIENT_CONNECTION_H
|
||||||
@ -13,10 +13,6 @@
|
|||||||
|
|
||||||
#define CMD_LOCK cMutexLock CmdLock((cMutex*)&m_Mutex)
|
#define CMD_LOCK cMutexLock CmdLock((cMutex*)&m_Mutex)
|
||||||
|
|
||||||
class cRemoteRecordings;
|
|
||||||
class cRemoteRecording;
|
|
||||||
class cRemoteTimers;
|
|
||||||
class cRemoteTimer;
|
|
||||||
class cPES2TSRemux;
|
class cPES2TSRemux;
|
||||||
|
|
||||||
class cClientSocket: public cTBSocket {
|
class cClientSocket: public cTBSocket {
|
||||||
@ -53,13 +49,6 @@ public:
|
|||||||
bool SetFilter(ushort Pid, uchar Tid, uchar Mask, bool On);
|
bool SetFilter(ushort Pid, uchar Tid, uchar Mask, bool On);
|
||||||
bool CloseDvr(void);
|
bool CloseDvr(void);
|
||||||
bool SynchronizeEPG(void);
|
bool SynchronizeEPG(void);
|
||||||
bool LoadRecordings(cRemoteRecordings &Recordings);
|
|
||||||
bool StartReplay(const char *Filename);
|
|
||||||
bool AbortReplay(void);
|
|
||||||
bool DeleteRecording(cRemoteRecording *Recording);
|
|
||||||
bool LoadTimers(cRemoteTimers &Timers);
|
|
||||||
bool SaveTimer(cRemoteTimer *Old, cRemoteTimer &New);
|
|
||||||
bool DeleteTimer(cRemoteTimer *Timer);
|
|
||||||
bool SuspendServer(void);
|
bool SuspendServer(void);
|
||||||
bool Quit(void);
|
bool Quit(void);
|
||||||
|
|
||||||
|
7
common.h
7
common.h
@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
* $Id: common.h,v 1.10 2008/04/07 14:27:27 schmirl Exp $
|
* $Id: common.h,v 1.11 2008/04/07 14:40:39 schmirl Exp $
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#ifndef VDR_STREAMDEV_COMMON_H
|
#ifndef VDR_STREAMDEV_COMMON_H
|
||||||
@ -25,11 +25,6 @@
|
|||||||
|
|
||||||
# define TRANSPONDER(c1, c2) (c1->Transponder() == c2->Transponder())
|
# define TRANSPONDER(c1, c2) (c1->Transponder() == c2->Transponder())
|
||||||
|
|
||||||
# define INFO(s) Skins.Message(mtInfo, s)
|
|
||||||
# define STATUS(s) Skins.Message(mtInfo, s)
|
|
||||||
# define ERROR(s) Skins.Message(mtStatus, s)
|
|
||||||
# define FLUSH() Skins.Flush()
|
|
||||||
|
|
||||||
# define MAXPARSEBUFFER KILOBYTE(16)
|
# define MAXPARSEBUFFER KILOBYTE(16)
|
||||||
|
|
||||||
/* Check if a channel is a radio station. */
|
/* Check if a channel is a radio station. */
|
||||||
|
200
i18n.c
200
i18n.c
@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
* $Id: i18n.c,v 1.6 2008/04/07 14:27:27 schmirl Exp $
|
* $Id: i18n.c,v 1.7 2008/04/07 14:40:39 schmirl Exp $
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include "i18n.h"
|
#include "i18n.h"
|
||||||
@ -421,78 +421,6 @@ const tI18nPhrase Phrases[] = {
|
|||||||
"", // Catala
|
"", // Catala
|
||||||
"" // Russian
|
"" // Russian
|
||||||
},
|
},
|
||||||
{ "Streaming Control", // English
|
|
||||||
"Streamkontrolle", // Deutsch
|
|
||||||
"", // Slovenski
|
|
||||||
"", // Italiano
|
|
||||||
"", // Nederlands
|
|
||||||
"", // Português
|
|
||||||
"", // Français
|
|
||||||
"", // Norsk
|
|
||||||
"Suoratoiston hallinta", // suomi
|
|
||||||
"", // Polski
|
|
||||||
"", // Español
|
|
||||||
"", // Ellinika
|
|
||||||
"", // Svenska
|
|
||||||
"", // Romaneste
|
|
||||||
"", // Magyar
|
|
||||||
"", // Catala
|
|
||||||
"" // Russian
|
|
||||||
},
|
|
||||||
{ "Fetching recordings...",// English
|
|
||||||
"Hole Aufnahmen...", // Deutsch
|
|
||||||
"", // Slovenski
|
|
||||||
"", // Italiano
|
|
||||||
"", // Nederlands
|
|
||||||
"", // Português
|
|
||||||
"", // Français
|
|
||||||
"", // Norsk
|
|
||||||
"Haetaan tallenteita...", // suomi
|
|
||||||
"", // Polski
|
|
||||||
"", // Español
|
|
||||||
"", // Ellinika
|
|
||||||
"", // Svenska
|
|
||||||
"", // Romaneste
|
|
||||||
"", // Magyar
|
|
||||||
"", // Catala
|
|
||||||
"" // Russian
|
|
||||||
},
|
|
||||||
{ "Remote Recordings", // English
|
|
||||||
"Entfernte Aufnahmen", // Deutsch
|
|
||||||
"", // Slovenski
|
|
||||||
"", // Italiano
|
|
||||||
"", // Nederlands
|
|
||||||
"", // Português
|
|
||||||
"", // Français
|
|
||||||
"", // Norsk
|
|
||||||
"Etätallenteet", // suomi
|
|
||||||
"", // Polski
|
|
||||||
"", // Español
|
|
||||||
"", // Ellinika
|
|
||||||
"", // Svenska
|
|
||||||
"", // Romaneste
|
|
||||||
"", // Magyar
|
|
||||||
"", // Catala
|
|
||||||
"" // Russian
|
|
||||||
},
|
|
||||||
{ "Remote Timers", // English
|
|
||||||
"Entfernte Timer", // Deutsch
|
|
||||||
"", // Slovenski
|
|
||||||
"", // Italiano
|
|
||||||
"", // Nederlands
|
|
||||||
"", // Português
|
|
||||||
"", // Français
|
|
||||||
"", // Norsk
|
|
||||||
"Etäajastimet", // suomi
|
|
||||||
"", // Polski
|
|
||||||
"", // Español
|
|
||||||
"", // Ellinika
|
|
||||||
"", // Svenska
|
|
||||||
"", // Romaneste
|
|
||||||
"", // Magyar
|
|
||||||
"", // Catala
|
|
||||||
"" // Russian
|
|
||||||
},
|
|
||||||
{ "Suspend Server", // English
|
{ "Suspend Server", // English
|
||||||
"Server pausieren", // Deutsch
|
"Server pausieren", // Deutsch
|
||||||
"", // Slovenski
|
"", // Slovenski
|
||||||
@ -547,114 +475,6 @@ const tI18nPhrase Phrases[] = {
|
|||||||
"", // Catala
|
"", // Catala
|
||||||
"" // Russian
|
"" // Russian
|
||||||
},
|
},
|
||||||
{ "Edit remote timer", // English
|
|
||||||
"Entfernten Timer editieren",// Deutsch
|
|
||||||
"", // Slovenski
|
|
||||||
"", // Italiano
|
|
||||||
"", // Nederlands
|
|
||||||
"", // Português
|
|
||||||
"", // Français
|
|
||||||
"", // Norsk
|
|
||||||
"Muokkaa etäajastinta", // suomi
|
|
||||||
"", // Polski
|
|
||||||
"", // Español
|
|
||||||
"", // Ellinika
|
|
||||||
"", // Svenska
|
|
||||||
"", // Romaneste
|
|
||||||
"", // Magyar
|
|
||||||
"", // Catala
|
|
||||||
"" // Russian
|
|
||||||
},
|
|
||||||
{ "Timers not in sync! Try again...",// Englisch
|
|
||||||
"Timer nicht synchron! Bitte wiederholen...",//Deutsch
|
|
||||||
"", // Slovenski
|
|
||||||
"", // Italiano
|
|
||||||
"", // Nederlands
|
|
||||||
"", // Português
|
|
||||||
"", // Français
|
|
||||||
"", // Norsk
|
|
||||||
"Ajastimet eivät täsmää! Yritä uudelleen...", // suomi
|
|
||||||
"", // Polski
|
|
||||||
"", // Español
|
|
||||||
"", // Ellinika
|
|
||||||
"", // Svenska
|
|
||||||
"", // Romaneste
|
|
||||||
"", // Magyar
|
|
||||||
"", // Catala
|
|
||||||
"" // Russian
|
|
||||||
},
|
|
||||||
{ "Couldn't save timer! Try again...",// English
|
|
||||||
"Konnte Timer nicht speichern! Bitte wiederholen...",// Deutsch
|
|
||||||
"", // Slovenski
|
|
||||||
"", // Italiano
|
|
||||||
"", // Nederlands
|
|
||||||
"", // Português
|
|
||||||
"", // Français
|
|
||||||
"", // Norsk
|
|
||||||
"Ajastimen tallennus epäonnistui! Yritä uudelleen...", // suomi
|
|
||||||
"", // Polski
|
|
||||||
"", // Español
|
|
||||||
"", // Ellinika
|
|
||||||
"", // Svenska
|
|
||||||
"", // Romaneste
|
|
||||||
"", // Magyar
|
|
||||||
"", // Catala
|
|
||||||
"" // Russian
|
|
||||||
},
|
|
||||||
{ "Couldn't delete timer! Try again...",// English
|
|
||||||
"Konnte Timer nicht löschen! Bitte wiederholen...",// Deutsch
|
|
||||||
"", // Slovenski
|
|
||||||
"", // Italiano
|
|
||||||
"", // Nederlands
|
|
||||||
"", // Português
|
|
||||||
"", // Français
|
|
||||||
"", // Norsk
|
|
||||||
"Ajastimen poistaminen epäonnistui! Yritä uudelleen...", // suomi
|
|
||||||
"", // Polski
|
|
||||||
"", // Español
|
|
||||||
"", // Ellinika
|
|
||||||
"", // Svenska
|
|
||||||
"", // Romaneste
|
|
||||||
"", // Magyar
|
|
||||||
"", // Catala
|
|
||||||
"" // Russian
|
|
||||||
},
|
|
||||||
{ "Server error! Try again...",// English
|
|
||||||
"Serverfehler! Bitte wiederholen...",// Deutsch
|
|
||||||
"", // Slovenski
|
|
||||||
"", // Italiano
|
|
||||||
"", // Nederlands
|
|
||||||
"", // Português
|
|
||||||
"", // Français
|
|
||||||
"", // Norsk
|
|
||||||
"Palvelimessa virhe! Yritä uudelleen...", // suomi
|
|
||||||
"", // Polski
|
|
||||||
"", // Español
|
|
||||||
"", // Ellinika
|
|
||||||
"", // Svenska
|
|
||||||
"", // Romaneste
|
|
||||||
"", // Magyar
|
|
||||||
"", // Catala
|
|
||||||
"" // Russian
|
|
||||||
},
|
|
||||||
{ "MultiPID Streaming", // English
|
|
||||||
"Multiple PIDs streamen",// Deutsch
|
|
||||||
"", // Slovenski
|
|
||||||
"", // Italiano
|
|
||||||
"", // Nederlands
|
|
||||||
"", // Português
|
|
||||||
"", // Français
|
|
||||||
"", // Norsk
|
|
||||||
"Usean PID:in suoratoisto", // suomi
|
|
||||||
"", // Polski
|
|
||||||
"", // Español
|
|
||||||
"", // Ellinika
|
|
||||||
"", // Svenska
|
|
||||||
"", // Romaneste
|
|
||||||
"", // Magyar
|
|
||||||
"", // Catala
|
|
||||||
"" // Russian
|
|
||||||
},
|
|
||||||
{ "Client may suspend", // English
|
{ "Client may suspend", // English
|
||||||
"Client darf pausieren",// Deutsch
|
"Client darf pausieren",// Deutsch
|
||||||
"", // Slovenski
|
"", // Slovenski
|
||||||
@ -691,24 +511,6 @@ const tI18nPhrase Phrases[] = {
|
|||||||
"", // Catala
|
"", // Catala
|
||||||
"" // Russian
|
"" // Russian
|
||||||
},
|
},
|
||||||
{ "Remote Schedule", // English
|
|
||||||
"",// Deutsch
|
|
||||||
"", // Slovenski
|
|
||||||
"", // Italiano
|
|
||||||
"", // Nederlands
|
|
||||||
"", // Português
|
|
||||||
"", // Français
|
|
||||||
"", // Norsk
|
|
||||||
"Etäkoneen ohjelmaopas", // suomi
|
|
||||||
"", // Polski
|
|
||||||
"", // Español
|
|
||||||
"", // Ellinika
|
|
||||||
"", // Svenska
|
|
||||||
"", // Romaneste
|
|
||||||
"", // Magyar
|
|
||||||
"", // Catala
|
|
||||||
"" // Russian
|
|
||||||
},
|
|
||||||
{ "Filter Streaming", // English
|
{ "Filter Streaming", // English
|
||||||
"",// Deutsch
|
"",// Deutsch
|
||||||
"", // Slovenski
|
"", // Slovenski
|
||||||
|
@ -1,446 +0,0 @@
|
|||||||
#ifndef _DVB_DEV_HH_
|
|
||||||
#define _DVB_DEV_HH_
|
|
||||||
|
|
||||||
extern "C" {
|
|
||||||
#include <asm/errno.h>
|
|
||||||
#include <fcntl.h>
|
|
||||||
#include <netdb.h>
|
|
||||||
#include <netinet/in.h>
|
|
||||||
#include <stdint.h>
|
|
||||||
#include <stdio.h>
|
|
||||||
#include <sys/ioctl.h>
|
|
||||||
#include <sys/poll.h>
|
|
||||||
#include <sys/socket.h>
|
|
||||||
#include <sys/stat.h>
|
|
||||||
#include <sys/time.h>
|
|
||||||
#include <sys/types.h>
|
|
||||||
#include <sys/uio.h>
|
|
||||||
#include <sys/un.h>
|
|
||||||
#include <time.h>
|
|
||||||
#include <unistd.h>
|
|
||||||
|
|
||||||
#define NEWSTRUCT
|
|
||||||
#include <channel.h>
|
|
||||||
}
|
|
||||||
|
|
||||||
#include <sstream>
|
|
||||||
#include <iostream>
|
|
||||||
#include <iomanip>
|
|
||||||
using namespace std;
|
|
||||||
|
|
||||||
#include <osd.hh>
|
|
||||||
#include <devices.hh>
|
|
||||||
|
|
||||||
#ifndef MAXNAM
|
|
||||||
#define MAXNAM 80
|
|
||||||
#endif
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
#define FRONT_DVBS 1
|
|
||||||
#define FRONT_DVBC 2
|
|
||||||
#define FRONT_DVBT 3
|
|
||||||
|
|
||||||
#define VTXDIR "/var/vtx"
|
|
||||||
|
|
||||||
#define DEC(N) dec << setw(N) << setfill('0')
|
|
||||||
#define HEX(N) hex << setw(N) << setfill('0')
|
|
||||||
|
|
||||||
#define MAXSECSIZE 4096
|
|
||||||
|
|
||||||
#define NK 10
|
|
||||||
enum {LNB=0,DIS,ROTOR,TRANS,CHAN,BOU,SAT,PICS,SWI,NTW};
|
|
||||||
static const int nums[]={LNB,DIS,ROTOR,TRANS,CHAN,BOU,SAT,PICS,SWI,NTW};
|
|
||||||
static const int maxs[]={ 32, 32, 32, 512,16384,512,100, 50, 10, 100};
|
|
||||||
|
|
||||||
#define MAX_TRANS_CHAN 1024
|
|
||||||
|
|
||||||
enum{DVB_ORIG=0, DVB_NOKIA, DVB_XML, DVB_SATCO};
|
|
||||||
|
|
||||||
typedef struct frontend_stat_s{
|
|
||||||
fe_status_t status;
|
|
||||||
uint16_t snr;
|
|
||||||
uint16_t strength;
|
|
||||||
uint32_t ber;
|
|
||||||
uint32_t u_blocks;
|
|
||||||
} frontend_stat;
|
|
||||||
|
|
||||||
|
|
||||||
extern uint8_t hamtab[256];
|
|
||||||
extern uint8_t invtab[256];
|
|
||||||
|
|
||||||
#define MAX_MAG 8
|
|
||||||
typedef struct mag_struct_ {
|
|
||||||
int valid;
|
|
||||||
int magn;
|
|
||||||
uint8_t flags;
|
|
||||||
uint8_t lang;
|
|
||||||
int pnum,sub;
|
|
||||||
uint8_t pagebuf[25*40];
|
|
||||||
} magazin_t;
|
|
||||||
|
|
||||||
|
|
||||||
class DVB {
|
|
||||||
public:
|
|
||||||
int no_open;
|
|
||||||
int fd_frontend;
|
|
||||||
int fd_demuxa;
|
|
||||||
int fd_demuxv;
|
|
||||||
int fd_demuxpcr;
|
|
||||||
int fd_demuxtt;
|
|
||||||
int fdvb;
|
|
||||||
|
|
||||||
int minor;
|
|
||||||
int adapter;
|
|
||||||
int max_tpid;
|
|
||||||
int max_satid;
|
|
||||||
int max_chanid;
|
|
||||||
|
|
||||||
frontend_stat festat;
|
|
||||||
|
|
||||||
struct dvb_diseqc_master_cmd dcmd;
|
|
||||||
fe_sec_tone_mode_t tone;
|
|
||||||
fe_sec_voltage_t voltage;
|
|
||||||
int burst;
|
|
||||||
struct dmx_pes_filter_params pesFilterParamsV;
|
|
||||||
struct dmx_pes_filter_params pesFilterParamsA;
|
|
||||||
struct dmx_pes_filter_params pesFilterParamsP;
|
|
||||||
struct dmx_pes_filter_params pesFilterParamsTT;
|
|
||||||
struct dvb_frontend_parameters front_param;
|
|
||||||
int front_type;
|
|
||||||
int dvr_enabled;
|
|
||||||
OSD osd;
|
|
||||||
uint32_t transponder_freq;
|
|
||||||
char transponder_pol;
|
|
||||||
uint32_t transponder_srate;
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
fe_status_t status;
|
|
||||||
uint32_t ber, uncorrected_blocks;
|
|
||||||
uint16_t snr, signal;
|
|
||||||
|
|
||||||
|
|
||||||
struct Lnb *lnbs;
|
|
||||||
struct DiSEqC *diseqcs;
|
|
||||||
struct Rotor *rotors;
|
|
||||||
struct Transponder *tps;
|
|
||||||
struct Channel *chans;
|
|
||||||
struct Bouquet *bouqs;
|
|
||||||
struct Sat *sats;
|
|
||||||
struct Picture *pics;
|
|
||||||
struct Switch *swis;
|
|
||||||
struct Network *ntws;
|
|
||||||
int num[NK];
|
|
||||||
int oldsec;
|
|
||||||
int tryit;
|
|
||||||
int oldpol;
|
|
||||||
|
|
||||||
char *vtxdir;
|
|
||||||
magazin_t magazin[MAX_MAG];
|
|
||||||
|
|
||||||
DVB(){
|
|
||||||
no_open = 0;
|
|
||||||
max_tpid = 0;
|
|
||||||
max_satid = 0;
|
|
||||||
max_chanid = 0;
|
|
||||||
minor = 0;
|
|
||||||
|
|
||||||
fd_frontend = -1;
|
|
||||||
fd_demuxa = -1;
|
|
||||||
fd_demuxpcr = -1;
|
|
||||||
fd_demuxv = -1;
|
|
||||||
fd_demuxtt = -1;
|
|
||||||
fdvb = -1;
|
|
||||||
vtxdir = NULL;
|
|
||||||
transponder_freq=0;
|
|
||||||
transponder_pol=0;
|
|
||||||
transponder_srate=0;
|
|
||||||
}
|
|
||||||
|
|
||||||
DVB(int i){
|
|
||||||
if (i >= 0)
|
|
||||||
no_open = 0;
|
|
||||||
else
|
|
||||||
no_open = 1;
|
|
||||||
max_tpid = 0;
|
|
||||||
max_satid = 0;
|
|
||||||
max_chanid = 0;
|
|
||||||
|
|
||||||
fd_frontend = -1;
|
|
||||||
fd_demuxa = -1;
|
|
||||||
fd_demuxpcr = -1;
|
|
||||||
fd_demuxv = -1;
|
|
||||||
fd_demuxtt = -1;
|
|
||||||
fdvb = -1;
|
|
||||||
vtxdir = NULL;
|
|
||||||
transponder_freq=0;
|
|
||||||
transponder_pol=0;
|
|
||||||
transponder_srate=0;
|
|
||||||
|
|
||||||
init("","",i);
|
|
||||||
}
|
|
||||||
|
|
||||||
DVB(char *a, char *b) {
|
|
||||||
max_tpid = 0;
|
|
||||||
max_satid = 0;
|
|
||||||
max_chanid = 0;
|
|
||||||
|
|
||||||
fd_frontend = -1;
|
|
||||||
fd_demuxa = -1;
|
|
||||||
fd_demuxpcr = -1;
|
|
||||||
fd_demuxv = -1;
|
|
||||||
fd_demuxtt = -1;
|
|
||||||
|
|
||||||
fdvb = -1;
|
|
||||||
vtxdir = NULL;
|
|
||||||
init(a,b,0);
|
|
||||||
}
|
|
||||||
|
|
||||||
~DVB();
|
|
||||||
|
|
||||||
void use_osd(int fd = -1){
|
|
||||||
char dvn[32];
|
|
||||||
if (no_open) return;
|
|
||||||
if (fd < 0) fd = 0;
|
|
||||||
sprintf(dvn,OSD_DEV,adapter,fd);
|
|
||||||
fdvb = open(dvn, O_RDWR);
|
|
||||||
|
|
||||||
if (fdvb >= 0){
|
|
||||||
cerr << dvn << " for OSD" << endl;
|
|
||||||
osd.init(fdvb);
|
|
||||||
} else perror("osd");
|
|
||||||
osd.Open(80, 500, 640, 540, 2, 0, 2);
|
|
||||||
osd.SetColor(0, 0, 0, 0, 255);
|
|
||||||
osd.SetColor(1, 240, 240, 240, 255);
|
|
||||||
osd.Show();
|
|
||||||
}
|
|
||||||
|
|
||||||
void set_vtxdir(char *newname){
|
|
||||||
if (!newname) return;
|
|
||||||
if (vtxdir) free(vtxdir);
|
|
||||||
vtxdir = (char *) malloc(sizeof(char)*(strlen(newname)+1));
|
|
||||||
if (vtxdir)
|
|
||||||
strncpy(vtxdir, newname, strlen(newname));
|
|
||||||
}
|
|
||||||
|
|
||||||
void close_osd(){
|
|
||||||
osd.Close(fdvb);
|
|
||||||
close(fdvb);
|
|
||||||
}
|
|
||||||
|
|
||||||
int DVR_enabled(){
|
|
||||||
if (no_open) return -1;
|
|
||||||
return dvr_enabled;
|
|
||||||
}
|
|
||||||
|
|
||||||
void enable_DVR(){
|
|
||||||
if (no_open) return;
|
|
||||||
dvr_enabled = 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
void enable_DVR_other(){
|
|
||||||
if (no_open) return;
|
|
||||||
dvr_enabled = 2;
|
|
||||||
}
|
|
||||||
|
|
||||||
void disable_DVR(){
|
|
||||||
if (no_open) return;
|
|
||||||
dvr_enabled = 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
void init(char *a="/dev/video0", char *b="/dev/vbi0",int adapt=0,
|
|
||||||
int minor = 0);
|
|
||||||
|
|
||||||
|
|
||||||
inline void init(char *a, char *b){
|
|
||||||
if (no_open) return;
|
|
||||||
init(a,b,0,0);
|
|
||||||
}
|
|
||||||
|
|
||||||
int check_frontend();
|
|
||||||
|
|
||||||
void set_apid(ushort apid);
|
|
||||||
void set_vpid(ushort vpid);
|
|
||||||
void set_pcrpid(ushort vpid);
|
|
||||||
void set_ttpid(ushort ttpid);
|
|
||||||
int set_apid_fd(ushort apid, int fd);
|
|
||||||
int set_vpid_fd(ushort vpid, int fd);
|
|
||||||
int set_ttpid_fd(ushort ttpid, int fd);
|
|
||||||
int set_pcrpid_fd(ushort pcrpid, int fd);
|
|
||||||
int set_otherpid_fd(ushort otherpid, int fd);
|
|
||||||
|
|
||||||
|
|
||||||
int set_lnb(int dis);
|
|
||||||
void set_diseqc_nb(int nr);
|
|
||||||
int set_front(void);
|
|
||||||
void get_front(void);
|
|
||||||
|
|
||||||
void scan_pf_eit(int chnr,
|
|
||||||
int (*callback)(uint8_t *data, int l, int pnr,
|
|
||||||
int c_n, uint8_t *t));
|
|
||||||
|
|
||||||
void scan_pf_eit(Channel *chan,
|
|
||||||
int (*callback)(uint8_t *data, int l, int pnr,
|
|
||||||
int c_n, uint8_t *t));
|
|
||||||
void scan_pf_eit(int chnr);
|
|
||||||
|
|
||||||
|
|
||||||
int search_in_TP(Transponder &tp, int show=1, int verbose=0);
|
|
||||||
int search_in_TP(uint16_t tpid, uint16_t satid, int show=1,
|
|
||||||
int verbose=0);
|
|
||||||
int scan_TP(uint16_t tpid, uint16_t satid, int timeout=-1, int verbose=0);
|
|
||||||
|
|
||||||
int GetSection(uint8_t *buf,
|
|
||||||
uint16_t PID, uint8_t TID, uint16_t TIDExt,
|
|
||||||
uint16_t FilterTIDExt,
|
|
||||||
uint8_t secnum, uint8_t &msecnum);
|
|
||||||
int GetSection(uint8_t *buf,
|
|
||||||
uint16_t PID, uint8_t *filter, uint8_t *mask,
|
|
||||||
uint8_t secnum, uint8_t &msecnum);
|
|
||||||
int GetSection(uint8_t *buf, ushort PID, uint8_t sec,
|
|
||||||
uint8_t secnum, uint8_t &msecnum);
|
|
||||||
int SetFilter(uint16_t pid, uint8_t *filter,
|
|
||||||
uint8_t *mask,
|
|
||||||
uint32_t timeout, uint32_t flags);
|
|
||||||
uint16_t SetFilter(uint16_t pid, uint16_t section, uint16_t mode);
|
|
||||||
int CloseFilter(int h);
|
|
||||||
|
|
||||||
|
|
||||||
void bar2(int x, int y, int w, int h, int val, int col1, int col2);
|
|
||||||
|
|
||||||
int SetTP(unsigned int, unsigned int);
|
|
||||||
int scan(void);
|
|
||||||
int scan_all_tps(void);
|
|
||||||
int scan_lnb(struct Lnb &);
|
|
||||||
int scan_cable(Sat &sat);
|
|
||||||
int scan_sat(struct Sat &);
|
|
||||||
int scan_tp(struct Transponder &);
|
|
||||||
|
|
||||||
int AddLNB(int id, int t, uint l1, uint l2, uint sl,
|
|
||||||
int dnr, int dis, int sw);
|
|
||||||
int AddSat(Sat &sat);
|
|
||||||
int AddSat(int satid, unsigned int lnbid, char *name, uint fmin, uint fmax);
|
|
||||||
int AddTP(Transponder &tp);
|
|
||||||
int AddChannel(Channel &chan);
|
|
||||||
int parse_descriptor(Channel *chan, uint8_t *data, int length);
|
|
||||||
int parse_pmt(Channel *chan, uint8_t *data);
|
|
||||||
int parse_pat(Channel *chan, uint8_t *data);
|
|
||||||
|
|
||||||
int check_pids(Channel *chan);
|
|
||||||
void check_all_pids();
|
|
||||||
void scan_sdt(Channel *chan);
|
|
||||||
int scan_sdts(int *chs, int n);
|
|
||||||
|
|
||||||
int channel_num(void) {
|
|
||||||
return num[CHAN];
|
|
||||||
};
|
|
||||||
|
|
||||||
int channel_change(int n) {
|
|
||||||
return 0;
|
|
||||||
};
|
|
||||||
int SetChannel(uint16_t, uint16_t, uint16_t, uint16_t);
|
|
||||||
int SetChannel(Channel *chan, char* apref=NULL, uint16_t *apidp=NULL,
|
|
||||||
uint16_t *vpidp=NULL) ;
|
|
||||||
int SetChannel(int chnr, char *apref=NULL, uint16_t *apidp=NULL,
|
|
||||||
uint16_t *vpidp=NULL);
|
|
||||||
int GetChannel(int chnr, struct channel *);
|
|
||||||
int NumChannel(void) {
|
|
||||||
return num[CHAN];
|
|
||||||
}
|
|
||||||
int tune_it(struct dvb_frontend_parameters *qpsk);
|
|
||||||
void find_satid(Channel &chan);
|
|
||||||
int check_input_format(istream &ins);
|
|
||||||
void read_original(istream &ins);
|
|
||||||
int get_all_progs(uint16_t *progbuf, uint16_t *pnrbuf, int length);
|
|
||||||
uint16_t find_pnr(uint16_t vpid, uint16_t apid);
|
|
||||||
int get_pids(uint16_t prog_pid, uint16_t *vpid, uint16_t *apids,
|
|
||||||
uint16_t *ttpid, uint8_t *apids_name=NULL);
|
|
||||||
void AddECM(Channel *chan, uint8_t *data, int length);
|
|
||||||
int check_ecm(Channel *chan);
|
|
||||||
void add_vtx_line(magazin_t *mag, int line, uint8_t *data, int pnr);
|
|
||||||
|
|
||||||
friend ostream &operator<<(ostream &stream, DVB &x);
|
|
||||||
friend istream &operator>>(istream &stream, DVB &x);
|
|
||||||
|
|
||||||
};
|
|
||||||
|
|
||||||
#define NOKIA_MAX_SAT 4
|
|
||||||
class nokiaconv{
|
|
||||||
public:
|
|
||||||
DVB *dvb;
|
|
||||||
struct lnb_sat_l{
|
|
||||||
int n;
|
|
||||||
int diseqc[NOKIA_MAX_SAT];
|
|
||||||
char sat_names[NOKIA_MAX_SAT][MAXNAM+1];
|
|
||||||
int satid[NOKIA_MAX_SAT];
|
|
||||||
} lnb_sat;
|
|
||||||
|
|
||||||
nokiaconv(DVB *d){
|
|
||||||
dvb = d;
|
|
||||||
}
|
|
||||||
|
|
||||||
friend istream &operator>>(istream &stream, nokiaconv &x);
|
|
||||||
};
|
|
||||||
|
|
||||||
#define XML_MAX_SAT 4
|
|
||||||
class xmlconv{
|
|
||||||
public:
|
|
||||||
DVB *dvb;
|
|
||||||
struct lnb_sat_l{
|
|
||||||
int n;
|
|
||||||
int diseqc[XML_MAX_SAT];
|
|
||||||
char sat_names[XML_MAX_SAT][MAXNAM+1];
|
|
||||||
int satid[XML_MAX_SAT];
|
|
||||||
} lnb_sat;
|
|
||||||
|
|
||||||
xmlconv(DVB *d){
|
|
||||||
dvb = d;
|
|
||||||
}
|
|
||||||
int read_stream(istream &ins, int nchan);
|
|
||||||
int read_desc(istream &ins, int nchan);
|
|
||||||
int read_serv(istream &ins, int ctp, int csat);
|
|
||||||
int read_trans(istream &ins, int satid);
|
|
||||||
int read_sat(istream &ins, int satid = -1);
|
|
||||||
int skip_tag(istream &ins, char *tag);
|
|
||||||
int read_iso639(istream &ins, int nchan, int apids);
|
|
||||||
|
|
||||||
friend istream &operator>>(istream &stream, xmlconv &x);
|
|
||||||
};
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
#define SATCO_MAX_SAT 10
|
|
||||||
class satcoconv{
|
|
||||||
public:
|
|
||||||
DVB *dvb;
|
|
||||||
int nlnb;
|
|
||||||
|
|
||||||
satcoconv(DVB *d){
|
|
||||||
dvb = d;
|
|
||||||
}
|
|
||||||
|
|
||||||
friend istream &operator>>(istream &stream, satcoconv &x);
|
|
||||||
};
|
|
||||||
|
|
||||||
void hdump(uint8_t *buf, int n);
|
|
||||||
int get_dvbrc(char *path, DVB &dv, int dev, int len);
|
|
||||||
int set_dvbrc(char *path, DVB &dv, int dev, int len);
|
|
||||||
void dvb2txt(char *out, char *in, int len);
|
|
||||||
int set_sfront(int fdf, uint32_t freq, uint32_t pol, uint32_t sr , int snum, fe_code_rate_t fec);
|
|
||||||
void set_pes_filt(int fd,uint16_t pes_pid);
|
|
||||||
void set_diseqc(int fdf, int snum, fe_sec_voltage_t v, fe_sec_tone_mode_t t);
|
|
||||||
int tune(int fdf, uint32_t freq, uint32_t sr, fe_code_rate_t fec);
|
|
||||||
int set_sfront(int fdf, uint32_t freq, uint32_t pol, uint32_t sr , int snum,
|
|
||||||
fe_code_rate_t fec);
|
|
||||||
|
|
||||||
|
|
||||||
struct in_addr getaddress (const char *name);
|
|
||||||
int tcp_client_connect(const char *hostname, int sckt);
|
|
||||||
int udp_client_connect(const char *filename);
|
|
||||||
void client_send_msg(int fd, uint8_t *msg, int size);
|
|
||||||
int chck_frontend (int fefd, frontend_stat *festat);
|
|
||||||
|
|
||||||
uint8_t deham(uint8_t x, uint8_t y);
|
|
||||||
|
|
||||||
#endif
|
|
@ -1,14 +1,12 @@
|
|||||||
INCS = -I.
|
INCS = -I.
|
||||||
CFLAGS = -g -Wall -O2 -D_FILE_OFFSET_BITS=64 -D_LARGEFILE_SOURCE -D_LARGEFILE64_SOURCE -fPIC
|
CFLAGS = -g -Wall -O2 -D_FILE_OFFSET_BITS=64 -D_LARGEFILE_SOURCE -D_LARGEFILE64_SOURCE -fPIC
|
||||||
MFLAG = -M
|
MFLAG = -M
|
||||||
OBJS = ctools.o ringbuffy.o remux.o transform.o cpptools.o
|
OBJS = ctools.o ringbuffy.o remux.o transform.o
|
||||||
SRC = $(wildcard *.c)
|
SRC = $(wildcard *.c)
|
||||||
CPPSRC = $(wildcard *.cpp)
|
|
||||||
CSRC = $(wildcard *.cc)
|
|
||||||
|
|
||||||
DESTDIR = /usr/local
|
DESTDIR = /usr/local
|
||||||
|
|
||||||
.PHONY: depend clean install uninstall
|
.PHONY: clean
|
||||||
|
|
||||||
clean:
|
clean:
|
||||||
- rm -f *.o *~ *.a .depend
|
- rm -f *.o *~ *.a .depend
|
||||||
@ -16,17 +14,11 @@ clean:
|
|||||||
libdvbmpegtools.a: $(OBJS)
|
libdvbmpegtools.a: $(OBJS)
|
||||||
ar -rcs libdvbmpegtools.a $(OBJS)
|
ar -rcs libdvbmpegtools.a $(OBJS)
|
||||||
|
|
||||||
%.o: %.cc
|
|
||||||
$(CXX) -c $(CFLAGS) $(INCS) $(DEFINES) $<
|
|
||||||
|
|
||||||
%.o: %.cpp
|
|
||||||
$(CXX) -c $(CFLAGS) $(INCS) $(DEFINES) $<
|
|
||||||
|
|
||||||
%.o: %.c
|
%.o: %.c
|
||||||
$(CC) -c $(CFLAGS) $(INCS) $(DEFINES) $<
|
$(CC) -c $(CFLAGS) $(INCS) $(DEFINES) $<
|
||||||
|
|
||||||
.depend:
|
.depend:
|
||||||
$(CXX) $(DEFINES) $(MFLAG) $(SRC) $(CSRC) $(CPPSRC) $(INCS)> .depend
|
$(CXX) $(DEFINES) $(MFLAG) $(SRC) $(INCS)> .depend
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
@ -1,30 +0,0 @@
|
|||||||
#ifndef _OSD_H_
|
|
||||||
#define _OSD_H_
|
|
||||||
|
|
||||||
#ifdef __cplusplus
|
|
||||||
extern "C" {
|
|
||||||
#endif /* __cplusplus */
|
|
||||||
int OSDClose(int dev);
|
|
||||||
int OSDOpen(int dev, int x0, int y0, int x1, int y1, int BitPerPixel, int mix);
|
|
||||||
int OSDShow(int dev);
|
|
||||||
int OSDHide(int dev);
|
|
||||||
int OSDClear(int dev);
|
|
||||||
int OSDFill(int dev, int color);
|
|
||||||
int OSDSetColor(int dev, int color, int r, int g, int b, int op);
|
|
||||||
int OSDText(int dev, int x, int y, int size, int color, const char *text);
|
|
||||||
int OSDSetPalette(int dev, int first, int last, unsigned char *data);
|
|
||||||
int OSDSetTrans(int dev, int trans);
|
|
||||||
int OSDSetPixel(int dev, int x, int y, unsigned int color);
|
|
||||||
int OSDGetPixel(int dev, int x, int y);
|
|
||||||
int OSDSetRow(int dev, int x, int y, int x1, unsigned char *data);
|
|
||||||
int OSDSetBlock(int dev, int x, int y, int x1, int y1, int inc, unsigned char *data);
|
|
||||||
int OSDFillRow(int dev, int x, int y, int x1, int color);
|
|
||||||
int OSDFillBlock(int dev, int x, int y, int x1, int y1, int color);
|
|
||||||
int OSDLine(int dev, int x, int y, int x1, int y1, int color);
|
|
||||||
int OSDQuery(int dev);
|
|
||||||
int OSDSetWindow(int dev, int win);
|
|
||||||
int OSDMoveWindow(int dev, int x, int y);
|
|
||||||
#ifdef __cplusplus
|
|
||||||
}
|
|
||||||
#endif /* __cplusplus */
|
|
||||||
#endif
|
|
@ -1,58 +0,0 @@
|
|||||||
#ifndef _CHANNEL_H
|
|
||||||
#define _CHANNEL_H
|
|
||||||
|
|
||||||
#include <sys/types.h>
|
|
||||||
|
|
||||||
struct channel {
|
|
||||||
int id;
|
|
||||||
char name[81];
|
|
||||||
int type;
|
|
||||||
ushort pnr;
|
|
||||||
ushort vpid;
|
|
||||||
ushort apids[8];
|
|
||||||
ushort apidnum;
|
|
||||||
ushort ac3pid;
|
|
||||||
ushort pcrpid;
|
|
||||||
|
|
||||||
uint freq;
|
|
||||||
int pol;
|
|
||||||
int qam;
|
|
||||||
uint srate;
|
|
||||||
int fec;
|
|
||||||
};
|
|
||||||
|
|
||||||
#ifdef NEWSTRUCT
|
|
||||||
|
|
||||||
#include <linux/dvb/dmx.h>
|
|
||||||
#include <linux/dvb/frontend.h>
|
|
||||||
#include <linux/dvb/video.h>
|
|
||||||
#include <linux/dvb/audio.h>
|
|
||||||
|
|
||||||
#define DVR_DEV "/dev/dvb/adapter%d/dvr%d"
|
|
||||||
#define VIDEO_DEV "/dev/dvb/adapter%d/video%d"
|
|
||||||
#define AUDIO_DEV "/dev/dvb/adapter%d/audio%d"
|
|
||||||
#define DEMUX_DEV "/dev/dvb/adapter%d/demux%d"
|
|
||||||
#define FRONT_DEV "/dev/dvb/adapter%d/frontend%d"
|
|
||||||
#define OSD_DEV "/dev/dvb/adapter%d/osd%d"
|
|
||||||
#define CA_DEV "/dev/dvb/adapter%d/ca%d"
|
|
||||||
|
|
||||||
#else
|
|
||||||
|
|
||||||
#include <ost/dmx.h>
|
|
||||||
#include <ost/frontend.h>
|
|
||||||
#include <ost/sec.h>
|
|
||||||
#include <ost/video.h>
|
|
||||||
#include <ost/audio.h>
|
|
||||||
|
|
||||||
#define DVR_DEV "/dev/ost/dvr%d"
|
|
||||||
#define VIDEO_DEV "/dev/ost/video%d"
|
|
||||||
#define AUDIO_DEV "/dev/ost/audio%d"
|
|
||||||
#define DEMUX_DEV "/dev/ost/demux%d"
|
|
||||||
#define FRONT_DEV "/dev/ost/frontend%d"
|
|
||||||
#define OSD_DEV "/dev/ost/osd%d"
|
|
||||||
#define CA_DEV "/dev/ost/ca%d"
|
|
||||||
|
|
||||||
#endif
|
|
||||||
|
|
||||||
|
|
||||||
#endif
|
|
167
libdvbmpeg/ci.hh
167
libdvbmpeg/ci.hh
@ -1,167 +0,0 @@
|
|||||||
/*
|
|
||||||
* ci.hh: Common Interface
|
|
||||||
*
|
|
||||||
* Copyright (C) 2000 Klaus Schmidinger
|
|
||||||
*
|
|
||||||
* This program is free software; you can redistribute it and/or
|
|
||||||
* modify it under the terms of the GNU General Public License
|
|
||||||
* as published by the Free Software Foundation; either version 2
|
|
||||||
* of the License, or (at your option) any later version.
|
|
||||||
*
|
|
||||||
* This program is distributed in the hope that it will be useful,
|
|
||||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
||||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
||||||
* GNU General Public License for more details.
|
|
||||||
*
|
|
||||||
* You should have received a copy of the GNU General Public License
|
|
||||||
* along with this program; if not, write to the Free Software
|
|
||||||
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
|
||||||
* Or, point your browser to http://www.gnu.org/copyleft/gpl.html
|
|
||||||
*
|
|
||||||
* The author can be reached at kls@cadsoft.de
|
|
||||||
*
|
|
||||||
* The project's page is at http://www.cadsoft.de/people/kls/vdr
|
|
||||||
*
|
|
||||||
*/
|
|
||||||
|
|
||||||
#ifndef __CI_H
|
|
||||||
#define __CI_H
|
|
||||||
|
|
||||||
#include <stdint.h>
|
|
||||||
#include <stdio.h>
|
|
||||||
|
|
||||||
#include <pthread.h>
|
|
||||||
#include <sys/types.h>
|
|
||||||
#include <sys/socket.h>
|
|
||||||
#include <netinet/in.h>
|
|
||||||
#include <sys/un.h>
|
|
||||||
#include <sys/stat.h>
|
|
||||||
#include <sys/uio.h>
|
|
||||||
|
|
||||||
#define MAXCASYSTEMIDS 16
|
|
||||||
|
|
||||||
class cMutex {
|
|
||||||
friend class cCondVar;
|
|
||||||
private:
|
|
||||||
pthread_mutex_t mutex;
|
|
||||||
pid_t lockingPid;
|
|
||||||
int locked;
|
|
||||||
public:
|
|
||||||
cMutex(void);
|
|
||||||
~cMutex();
|
|
||||||
void Lock(void);
|
|
||||||
void Unlock(void);
|
|
||||||
};
|
|
||||||
|
|
||||||
class cMutexLock {
|
|
||||||
private:
|
|
||||||
cMutex *mutex;
|
|
||||||
bool locked;
|
|
||||||
public:
|
|
||||||
cMutexLock(cMutex *Mutex = NULL);
|
|
||||||
~cMutexLock();
|
|
||||||
bool Lock(cMutex *Mutex);
|
|
||||||
};
|
|
||||||
|
|
||||||
|
|
||||||
class cCiMMI;
|
|
||||||
|
|
||||||
class cCiMenu {
|
|
||||||
friend class cCiMMI;
|
|
||||||
private:
|
|
||||||
enum { MAX_CIMENU_ENTRIES = 64 }; ///< XXX is there a specified maximum?
|
|
||||||
cCiMMI *mmi;
|
|
||||||
bool selectable;
|
|
||||||
char *titleText;
|
|
||||||
char *subTitleText;
|
|
||||||
char *bottomText;
|
|
||||||
char *entries[MAX_CIMENU_ENTRIES];
|
|
||||||
int numEntries;
|
|
||||||
bool AddEntry(char *s);
|
|
||||||
cCiMenu(cCiMMI *MMI, bool Selectable);
|
|
||||||
public:
|
|
||||||
~cCiMenu();
|
|
||||||
const char *TitleText(void) { return titleText; }
|
|
||||||
const char *SubTitleText(void) { return subTitleText; }
|
|
||||||
const char *BottomText(void) { return bottomText; }
|
|
||||||
const char *Entry(int n) { return n < numEntries ? entries[n] : NULL; }
|
|
||||||
int NumEntries(void) { return numEntries; }
|
|
||||||
bool Selectable(void) { return selectable; }
|
|
||||||
bool Select(int Index);
|
|
||||||
bool Cancel(void);
|
|
||||||
};
|
|
||||||
|
|
||||||
class cCiEnquiry {
|
|
||||||
friend class cCiMMI;
|
|
||||||
private:
|
|
||||||
cCiMMI *mmi;
|
|
||||||
char *text;
|
|
||||||
bool blind;
|
|
||||||
int expectedLength;
|
|
||||||
cCiEnquiry(cCiMMI *MMI);
|
|
||||||
public:
|
|
||||||
~cCiEnquiry();
|
|
||||||
const char *Text(void) { return text; }
|
|
||||||
bool Blind(void) { return blind; }
|
|
||||||
int ExpectedLength(void) { return expectedLength; }
|
|
||||||
bool Reply(const char *s);
|
|
||||||
bool Cancel(void);
|
|
||||||
};
|
|
||||||
|
|
||||||
class cCiCaPmt {
|
|
||||||
friend class cCiConditionalAccessSupport;
|
|
||||||
private:
|
|
||||||
int length;
|
|
||||||
int esInfoLengthPos;
|
|
||||||
uint8_t capmt[2048]; ///< XXX is there a specified maximum?
|
|
||||||
public:
|
|
||||||
cCiCaPmt(int ProgramNumber);
|
|
||||||
void AddPid(int Pid);
|
|
||||||
void AddCaDescriptor(int Length, uint8_t *Data);
|
|
||||||
};
|
|
||||||
|
|
||||||
#define MAX_CI_SESSION 16 //XXX
|
|
||||||
|
|
||||||
class cCiSession;
|
|
||||||
class cCiTransportLayer;
|
|
||||||
class cCiTransportConnection;
|
|
||||||
|
|
||||||
class cCiHandler {
|
|
||||||
private:
|
|
||||||
cMutex mutex;
|
|
||||||
int numSlots;
|
|
||||||
bool newCaSupport;
|
|
||||||
bool hasUserIO;
|
|
||||||
cCiSession *sessions[MAX_CI_SESSION];
|
|
||||||
cCiTransportLayer *tpl;
|
|
||||||
cCiTransportConnection *tc;
|
|
||||||
int ResourceIdToInt(const uint8_t *Data);
|
|
||||||
bool Send(uint8_t Tag, int SessionId, int ResourceId = 0, int Status = -1);
|
|
||||||
cCiSession *GetSessionBySessionId(int SessionId);
|
|
||||||
cCiSession *GetSessionByResourceId(int ResourceId, int Slot);
|
|
||||||
cCiSession *CreateSession(int ResourceId);
|
|
||||||
bool OpenSession(int Length, const uint8_t *Data);
|
|
||||||
bool CloseSession(int SessionId);
|
|
||||||
int CloseAllSessions(int Slot);
|
|
||||||
cCiHandler(int Fd, int NumSlots);
|
|
||||||
public:
|
|
||||||
~cCiHandler();
|
|
||||||
static cCiHandler *CreateCiHandler(const char *FileName);
|
|
||||||
int NumSlots(void) { return numSlots; }
|
|
||||||
bool Process(void);
|
|
||||||
bool HasUserIO(void) { return hasUserIO; }
|
|
||||||
bool EnterMenu(int Slot);
|
|
||||||
cCiMenu *GetMenu(void);
|
|
||||||
cCiEnquiry *GetEnquiry(void);
|
|
||||||
bool SetCaPmt(cCiCaPmt &CaPmt);
|
|
||||||
const unsigned short *GetCaSystemIds(int Slot);
|
|
||||||
bool SetCaPmt(cCiCaPmt &CaPmt, int Slot);
|
|
||||||
bool Reset(int Slot);
|
|
||||||
};
|
|
||||||
|
|
||||||
int tcp_listen(struct sockaddr_in *name,int sckt,unsigned long address=INADDR_ANY);
|
|
||||||
int accept_tcp(int ip_sock,struct sockaddr_in *ip_name);
|
|
||||||
int udp_listen(struct sockaddr_un *name,char const * const filename);
|
|
||||||
int accept_udp(int ip_sock,struct sockaddr_un *ip_name);
|
|
||||||
|
|
||||||
#endif //__CI_H
|
|
@ -1,948 +0,0 @@
|
|||||||
/*
|
|
||||||
* dvb-mpegtools for the Siemens Fujitsu DVB PCI card
|
|
||||||
*
|
|
||||||
* Copyright (C) 2000, 2001 Marcus Metzler
|
|
||||||
* for convergence integrated media GmbH
|
|
||||||
* Copyright (C) 2002 Marcus Metzler
|
|
||||||
*
|
|
||||||
* This program is free software; you can redistribute it and/or
|
|
||||||
* modify it under the terms of the GNU General Public License
|
|
||||||
* as published by the Free Software Foundation; either version 2
|
|
||||||
* of the License, or (at your option) any later version.
|
|
||||||
*
|
|
||||||
|
|
||||||
* This program is distributed in the hope that it will be useful,
|
|
||||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
||||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
||||||
* GNU General Public License for more details.
|
|
||||||
*
|
|
||||||
|
|
||||||
* You should have received a copy of the GNU General Public License
|
|
||||||
* along with this program; if not, write to the Free Software
|
|
||||||
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
|
||||||
* Or, point your browser to http://www.gnu.org/copyleft/gpl.html
|
|
||||||
*
|
|
||||||
|
|
||||||
* The author can be reached at mocm@metzlerbros.de
|
|
||||||
*/
|
|
||||||
|
|
||||||
#include "cpptools.hh"
|
|
||||||
|
|
||||||
#define HEX(N) "0x" << hex << setw(2) << setfill('0') \
|
|
||||||
<< int(N) << " " << dec
|
|
||||||
#define HHEX(N,M) "0x" << hex << setw(M) << setfill('0') \
|
|
||||||
<< int(N) << " " << dec
|
|
||||||
#define LHEX(N,M) "0x" << hex << setw(M) << setfill('0') \
|
|
||||||
<< long(N) << " " << dec
|
|
||||||
|
|
||||||
#define MAX_SEARCH 1024 * 1024
|
|
||||||
|
|
||||||
ostream & operator << (ostream & stream, PES_Packet & x){
|
|
||||||
|
|
||||||
if (x.info){
|
|
||||||
cerr << "PES Packet: " ;
|
|
||||||
switch ( x.p.stream_id ) {
|
|
||||||
|
|
||||||
case PROG_STREAM_MAP:
|
|
||||||
cerr << "Program Stream Map";
|
|
||||||
break;
|
|
||||||
case PRIVATE_STREAM2:
|
|
||||||
cerr << "Private Stream 2";
|
|
||||||
break;
|
|
||||||
case PROG_STREAM_DIR:
|
|
||||||
cerr << "Program Stream Directory";
|
|
||||||
break;
|
|
||||||
case ECM_STREAM :
|
|
||||||
cerr << "ECM Stream";
|
|
||||||
break;
|
|
||||||
case EMM_STREAM :
|
|
||||||
cerr << "EMM Stream";
|
|
||||||
break;
|
|
||||||
case PADDING_STREAM :
|
|
||||||
cerr << "Padding Stream";
|
|
||||||
break;
|
|
||||||
case DSM_CC_STREAM :
|
|
||||||
cerr << "DSM Stream";
|
|
||||||
break;
|
|
||||||
case ISO13522_STREAM:
|
|
||||||
cerr << "ISO13522 Stream";
|
|
||||||
break;
|
|
||||||
case PRIVATE_STREAM1:
|
|
||||||
cerr << "Private Stream 1";
|
|
||||||
break;
|
|
||||||
case AUDIO_STREAM_S ... AUDIO_STREAM_E:
|
|
||||||
cerr << "Audio Stream " << HEX(x.p.stream_id);
|
|
||||||
break;
|
|
||||||
case VIDEO_STREAM_S ... VIDEO_STREAM_E:
|
|
||||||
cerr << "Video Stream " << HEX(x.p.stream_id);
|
|
||||||
break;
|
|
||||||
|
|
||||||
}
|
|
||||||
cerr << " MPEG" << x.p.mpeg << endl;
|
|
||||||
if ( x.p.mpeg == 2 ){
|
|
||||||
cerr << " FLAGS: ";
|
|
||||||
|
|
||||||
if (x.p.flags1 & SCRAMBLE_FLAGS){
|
|
||||||
cerr << " SCRAMBLE(";
|
|
||||||
cerr << ((x.p.flags1 & SCRAMBLE_FLAGS)>>4);
|
|
||||||
cerr << ")";
|
|
||||||
}
|
|
||||||
if (x.p.flags1 & PRIORITY_FLAG)
|
|
||||||
cerr << " PRIORITY";
|
|
||||||
if (x.p.flags1 & DATA_ALIGN_FLAG)
|
|
||||||
cerr << " DATA_ALIGN";
|
|
||||||
if (x.p.flags1 & COPYRIGHT_FLAG)
|
|
||||||
cerr << " COPYRIGHT";
|
|
||||||
if (x.p.flags1 & ORIGINAL_FLAG)
|
|
||||||
cerr << " ORIGINAL";
|
|
||||||
|
|
||||||
if (x.p.flags2 & PTS_DTS_FLAGS){
|
|
||||||
cerr << " PTS_DTS(";
|
|
||||||
cerr << ((x.p.flags2 & PTS_DTS_FLAGS)>>6);
|
|
||||||
cerr << ")";
|
|
||||||
}
|
|
||||||
if (x.p.flags2 & ESCR_FLAG)
|
|
||||||
cerr << " ESCR";
|
|
||||||
if (x.p.flags2 & ES_RATE_FLAG)
|
|
||||||
cerr << " ES_RATE";
|
|
||||||
if (x.p.flags2 & DSM_TRICK_FLAG)
|
|
||||||
cerr << " DSM_TRICK";
|
|
||||||
if (x.p.flags2 & ADD_CPY_FLAG)
|
|
||||||
cerr << " ADD_CPY";
|
|
||||||
if (x.p.flags2 & PES_CRC_FLAG)
|
|
||||||
cerr << " CRC";
|
|
||||||
if (x.p.flags2 & PES_EXT_FLAG)
|
|
||||||
cerr << " EXT";
|
|
||||||
|
|
||||||
cerr << endl;
|
|
||||||
|
|
||||||
if ((x.p.flags2 & PTS_DTS_FLAGS) == PTS_ONLY)
|
|
||||||
cerr << " PTS: "
|
|
||||||
<< LHEX(ntohl(x.WPTS()),8)
|
|
||||||
<< "(h" << int(x.high_pts()) << ")"
|
|
||||||
<< endl;
|
|
||||||
else if ((x.p.flags2 & PTS_DTS_FLAGS) == PTS_DTS){
|
|
||||||
cerr << " PTS: "
|
|
||||||
<< LHEX(ntohl(x.WPTS()),8)
|
|
||||||
<< "(h" << int(x.high_pts()) << ")";
|
|
||||||
cerr << " DTS: "
|
|
||||||
<< LHEX(ntohl(x.WDTS()),8)
|
|
||||||
<< "(h" << int(x.high_dts()) << ")"
|
|
||||||
<< endl;
|
|
||||||
}
|
|
||||||
/*
|
|
||||||
if (x.p.flags2 & ESCR_FLAG)
|
|
||||||
|
|
||||||
|
|
||||||
if (x.p.flags2 & ES_RATE_FLAG)
|
|
||||||
|
|
||||||
|
|
||||||
if (x.p.flags2 & DSM_TRICK_FLAG)
|
|
||||||
|
|
||||||
|
|
||||||
if (x.p.flags2 & ADD_CPY_FLAG)
|
|
||||||
|
|
||||||
|
|
||||||
if (x.p.flags2 & PES_CRC_FLAG)
|
|
||||||
|
|
||||||
|
|
||||||
if (x.p.flags2 & PES_EXT_FLAG){
|
|
||||||
|
|
||||||
if (x.p.priv_flags & PRIVATE_DATA)
|
|
||||||
stream.write(x.p.pes_priv_data,16);
|
|
||||||
|
|
||||||
if (x.p.priv_flags & HEADER_FIELD){
|
|
||||||
stream.write(&x.p.pack_field_length,1);
|
|
||||||
x.p.pack_header = new
|
|
||||||
uint8_t[x.p.pack_field_length];
|
|
||||||
stream.write(x.p.pack_header,
|
|
||||||
x.p.pack_field_length);
|
|
||||||
}
|
|
||||||
|
|
||||||
if ( x.p.priv_flags & PACK_SEQ_CTR){
|
|
||||||
stream.write(&x.p.pck_sqnc_cntr,1);
|
|
||||||
stream.write(&x.p.org_stuff_length,1);
|
|
||||||
}
|
|
||||||
|
|
||||||
if ( x.p.priv_flags & P_STD_BUFFER)
|
|
||||||
stream.write(x.p.p_std,2);
|
|
||||||
|
|
||||||
if ( x.p.priv_flags & PES_EXT_FLAG2){
|
|
||||||
stream.write(&x.p.pes_ext_lngth,1);
|
|
||||||
x.p.pes_ext = new
|
|
||||||
uint8_t[x.p.pes_ext_lngth];
|
|
||||||
stream.write(x.p.pes_ext,
|
|
||||||
x.p.pes_ext_lngth);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
if ((x.p.flags2 & PTS_DTS_FLAGS) == PTS_ONLY)
|
|
||||||
stream.write(x.p.pts,5);
|
|
||||||
else if ((x.p.flags2 & PTS_DTS_FLAGS) ==
|
|
||||||
PTS_DTS){
|
|
||||||
stream.write(x.p.pts,5);
|
|
||||||
stream.write(x.p.dts,5);
|
|
||||||
}
|
|
||||||
*/
|
|
||||||
}
|
|
||||||
cerr << endl << endl;
|
|
||||||
return stream;
|
|
||||||
}
|
|
||||||
|
|
||||||
int l = x.p.length+x.p.pes_hlength+9;
|
|
||||||
uint8_t buf[l];
|
|
||||||
int length = cwrite_pes(buf,&(x.p),l);
|
|
||||||
stream.write((char *)buf,length);
|
|
||||||
|
|
||||||
return stream;
|
|
||||||
}
|
|
||||||
|
|
||||||
static unsigned int find_length(istream & stream){
|
|
||||||
streampos p = 0;
|
|
||||||
streampos start = 0;
|
|
||||||
streampos q = 0;
|
|
||||||
int found = 0;
|
|
||||||
uint8_t sync4[4];
|
|
||||||
|
|
||||||
start = stream.tellg();
|
|
||||||
start -=2;
|
|
||||||
stream.seekg(start);
|
|
||||||
while ( !stream.eof() && !found ){
|
|
||||||
p = stream.tellg();
|
|
||||||
stream.read((char *)&sync4,4);
|
|
||||||
if (sync4[0] == 0x00 && sync4[1] == 0x00 && sync4[2] == 0x01) {
|
|
||||||
switch ( sync4[3] ) {
|
|
||||||
|
|
||||||
case PROG_STREAM_MAP:
|
|
||||||
case PRIVATE_STREAM2:
|
|
||||||
case PROG_STREAM_DIR:
|
|
||||||
case ECM_STREAM :
|
|
||||||
case EMM_STREAM :
|
|
||||||
case PADDING_STREAM :
|
|
||||||
case DSM_CC_STREAM :
|
|
||||||
case ISO13522_STREAM:
|
|
||||||
case PRIVATE_STREAM1:
|
|
||||||
case AUDIO_STREAM_S ... AUDIO_STREAM_E:
|
|
||||||
case VIDEO_STREAM_S ... VIDEO_STREAM_E:
|
|
||||||
found = 1;
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
q = stream.tellg();
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
q = stream.tellg();
|
|
||||||
stream.seekg(streampos(2)+start);
|
|
||||||
if (found) return (unsigned int)(q-start)-4-2;
|
|
||||||
else return (unsigned int)(q-start)-2;
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
istream & operator >> (istream & stream, PES_Packet & x){
|
|
||||||
|
|
||||||
uint8_t sync4[4];
|
|
||||||
int found=0;
|
|
||||||
int done=0;
|
|
||||||
streampos p = 0;
|
|
||||||
|
|
||||||
while (!stream.eof() && !found) {
|
|
||||||
p = stream.tellg();
|
|
||||||
stream.read((char *)&sync4,4);
|
|
||||||
if (sync4[0] == 0x00 && sync4[1] == 0x00 && sync4[2] == 0x01) {
|
|
||||||
x.p.stream_id = sync4[3];
|
|
||||||
|
|
||||||
switch ( sync4[3] ) {
|
|
||||||
|
|
||||||
case PROG_STREAM_MAP:
|
|
||||||
case PRIVATE_STREAM2:
|
|
||||||
case PROG_STREAM_DIR:
|
|
||||||
case ECM_STREAM :
|
|
||||||
case EMM_STREAM :
|
|
||||||
found = 1;
|
|
||||||
stream.read((char *)x.p.llength,2);
|
|
||||||
x.setlength();
|
|
||||||
if (!x.p.length){
|
|
||||||
x.p.length = find_length(stream);
|
|
||||||
x.Nlength();
|
|
||||||
}
|
|
||||||
stream.read((char *)x.p.pes_pckt_data,x.p.length);
|
|
||||||
done = 1;
|
|
||||||
break;
|
|
||||||
case PADDING_STREAM :
|
|
||||||
found = 1;
|
|
||||||
stream.read((char *)x.p.llength,2);
|
|
||||||
x.setlength();
|
|
||||||
if (!x.p.length){
|
|
||||||
x.p.length = find_length(stream);
|
|
||||||
x.Nlength();
|
|
||||||
}
|
|
||||||
x.p.padding = x.p.length;
|
|
||||||
stream.read((char *)x.p.pes_pckt_data,x.p.length);
|
|
||||||
done = 1;
|
|
||||||
break;
|
|
||||||
|
|
||||||
case DSM_CC_STREAM :
|
|
||||||
case ISO13522_STREAM:
|
|
||||||
case PRIVATE_STREAM1:
|
|
||||||
case AUDIO_STREAM_S ... AUDIO_STREAM_E:
|
|
||||||
case VIDEO_STREAM_S ... VIDEO_STREAM_E:
|
|
||||||
stream.read((char *)x.p.llength,2);
|
|
||||||
x.setlength();
|
|
||||||
if (!x.p.length){
|
|
||||||
x.p.length = find_length(stream);
|
|
||||||
x.Nlength();
|
|
||||||
}
|
|
||||||
found = 1;
|
|
||||||
break;
|
|
||||||
|
|
||||||
default:
|
|
||||||
stream.seekg(p+streampos(1));
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
} else stream.seekg(p+streampos(1));
|
|
||||||
}
|
|
||||||
|
|
||||||
if ( found && !done) {
|
|
||||||
p = stream.tellg();
|
|
||||||
stream.read((char *)&x.p.flags1,1);
|
|
||||||
if ( (x.p.flags1 & 0xC0) == 0x80 )
|
|
||||||
x.p.mpeg = 2;
|
|
||||||
else
|
|
||||||
x.p.mpeg = 1;
|
|
||||||
if ( x.p.mpeg == 2 ){
|
|
||||||
stream.read((char *)&x.p.flags2,1);
|
|
||||||
stream.read((char *)&x.p.pes_hlength,1);
|
|
||||||
|
|
||||||
if ((int)x.p.length > x.p.pes_hlength+3)
|
|
||||||
x.p.length -=x.p.pes_hlength+3;
|
|
||||||
else
|
|
||||||
return stream;
|
|
||||||
|
|
||||||
uint8_t count = x.p.pes_hlength;
|
|
||||||
|
|
||||||
if ((x.p.flags2 & PTS_DTS_FLAGS) == PTS_ONLY){
|
|
||||||
stream.read((char *)x.p.pts,5);
|
|
||||||
count -=5;
|
|
||||||
} else
|
|
||||||
if ((x.p.flags2 & PTS_DTS_FLAGS) == PTS_DTS){
|
|
||||||
stream.read((char *)x.p.pts,5);
|
|
||||||
stream.read((char *)x.p.dts,5);
|
|
||||||
count -= 10;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (x.p.flags2 & ESCR_FLAG){
|
|
||||||
stream.read((char *)x.p.escr,6);
|
|
||||||
count -= 6;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (x.p.flags2 & ES_RATE_FLAG){
|
|
||||||
stream.read((char *)x.p.es_rate,3);
|
|
||||||
count -= 6;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (x.p.flags2 & DSM_TRICK_FLAG){
|
|
||||||
stream.read((char *)&x.p.trick,1);
|
|
||||||
count -= 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (x.p.flags2 & ADD_CPY_FLAG){
|
|
||||||
stream.read((char *)&x.p.add_cpy,1);
|
|
||||||
count -= 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (x.p.flags2 & PES_CRC_FLAG){
|
|
||||||
stream.read((char *)x.p.prev_pes_crc,2);
|
|
||||||
count -= 2;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (x.p.flags2 & PES_EXT_FLAG){
|
|
||||||
stream.read((char *)&x.p.priv_flags,1);
|
|
||||||
count -= 1;
|
|
||||||
|
|
||||||
if (x.p.priv_flags & PRIVATE_DATA){
|
|
||||||
stream.read((char *)x.p.pes_priv_data,16);
|
|
||||||
count -= 16;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (x.p.priv_flags & HEADER_FIELD){
|
|
||||||
stream.read((char *)&x.p.pack_field_length,1);
|
|
||||||
x.p.pack_header = new
|
|
||||||
uint8_t[x.p.pack_field_length];
|
|
||||||
stream.read((char *)x.p.pack_header,
|
|
||||||
x.p.pack_field_length);
|
|
||||||
count -= 1+x.p.pack_field_length;
|
|
||||||
}
|
|
||||||
|
|
||||||
if ( x.p.priv_flags & PACK_SEQ_CTR){
|
|
||||||
stream.read((char *)&x.p.pck_sqnc_cntr,1);
|
|
||||||
stream.read((char *)&x.p.org_stuff_length,1);
|
|
||||||
count -= 2;
|
|
||||||
}
|
|
||||||
|
|
||||||
if ( x.p.priv_flags & P_STD_BUFFER){
|
|
||||||
stream.read((char *)x.p.p_std,2);
|
|
||||||
count -= 2;
|
|
||||||
}
|
|
||||||
|
|
||||||
if ( x.p.priv_flags & PES_EXT_FLAG2){
|
|
||||||
stream.read((char *)&x.p.pes_ext_lngth,1);
|
|
||||||
x.p.pes_ext = new
|
|
||||||
uint8_t[x.p.pes_ext_lngth];
|
|
||||||
stream.read((char *)x.p.pes_ext,
|
|
||||||
x.p.pes_ext_lngth);
|
|
||||||
count -= 1+x.p.pes_ext_lngth;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
x.p.stuffing = count;
|
|
||||||
uint8_t dummy;
|
|
||||||
for(int i = 0; i< count ;i++)
|
|
||||||
stream.read((char *)&dummy,1);
|
|
||||||
|
|
||||||
} else {
|
|
||||||
uint8_t check;
|
|
||||||
x.p.mpeg1_pad = 1;
|
|
||||||
check = x.p.flags1;
|
|
||||||
while (check == 0xFF){
|
|
||||||
stream.read((char *)&check,1);
|
|
||||||
x.p.mpeg1_pad++;
|
|
||||||
}
|
|
||||||
|
|
||||||
if ( (check & 0xC0) == 0x40){
|
|
||||||
stream.read((char *)&check,1);
|
|
||||||
x.p.mpeg1_pad++;
|
|
||||||
stream.read((char *)&check,1);
|
|
||||||
x.p.mpeg1_pad++;
|
|
||||||
}
|
|
||||||
x.p.flags2 = 0;
|
|
||||||
x.p.length -= x.p.mpeg1_pad;
|
|
||||||
|
|
||||||
stream.seekg(p);
|
|
||||||
if ( (check & 0x30)){
|
|
||||||
x.p.length ++;
|
|
||||||
x.p.mpeg1_pad --;
|
|
||||||
|
|
||||||
if (check == x.p.flags1){
|
|
||||||
x.p.pes_hlength = 0;
|
|
||||||
} else {
|
|
||||||
x.p.mpeg1_headr =
|
|
||||||
new uint8_t[x.p.mpeg1_pad];
|
|
||||||
x.p.pes_hlength = x.p.mpeg1_pad;
|
|
||||||
stream.read((char *)x.p.mpeg1_headr,
|
|
||||||
x.p.mpeg1_pad);
|
|
||||||
}
|
|
||||||
|
|
||||||
x.p.flags2 = (check & 0xF0) << 2;
|
|
||||||
if ((x.p.flags2 & PTS_DTS_FLAGS) == PTS_ONLY){
|
|
||||||
stream.read((char *)x.p.pts,5);
|
|
||||||
x.p.length -= 5;
|
|
||||||
x.p.pes_hlength += 5;
|
|
||||||
}
|
|
||||||
else if ((x.p.flags2 & PTS_DTS_FLAGS) ==
|
|
||||||
PTS_DTS){
|
|
||||||
stream.read((char *)x.p.pts,5);
|
|
||||||
stream.read((char *)x.p.dts,5);
|
|
||||||
x.p.length -= 10;
|
|
||||||
x.p.pes_hlength += 10;
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
x.p.mpeg1_headr = new uint8_t[x.p.mpeg1_pad];
|
|
||||||
x.p.pes_hlength = x.p.mpeg1_pad;
|
|
||||||
stream.read((char *)x.p.mpeg1_headr,x.p.mpeg1_pad);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
stream.read((char *)x.p.pes_pckt_data,x.p.length);
|
|
||||||
}
|
|
||||||
return stream;
|
|
||||||
}
|
|
||||||
|
|
||||||
ostream & operator << (ostream & stream, TS_Packet & x){
|
|
||||||
|
|
||||||
uint8_t buf[TS_SIZE];
|
|
||||||
int length = cwrite_ts(buf,&(x.p),TS_SIZE);
|
|
||||||
stream.write((char *)buf,length);
|
|
||||||
|
|
||||||
return stream;
|
|
||||||
}
|
|
||||||
|
|
||||||
istream & operator >> (istream & stream, TS_Packet & x){
|
|
||||||
uint8_t sync;
|
|
||||||
int found=0;
|
|
||||||
streampos p,q;
|
|
||||||
|
|
||||||
sync=0;
|
|
||||||
while (!stream.eof() && !found) {
|
|
||||||
stream.read((char *)&sync,1);
|
|
||||||
if (sync == 0x47)
|
|
||||||
found = 1;
|
|
||||||
}
|
|
||||||
stream.read((char *)x.p.pid,2);
|
|
||||||
stream.read((char *)&x.p.flags,1);
|
|
||||||
x.p.count = x.p.flags & COUNT_MASK;
|
|
||||||
|
|
||||||
if (!(x.p.flags & ADAPT_FIELD) && (x.p.flags & PAYLOAD)){
|
|
||||||
//no adapt. field only payload
|
|
||||||
stream.read((char *)x.p.data,184);
|
|
||||||
x.p.rest = 184;
|
|
||||||
return stream;
|
|
||||||
}
|
|
||||||
|
|
||||||
if ( x.p.flags & ADAPT_FIELD ) {
|
|
||||||
// adaption field
|
|
||||||
stream.read((char *)&x.p.adapt_length,1);
|
|
||||||
if (x.p.adapt_length){
|
|
||||||
p = stream.tellg();
|
|
||||||
stream.read((char *)&x.p.adapt_flags,1);
|
|
||||||
|
|
||||||
if ( x.p.adapt_flags & PCR_FLAG )
|
|
||||||
stream.read((char *) x.p.pcr,6);
|
|
||||||
|
|
||||||
if ( x.p.adapt_flags & OPCR_FLAG )
|
|
||||||
stream.read((char *) x.p.opcr,6);
|
|
||||||
|
|
||||||
if ( x.p.adapt_flags & SPLICE_FLAG )
|
|
||||||
stream.read((char *) &x.p.splice_count,1);
|
|
||||||
|
|
||||||
if( x.p.adapt_flags & TRANS_PRIV){
|
|
||||||
stream.read((char *)&x.p.priv_dat_len,1);
|
|
||||||
x.p.priv_dat = new uint8_t[x.p.priv_dat_len];
|
|
||||||
stream.read((char *)x.p.priv_dat,x.p.priv_dat_len);
|
|
||||||
}
|
|
||||||
|
|
||||||
if( x.p.adapt_flags & ADAP_EXT_FLAG){
|
|
||||||
stream.read((char *)&x.p.adapt_ext_len,1);
|
|
||||||
stream.read((char *)&x.p.adapt_eflags,1);
|
|
||||||
if( x.p.adapt_eflags & LTW_FLAG)
|
|
||||||
stream.read((char *)x.p.ltw,2);
|
|
||||||
|
|
||||||
if( x.p.adapt_eflags & PIECE_RATE)
|
|
||||||
stream.read((char *)x.p.piece_rate,3);
|
|
||||||
|
|
||||||
if( x.p.adapt_eflags & SEAM_SPLICE)
|
|
||||||
stream.read((char *)x.p.dts,5);
|
|
||||||
}
|
|
||||||
q = stream.tellg();
|
|
||||||
x.p.stuffing = x.p.adapt_length -(q-p);
|
|
||||||
x.p.rest = 183-x.p.adapt_length;
|
|
||||||
stream.seekg(q+streampos(x.p.stuffing));
|
|
||||||
if (x.p.flags & PAYLOAD) // payload
|
|
||||||
stream.read((char *)x.p.data,x.p.rest);
|
|
||||||
else
|
|
||||||
stream.seekg(q+streampos(x.p.rest));
|
|
||||||
} else {
|
|
||||||
x.p.rest = 182;
|
|
||||||
stream.read((char *)x.p.data, 183);
|
|
||||||
return stream;
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
return stream;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
ostream & operator << (ostream & stream, PS_Packet & x){
|
|
||||||
|
|
||||||
uint8_t buf[PS_MAX];
|
|
||||||
int length = cwrite_ps(buf,&(x.p),PS_MAX);
|
|
||||||
stream.write((char *)buf,length);
|
|
||||||
|
|
||||||
return stream;
|
|
||||||
}
|
|
||||||
|
|
||||||
istream & operator >> (istream & stream, PS_Packet & x){
|
|
||||||
uint8_t headr[4];
|
|
||||||
int found=0;
|
|
||||||
streampos p = 0;
|
|
||||||
streampos q = 0;
|
|
||||||
int count = 0;
|
|
||||||
|
|
||||||
p = stream.tellg();
|
|
||||||
while (!stream.eof() && !found && count < MAX_SEARCH) {
|
|
||||||
stream.read((char *)&headr,4);
|
|
||||||
if (headr[0] == 0x00 && headr[1] == 0x00 && headr[2] == 0x01) {
|
|
||||||
if ( headr[3] == 0xBA )
|
|
||||||
found = 1;
|
|
||||||
else if ( headr[3] == 0xB9 ) break;
|
|
||||||
else stream.seekg(p+streampos(1));
|
|
||||||
}
|
|
||||||
count++;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (found){
|
|
||||||
stream.read((char *)x.p.scr,6);
|
|
||||||
if (x.p.scr[0] & 0x40)
|
|
||||||
x.p.mpeg = 2;
|
|
||||||
else
|
|
||||||
x.p.mpeg = 1;
|
|
||||||
|
|
||||||
if (x.p.mpeg == 2){
|
|
||||||
stream.read((char *)x.p.mux_rate,3);
|
|
||||||
stream.read((char *)&x.p.stuff_length,1);
|
|
||||||
p = stream.tellg();
|
|
||||||
stream.seekg(p+streampos(x.p.stuff_length & 3));
|
|
||||||
} else {
|
|
||||||
x.p.mux_rate[0] = x.p.scr[5]; //mpeg1 scr is only 5 bytes
|
|
||||||
stream.read((char *)x.p.mux_rate+1,2);
|
|
||||||
}
|
|
||||||
|
|
||||||
p=stream.tellg();
|
|
||||||
stream.read((char *)headr,4);
|
|
||||||
if (headr[0] == 0x00 && headr[1] == 0x00 &&
|
|
||||||
headr[2] == 0x01 && headr[3] == 0xBB ) {
|
|
||||||
stream.read((char *)x.p.sheader_llength,2);
|
|
||||||
x.setlength();
|
|
||||||
if (x.p.mpeg == 2){
|
|
||||||
stream.read((char *)x.p.rate_bound,3);
|
|
||||||
stream.read((char *)&x.p.audio_bound,1);
|
|
||||||
stream.read((char *)&x.p.video_bound,1);
|
|
||||||
stream.read((char *)&x.p.reserved,1);
|
|
||||||
}
|
|
||||||
stream.read((char *)x.p.data,x.p.sheader_length);
|
|
||||||
} else {
|
|
||||||
stream.seekg(p);
|
|
||||||
x.p.sheader_length = 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
int i = 0;
|
|
||||||
int done = 0;
|
|
||||||
q = stream.tellg();
|
|
||||||
PES_Packet pes;
|
|
||||||
do {
|
|
||||||
p=stream.tellg();
|
|
||||||
stream.read((char *)headr,4);
|
|
||||||
stream.seekg(p);
|
|
||||||
if ( headr[0] == 0x00 && headr[1] == 0x00
|
|
||||||
&& headr[2] == 0x01 && headr[3] != 0xBA){
|
|
||||||
pes.init();
|
|
||||||
stream >> pes;
|
|
||||||
i++;
|
|
||||||
} else done = 1;
|
|
||||||
} while (!stream.eof() && !done);
|
|
||||||
x.p.npes = i;
|
|
||||||
stream.seekg(q);
|
|
||||||
}
|
|
||||||
return stream;
|
|
||||||
}
|
|
||||||
|
|
||||||
void extract_audio_from_PES(istream &in, ostream &out){
|
|
||||||
PES_Packet pes;
|
|
||||||
|
|
||||||
while(!in.eof()){
|
|
||||||
pes.init();
|
|
||||||
in >> pes ;
|
|
||||||
if (pes.Stream_ID() == 0xC0)
|
|
||||||
out << pes;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void extract_video_from_PES(istream &in, ostream &out){
|
|
||||||
PES_Packet pes;
|
|
||||||
|
|
||||||
while(!in.eof()){
|
|
||||||
pes.init();
|
|
||||||
in >> pes ;
|
|
||||||
if (pes.Stream_ID() == 0xE0)
|
|
||||||
out << pes;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void extract_es_audio_from_PES(istream &in, ostream &out){
|
|
||||||
PES_Packet pes;
|
|
||||||
|
|
||||||
while(!in.eof()){
|
|
||||||
pes.init();
|
|
||||||
in >> pes ;
|
|
||||||
if (pes.Stream_ID() == 0xC0)
|
|
||||||
out.write((char *)pes.Data(),pes.Length());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void extract_es_video_from_PES(istream &in, ostream &out){
|
|
||||||
PES_Packet pes;
|
|
||||||
|
|
||||||
while(!in.eof()){
|
|
||||||
pes.init();
|
|
||||||
in >> pes ;
|
|
||||||
if (pes.Stream_ID() == 0xE0)
|
|
||||||
out.write((char *)pes.Data(),pes.Length());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
#define MAX_PID 20
|
|
||||||
int TS_PIDS(istream &in, ostream &out){
|
|
||||||
int pid[MAX_PID];
|
|
||||||
TS_Packet ts;
|
|
||||||
int npid=0;
|
|
||||||
|
|
||||||
for (int i=0 ; i<MAX_PID; i++)
|
|
||||||
pid[i] = -1;
|
|
||||||
while (!in.eof()) {
|
|
||||||
ts.init();
|
|
||||||
in >> ts;
|
|
||||||
int j;
|
|
||||||
int found = 0;
|
|
||||||
for (j=0;j<npid;j++){
|
|
||||||
if ( ts.PID() == pid[j] )
|
|
||||||
found = 1;
|
|
||||||
}
|
|
||||||
if (! found){
|
|
||||||
out << ts.PID() << " ";
|
|
||||||
pid[npid] = ts.PID();
|
|
||||||
npid++;
|
|
||||||
if (npid == MAX_PID) return -1;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
out << endl;
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
int tv_norm(istream &stream){
|
|
||||||
uint8_t headr[4];
|
|
||||||
int found=0;
|
|
||||||
streampos p = 0;
|
|
||||||
streampos q = 0;
|
|
||||||
int hsize,vsize;
|
|
||||||
int form= 0;
|
|
||||||
|
|
||||||
q = stream.tellg();
|
|
||||||
while (!stream.eof() && !found) {
|
|
||||||
p = stream.tellg();
|
|
||||||
stream.read((char *)headr,4);
|
|
||||||
if (headr[0] == 0x00 && headr[1] == 0x00 && headr[2] == 0x01)
|
|
||||||
if ( headr[3] == 0xB3 ){
|
|
||||||
found = 1;
|
|
||||||
}
|
|
||||||
if (! found) stream.seekg(p+streampos(1));
|
|
||||||
}
|
|
||||||
stream.read((char *)headr,4);
|
|
||||||
|
|
||||||
hsize = (headr[1] &0xF0) >> 4 | headr[0] << 4;
|
|
||||||
vsize = (headr[1] &0x0F) << 8 | headr[2];
|
|
||||||
cerr << "SIZE: " << hsize << "x" << vsize << endl;
|
|
||||||
|
|
||||||
switch(((headr[3]&0xF0) >>4)){
|
|
||||||
case 1:
|
|
||||||
cerr << "ASPECT: 1:1" << endl;
|
|
||||||
break;
|
|
||||||
case 2:
|
|
||||||
cerr << "ASPECT: 4:3" << endl;
|
|
||||||
break;
|
|
||||||
case 3:
|
|
||||||
cerr << "ASPECT: 16:9" << endl;
|
|
||||||
break;
|
|
||||||
case 4:
|
|
||||||
cerr << "ASPECT: 2.21:1" << endl;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
switch (int(headr[3]&0x0F)){
|
|
||||||
case 1:
|
|
||||||
cerr << "FRAMERATE: 23.976" << endl;
|
|
||||||
form = pDUNNO;
|
|
||||||
break;
|
|
||||||
case 2:
|
|
||||||
cerr << "FRAMERATE: 24" << endl;
|
|
||||||
form = pDUNNO;
|
|
||||||
break;
|
|
||||||
case 3:
|
|
||||||
cerr << "FRAMERATE: 25" << endl;
|
|
||||||
form = pPAL;
|
|
||||||
break;
|
|
||||||
case 4:
|
|
||||||
cerr << "FRAMERATE: 29.97" << endl;
|
|
||||||
form = pNTSC;
|
|
||||||
break;
|
|
||||||
case 5:
|
|
||||||
cerr << "FRAMERATE: 30" << endl;
|
|
||||||
form = pNTSC;
|
|
||||||
break;
|
|
||||||
case 6:
|
|
||||||
cerr << "FRAMERATE: 50" << endl;
|
|
||||||
form = pPAL;
|
|
||||||
break;
|
|
||||||
case 7:
|
|
||||||
cerr << "FRAMERATE: 59.94" << endl;
|
|
||||||
form = pNTSC;
|
|
||||||
break;
|
|
||||||
case 8:
|
|
||||||
cerr << "FRAMERATE: 60" << endl;
|
|
||||||
form = pNTSC;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
int mpeg = 0;
|
|
||||||
found = 0;
|
|
||||||
while (!stream.eof() && !found) {
|
|
||||||
p = stream.tellg();
|
|
||||||
stream.read((char *)headr,4);
|
|
||||||
if (headr[0] == 0x00 && headr[1] == 0x00 && headr[2] == 0x01) {
|
|
||||||
if ( headr[3] == 0xB5 ){
|
|
||||||
const char *profile[] = {"reserved", "High", "Spatially Scalable",
|
|
||||||
"SNR Scalable", "Main", "Simple", "undef",
|
|
||||||
"undef"};
|
|
||||||
const char *level[] = {"res", "res", "res", "res",
|
|
||||||
"High","res", "High 1440", "res",
|
|
||||||
"Main","res", "Low", "res",
|
|
||||||
"res", "res", "res", "res"};
|
|
||||||
const char *chroma[] = {"res", "4:2:0", "4:2:2", "4:4:4:"};
|
|
||||||
mpeg = 2;
|
|
||||||
stream.read((char *)headr,4);
|
|
||||||
cerr << "PROFILE: " << profile[headr[0] & 0x7] << endl;
|
|
||||||
cerr << "LEVEL: " << level[headr[1]>>4 & 0xF] << endl;
|
|
||||||
cerr << "CHROMA: " << chroma[headr[1]>>1 & 0x3] << endl;
|
|
||||||
found = 1;
|
|
||||||
} else {
|
|
||||||
mpeg = 1;
|
|
||||||
found = 1;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (! found) stream.seekg(p+streampos(1));
|
|
||||||
}
|
|
||||||
|
|
||||||
stream.seekg(q);
|
|
||||||
return (form | mpeg << 4);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
int stream_type(istream &fin){
|
|
||||||
uint8_t headr[4];
|
|
||||||
streampos p=fin.tellg();
|
|
||||||
|
|
||||||
TS_Packet ts;
|
|
||||||
fin >> ts;
|
|
||||||
fin.read((char *)headr,1);
|
|
||||||
fin.seekg(p);
|
|
||||||
if(fin && headr[0] == 0x47){
|
|
||||||
return TS_STREAM;
|
|
||||||
}
|
|
||||||
|
|
||||||
PS_Packet ps;
|
|
||||||
fin >> ps;
|
|
||||||
PES_Packet pes;
|
|
||||||
for(int j=0;j < ps.NPES();j++){
|
|
||||||
fin >> pes;
|
|
||||||
}
|
|
||||||
fin.read((char *)headr,4);
|
|
||||||
fin.seekg(p);
|
|
||||||
if (fin && headr[0] == 0x00 && headr[1] == 0x00
|
|
||||||
&& headr[2] == 0x01 && headr[3] == 0xBA){
|
|
||||||
return PS_STREAM;
|
|
||||||
}
|
|
||||||
|
|
||||||
fin >> pes;
|
|
||||||
fin.read((char *)NULL,4);
|
|
||||||
fin.seekg(p);
|
|
||||||
if (fin && headr[0] == 0x00 && headr[1] == 0x00
|
|
||||||
&& headr[2] == 0x01 ){
|
|
||||||
int found = 0;
|
|
||||||
switch ( headr[3] ) {
|
|
||||||
|
|
||||||
case PROG_STREAM_MAP:
|
|
||||||
case PRIVATE_STREAM2:
|
|
||||||
case PROG_STREAM_DIR:
|
|
||||||
case ECM_STREAM :
|
|
||||||
case EMM_STREAM :
|
|
||||||
case PADDING_STREAM :
|
|
||||||
case DSM_CC_STREAM :
|
|
||||||
case ISO13522_STREAM:
|
|
||||||
case PRIVATE_STREAM1:
|
|
||||||
case AUDIO_STREAM_S ... AUDIO_STREAM_E:
|
|
||||||
case VIDEO_STREAM_S ... VIDEO_STREAM_E:
|
|
||||||
found = 1;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
if (found){
|
|
||||||
return PES_STREAM;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
void analyze(istream &fin)
|
|
||||||
{
|
|
||||||
PS_Packet ps;
|
|
||||||
PES_Packet pes;
|
|
||||||
int fc = 0;
|
|
||||||
const char *frames[3] = {"I-Frame","P-Frame","B-Frame"};
|
|
||||||
|
|
||||||
while(fin){
|
|
||||||
uint32_t pts;
|
|
||||||
fin >> ps;
|
|
||||||
cerr << "SCR base: " << hex << setw(5)
|
|
||||||
<< setfill('0') \
|
|
||||||
<< ps.SCR_base() << " " << dec
|
|
||||||
<< "ext : " << ps.SCR_ext();
|
|
||||||
|
|
||||||
cerr << " MUX rate: " << ps.MUX()*50*8/1000000.0
|
|
||||||
<< " Mbit/s ";
|
|
||||||
cerr << "RATE bound: " << ps.Rate()*50*8/1000000.0
|
|
||||||
<< " Mbit/s" << endl;
|
|
||||||
cerr << " Audio bound: "
|
|
||||||
<< hex << "0x"
|
|
||||||
<< int(ps.P()->audio_bound);
|
|
||||||
cerr << " Video bound: " << hex << "0x"
|
|
||||||
<< int(ps.P()->video_bound)
|
|
||||||
<< dec
|
|
||||||
<< endl;
|
|
||||||
cerr << endl;
|
|
||||||
|
|
||||||
for (int i=0; i < ps.NPES(); i++){
|
|
||||||
pes.init();
|
|
||||||
fin >> pes;
|
|
||||||
pts2pts((uint8_t *)&pts,pes.PTS());
|
|
||||||
pes.Info() = 1;
|
|
||||||
cerr << pes;
|
|
||||||
|
|
||||||
uint8_t *buf = pes.P()->pes_pckt_data;
|
|
||||||
int c = 0;
|
|
||||||
int l;
|
|
||||||
switch (pes.P()->stream_id){
|
|
||||||
case VIDEO_STREAM_S ... VIDEO_STREAM_E:
|
|
||||||
l=pes.P()->length;
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
l = 0;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
while ( c < l - 6){
|
|
||||||
if (buf[c] == 0x00 &&
|
|
||||||
buf[c+1] == 0x00 &&
|
|
||||||
buf[c+2] == 0x01 &&
|
|
||||||
buf[c+3] == 0xB8) {
|
|
||||||
c += 4;
|
|
||||||
cerr << "TIME hours: "
|
|
||||||
<< int((buf[c]>>2)& 0x1F)
|
|
||||||
<< " minutes: "
|
|
||||||
<< int(((buf[c]<<4)& 0x30)|
|
|
||||||
((buf[c+1]>>4)& 0x0F))
|
|
||||||
<< " seconds: "
|
|
||||||
<< int(((buf[c+1]<<3)& 0x38)|
|
|
||||||
((buf[c+2]>>5)& 0x0F))
|
|
||||||
<< endl;
|
|
||||||
}
|
|
||||||
|
|
||||||
if ( buf[c] == 0x00 &&
|
|
||||||
buf[c+1] == 0x00 &&
|
|
||||||
buf[c+2] == 0x01 &&
|
|
||||||
buf[c+3] == 0x00) {
|
|
||||||
fc++;
|
|
||||||
c += 4;
|
|
||||||
cerr << "picture: "
|
|
||||||
<< fc
|
|
||||||
<< " ("
|
|
||||||
<< frames[((buf[c+1]&0x38) >>3)-1]
|
|
||||||
<< ")" << endl << endl;
|
|
||||||
} else c++;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
@ -1,330 +0,0 @@
|
|||||||
/*
|
|
||||||
* dvb-mpegtools for the Siemens Fujitsu DVB PCI card
|
|
||||||
*
|
|
||||||
* Copyright (C) 2000, 2001 Marcus Metzler
|
|
||||||
* for convergence integrated media GmbH
|
|
||||||
* Copyright (C) 2002 Marcus Metzler
|
|
||||||
*
|
|
||||||
* This program is free software; you can redistribute it and/or
|
|
||||||
* modify it under the terms of the GNU General Public License
|
|
||||||
* as published by the Free Software Foundation; either version 2
|
|
||||||
* of the License, or (at your option) any later version.
|
|
||||||
*
|
|
||||||
|
|
||||||
* This program is distributed in the hope that it will be useful,
|
|
||||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
||||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
||||||
* GNU General Public License for more details.
|
|
||||||
*
|
|
||||||
|
|
||||||
* You should have received a copy of the GNU General Public License
|
|
||||||
* along with this program; if not, write to the Free Software
|
|
||||||
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
|
||||||
* Or, point your browser to http://www.gnu.org/copyleft/gpl.html
|
|
||||||
*
|
|
||||||
|
|
||||||
* The author can be reached at mocm@metzlerbros.de,
|
|
||||||
*/
|
|
||||||
|
|
||||||
#include <fstream>
|
|
||||||
#include <sstream>
|
|
||||||
#include <iostream>
|
|
||||||
#include <iomanip>
|
|
||||||
using namespace std;
|
|
||||||
|
|
||||||
|
|
||||||
#ifndef _CPPTOOLS_HH_
|
|
||||||
#define _CPPTOOLS_HH_
|
|
||||||
|
|
||||||
#include "ctools.h"
|
|
||||||
|
|
||||||
|
|
||||||
class PES_Packet{
|
|
||||||
int info;
|
|
||||||
pes_packet p;
|
|
||||||
public:
|
|
||||||
PES_Packet(){
|
|
||||||
info = 0;
|
|
||||||
init_pes(&p);
|
|
||||||
}
|
|
||||||
|
|
||||||
~PES_Packet(){
|
|
||||||
if (p.pack_header)
|
|
||||||
delete [] p.pack_header;
|
|
||||||
if (p.pes_ext)
|
|
||||||
delete [] p.pes_ext;
|
|
||||||
if (p.pes_pckt_data)
|
|
||||||
delete [] p.pes_pckt_data;
|
|
||||||
if (p.mpeg1_headr)
|
|
||||||
delete [] p.mpeg1_headr;
|
|
||||||
}
|
|
||||||
|
|
||||||
inline void init(){
|
|
||||||
if (p.pack_header)
|
|
||||||
delete [] p.pack_header;
|
|
||||||
if (p.pes_ext)
|
|
||||||
delete [] p.pes_ext;
|
|
||||||
if (p.pes_pckt_data)
|
|
||||||
delete [] p.pes_pckt_data;
|
|
||||||
if (p.mpeg1_headr)
|
|
||||||
delete [] p.mpeg1_headr;
|
|
||||||
|
|
||||||
info = 0;
|
|
||||||
init_pes(&p);
|
|
||||||
}
|
|
||||||
|
|
||||||
inline pes_packet *P(){
|
|
||||||
return &p;
|
|
||||||
}
|
|
||||||
|
|
||||||
inline void setlength(){
|
|
||||||
setlength_pes(&p);
|
|
||||||
if (p.length)
|
|
||||||
p.pes_pckt_data = new uint8_t[p.length];
|
|
||||||
}
|
|
||||||
|
|
||||||
inline void Nlength(){
|
|
||||||
nlength_pes(&p);
|
|
||||||
p.pes_pckt_data = new uint8_t[p.length];
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
inline uint8_t &Stream_ID(){
|
|
||||||
return p.stream_id;
|
|
||||||
}
|
|
||||||
|
|
||||||
inline uint8_t &Flags1(){
|
|
||||||
return p.flags1;
|
|
||||||
}
|
|
||||||
|
|
||||||
inline uint8_t &Flags2(){
|
|
||||||
return p.flags2;
|
|
||||||
}
|
|
||||||
|
|
||||||
inline uint32_t &Length(){
|
|
||||||
return p.length;
|
|
||||||
}
|
|
||||||
|
|
||||||
inline uint8_t &HLength(){
|
|
||||||
return p.pes_hlength;
|
|
||||||
}
|
|
||||||
|
|
||||||
inline uint8_t &Stuffing(){
|
|
||||||
return p.stuffing;
|
|
||||||
}
|
|
||||||
|
|
||||||
inline uint8_t *Data(){
|
|
||||||
return p.pes_pckt_data;
|
|
||||||
}
|
|
||||||
|
|
||||||
inline int has_pts(){
|
|
||||||
return (p.flags2 & PTS_DTS);
|
|
||||||
}
|
|
||||||
|
|
||||||
inline int &MPEG(){
|
|
||||||
return p.mpeg;
|
|
||||||
}
|
|
||||||
inline uint8_t *PTS(){
|
|
||||||
return p.pts;
|
|
||||||
}
|
|
||||||
|
|
||||||
inline uint8_t *DTS(){
|
|
||||||
return p.dts;
|
|
||||||
}
|
|
||||||
|
|
||||||
inline int &Info(){
|
|
||||||
return info;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
inline uint8_t high_pts(){
|
|
||||||
if (has_pts())
|
|
||||||
return ((p.pts[0] & 0x08)>>3);
|
|
||||||
else
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
inline uint8_t high_dts(){
|
|
||||||
return ((p.dts[0] & 0x08)>>3);
|
|
||||||
}
|
|
||||||
|
|
||||||
inline int WDTS(){
|
|
||||||
int w_dts;
|
|
||||||
w_dts = (int)trans_pts_dts(p.dts);
|
|
||||||
return w_dts;
|
|
||||||
}
|
|
||||||
|
|
||||||
inline int WPTS(){
|
|
||||||
int w_dts;
|
|
||||||
w_dts = (int)trans_pts_dts(p.pts);
|
|
||||||
return w_dts;
|
|
||||||
}
|
|
||||||
|
|
||||||
friend ostream & operator << (ostream & stream, PES_Packet & x);
|
|
||||||
friend istream & operator >> (istream & stream, PES_Packet & x);
|
|
||||||
|
|
||||||
};
|
|
||||||
|
|
||||||
|
|
||||||
class TS_Packet{
|
|
||||||
ts_packet p;
|
|
||||||
int info;
|
|
||||||
|
|
||||||
public:
|
|
||||||
TS_Packet(){
|
|
||||||
init_ts(&p);
|
|
||||||
info = 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
~TS_Packet(){
|
|
||||||
if (p.priv_dat)
|
|
||||||
delete [] p.priv_dat;
|
|
||||||
}
|
|
||||||
|
|
||||||
inline void init(){
|
|
||||||
if (p.priv_dat)
|
|
||||||
delete [] p.priv_dat;
|
|
||||||
|
|
||||||
init_ts(&p);
|
|
||||||
info = 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
inline ts_packet *P(){
|
|
||||||
return &p;
|
|
||||||
}
|
|
||||||
|
|
||||||
inline int &Rest(){
|
|
||||||
return p.rest;
|
|
||||||
}
|
|
||||||
|
|
||||||
inline uint8_t *Data(){
|
|
||||||
return p.data;
|
|
||||||
}
|
|
||||||
|
|
||||||
inline short PID(){
|
|
||||||
return pid_ts(&p);
|
|
||||||
}
|
|
||||||
|
|
||||||
inline uint8_t FLAG1(){
|
|
||||||
return (p.pid[0] & ~PID_MASK_HI);
|
|
||||||
}
|
|
||||||
|
|
||||||
inline int &Info(){
|
|
||||||
return info;
|
|
||||||
}
|
|
||||||
|
|
||||||
friend ostream & operator << (ostream & stream, TS_Packet & x);
|
|
||||||
friend istream & operator >> (istream & stream, TS_Packet & x);
|
|
||||||
};
|
|
||||||
|
|
||||||
|
|
||||||
class PS_Packet{
|
|
||||||
int info;
|
|
||||||
ps_packet p;
|
|
||||||
public:
|
|
||||||
|
|
||||||
PS_Packet(){
|
|
||||||
init_ps(&p);
|
|
||||||
info = 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
~PS_Packet(){
|
|
||||||
if (p.data)
|
|
||||||
delete [] p.data;
|
|
||||||
}
|
|
||||||
|
|
||||||
inline void init(){
|
|
||||||
if (p.data)
|
|
||||||
delete [] p.data;
|
|
||||||
|
|
||||||
init_ps(&p);
|
|
||||||
info = 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
inline ps_packet *P(){
|
|
||||||
return &p;
|
|
||||||
}
|
|
||||||
|
|
||||||
inline int MUX(){
|
|
||||||
return mux_ps(&p);
|
|
||||||
}
|
|
||||||
|
|
||||||
inline int Rate(){
|
|
||||||
return rate_ps(&p);
|
|
||||||
}
|
|
||||||
|
|
||||||
inline void setlength(){
|
|
||||||
setlength_ps(&p);
|
|
||||||
p.data = new uint8_t[p.sheader_length];
|
|
||||||
}
|
|
||||||
|
|
||||||
inline int Stuffing(){
|
|
||||||
return p.stuff_length & PACK_STUFF_MASK;
|
|
||||||
}
|
|
||||||
|
|
||||||
inline int NPES(){
|
|
||||||
return p.npes;
|
|
||||||
}
|
|
||||||
|
|
||||||
inline int &MPEG(){
|
|
||||||
return p.mpeg;
|
|
||||||
}
|
|
||||||
|
|
||||||
inline uint8_t &operator()(int l){
|
|
||||||
return p.data[l];
|
|
||||||
}
|
|
||||||
|
|
||||||
inline char * Data() {
|
|
||||||
return (char *)p.data+p.stuff_length;
|
|
||||||
}
|
|
||||||
|
|
||||||
inline int &SLENGTH(){
|
|
||||||
return p.sheader_length;
|
|
||||||
}
|
|
||||||
|
|
||||||
inline int &Info(){
|
|
||||||
return info;
|
|
||||||
}
|
|
||||||
|
|
||||||
uint32_t SCR_base(){
|
|
||||||
return scr_base_ps(&p);
|
|
||||||
}
|
|
||||||
|
|
||||||
uint16_t SCR_ext(){
|
|
||||||
return scr_ext_ps(&p);
|
|
||||||
}
|
|
||||||
|
|
||||||
friend ostream & operator << (ostream & stream, PS_Packet & x);
|
|
||||||
friend istream & operator >> (istream & stream, PS_Packet & x);
|
|
||||||
};
|
|
||||||
|
|
||||||
|
|
||||||
typedef void (* FILTER)(istream &in, ostream &out);
|
|
||||||
|
|
||||||
typedef struct thread_args_{
|
|
||||||
FILTER function;
|
|
||||||
int *fd;
|
|
||||||
int in;
|
|
||||||
int out;
|
|
||||||
} thread_args;
|
|
||||||
|
|
||||||
|
|
||||||
void extract_audio_from_PES(istream &in, ostream &out);
|
|
||||||
void extract_video_from_PES(istream &in, ostream &out);
|
|
||||||
void extract_es_audio_from_PES(istream &in, ostream &out);
|
|
||||||
void extract_es_video_from_PES(istream &in, ostream &out);
|
|
||||||
int TS_PIDS(istream &in, ostream &out);
|
|
||||||
int ifilter (istream &in, FILTER function);
|
|
||||||
int ofilter (istream &in, FILTER function);
|
|
||||||
int itfilter (int in, FILTER function);
|
|
||||||
int otfilter (istream &in, FILTER function);
|
|
||||||
int stream_type(int fd);
|
|
||||||
int stream_type(istream &stream);
|
|
||||||
int tv_norm(istream &fin);
|
|
||||||
|
|
||||||
void analyze(istream &fin);
|
|
||||||
|
|
||||||
|
|
||||||
#endif //_CPPTOOLS_HH_
|
|
||||||
|
|
@ -1,310 +0,0 @@
|
|||||||
#ifndef _channel_hh
|
|
||||||
#define _channel_hh
|
|
||||||
|
|
||||||
using namespace std;
|
|
||||||
#include <stdint.h>
|
|
||||||
|
|
||||||
#include <stdio.h>
|
|
||||||
#include <string.h>
|
|
||||||
#include <stdlib.h>
|
|
||||||
|
|
||||||
#include <iostream>
|
|
||||||
#include <fstream>
|
|
||||||
#include <sstream>
|
|
||||||
|
|
||||||
#include "DVB.hh"
|
|
||||||
|
|
||||||
#define MAXNAM 80
|
|
||||||
#define MAXKEY 15
|
|
||||||
|
|
||||||
const int maxname=80;
|
|
||||||
const int MAXAPIDS=32;
|
|
||||||
const uint32_t UNSET=0xffffffff;
|
|
||||||
const uint16_t NOID=0xffff;
|
|
||||||
const uint16_t NOPID=0xffff;
|
|
||||||
|
|
||||||
class Transponder {
|
|
||||||
public:
|
|
||||||
uint16_t id;
|
|
||||||
uint16_t onid;
|
|
||||||
uint16_t satid;
|
|
||||||
int type;
|
|
||||||
char name[maxname+1];
|
|
||||||
uint32_t freq;
|
|
||||||
int pol;
|
|
||||||
int qam;
|
|
||||||
uint32_t srate;
|
|
||||||
int fec;
|
|
||||||
int band;
|
|
||||||
int hp_rate;
|
|
||||||
int lp_rate;
|
|
||||||
int mod;
|
|
||||||
int transmode;
|
|
||||||
int guard;
|
|
||||||
int hierarchy;
|
|
||||||
|
|
||||||
struct Sat *sat;
|
|
||||||
|
|
||||||
Transponder() {
|
|
||||||
name[0]='\0';
|
|
||||||
id = NOID;
|
|
||||||
onid = NOID;
|
|
||||||
satid = NOID;
|
|
||||||
type = 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
friend ostream &operator<<(ostream &stream, Transponder &x);
|
|
||||||
friend istream &operator>>(istream &stream, Transponder &x);
|
|
||||||
};
|
|
||||||
|
|
||||||
class Sat {
|
|
||||||
public:
|
|
||||||
uint16_t id;
|
|
||||||
char name[maxname+1];
|
|
||||||
unsigned int lnbid;
|
|
||||||
struct Lnb *lnb;
|
|
||||||
unsigned int rotorid;
|
|
||||||
unsigned int fmin;
|
|
||||||
unsigned int fmax;
|
|
||||||
|
|
||||||
Sat() {
|
|
||||||
id=NOID;
|
|
||||||
name[0]='\0';
|
|
||||||
lnb=NULL;
|
|
||||||
rotorid=NOID;
|
|
||||||
lnbid=NOID;
|
|
||||||
fmin=fmax=0;
|
|
||||||
};
|
|
||||||
int set(int sid, char *sname, int slnbid, int srotorid) {
|
|
||||||
return 0;
|
|
||||||
};
|
|
||||||
|
|
||||||
friend ostream &operator<<(ostream &stream, Sat &x);
|
|
||||||
friend istream &operator>>(istream &stream, Sat &x);
|
|
||||||
};
|
|
||||||
|
|
||||||
|
|
||||||
class Lnb {
|
|
||||||
public:
|
|
||||||
Sat *sat;
|
|
||||||
uint16_t id;
|
|
||||||
struct DVB *dvbd;
|
|
||||||
char name[maxname+1];
|
|
||||||
int type;
|
|
||||||
unsigned int lof1;
|
|
||||||
unsigned int lof2;
|
|
||||||
unsigned int slof;
|
|
||||||
int diseqcnr;
|
|
||||||
uint16_t diseqcid;
|
|
||||||
uint16_t swiid;
|
|
||||||
|
|
||||||
|
|
||||||
void cpy (const Lnb &olnb){
|
|
||||||
this->id=olnb.id;
|
|
||||||
this->type=olnb.type;
|
|
||||||
this->lof1=olnb.lof1;
|
|
||||||
this->lof2=olnb.lof2;
|
|
||||||
this->slof=olnb.slof;
|
|
||||||
this->diseqcnr=olnb.diseqcnr;
|
|
||||||
this->diseqcid=olnb.diseqcid;
|
|
||||||
this->swiid=olnb.swiid;
|
|
||||||
strncpy(this->name,olnb.name,maxname);
|
|
||||||
}
|
|
||||||
|
|
||||||
void init(int t, uint l1, uint l2, uint sl,
|
|
||||||
int dnr, int disid, int sw) {
|
|
||||||
type=t;
|
|
||||||
lof1=l1;
|
|
||||||
lof2=l2;
|
|
||||||
slof=sl;
|
|
||||||
diseqcnr=dnr;
|
|
||||||
diseqcid=disid;
|
|
||||||
swiid=sw;
|
|
||||||
dvbd=0;
|
|
||||||
name[0]='\0';
|
|
||||||
}
|
|
||||||
|
|
||||||
Lnb () {
|
|
||||||
lof1=lof2=slof=0;
|
|
||||||
swiid=NOID;
|
|
||||||
diseqcid=NOID;
|
|
||||||
diseqcnr=-1;
|
|
||||||
name[0]='\0';
|
|
||||||
}
|
|
||||||
|
|
||||||
Lnb (const Lnb &olnb){
|
|
||||||
cpy(olnb);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
friend ostream &operator<<(ostream &stream, Lnb &x);
|
|
||||||
friend istream &operator>>(istream &stream, Lnb &x);
|
|
||||||
};
|
|
||||||
|
|
||||||
struct diseqcmsg {
|
|
||||||
int burst;
|
|
||||||
int len;
|
|
||||||
unsigned char msg[8];
|
|
||||||
};
|
|
||||||
|
|
||||||
class DiSEqC {
|
|
||||||
public:
|
|
||||||
uint16_t id;
|
|
||||||
char name[maxname+1];
|
|
||||||
diseqcmsg msgs[4];
|
|
||||||
|
|
||||||
friend ostream &operator<<(ostream &stream, DiSEqC &x);
|
|
||||||
friend istream &operator>>(istream &stream, DiSEqC &x);
|
|
||||||
};
|
|
||||||
|
|
||||||
class Rotor {
|
|
||||||
public:
|
|
||||||
uint16_t id;
|
|
||||||
char name[maxname+1];
|
|
||||||
diseqcmsg msgs[4];
|
|
||||||
|
|
||||||
friend ostream &operator<<(ostream &stream, Rotor &x);
|
|
||||||
friend istream &operator>>(istream &stream, Rotor &x);
|
|
||||||
};
|
|
||||||
|
|
||||||
class Switch {
|
|
||||||
public:
|
|
||||||
uint16_t id;
|
|
||||||
int switchid;
|
|
||||||
char name[maxname+1];
|
|
||||||
diseqcmsg msg;
|
|
||||||
|
|
||||||
friend ostream &operator<<(ostream &stream, Switch &x);
|
|
||||||
friend istream &operator>>(istream &stream, Switch &x);
|
|
||||||
};
|
|
||||||
|
|
||||||
class Network {
|
|
||||||
public:
|
|
||||||
uint16_t id;
|
|
||||||
char name[maxname+1];
|
|
||||||
|
|
||||||
friend ostream &operator<<(ostream &stream, Network &x);
|
|
||||||
friend istream &operator>>(istream &stream, Network &x);
|
|
||||||
};
|
|
||||||
|
|
||||||
class Bouquet {
|
|
||||||
public:
|
|
||||||
uint16_t id;
|
|
||||||
char name[maxname+1];
|
|
||||||
|
|
||||||
friend ostream &operator<<(ostream &stream, Bouquet &x);
|
|
||||||
friend istream &operator>>(istream &stream, Bouquet &x);
|
|
||||||
};
|
|
||||||
|
|
||||||
|
|
||||||
#define MAX_ECM 16
|
|
||||||
#define MAX_ECM_DESC 256
|
|
||||||
typedef struct ecm_struct {
|
|
||||||
int num;
|
|
||||||
uint16_t sysid[MAX_ECM];
|
|
||||||
uint16_t pid[MAX_ECM];
|
|
||||||
uint16_t length[MAX_ECM];
|
|
||||||
uint8_t data[MAX_ECM*MAX_ECM_DESC];
|
|
||||||
} ecm_t;
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
class Channel{
|
|
||||||
public:
|
|
||||||
Channel *next;
|
|
||||||
uint32_t id;
|
|
||||||
char name[maxname+1];
|
|
||||||
int32_t type;
|
|
||||||
int checked;
|
|
||||||
|
|
||||||
uint16_t pnr;
|
|
||||||
uint16_t vpid;
|
|
||||||
uint16_t apids[MAXAPIDS];
|
|
||||||
char apids_name[MAXAPIDS*4];
|
|
||||||
int32_t apidnum;
|
|
||||||
int last_apidn;
|
|
||||||
uint16_t ac3pid;
|
|
||||||
uint16_t ttpid;
|
|
||||||
uint16_t pmtpid;
|
|
||||||
uint16_t pcrpid;
|
|
||||||
uint16_t casystem;
|
|
||||||
uint16_t capid;
|
|
||||||
|
|
||||||
ecm_t ecm;
|
|
||||||
int (*ecm_callback)(Channel *chan);
|
|
||||||
|
|
||||||
int has_eit;
|
|
||||||
int pres_follow;
|
|
||||||
|
|
||||||
uint16_t satid;
|
|
||||||
uint16_t tpid;
|
|
||||||
uint16_t onid;
|
|
||||||
uint16_t bid;
|
|
||||||
int8_t eit_ver_n;
|
|
||||||
int8_t eit_ver_c;
|
|
||||||
|
|
||||||
void clearall(void) {
|
|
||||||
id=UNSET;
|
|
||||||
name[0]='\0';
|
|
||||||
type=0;
|
|
||||||
checked = 0;
|
|
||||||
has_eit = -1;
|
|
||||||
pres_follow = -1;
|
|
||||||
eit_ver_c = -1;
|
|
||||||
eit_ver_n = -1;
|
|
||||||
|
|
||||||
pnr=NOPID;
|
|
||||||
vpid=NOPID;
|
|
||||||
memset(apids, 0, sizeof(uint16_t)*MAXAPIDS);
|
|
||||||
memset(apids_name, 0, sizeof(char)*MAXAPIDS*4);
|
|
||||||
apidnum=0;
|
|
||||||
last_apidn=-1;
|
|
||||||
ac3pid=NOPID;
|
|
||||||
ttpid=NOPID;
|
|
||||||
pmtpid=NOPID;
|
|
||||||
pcrpid=NOPID;
|
|
||||||
capid=NOPID;
|
|
||||||
|
|
||||||
satid=NOID;
|
|
||||||
tpid=NOID;
|
|
||||||
onid=NOID;
|
|
||||||
bid=NOID;
|
|
||||||
ecm_callback = NULL;
|
|
||||||
memset(&ecm,0, sizeof(ecm_t));
|
|
||||||
};
|
|
||||||
|
|
||||||
Channel() {
|
|
||||||
clearall();
|
|
||||||
}
|
|
||||||
|
|
||||||
Channel(int cid, char *nam, int ty, int prognr,
|
|
||||||
int vid, int aid, int tid) {
|
|
||||||
int l=strlen(nam);
|
|
||||||
|
|
||||||
clearall();
|
|
||||||
if (l>maxname){
|
|
||||||
cerr << "" << endl;
|
|
||||||
l=maxname;
|
|
||||||
}
|
|
||||||
strncpy(name, nam, l);
|
|
||||||
name[l]='\0';
|
|
||||||
type=ty;
|
|
||||||
pnr=prognr;
|
|
||||||
vpid=vid;
|
|
||||||
apids[0]=aid;
|
|
||||||
}
|
|
||||||
|
|
||||||
#ifdef DEBUG
|
|
||||||
~Channel(){
|
|
||||||
cerr <<"Channel " << name << " destroyed" << endl;
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
friend ostream &operator<<(ostream &stream, Channel &x);
|
|
||||||
friend istream &operator>>(istream &stream, Channel &x);
|
|
||||||
};
|
|
||||||
|
|
||||||
int findkey(char *name, char *keys[]);
|
|
||||||
void getname(char *name,istream &ins);
|
|
||||||
#endif /*channel.h*/
|
|
@ -1,84 +0,0 @@
|
|||||||
#ifndef _OSD_HH_
|
|
||||||
#define _OSD_HH_
|
|
||||||
|
|
||||||
extern "C" {
|
|
||||||
#include "OSD.h"
|
|
||||||
}
|
|
||||||
struct OSD {
|
|
||||||
int dev;
|
|
||||||
|
|
||||||
void init(int d) {
|
|
||||||
dev=d;
|
|
||||||
}
|
|
||||||
int Open(int x0, int y0, int x1, int y1, int BitPerPixel, int mix, int win) {
|
|
||||||
if (OSDSetWindow(dev, win))
|
|
||||||
return -1;
|
|
||||||
return OSDOpen(dev, x0, y0, x1, y1, BitPerPixel, mix);
|
|
||||||
}
|
|
||||||
int Open(int x0, int y0, int x1, int y1, int BitPerPixel, int mix) {
|
|
||||||
return OSDOpen(dev, x0, y0, x1, y1, BitPerPixel, mix);
|
|
||||||
}
|
|
||||||
int Close(int win) {
|
|
||||||
if (OSDSetWindow(dev, win))
|
|
||||||
return -1;
|
|
||||||
return OSDClose(dev);
|
|
||||||
}
|
|
||||||
int Close(void) {
|
|
||||||
return OSDClose(dev);
|
|
||||||
}
|
|
||||||
int Show(void) {
|
|
||||||
return OSDShow(dev);
|
|
||||||
}
|
|
||||||
int Hide(void) {
|
|
||||||
return OSDHide(dev);
|
|
||||||
}
|
|
||||||
int Clear(void) {
|
|
||||||
return OSDClear(dev);
|
|
||||||
}
|
|
||||||
int Fill(int color) {
|
|
||||||
return OSDFill(dev, color);
|
|
||||||
}
|
|
||||||
int SetColor(int color, int r, int g, int b, int op) {
|
|
||||||
return OSDSetColor(dev, color, r, g, b, op);
|
|
||||||
}
|
|
||||||
int Text(int x, int y, int size, int color, const char *text) {
|
|
||||||
return OSDText(dev, x, y, size, color, text);
|
|
||||||
}
|
|
||||||
int SetPalette(int first, int last, unsigned char *data) {
|
|
||||||
return OSDSetPalette(dev, first, last, data);
|
|
||||||
|
|
||||||
}
|
|
||||||
int SetTrans(int trans) {
|
|
||||||
return OSDSetTrans(dev, trans);
|
|
||||||
|
|
||||||
}
|
|
||||||
int SetPixel(int dev, int x, int y, unsigned int color) {
|
|
||||||
return OSDSetPixel(dev, x, y, color);
|
|
||||||
}
|
|
||||||
int GetPixel(int dev, int x, int y) {
|
|
||||||
return OSDGetPixel(dev, x, y);
|
|
||||||
}
|
|
||||||
int SetRow(int x, int y, int x1, unsigned char *data) {
|
|
||||||
return OSDSetRow(dev, x, y, x1, data);
|
|
||||||
}
|
|
||||||
int SetBlock(int x, int y, int x1, int y1, int inc, unsigned char *data) {
|
|
||||||
return OSDSetBlock(dev, x, y, x1, y1, inc, data);
|
|
||||||
}
|
|
||||||
int FillRow(int x, int y, int x1, int color) {
|
|
||||||
return OSDFillRow(dev, x, y, x1, color);
|
|
||||||
}
|
|
||||||
int FillBlock(int x, int y, int x1, int y1, int color) {
|
|
||||||
return OSDFillBlock(dev, x, y, x1, y1, color);
|
|
||||||
}
|
|
||||||
int Line(int x, int y, int x1, int y1, int color) {
|
|
||||||
return OSDLine(dev, x, y, x1, y1, color);
|
|
||||||
}
|
|
||||||
int Query() {
|
|
||||||
return OSDQuery(dev);
|
|
||||||
}
|
|
||||||
int SetWindow(int win) {
|
|
||||||
return OSDSetWindow(dev, win);
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
#endif
|
|
@ -3,13 +3,12 @@
|
|||||||
*
|
*
|
||||||
* See the README file for copyright information and how to reach the author.
|
* See the README file for copyright information and how to reach the author.
|
||||||
*
|
*
|
||||||
* $Id: streamdev-client.c,v 1.3 2008/04/07 14:27:27 schmirl Exp $
|
* $Id: streamdev-client.c,v 1.4 2008/04/07 14:40:39 schmirl Exp $
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include "streamdev-client.h"
|
#include "streamdev-client.h"
|
||||||
#include "client/device.h"
|
#include "client/device.h"
|
||||||
#include "client/setup.h"
|
#include "client/setup.h"
|
||||||
//#include "client/menu.h"
|
|
||||||
#include "i18n.h"
|
#include "i18n.h"
|
||||||
|
|
||||||
#if VDRVERSNUM < 10400
|
#if VDRVERSNUM < 10400
|
||||||
@ -43,13 +42,15 @@ void cPluginStreamdevClient::Housekeeping(void) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
const char *cPluginStreamdevClient::MainMenuEntry(void) {
|
const char *cPluginStreamdevClient::MainMenuEntry(void) {
|
||||||
return NULL;
|
return StreamdevClientSetup.StartClient ? tr("Suspend Server") : NULL;
|
||||||
//return StreamdevClientSetup.StartClient ? tr("Streaming Control") : NULL;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
cOsdObject *cPluginStreamdevClient::MainMenuAction(void) {
|
cOsdObject *cPluginStreamdevClient::MainMenuAction(void) {
|
||||||
|
if (ClientSocket.SuspendServer())
|
||||||
|
Skins.Message(mtInfo, tr("Server is suspended"));
|
||||||
|
else
|
||||||
|
Skins.Message(mtError, tr("Couldn't suspend Server!"));
|
||||||
return NULL;
|
return NULL;
|
||||||
//return StreamdevClientSetup.StartClient ? new cStreamdevMenu : NULL;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
cMenuSetupPage *cPluginStreamdevClient::SetupMenu(void) {
|
cMenuSetupPage *cPluginStreamdevClient::SetupMenu(void) {
|
||||||
|
Loading…
Reference in New Issue
Block a user