[mythtv] DVB fixes
Ben Bucksch
linux.news at bucksch.org
Sun Jun 22 01:56:53 EDT 2003
The patch here contains what I fixed over the last time, during looking
over the checkin, as result of feedback and coincidentially. This
contains the fix I sent to the list a long time ago, but which was never
applied (maybe went under?). It also contains a fix by zaheer.
List of changes, by purpose:
* Readded a few comments which were not included during the DVB
checkin, but I really think they are important, for new developers
to understand the source or to prevent regressions by pointing out
pitfalls I fell into. Some of the comments shortened from previous
version, in case the length was the problem.
* Prevent malfunction/crash in case of bad settings (cardnumber)
* Fix compile problem with gcc 2.95 as reported by Leandro
* Learned that DVB-C needs a lot more tuning options than I thought,
added provisions for them.
* Fixed a typo in channel parameters parsing
* Fixed channel tuning during recording. Contributed by zaheer
(thanks!).
* Random fixes for comments in the DVB files
* Added an error msg.
With zaheer's fix, I think recording and playback works now. zaheer, is
that correct?
-------------- next part --------------
Index: libs/libdvbdev/dvbdev.c
===================================================================
RCS file: /var/lib/mythcvs/mythtv/libs/libdvbdev/dvbdev.c,v
retrieving revision 1.2
diff -u -r1.2 dvbdev.c
--- libs/libdvbdev/dvbdev.c 17 May 2003 17:06:17 -0000 1.2
+++ libs/libdvbdev/dvbdev.c 21 Jun 2003 22:44:18 -0000
@@ -63,6 +63,9 @@
char* demuxdev[4]={"/dev/ost/demux0","/dev/ost/demux1","/dev/ost/demux2","/dev/ost/demux3"};
#endif
+ if (cardnum > 3)
+ return "no such device number";
+
switch(type)
{
case dvbdev_frontend:
@@ -70,7 +73,11 @@
case dvbdev_dvr:
return dvrdev[cardnum];
case dvbdev_sec:
+#ifdef NEWSTRUCT
return "not valid in newstruct";
+#else
+ return secdev[cardnum];
+#endif
case dvbdev_demux:
return demuxdev[cardnum];
}
@@ -154,6 +161,7 @@
uint8_t off = 0;
ipack *p = 0;
int i;
+ struct append_buffer app_buf;
if (!(buf[3] & 0x10)) // no payload?
return;
@@ -164,7 +172,6 @@
if (p == 0)
return;
- struct append_buffer app_buf;
app_buf.memory = out_buf;
app_buf.buf_len = out_buf_max_len;
app_buf.content_len = 0;
Index: libs/libmythtv/channel.h
===================================================================
RCS file: /var/lib/mythcvs/mythtv/libs/libmythtv/channel.h,v
retrieving revision 1.21
diff -u -r1.21 channel.h
--- libs/libmythtv/channel.h 14 May 2003 02:43:29 -0000 1.21
+++ libs/libmythtv/channel.h 21 Jun 2003 22:44:18 -0000
@@ -9,6 +9,9 @@
class TVRec;
+/* Implements tuning for analog TV cards (both software and hardware encoding)
+ using the V4L driver API */
+
class Channel : public ChannelBase
{
public:
Index: libs/libmythtv/dvbchannel.cpp
===================================================================
RCS file: /var/lib/mythcvs/mythtv/libs/libmythtv/dvbchannel.cpp,v
retrieving revision 1.1
diff -u -r1.1 dvbchannel.cpp
--- libs/libmythtv/dvbchannel.cpp 14 May 2003 02:43:29 -0000 1.1
+++ libs/libmythtv/dvbchannel.cpp 21 Jun 2003 22:44:19 -0000
@@ -117,12 +117,12 @@
if (demux_fd.size() != pid.size())
cerr << "aaarggg! sizes don't match" <<endl;
for (unsigned int i = 0; i < pid.size(); i++)
- {
+ {
cout << "demux" << i << "=" << demux_fd[i] << " pid " << pid[i] << endl;
set_ts_filt(demux_fd[i], pid[i], DMX_PES_OTHER);
/* if we used DMX_PES_VIDEO/AUDIO, it would allow the full cards
to decode, but we don't need that anyways. */
- }
+ }
#endif
}
// else we did that in Open() already
@@ -258,22 +258,24 @@
QString option;
if (dvb_type == DVBChannel::DVB_S)
{
- int opt_int = query.value(1).toInt();
- if (opt_int == 'V' || opt_int == 'v')
+ option = query.value(1).toString();
+ if (option == 'V' || option == 'v')
s.pol_v = true;
- else if (opt_int == 'H' || opt_int == 'h')
+ else if (option == 'H' || option == 'h')
s.pol_v = false;
else
return false;
-
+ // for symbol rate, see below
+ s.tone = query.value(3).toInt();
+ s.diseqc = query.value(4).toInt();
+ }
+ if (dvb_type == DVBChannel::DVB_S || dvb_type == DVBChannel::DVB_C)
+ {
s.symbol_rate = query.value(2).toInt();
if (s.symbol_rate == 0)
return false;
-
- s.tone = query.value(3).toInt();
- s.diseqc = query.value(4).toInt();
}
- else if (dvb_type == DVBChannel::DVB_T)
+ if (dvb_type == DVBChannel::DVB_T)
{
/* All DVB-T settings are optional in the channel settings,
they are usually the same all over the country and we'll use
@@ -282,16 +284,7 @@
The driver defines all the settings as enums, so I have to hardcode
all possible value here *sigh* */
- if ((option = query.value(5).toString().lower()) != QString::null)
- {
- if (option == "1" || option == "on"
- || option == "yes") s.inversion = INVERSION_ON;
- else if (option == "0" || option == "off"
- || option == "no") s.inversion = INVERSION_OFF;
- else if (option == "auto") s.inversion = INVERSION_AUTO;
- else cerr << "invalid inversion option " << option
- << " for channel " << chan << endl;
- }
+ // for inversion, see below
if ((option = query.value(6).toString().lower()) != QString::null)
{
if (option == "6") s.bandwidth = BANDWIDTH_6_MHZ;
@@ -312,6 +305,7 @@
else if (option == "4_5") s.hp_code_rate = FEC_4_5;
else if (option == "5_6") s.hp_code_rate = FEC_5_6;
else if (option == "6_7") s.hp_code_rate = FEC_6_7;
+ else if (option == "7_8") s.hp_code_rate = FEC_7_8;
else if (option == "8_9") s.hp_code_rate = FEC_8_9;
else if (option == "auto") s.hp_code_rate = FEC_AUTO;
else cerr << "invalid hp code rate option " << option
@@ -328,23 +322,13 @@
else if (option == "4_5") s.lp_code_rate = FEC_4_5;
else if (option == "5_6") s.lp_code_rate = FEC_5_6;
else if (option == "6_7") s.lp_code_rate = FEC_6_7;
+ else if (option == "7_8") s.lp_code_rate = FEC_7_8;
else if (option == "8_9") s.lp_code_rate = FEC_8_9;
else if (option == "auto") s.lp_code_rate = FEC_AUTO;
else cerr << "invalid lp code rate option " << option
<< " for channel " << chan << endl;
}
- if ((option = query.value(9).toString().lower()) != QString::null)
- {
- if (option == "qpsk") s.modulation = QPSK;
- else if (option == "qam_16") s.modulation = QAM_16;
- else if (option == "qam_32") s.modulation = QAM_32;
- else if (option == "qam_64") s.modulation = QAM_64;
- else if (option == "qam_128") s.modulation = QAM_128;
- else if (option == "qam_256") s.modulation = QAM_256;
- else if (option == "qam_auto") s.modulation = QAM_AUTO;
- else cerr << "invalid modulation option " << option
- << " for channel " << chan << endl;
- }
+ // for modulation, see below
if ((option = query.value(10).toString().lower()) != QString::null)
{
if (option == "2") s.transmission_mode = TRANSMISSION_MODE_2K;
@@ -377,6 +361,31 @@
<< " for channel " << chan << endl;
}
}
+ if (dvb_type == DVBChannel::DVB_T || dvb_type == DVBChannel::DVB_C)
+ {
+ if ((option = query.value(5).toString().lower()) != QString::null)
+ {
+ if (option == "1" || option == "on"
+ || option == "yes") s.inversion = INVERSION_ON;
+ else if (option == "0" || option == "off"
+ || option == "no") s.inversion = INVERSION_OFF;
+ else if (option == "auto") s.inversion = INVERSION_AUTO;
+ else cerr << "invalid inversion option " << option
+ << " for channel " << chan << endl;
+ }
+ if ((option = query.value(9).toString().lower()) != QString::null)
+ {
+ if (option == "qpsk") s.modulation = QPSK;
+ else if (option == "qam_16") s.modulation = QAM_16;
+ else if (option == "qam_32") s.modulation = QAM_32;
+ else if (option == "qam_64") s.modulation = QAM_64;
+ else if (option == "qam_128") s.modulation = QAM_128;
+ else if (option == "qam_256") s.modulation = QAM_256;
+ else if (option == "qam_auto") s.modulation = QAM_AUTO;
+ else cerr << "invalid modulation option " << option
+ << " for channel " << chan << endl;
+ }
+ }
// PIDs
option = query.value(13).toString();
@@ -459,7 +468,10 @@
cout << "got tuning parameters" << endl;
if (!DVBTune(tunerSettings, cardnum))
+ {
+ cerr << "invalid tuning parameters" << endl;
return false;
+ }
pid = tunerSettings.pid;
if (!SetPID())
@@ -475,4 +487,9 @@
cerr << "DVB support not compiled in" << endl;
return false;
#endif
+}
+
+void DVBChannel::SwitchToInput(const QString &input, const QString &chan)
+{
+ SetChannelByString(chan);
}
Index: libs/libmythtv/dvbchannel.h
===================================================================
RCS file: /var/lib/mythcvs/mythtv/libs/libmythtv/dvbchannel.h,v
retrieving revision 1.1
diff -u -r1.1 dvbchannel.h
--- libs/libmythtv/dvbchannel.h 14 May 2003 02:43:29 -0000 1.1
+++ libs/libmythtv/dvbchannel.h 21 Jun 2003 22:44:19 -0000
@@ -31,7 +31,7 @@
virtual void SetFormat(const QString &format) {}
virtual void ToggleInputs() {}
virtual void SwitchToInput(const QString &input) {}
- virtual void SwitchToInput(const QString &input, const QString &chan) {}
+ virtual void SwitchToInput(const QString &input, const QString &chan);
virtual void SwitchToInput(int newcapchannel, bool setstarting) {}
enum DVB_Type {DVB_S, DVB_T, DVB_C};
Index: libs/libmythtv/dvbrecorder.cpp
===================================================================
RCS file: /var/lib/mythcvs/mythtv/libs/libmythtv/dvbrecorder.cpp,v
retrieving revision 1.5
diff -u -r1.5 dvbrecorder.cpp
--- libs/libmythtv/dvbrecorder.cpp 6 Jun 2003 15:41:29 -0000 1.5
+++ libs/libmythtv/dvbrecorder.cpp 21 Jun 2003 22:44:19 -0000
@@ -64,7 +64,7 @@
/* This Recorder fetches the PIDs itself when the recording starts,
but maybe the channel gets changed during a recording?
- We can't rely on this SetOption either, because that's called by the
+ We can't rely on this SetPID either, because that's called by the
Channel when the channel changes, and when the initial channel is
set, this Recorder doesn't exist yet. */
void DVBRecorder::SetPID(const vector<int>& some_pids)
@@ -146,6 +146,7 @@
}
else if (was_paused)
{
+ // Re-open
if (Open())
was_paused = false;
// XXX need to set mainpaused = false? mpegrecorder doesn't.
@@ -183,10 +184,10 @@
}
/* This function call fulfills 2 purposes:
- - Converts MPEG-TS (transport stream) to MPEG-PS (what's
- usually used in MPEG video files)
+ - Converts MPEG-TS (transport stream for transmission)
+ to MPEG-PS (what's usually used in MPEG video files)
- Filters out all unneeded program streams.
- This is redundant for use_ts==false,
+ This is redundant (but cheap) for use_ts==false,
but required for use_ts==true. */
ts_to_ps(buffer_raw,
pid_array, npids, &ipacks_p,
@@ -231,7 +232,7 @@
Generic MPEG code follows (identical in MpegRecorder, DVBRecorder and co).
I would have liked to use a common base class for that, but Isaac preferred
to have all the code for a given class in one file
- =========================================================================== */
+ ========================================================================= */
static void mpg_write_packet(void *opaque, uint8_t *buf, int buf_size)
{
Index: libs/libmythtv/tv_rec.cpp
===================================================================
RCS file: /var/lib/mythcvs/mythtv/libs/libmythtv/tv_rec.cpp,v
retrieving revision 1.86
diff -u -r1.86 tv_rec.cpp
--- libs/libmythtv/tv_rec.cpp 19 Jun 2003 02:20:42 -0000 1.86
+++ libs/libmythtv/tv_rec.cpp 21 Jun 2003 22:44:20 -0000
@@ -72,10 +72,10 @@
channel->SetChannelOrdering(chanorder);
// don't close this channel, otherwise we cannot read data
}
- else
+ else // "V4L" or "MPEG", i.e. analog TV
{
Channel *achannel = new Channel(this, videodev);
- channel = achannel;
+ channel = achannel; // here for SetFormat()->RetrieveInputChannels()
channel->Open();
achannel->SetFormat(gContext->GetSetting("TVFormat"));
achannel->SetFreqTable(gContext->GetSetting("FreqTable"));
@@ -554,6 +554,7 @@
nvr->Initialize();
return;
}
+ // else V4L
nvr = new NuppelVideoRecorder();
More information about the mythtv-dev
mailing list