bool cDvbDevice::SetChannelDevice(const cChannel *Channel, bool LiveView) { bool DoTune = !dvbTuner->IsTunedTo(Channel); bool TurnOffLivePIDs = HasDecoder() && (DoTune || !IsPrimaryDevice() || LiveView // for a new live view the old PIDs need to be turned off || pidHandles[ptVideo].pid == Channel->Vpid() // for recording the PIDs must be shifted from DMX_PES_AUDIO/VIDEO to DMX_PES_OTHER ); bool StartTransferMode = IsPrimaryDevice() && !DoTune && (LiveView && HasPid(Channel->Vpid() ? Channel->Vpid() : Channel->Apid(0)) && (pidHandles[ptVideo].pid != Channel->Vpid() || (pidHandles[ptAudio].pid != Channel->Apid(0) && (Channel->Dpid(0) ? pidHandles[ptAudio].pid != Channel->Dpid(0) : true)))// the PID is already set as DMX_PES_OTHER || !LiveView && (pidHandles[ptVideo].pid == Channel->Vpid() || pidHandles[ptAudio].pid == Channel->Apid(0)) // a recording is going to shift the PIDs from DMX_PES_AUDIO/VIDEO to DMX_PES_OTHER ); bool TurnOnLivePIDs = HasDecoder() && !StartTransferMode && LiveView; #ifndef DO_MULTIPLE_RECORDINGS TurnOffLivePIDs = TurnOnLivePIDs = true; StartTransferMode = false; #endif // Turn off live PIDs if necessary: if (TurnOffLivePIDs) TurnOffLiveMode(LiveView); // Set the tuner: dvbTuner->Set(Channel, DoTune); // If this channel switch was requested by the EITScanner we don't wait for // a lock and don't set any live PIDs (the EITScanner will wait for the lock // by itself before setting any filters): if (EITScanner.UsesDevice(this)) //XXX return true; // PID settings: if (TurnOnLivePIDs) { SetAudioBypass(false); if (!(AddPid(Channel->Ppid(), ptPcr) && AddPid(Channel->Vpid(), ptVideo) && AddPid(Channel->Apid(0), ptAudio))) { esyslog("ERROR: failed to set PIDs for channel %d on device %d", Channel->Number(), CardIndex() + 1); return false; } if (IsPrimaryDevice()) AddPid(Channel->Tpid(), ptTeletext); CHECK(ioctl(fd_audio, AUDIO_SET_MUTE, true)); // actually one would expect 'false' here, but according to Marco Schlüßler <*****@*****.**> this works // to avoid missing audio after replaying a DVD; with 'false' there is an audio disturbance when switching // between two channels on the same transponder on DVB-S CHECK(ioctl(fd_audio, AUDIO_SET_AV_SYNC, true)); } else if (StartTransferMode) cControl::Launch(new cTransferControl(this, Channel->Vpid(), Channel->Apids(), Channel->Dpids(), Channel->Spids())); return true; }
void cDvbDevice::SetVideoFormat(bool VideoFormat16_9) { if (HasDecoder()) { CHECK(ioctl(fd_video, VIDEO_SET_FORMAT, VideoFormat16_9 ? VIDEO_FORMAT_16_9 : VIDEO_FORMAT_4_3)); SetVideoDisplayFormat(eVideoDisplayFormat(Setup.VideoDisplayFormat)); } }
int cDvbDevice::GetAudioChannelDevice(void) { if (HasDecoder()) { audio_status_t as; CHECK(ioctl(fd_audio, AUDIO_GET_STATUS, &as)); return as.channel_select; } return 0; }
void cDvbDevice::SetVolumeDevice(int Volume) { if (HasDecoder()) { if (digitalAudio) Volume = 0; audio_mixer_t am; // conversion for linear volume response: am.volume_left = am.volume_right = 2 * Volume - Volume * Volume / 255; CHECK(ioctl(fd_audio, AUDIO_SET_MIXER, &am)); } }
void SCDEVICE::LateInit(void) { DEBUGLOG("%s", __FUNCTION__); int n = CardIndex(); if (DeviceNumber() != n) ERRORLOG("CardIndex - DeviceNumber mismatch! Put DVBAPI plugin first on VDR commandline!"); softcsa = (fd_ca < 0); if (softcsa) { if (HasDecoder()) INFOLOG("Card %s is a full-featured card but no ca device found!", devId); } else if (cScDevices::ForceBudget(n)) { INFOLOG("Budget mode forced on card %s", devId); softcsa = true; } if (softcsa) { INFOLOG("Using software decryption on card %s", devId); } }
void cDvbDevice::SetVideoDisplayFormat(eVideoDisplayFormat VideoDisplayFormat) { cDevice::SetVideoDisplayFormat(VideoDisplayFormat); if (HasDecoder()) { if (Setup.VideoFormat) { CHECK(ioctl(fd_video, VIDEO_SET_DISPLAY_FORMAT, VIDEO_LETTER_BOX)); } else { switch (VideoDisplayFormat) { case vdfPanAndScan: CHECK(ioctl(fd_video, VIDEO_SET_DISPLAY_FORMAT, VIDEO_PAN_SCAN)); break; case vdfLetterBox: CHECK(ioctl(fd_video, VIDEO_SET_DISPLAY_FORMAT, VIDEO_LETTER_BOX)); break; case vdfCenterCutOut: CHECK(ioctl(fd_video, VIDEO_SET_DISPLAY_FORMAT, VIDEO_CENTER_CUT_OUT)); break; } } } }
bool cScDvbSdFfDevice::CheckFullTs(void) { return IsPrimaryDevice() && HasDecoder(); }
void cDvbDevice::SetAudioChannelDevice(int AudioChannel) { if (HasDecoder()) CHECK(ioctl(fd_audio, AUDIO_CHANNEL_SELECT, AudioChannel)); }
void cDvbDevice::MakePrimaryDevice(bool On) { if (HasDecoder()) new cDvbOsdProvider(fd_osd); }
cDvbDevice::cDvbDevice(int n) { dvbTuner = NULL; frontendType = fe_type_t(-1); // don't know how else to initialize this - there is no FE_UNKNOWN spuDecoder = NULL; digitalAudio = false; playMode = pmNone; // Devices that are present on all card types: int fd_frontend = DvbOpen(DEV_DVB_FRONTEND, n, O_RDWR | O_NONBLOCK); // Devices that are only present on cards with decoders: fd_osd = DvbOpen(DEV_DVB_OSD, n, O_RDWR); fd_video = DvbOpen(DEV_DVB_VIDEO, n, O_RDWR | O_NONBLOCK); fd_audio = DvbOpen(DEV_DVB_AUDIO, n, O_RDWR | O_NONBLOCK); fd_stc = DvbOpen(DEV_DVB_DEMUX, n, O_RDWR); // The DVR device (will be opened and closed as needed): fd_dvr = -1; // The offset of the /dev/video devices: if (devVideoOffset < 0) { // the first one checks this FILE *f = NULL; char buffer[PATH_MAX]; for (int ofs = 0; ofs < 100; ofs++) { snprintf(buffer, sizeof(buffer), "/proc/video/dev/video%d", ofs); if ((f = fopen(buffer, "r")) != NULL) { if (fgets(buffer, sizeof(buffer), f)) { if (strstr(buffer, "DVB Board")) { // found the _first_ DVB card devVideoOffset = ofs; dsyslog("video device offset is %d", devVideoOffset); break; } } else break; fclose(f); } else break; } if (devVideoOffset < 0) devVideoOffset = 0; if (f) fclose(f); } devVideoIndex = (devVideoOffset >= 0 && HasDecoder()) ? devVideoOffset++ : -1; // Video format: SetVideoFormat(Setup.VideoFormat); // We only check the devices that must be present - the others will be checked before accessing them://XXX if (fd_frontend >= 0) { dvb_frontend_info feinfo; if (ioctl(fd_frontend, FE_GET_INFO, &feinfo) >= 0) { frontendType = feinfo.type; ciHandler = cCiHandler::CreateCiHandler(*cDvbName(DEV_DVB_CA, n)); dvbTuner = new cDvbTuner(fd_frontend, CardIndex(), frontendType, ciHandler); } else LOG_ERROR; } else esyslog("ERROR: can't open DVB device %d", n); StartSectionHandler(); }