mirror of
https://github.com/VDR4Arch/vdr.git
synced 2023-10-10 13:36:52 +02:00
No longer actually tuning the primary interface in 'Transfer Mode'
This commit is contained in:
parent
5d415c08d0
commit
bdfeda21c7
5
HISTORY
5
HISTORY
@ -586,7 +586,6 @@ Video Disk Recorder Revision History
|
|||||||
- DiSEqC support can now be generally enabled/disabled in the Setup menu. This
|
- DiSEqC support can now be generally enabled/disabled in the Setup menu. This
|
||||||
may be necessary if your multiswitch gets irritated by the default DiSEqC
|
may be necessary if your multiswitch gets irritated by the default DiSEqC
|
||||||
codes '0' (thanks to Markus Lang).
|
codes '0' (thanks to Markus Lang).
|
||||||
- Avoiding audio/video distortions in 'Transfer Mode'.
|
|
||||||
- Fixed replaying in case there is no index file.
|
- Fixed replaying in case there is no index file.
|
||||||
- Fixed jumping to an editing mark when replay has been paused.
|
- Fixed jumping to an editing mark when replay has been paused.
|
||||||
- Avoiding unnecessary code execution in the replay progress display (thanks
|
- Avoiding unnecessary code execution in the replay progress display (thanks
|
||||||
@ -603,3 +602,7 @@ Video Disk Recorder Revision History
|
|||||||
confirmation messages (like "Delete...") to "black on yellow".
|
confirmation messages (like "Delete...") to "black on yellow".
|
||||||
- Fixed display with DEBUG_OSD (it still crashes sometimes, esp. when replaying,
|
- Fixed display with DEBUG_OSD (it still crashes sometimes, esp. when replaying,
|
||||||
but I can't seem to find what causes this... any ideas anybody?).
|
but I can't seem to find what causes this... any ideas anybody?).
|
||||||
|
- Avoiding audio/video distortions in 'Transfer Mode' by no longer actually
|
||||||
|
tuning the primary interface (which can't receive this channel, anyway).
|
||||||
|
Apparently the driver gets irritated when the channel is switched and a
|
||||||
|
replay session is started immediately after that.
|
||||||
|
235
dvbapi.c
235
dvbapi.c
@ -4,7 +4,7 @@
|
|||||||
* See the main source file 'vdr.c' for copyright information and
|
* See the main source file 'vdr.c' for copyright information and
|
||||||
* how to reach the author.
|
* how to reach the author.
|
||||||
*
|
*
|
||||||
* $Id: dvbapi.c 1.93 2001/07/28 11:45:04 kls Exp $
|
* $Id: dvbapi.c 1.94 2001/07/29 09:00:19 kls Exp $
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include "dvbapi.h"
|
#include "dvbapi.h"
|
||||||
@ -2116,6 +2116,15 @@ bool cDvbApi::SetChannel(int ChannelNumber, int FrequencyMHz, char Polarization,
|
|||||||
StopTransfer();
|
StopTransfer();
|
||||||
StopReplay();
|
StopReplay();
|
||||||
|
|
||||||
|
// Must set this anyway to avoid getting stuck when switching through
|
||||||
|
// channels with 'Up' and 'Down' keys:
|
||||||
|
currentChannel = ChannelNumber;
|
||||||
|
vPid = Vpid;
|
||||||
|
aPid1 = Apid1;
|
||||||
|
aPid2 = Apid2;
|
||||||
|
dPid1 = Dpid1;
|
||||||
|
dPid2 = Dpid2;
|
||||||
|
|
||||||
// Avoid noise while switching:
|
// Avoid noise while switching:
|
||||||
|
|
||||||
if (fd_video >= 0 && fd_audio >= 0) {
|
if (fd_video >= 0 && fd_audio >= 0) {
|
||||||
@ -2125,150 +2134,150 @@ bool cDvbApi::SetChannel(int ChannelNumber, int FrequencyMHz, char Polarization,
|
|||||||
CHECK(ioctl(fd_audio, AUDIO_CLEAR_BUFFER));
|
CHECK(ioctl(fd_audio, AUDIO_CLEAR_BUFFER));
|
||||||
}
|
}
|
||||||
|
|
||||||
// Turn off current PIDs:
|
// If this card can't receive this channel, we must not actually switch
|
||||||
|
// the channel here, because that would irritate the driver when we
|
||||||
|
// start replaying in Transfer Mode immediately after switching the channel:
|
||||||
|
bool NeedsTransferMode = (this == PrimaryDvbApi && Ca && Ca != Index() + 1);
|
||||||
|
|
||||||
SetVpid( 0x1FFF, DMX_OUT_DECODER);
|
if (!NeedsTransferMode) {
|
||||||
SetApid1(0x1FFF, DMX_OUT_DECODER);
|
|
||||||
SetApid2(0x1FFF, DMX_OUT_DECODER);
|
|
||||||
SetDpid1(0x1FFF, DMX_OUT_DECODER);
|
|
||||||
SetDpid2(0x1FFF, DMX_OUT_DECODER);
|
|
||||||
SetTpid( 0x1FFF, DMX_OUT_DECODER);
|
|
||||||
|
|
||||||
// Must set this anyway to avoid getting stuck when switching through
|
// Turn off current PIDs:
|
||||||
// channels with 'Up' and 'Down' keys:
|
|
||||||
currentChannel = ChannelNumber;
|
|
||||||
|
|
||||||
bool ChannelSynced = false;
|
SetVpid( 0x1FFF, DMX_OUT_DECODER);
|
||||||
|
SetApid1(0x1FFF, DMX_OUT_DECODER);
|
||||||
|
SetApid2(0x1FFF, DMX_OUT_DECODER);
|
||||||
|
SetDpid1(0x1FFF, DMX_OUT_DECODER);
|
||||||
|
SetDpid2(0x1FFF, DMX_OUT_DECODER);
|
||||||
|
SetTpid( 0x1FFF, DMX_OUT_DECODER);
|
||||||
|
|
||||||
if (fd_qpskfe >= 0 && fd_sec >= 0) { // DVB-S
|
bool ChannelSynced = false;
|
||||||
|
|
||||||
// Frequency offsets:
|
if (fd_qpskfe >= 0 && fd_sec >= 0) { // DVB-S
|
||||||
|
|
||||||
unsigned int freq = FrequencyMHz;
|
// Frequency offsets:
|
||||||
int tone = SEC_TONE_OFF;
|
|
||||||
|
|
||||||
if (freq < (unsigned int)Setup.LnbSLOF) {
|
unsigned int freq = FrequencyMHz;
|
||||||
freq -= Setup.LnbFrequLo;
|
int tone = SEC_TONE_OFF;
|
||||||
tone = SEC_TONE_OFF;
|
|
||||||
|
if (freq < (unsigned int)Setup.LnbSLOF) {
|
||||||
|
freq -= Setup.LnbFrequLo;
|
||||||
|
tone = SEC_TONE_OFF;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
freq -= Setup.LnbFrequHi;
|
||||||
|
tone = SEC_TONE_ON;
|
||||||
|
}
|
||||||
|
|
||||||
|
qpskParameters qpsk;
|
||||||
|
qpsk.iFrequency = freq * 1000UL;
|
||||||
|
qpsk.SymbolRate = Srate * 1000UL;
|
||||||
|
qpsk.FEC_inner = FEC_AUTO;
|
||||||
|
|
||||||
|
int volt = (Polarization == 'v' || Polarization == 'V') ? SEC_VOLTAGE_13 : SEC_VOLTAGE_18;
|
||||||
|
|
||||||
|
// DiseqC:
|
||||||
|
|
||||||
|
secCommand scmd;
|
||||||
|
scmd.type = 0;
|
||||||
|
scmd.u.diseqc.addr = 0x10;
|
||||||
|
scmd.u.diseqc.cmd = 0x38;
|
||||||
|
scmd.u.diseqc.numParams = 1;
|
||||||
|
scmd.u.diseqc.params[0] = 0xF0 | ((Diseqc * 4) & 0x0F) | (tone == SEC_TONE_ON ? 1 : 0) | (volt == SEC_VOLTAGE_18 ? 2 : 0);
|
||||||
|
|
||||||
|
secCmdSequence scmds;
|
||||||
|
scmds.voltage = volt;
|
||||||
|
scmds.miniCommand = SEC_MINI_NONE;
|
||||||
|
scmds.continuousTone = tone;
|
||||||
|
scmds.numCommands = Setup.DiSEqC ? 1 : 0;
|
||||||
|
scmds.commands = &scmd;
|
||||||
|
|
||||||
|
CHECK(ioctl(fd_sec, SEC_SEND_SEQUENCE, &scmds));
|
||||||
|
|
||||||
|
// Tuning:
|
||||||
|
|
||||||
|
CHECK(ioctl(fd_qpskfe, QPSK_TUNE, &qpsk));
|
||||||
|
|
||||||
|
// Wait for channel sync:
|
||||||
|
|
||||||
|
if (cFile::FileReady(fd_qpskfe, 5000)) {
|
||||||
|
qpskEvent event;
|
||||||
|
int res = ioctl(fd_qpskfe, QPSK_GET_EVENT, &event);
|
||||||
|
if (res >= 0)
|
||||||
|
ChannelSynced = event.type == FE_COMPLETION_EV;
|
||||||
|
else
|
||||||
|
esyslog(LOG_ERR, "ERROR %d in qpsk get event", res);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
esyslog(LOG_ERR, "ERROR: timeout while tuning\n");
|
||||||
|
}
|
||||||
|
else if (fd_qamfe >= 0) { // DVB-C
|
||||||
|
|
||||||
|
// Frequency and symbol rate:
|
||||||
|
|
||||||
|
qamParameters qam;
|
||||||
|
qam.Frequency = FrequencyMHz * 1000000UL;
|
||||||
|
qam.SymbolRate = Srate * 1000UL;
|
||||||
|
qam.FEC_inner = FEC_AUTO;
|
||||||
|
qam.QAM = QAM_64;
|
||||||
|
|
||||||
|
// Tuning:
|
||||||
|
|
||||||
|
CHECK(ioctl(fd_qamfe, QAM_TUNE, &qam));
|
||||||
|
|
||||||
|
// Wait for channel sync:
|
||||||
|
|
||||||
|
if (cFile::FileReady(fd_qamfe, 5000)) {
|
||||||
|
qamEvent event;
|
||||||
|
int res = ioctl(fd_qamfe, QAM_GET_EVENT, &event);
|
||||||
|
if (res >= 0)
|
||||||
|
ChannelSynced = event.type == FE_COMPLETION_EV;
|
||||||
|
else
|
||||||
|
esyslog(LOG_ERR, "ERROR %d in qam get event", res);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
esyslog(LOG_ERR, "ERROR: timeout while tuning\n");
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
freq -= Setup.LnbFrequHi;
|
esyslog(LOG_ERR, "ERROR: attempt to set channel without DVB-S or DVB-C device");
|
||||||
tone = SEC_TONE_ON;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
qpskParameters qpsk;
|
if (!ChannelSynced) {
|
||||||
qpsk.iFrequency = freq * 1000UL;
|
esyslog(LOG_ERR, "ERROR: channel %d not sync'ed!", ChannelNumber);
|
||||||
qpsk.SymbolRate = Srate * 1000UL;
|
if (this == PrimaryDvbApi)
|
||||||
qpsk.FEC_inner = FEC_AUTO;
|
cThread::RaisePanic();
|
||||||
|
return false;
|
||||||
int volt = (Polarization == 'v' || Polarization == 'V') ? SEC_VOLTAGE_13 : SEC_VOLTAGE_18;
|
|
||||||
|
|
||||||
// DiseqC:
|
|
||||||
|
|
||||||
secCommand scmd;
|
|
||||||
scmd.type = 0;
|
|
||||||
scmd.u.diseqc.addr = 0x10;
|
|
||||||
scmd.u.diseqc.cmd = 0x38;
|
|
||||||
scmd.u.diseqc.numParams = 1;
|
|
||||||
scmd.u.diseqc.params[0] = 0xF0 | ((Diseqc * 4) & 0x0F) | (tone == SEC_TONE_ON ? 1 : 0) | (volt == SEC_VOLTAGE_18 ? 2 : 0);
|
|
||||||
|
|
||||||
secCmdSequence scmds;
|
|
||||||
scmds.voltage = volt;
|
|
||||||
scmds.miniCommand = SEC_MINI_NONE;
|
|
||||||
scmds.continuousTone = tone;
|
|
||||||
scmds.numCommands = Setup.DiSEqC ? 1 : 0;
|
|
||||||
scmds.commands = &scmd;
|
|
||||||
|
|
||||||
CHECK(ioctl(fd_sec, SEC_SEND_SEQUENCE, &scmds));
|
|
||||||
|
|
||||||
// Tuning:
|
|
||||||
|
|
||||||
CHECK(ioctl(fd_qpskfe, QPSK_TUNE, &qpsk));
|
|
||||||
|
|
||||||
// Wait for channel sync:
|
|
||||||
|
|
||||||
if (cFile::FileReady(fd_qpskfe, 5000)) {
|
|
||||||
qpskEvent event;
|
|
||||||
int res = ioctl(fd_qpskfe, QPSK_GET_EVENT, &event);
|
|
||||||
if (res >= 0)
|
|
||||||
ChannelSynced = event.type == FE_COMPLETION_EV;
|
|
||||||
else
|
|
||||||
esyslog(LOG_ERR, "ERROR %d in qpsk get event", res);
|
|
||||||
}
|
}
|
||||||
else
|
|
||||||
esyslog(LOG_ERR, "ERROR: timeout while tuning\n");
|
|
||||||
}
|
|
||||||
else if (fd_qamfe >= 0) { // DVB-C
|
|
||||||
|
|
||||||
// Frequency and symbol rate:
|
// PID settings:
|
||||||
|
|
||||||
qamParameters qam;
|
if (!SetPids(false)) {
|
||||||
qam.Frequency = FrequencyMHz * 1000000UL;
|
esyslog(LOG_ERR, "ERROR: failed to set PIDs for channel %d", ChannelNumber);
|
||||||
qam.SymbolRate = Srate * 1000UL;
|
return false;
|
||||||
qam.FEC_inner = FEC_AUTO;
|
|
||||||
qam.QAM = QAM_64;
|
|
||||||
|
|
||||||
// Tuning:
|
|
||||||
|
|
||||||
CHECK(ioctl(fd_qamfe, QAM_TUNE, &qam));
|
|
||||||
|
|
||||||
// Wait for channel sync:
|
|
||||||
|
|
||||||
if (cFile::FileReady(fd_qamfe, 5000)) {
|
|
||||||
qamEvent event;
|
|
||||||
int res = ioctl(fd_qamfe, QAM_GET_EVENT, &event);
|
|
||||||
if (res >= 0)
|
|
||||||
ChannelSynced = event.type == FE_COMPLETION_EV;
|
|
||||||
else
|
|
||||||
esyslog(LOG_ERR, "ERROR %d in qam get event", res);
|
|
||||||
}
|
}
|
||||||
else
|
SetTpid(Tpid, DMX_OUT_DECODER);
|
||||||
esyslog(LOG_ERR, "ERROR: timeout while tuning\n");
|
if (fd_audio >= 0)
|
||||||
}
|
CHECK(ioctl(fd_audio, AUDIO_SET_AV_SYNC, true));
|
||||||
else {
|
|
||||||
esyslog(LOG_ERR, "ERROR: attempt to set channel without DVB-S or DVB-C device");
|
|
||||||
return false;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!ChannelSynced) {
|
|
||||||
esyslog(LOG_ERR, "ERROR: channel %d not sync'ed!", ChannelNumber);
|
|
||||||
if (this == PrimaryDvbApi)
|
|
||||||
cThread::RaisePanic();
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
// PID settings:
|
|
||||||
|
|
||||||
vPid = Vpid;
|
|
||||||
aPid1 = Apid1;
|
|
||||||
aPid2 = Apid2;
|
|
||||||
dPid1 = Dpid1;
|
|
||||||
dPid2 = Dpid2;
|
|
||||||
if (!SetPids(false)) {
|
|
||||||
esyslog(LOG_ERR, "ERROR: failed to set PIDs for channel %d", ChannelNumber);
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
SetTpid(Tpid, DMX_OUT_DECODER);
|
|
||||||
if (fd_audio >= 0)
|
|
||||||
CHECK(ioctl(fd_audio, AUDIO_SET_AV_SYNC, true));
|
|
||||||
if (this == PrimaryDvbApi && siProcessor)
|
if (this == PrimaryDvbApi && siProcessor)
|
||||||
siProcessor->SetCurrentServiceID(Pnr);
|
siProcessor->SetCurrentServiceID(Pnr);
|
||||||
|
|
||||||
// If this DVB card can't receive this channel, let's see if we can
|
// If this DVB card can't receive this channel, let's see if we can
|
||||||
// use the card that actually can receive it and transfer data from there:
|
// use the card that actually can receive it and transfer data from there:
|
||||||
|
|
||||||
if (this == PrimaryDvbApi && Ca && Ca != Index() + 1) {
|
if (NeedsTransferMode) {
|
||||||
cDvbApi *CaDvbApi = GetDvbApi(Ca, 0);
|
cDvbApi *CaDvbApi = GetDvbApi(Ca, 0);
|
||||||
if (CaDvbApi) {
|
if (CaDvbApi) {
|
||||||
if (!CaDvbApi->Recording()) {
|
if (!CaDvbApi->Recording()) {
|
||||||
if (CaDvbApi->SetChannel(ChannelNumber, FrequencyMHz, Polarization, Diseqc, Srate, Vpid, Apid1, Apid2, Dpid1, Dpid2, Tpid, Ca, Pnr)) {
|
if (CaDvbApi->SetChannel(ChannelNumber, FrequencyMHz, Polarization, Diseqc, Srate, Vpid, Apid1, Apid2, Dpid1, Dpid2, Tpid, Ca, Pnr)) {
|
||||||
usleep(500000); // avoids distortions (apparently switching into replay mode immediately after tuning causes problems)
|
|
||||||
SetModeReplay();
|
SetModeReplay();
|
||||||
transferringFromDvbApi = CaDvbApi->StartTransfer(fd_video);
|
transferringFromDvbApi = CaDvbApi->StartTransfer(fd_video);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (fd_video >= 0 && fd_audio >= 0) {
|
if (fd_video >= 0 && fd_audio >= 0) {
|
||||||
CHECK(ioctl(fd_audio, AUDIO_SET_MUTE, false));
|
CHECK(ioctl(fd_audio, AUDIO_SET_MUTE, false));
|
||||||
CHECK(ioctl(fd_video, VIDEO_SET_BLANK, false));
|
CHECK(ioctl(fd_video, VIDEO_SET_BLANK, false));
|
||||||
|
Loading…
Reference in New Issue
Block a user