From patchwork Fri Aug 31 19:25:43 2007 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Reinhard Nissl X-Patchwork-Id: 12520 Received: from mail.gmx.net ([213.165.64.20]) by www.linuxtv.org with smtp (Exim 4.63) (envelope-from ) id 1IRC8F-0002Ag-Hn for vdr@linuxtv.org; Fri, 31 Aug 2007 21:26:15 +0200 Received: (qmail invoked by alias); 31 Aug 2007 19:25:44 -0000 Received: from p54932D37.dip0.t-ipconnect.de (EHLO [192.168.101.15]) [84.147.45.55] by mail.gmx.net (mp028) with SMTP; 31 Aug 2007 21:25:44 +0200 X-Authenticated: #527675 X-Provags-ID: V01U2FsdGVkX18dPwICdxYdB49NwJsUywUC5kbS4f3Xhh7qrMuWRp yRrE7JDl3dqQ16 Message-ID: <46D86B37.3020701@gmx.de> Date: Fri, 31 Aug 2007 21:25:43 +0200 From: Reinhard Nissl User-Agent: Mozilla/5.0 (X11; U; Linux i686; en-US; rv:1.8.0.12) Gecko/20060911 SUSE/1.5.0.12-3.4 Thunderbird/1.5.0.12 Mnenhy/0.7.4.666 MIME-Version: 1.0 To: VDR Mailing List References: <46D4A316.8090409@gmx.de> <3e063bbf0708310232k647576advb447b8b69ab04ddc@mail.gmail.com> <46D85CE8.2050805@gmx.de> <1188585260.31994.12.camel@core> In-Reply-To: <1188585260.31994.12.camel@core> X-Y-GMX-Trusted: 0 Subject: Re: [vdr] [ANNOUNCE] H.264 updates for VDR-1.5.9 X-BeenThere: vdr@linuxtv.org X-Mailman-Version: 2.1.9 Precedence: list Reply-To: VDR Mailing List List-Id: VDR Mailing List List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Fri, 31 Aug 2007 19:26:16 -0000 Status: O X-Status: X-Keywords: X-UID: 13989 Hi, Petri Hintukainen wrote: >> But I don't understand why streamdev still delivers a decrypted video >> stream in that case. Can it be that the client asks streamdev to filter >> certain TS packets and therefore uses the correct VPID? > > Yes. In http streaming mode streamdev parses PIDs directly from PMT and > does not use VDR channel data. But the VDR<->VDR streaming mode probably > does not work if PIDs are not "real" ones. Please try the attached patch which adds VPID clipping to some locations. Bye. --- ../vdr-1.5.9-orig/ci.c 2007-04-30 15:02:49.000000000 +0200 +++ ci.c 2007-08-31 21:08:30.000000000 +0200 @@ -1880,7 +1880,7 @@ void cCamSlot::AddChannel(const cChannel source = Channel->Source(); transponder = Channel->Transponder(); if (Channel->Ca() >= CA_ENCRYPTED_MIN) { - AddPid(Channel->Sid(), Channel->Vpid(), STREAM_TYPE_VIDEO); + AddPid(Channel->Sid(), VPID_FROM_ANY(Channel->Vpid()), STREAM_TYPE_VIDEO); for (const int *Apid = Channel->Apids(); *Apid; Apid++) AddPid(Channel->Sid(), *Apid, STREAM_TYPE_AUDIO); for (const int *Dpid = Channel->Dpids(); *Dpid; Dpid++) @@ -1901,7 +1901,7 @@ bool cCamSlot::CanDecrypt(const cChannel if (cas && cas->RepliesToQuery()) { cCiCaPmt CaPmt(CPCI_QUERY, Channel->Source(), Channel->Transponder(), Channel->Sid(), GetCaSystemIds()); CaPmt.SetListManagement(CPLM_ADD); // WORKAROUND: CPLM_ONLY doesn't work with Alphacrypt 3.09 (deletes existing CA_PMTs) - CaPmt.AddPid(Channel->Vpid(), STREAM_TYPE_VIDEO); + CaPmt.AddPid(VPID_FROM_ANY(Channel->Vpid()), STREAM_TYPE_VIDEO); for (const int *Apid = Channel->Apids(); *Apid; Apid++) CaPmt.AddPid(*Apid, STREAM_TYPE_AUDIO); for (const int *Dpid = Channel->Dpids(); *Dpid; Dpid++) --- ../vdr-1.5.9-orig/dvbdevice.c 2007-08-17 15:37:56.000000000 +0200 +++ dvbdevice.c 2007-08-31 21:20:22.000000000 +0200 @@ -76,7 +76,7 @@ private: int tuneTimeout; int lockTimeout; time_t lastTimeoutReport; - fe_type_t frontendType; + dvbfe_delsys frontendType; cChannel channel; const char *diseqcCommands; eTunerStatus tunerStatus; @@ -87,14 +87,14 @@ private: bool SetFrontend(void); virtual void Action(void); public: - cDvbTuner(int Fd_Frontend, int CardIndex, fe_type_t FrontendType); + cDvbTuner(int Fd_Frontend, int CardIndex, dvbfe_delsys FrontendType); virtual ~cDvbTuner(); bool IsTunedTo(const cChannel *Channel) const; void Set(const cChannel *Channel, bool Tune); bool Locked(int TimeoutMs = 0); }; -cDvbTuner::cDvbTuner(int Fd_Frontend, int CardIndex, fe_type_t FrontendType) +cDvbTuner::cDvbTuner(int Fd_Frontend, int CardIndex, dvbfe_delsys FrontendType) { fd_frontend = Fd_Frontend; cardIndex = CardIndex; @@ -104,7 +104,7 @@ cDvbTuner::cDvbTuner(int Fd_Frontend, in lastTimeoutReport = 0; diseqcCommands = NULL; tunerStatus = tsIdle; - if (frontendType == FE_QPSK) + if (frontendType & (DVBFE_DELSYS_DVBS | DVBFE_DELSYS_DVBS2)) CHECK(ioctl(fd_frontend, FE_SET_VOLTAGE, SEC_VOLTAGE_13)); // must explicitly turn on LNB power SetDescription("tuner on device %d", cardIndex + 1); Start(); @@ -173,114 +173,165 @@ static unsigned int FrequencyToHz(unsign bool cDvbTuner::SetFrontend(void) { - dvb_frontend_parameters Frontend; - + dvbfe_params Frontend; memset(&Frontend, 0, sizeof(Frontend)); - switch (frontendType) { - case FE_QPSK: { // DVB-S - - unsigned int frequency = channel.Frequency(); - - if (Setup.DiSEqC) { - cDiseqc *diseqc = Diseqcs.Get(channel.Source(), channel.Frequency(), channel.Polarization()); - if (diseqc) { - if (diseqc->Commands() && (!diseqcCommands || strcmp(diseqcCommands, diseqc->Commands()) != 0)) { - cDiseqc::eDiseqcActions da; - for (char *CurrentAction = NULL; (da = diseqc->Execute(&CurrentAction)) != cDiseqc::daNone; ) { - switch (da) { - case cDiseqc::daNone: break; - case cDiseqc::daToneOff: CHECK(ioctl(fd_frontend, FE_SET_TONE, SEC_TONE_OFF)); break; - case cDiseqc::daToneOn: CHECK(ioctl(fd_frontend, FE_SET_TONE, SEC_TONE_ON)); break; - case cDiseqc::daVoltage13: CHECK(ioctl(fd_frontend, FE_SET_VOLTAGE, SEC_VOLTAGE_13)); break; - case cDiseqc::daVoltage18: CHECK(ioctl(fd_frontend, FE_SET_VOLTAGE, SEC_VOLTAGE_18)); break; - case cDiseqc::daMiniA: CHECK(ioctl(fd_frontend, FE_DISEQC_SEND_BURST, SEC_MINI_A)); break; - case cDiseqc::daMiniB: CHECK(ioctl(fd_frontend, FE_DISEQC_SEND_BURST, SEC_MINI_B)); break; - case cDiseqc::daCodes: { - int n = 0; - uchar *codes = diseqc->Codes(n); - if (codes) { - struct dvb_diseqc_master_cmd cmd; - memcpy(cmd.msg, codes, min(n, int(sizeof(cmd.msg)))); - cmd.msg_len = n; - CHECK(ioctl(fd_frontend, FE_DISEQC_SEND_MASTER_CMD, &cmd)); - } - } - break; - } - } - diseqcCommands = diseqc->Commands(); + if (frontendType & (DVBFE_DELSYS_DVBS | DVBFE_DELSYS_DVBS2)) { // DVB-S + unsigned int frequency = channel.Frequency(); + if (Setup.DiSEqC) { + cDiseqc *diseqc = Diseqcs.Get(channel.Source(), channel.Frequency(), channel.Polarization()); + if (diseqc) { + if (diseqc->Commands() && (!diseqcCommands || strcmp(diseqcCommands, diseqc->Commands()) != 0)) { +fprintf(stderr, "DiSEqC: %s\n", diseqc->Commands()); + cDiseqc::eDiseqcActions da; + for (char *CurrentAction = NULL; (da = diseqc->Execute(&CurrentAction)) != cDiseqc::daNone; ) { + switch (da) { + case cDiseqc::daNone: break; + case cDiseqc::daToneOff: CHECK(ioctl(fd_frontend, FE_SET_TONE, SEC_TONE_OFF)); break; + case cDiseqc::daToneOn: CHECK(ioctl(fd_frontend, FE_SET_TONE, SEC_TONE_ON)); break; + case cDiseqc::daVoltage13: CHECK(ioctl(fd_frontend, FE_SET_VOLTAGE, SEC_VOLTAGE_13)); break; + case cDiseqc::daVoltage18: CHECK(ioctl(fd_frontend, FE_SET_VOLTAGE, SEC_VOLTAGE_18)); break; + case cDiseqc::daMiniA: CHECK(ioctl(fd_frontend, FE_DISEQC_SEND_BURST, SEC_MINI_A)); break; + case cDiseqc::daMiniB: CHECK(ioctl(fd_frontend, FE_DISEQC_SEND_BURST, SEC_MINI_B)); break; + case cDiseqc::daCodes: { + int n = 0; + uchar *codes = diseqc->Codes(n); + if (codes) { + struct dvb_diseqc_master_cmd cmd; + memcpy(cmd.msg, codes, min(n, int(sizeof(cmd.msg)))); + cmd.msg_len = n; + CHECK(ioctl(fd_frontend, FE_DISEQC_SEND_MASTER_CMD, &cmd)); + } + } + break; + } } - frequency -= diseqc->Lof(); - } - else { - esyslog("ERROR: no DiSEqC parameters found for channel %d", channel.Number()); - return false; - } - } - else { - int tone = SEC_TONE_OFF; - - if (frequency < (unsigned int)Setup.LnbSLOF) { - frequency -= Setup.LnbFrequLo; - tone = SEC_TONE_OFF; - } - else { - frequency -= Setup.LnbFrequHi; - tone = SEC_TONE_ON; - } - int volt = (channel.Polarization() == 'v' || channel.Polarization() == 'V' || channel.Polarization() == 'r' || channel.Polarization() == 'R') ? SEC_VOLTAGE_13 : SEC_VOLTAGE_18; - CHECK(ioctl(fd_frontend, FE_SET_VOLTAGE, volt)); - CHECK(ioctl(fd_frontend, FE_SET_TONE, tone)); - } - - frequency = abs(frequency); // Allow for C-band, where the frequency is less than the LOF - Frontend.frequency = frequency * 1000UL; - Frontend.inversion = fe_spectral_inversion_t(channel.Inversion()); - Frontend.u.qpsk.symbol_rate = channel.Srate() * 1000UL; - Frontend.u.qpsk.fec_inner = fe_code_rate_t(channel.CoderateH()); - - tuneTimeout = DVBS_TUNE_TIMEOUT; - lockTimeout = DVBS_LOCK_TIMEOUT; - } - break; - case FE_QAM: { // DVB-C - - // Frequency and symbol rate: - - Frontend.frequency = FrequencyToHz(channel.Frequency()); - Frontend.inversion = fe_spectral_inversion_t(channel.Inversion()); - Frontend.u.qam.symbol_rate = channel.Srate() * 1000UL; - Frontend.u.qam.fec_inner = fe_code_rate_t(channel.CoderateH()); - Frontend.u.qam.modulation = fe_modulation_t(channel.Modulation()); - - tuneTimeout = DVBC_TUNE_TIMEOUT; - lockTimeout = DVBC_LOCK_TIMEOUT; - } - break; - case FE_OFDM: { // DVB-T - - // Frequency and OFDM paramaters: - - Frontend.frequency = FrequencyToHz(channel.Frequency()); - Frontend.inversion = fe_spectral_inversion_t(channel.Inversion()); - Frontend.u.ofdm.bandwidth = fe_bandwidth_t(channel.Bandwidth()); - Frontend.u.ofdm.code_rate_HP = fe_code_rate_t(channel.CoderateH()); - Frontend.u.ofdm.code_rate_LP = fe_code_rate_t(channel.CoderateL()); - Frontend.u.ofdm.constellation = fe_modulation_t(channel.Modulation()); - Frontend.u.ofdm.transmission_mode = fe_transmit_mode_t(channel.Transmission()); - Frontend.u.ofdm.guard_interval = fe_guard_interval_t(channel.Guard()); - Frontend.u.ofdm.hierarchy_information = fe_hierarchy_t(channel.Hierarchy()); - - tuneTimeout = DVBT_TUNE_TIMEOUT; - lockTimeout = DVBT_LOCK_TIMEOUT; - } - break; - default: - esyslog("ERROR: attempt to set channel with unknown DVB frontend type"); - return false; - } - if (ioctl(fd_frontend, FE_SET_FRONTEND, &Frontend) < 0) { + diseqcCommands = diseqc->Commands(); + } + frequency -= diseqc->Lof(); + } + else { + esyslog("ERROR: no DiSEqC parameters found for channel %d", channel.Number()); + return false; + } + } + else { + int tone = SEC_TONE_OFF; + if (frequency < (unsigned int)Setup.LnbSLOF) { + frequency -= Setup.LnbFrequLo; + tone = SEC_TONE_OFF; + } + else { + frequency -= Setup.LnbFrequHi; + tone = SEC_TONE_ON; + } + int volt = (channel.Polarization() == 'v' || channel.Polarization() == 'V' || channel.Polarization() == 'r' || channel.Polarization() == 'R') ? SEC_VOLTAGE_13 : SEC_VOLTAGE_18; + CHECK(ioctl(fd_frontend, FE_SET_VOLTAGE, volt)); + CHECK(ioctl(fd_frontend, FE_SET_TONE, tone)); + } + frequency = abs(frequency); // Allow for C-band, where the frequency is less than the LOF + Frontend.frequency = frequency * 1000UL; + Frontend.inversion = fe_spectral_inversion_t(channel.Inversion()); + + dvbfe_info feinfo; + if (channel.ModulationSystem() == DVBFE_DELSYS_DVBS) { + dsyslog("set DVB-S"); + feinfo.delivery = DVBFE_DELSYS_DVBS; + CHECK(ioctl(fd_frontend, DVBFE_GET_INFO, &feinfo)); //switch system + + Frontend.delivery = DVBFE_DELSYS_DVBS; + Frontend.inversion = fe_spectral_inversion_t(channel.Inversion()); + Frontend.delsys.dvbs.modulation = dvbfe_modulation(channel.Modulation()); + Frontend.delsys.dvbs.symbol_rate = channel.Srate() * 1000UL; + Frontend.delsys.dvbs.fec = dvbfe_fec(channel.CoderateH()); + } + else { + dsyslog("set DVB-S2"); + feinfo.delivery = DVBFE_DELSYS_DVBS2; + CHECK(ioctl(fd_frontend, DVBFE_GET_INFO, &feinfo)); //switch system + + Frontend.delivery = DVBFE_DELSYS_DVBS2; + Frontend.inversion = fe_spectral_inversion_t(channel.Inversion()); + Frontend.delsys.dvbs2.modulation = dvbfe_modulation(channel.Modulation()); + Frontend.delsys.dvbs2.symbol_rate = channel.Srate() * 1000UL; + Frontend.delsys.dvbs2.fec = dvbfe_fec(channel.CoderateH()); + Frontend.delsys.dvbs2.rolloff = dvbfe_rolloff(channel.RollOff()); + } + tuneTimeout = DVBS_TUNE_TIMEOUT; + lockTimeout = DVBS_LOCK_TIMEOUT; + } + else if (frontendType & DVBFE_DELSYS_DVBC) { // DVB-C + dvbfe_info feinfo; + feinfo.delivery = DVBFE_DELSYS_DVBC; + CHECK(ioctl(fd_frontend, DVBFE_GET_INFO, &feinfo)); //switch system + + Frontend.delivery = DVBFE_DELSYS_DVBC; + Frontend.frequency = FrequencyToHz(channel.Frequency()); + Frontend.inversion = fe_spectral_inversion_t(channel.Inversion()); + Frontend.delsys.dvbc.symbol_rate = channel.Srate() * 1000UL; + Frontend.delsys.dvbc.fec = dvbfe_fec(channel.CoderateH()); + Frontend.delsys.dvbc.modulation = dvbfe_modulation(channel.Modulation()); + + tuneTimeout = DVBC_TUNE_TIMEOUT; + lockTimeout = DVBC_LOCK_TIMEOUT; + } + else if (frontendType & DVBFE_DELSYS_DVBT) { // DVB-T + dvbfe_info feinfo; + feinfo.delivery = DVBFE_DELSYS_DVBT; + CHECK(ioctl(fd_frontend, DVBFE_GET_INFO, &feinfo)); //switch system + + Frontend.delivery = DVBFE_DELSYS_DVBT; + Frontend.frequency = FrequencyToHz(channel.Frequency()); + Frontend.inversion = fe_spectral_inversion_t(channel.Inversion()); + Frontend.delsys.dvbt.bandwidth = dvbfe_bandwidth(channel.Bandwidth()); + Frontend.delsys.dvbt.code_rate_HP = dvbfe_fec(channel.CoderateH()); + Frontend.delsys.dvbt.code_rate_LP = dvbfe_fec(channel.CoderateL()); + Frontend.delsys.dvbt.constellation = dvbfe_modulation(channel.Modulation()); + Frontend.delsys.dvbt.transmission_mode = dvbfe_transmission_mode(channel.Transmission()); + Frontend.delsys.dvbt.guard_interval = dvbfe_guard_interval(channel.Guard()); + Frontend.delsys.dvbt.hierarchy = dvbfe_hierarchy(channel.Hierarchy()); + Frontend.delsys.dvbt.alpha = dvbfe_alpha(channel.Alpha()); + Frontend.delsys.dvbt.priority = dvbfe_stream_priority(channel.Priority()); + + tuneTimeout = DVBT_TUNE_TIMEOUT; + lockTimeout = DVBT_LOCK_TIMEOUT; + } +/* XXX + else if (frontendType & DVBFE_DELSYS_DVBH) { // DVB-H + Frontend.delivery = DVBFE_DELSYS_DVBH; + Frontend.frequency = FrequencyToHz(channel.Frequency()); + Frontend.inversion = fe_spectral_inversion_t(channel.Inversion()); + + Frontend.delsys.dvbh.bandwidth = dvbfe_bandwidth(channel.Bandwidth()); + Frontend.delsys.dvbh.code_rate_HP = dvbfe_fec(channel.CoderateH()); + Frontend.delsys.dvbh.code_rate_LP = dvbfe_fec(channel.CoderateL()); + Frontend.delsys.dvbh.constellation = dvbfe_modulation(channel.Modulation()); + Frontend.delsys.dvbh.transmission_mode = dvbfe_transmission_mode(channel.Transmission()); + Frontend.delsys.dvbh.guard_interval = dvbfe_guard_interval(channel.Guard()); + Frontend.delsys.dvbh.hierarchy = dvbfe_hierarchy(channel.Hierarchy()); + +// Frontend.delsys.dvbh.alpha = 0; //XXX +// Frontend.delsys.dvbh.interleaver = 0; //XXX +// Frontend.delsys.dvbh.mpefec = 0; //XXX +// Frontend.delsys.dvbh.timeslicing = 0; //XXX +// Frontend.delsys.dvbh.priority = 0; //XXX + } + else if (frontendType & DVBFE_DELSYS_DSS) { // DDS + Frontend.delivery = DVBFE_DELSYS_DSS; + Frontend.delsys.dss.modulation = DVBFE_MOD_QPSK; //XXX + Frontend.delsys.dss.symbol_rate = channel.Srate() * 1000UL; + Frontend.delsys.dss.fec = dvbfe_fec(channel.CoderateH()); + } + else if (frontendType & DVBFE_DELSYS_ATSC) { // ATCS + Frontend.delivery = DVBFE_DELSYS_ATSC; + Frontend.delsys.atsc.modulation = DVBFE_MOD_QPSK; //XXX + } +*/ + else { + esyslog("ERROR: attempt to set channel with unknown DVB frontend type"); + return false; + } + if (ioctl(fd_frontend, DVBFE_SET_PARAMS, &Frontend) < 0) { esyslog("ERROR: frontend %d: %m", cardIndex); return false; } @@ -355,7 +406,7 @@ cDvbDevice::cDvbDevice(int n) { ciAdapter = NULL; dvbTuner = NULL; - frontendType = fe_type_t(-1); // don't know how else to initialize this - there is no FE_UNKNOWN + frontendType = DVBFE_DELSYS_DUMMY; spuDecoder = NULL; digitalAudio = false; playMode = pmNone; @@ -417,11 +468,8 @@ cDvbDevice::cDvbDevice(int n) // 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; + if (ioctl(fd_frontend, DVBFE_GET_DELSYS, &frontendType) >= 0) dvbTuner = new cDvbTuner(fd_frontend, CardIndex(), frontendType); - } else LOG_ERROR; } @@ -738,9 +786,9 @@ bool cDvbDevice::ProvidesSource(int Sour { int type = Source & cSource::st_Mask; return type == cSource::stNone - || type == cSource::stCable && frontendType == FE_QAM - || type == cSource::stSat && frontendType == FE_QPSK - || type == cSource::stTerr && frontendType == FE_OFDM; + || type == cSource::stCable && (frontendType & DVBFE_DELSYS_DVBC) + || type == cSource::stSat && (frontendType & (DVBFE_DELSYS_DVBS | DVBFE_DELSYS_DVBS2)) + || type == cSource::stTerr && (frontendType & DVBFE_DELSYS_DVBT); } bool cDvbDevice::ProvidesTransponder(const cChannel *Channel) const @@ -758,7 +806,7 @@ bool cDvbDevice::ProvidesChannel(const c result = hasPriority; if (Priority >= 0 && Receiving(true)) { if (dvbTuner->IsTunedTo(Channel)) { - if (Channel->Vpid() && !HasPid(Channel->Vpid()) || Channel->Apid(0) && !HasPid(Channel->Apid(0))) { + if (Channel->Vpid() && !HasPid(VPID_FROM_ANY(Channel->Vpid())) || Channel->Apid(0) && !HasPid(Channel->Apid(0))) { #ifdef DO_MULTIPLE_RECORDINGS if (CamSlot() && Channel->Ca() >= CA_ENCRYPTED_MIN) { if (CamSlot()->CanDecrypt(Channel)) @@ -794,7 +842,7 @@ bool cDvbDevice::IsTunedToTransponder(co bool cDvbDevice::SetChannelDevice(const cChannel *Channel, bool LiveView) { int apid = Channel->Apid(0); - int vpid = Channel->Vpid(); + int vpid = VPID_FROM_ANY(Channel->Vpid()); int dpid = Channel->Dpid(0); bool DoTune = !dvbTuner->IsTunedTo(Channel); @@ -855,7 +903,7 @@ bool cDvbDevice::SetChannelDevice(const CHECK(ioctl(fd_audio, AUDIO_SET_AV_SYNC, true)); } else if (StartTransferMode) - cControl::Launch(new cTransferControl(this, Channel->GetChannelID(), vpid, Channel->Apids(), Channel->Dpids(), Channel->Spids())); + cControl::Launch(new cTransferControl(this, Channel->GetChannelID(), Channel->Vpid(), Channel->Apids(), Channel->Dpids(), Channel->Spids())); return true; }