[mythtv] [DVB][PATCH] Fix demux problems + misc. minor stuff
Jesper Sörensen
jesper at datapartner.se
Mon Mar 28 14:34:36 UTC 2005
- Make DVB recorder recognize DTS audio streams
- Remove broken dvb_sw_filter option
- Add PCRPID logging
- Remove PS stream id overrides (allows PS recorder to handle multiple
audio streams)
- Workaround for demux problems caused by the DEC2000-t patch:
Basically, some DVB cards/drivers (e.g. the DEC2000-t) seem to need
DMX_PES_AUDIO/VIDEO
for the demux, but that causes problems for other cards. The best
solution is probably to fix the
drivers to handle DMX_PES_OTHER properly, but as a workaround I've added
an option in
mythtv-setup to activate "hardware decoder" mode for those who need it.
For some background on this, please see Marcus Metzler's e-mail to the
mythtv-dev list
on 2004-12-04, with the subject: "don't use DMX_PES_VIDEO".
-------------- next part --------------
Index: libs/libmythtv/dbcheck.cpp
===================================================================
RCS file: /var/lib/mythcvs/mythtv/libs/libmythtv/dbcheck.cpp,v
retrieving revision 1.95
diff -u -r1.95 dbcheck.cpp
--- libs/libmythtv/dbcheck.cpp 27 Mar 2005 18:18:56 -0000 1.95
+++ libs/libmythtv/dbcheck.cpp 28 Mar 2005 13:13:35 -0000
@@ -9,7 +9,7 @@
#include "mythcontext.h"
#include "mythdbcon.h"
-const QString currentDatabaseVersion = "1078";
+const QString currentDatabaseVersion = "1079";
static bool UpdateDBVersionNumber(const QString &newnumber);
static bool performActualUpdate(const QString updates[], QString version,
@@ -1583,6 +1583,17 @@
return false;
}
+ if (dbver == "1078")
+ {
+ const QString updates[] = {
+"ALTER TABLE capturecard CHANGE dvb_swfilter dvb_hw_decoder INT DEFAULT '0';",
+"UPDATE capturecard SET dvb_hw_decoder = 0;",
+""
+};
+ if (!performActualUpdate(updates, "1079", dbver))
+ return false;
+ }
+
return true;
}
Index: libs/libmythtv/dvbrecorder.cpp
===================================================================
RCS file: /var/lib/mythcvs/mythtv/libs/libmythtv/dvbrecorder.cpp,v
retrieving revision 1.48
diff -u -r1.48 dvbrecorder.cpp
--- libs/libmythtv/dvbrecorder.cpp 26 Mar 2005 15:16:49 -0000 1.48
+++ libs/libmythtv/dvbrecorder.cpp 28 Mar 2005 13:13:35 -0000
@@ -70,11 +70,9 @@
dvbchannel = advbchannel;
_dvb_on_demand_option = false;
- _software_filter_option = false;
+ _hw_decoder_option = false;
_record_transport_stream_option = false;
- _software_filter_open = false;
-
_continuity_error_count = 0;
_stream_overflow_count = 0;
_bad_packet_count = 0;
@@ -105,8 +103,8 @@
{
if (name == "cardnum")
_card_number_option = value;
- else if (name == "swfilter")
- _software_filter_option = (value == 1);
+ else if (name == "hw_decoder")
+ _hw_decoder_option = (value == 1);
else if (name == "recordts")
_record_transport_stream_option = (value == 1);
#if 0
@@ -223,11 +221,9 @@
}
}
pid_ipack.clear();
-
- _software_filter_open = false;
}
-void DVBRecorder::OpenFilters(uint16_t pid, ES_Type type)
+void DVBRecorder::OpenFilters(uint16_t pid, ES_Type type, dmx_pes_type_t pes_type)
{
VERBOSE(VB_RECORD, QString("DVB#%1 ").arg(_card_number_option) << QString("Adding pid %1").arg(pid));
@@ -236,78 +232,32 @@
WARNING(QString("PID value (%1) is outside DVB specification.")
.arg(pid));
- if (!_software_filter_option || !_software_filter_open)
- {
- struct dmx_pes_filter_params params;
- memset(¶ms, 0, sizeof(params));
- params.input = DMX_IN_FRONTEND;
- params.output = DMX_OUT_TS_TAP;
- params.flags = DMX_IMMEDIATE_START;
- params.pes_type = DMX_PES_OTHER;
+ struct dmx_pes_filter_params params;
+ memset(¶ms, 0, sizeof(params));
+ params.input = DMX_IN_FRONTEND;
+ params.output = DMX_OUT_TS_TAP;
+ params.flags = DMX_IMMEDIATE_START;
+ params.pid = pid;
+ params.pes_type = pes_type;
- if ( _software_filter_option )
- {
- params.pes_type = DMX_PES_OTHER;
- params.pid = DMX_DONT_FILTER;
- }
- else
- {
- params.pid = pid;
- switch ( type )
- {
- case ES_TYPE_VIDEO_MPEG1:
- case ES_TYPE_VIDEO_MPEG2:
- case ES_TYPE_VIDEO_MPEG4:
- case ES_TYPE_VIDEO_H264:
- params.pes_type = DMX_PES_VIDEO;
- break;
- case ES_TYPE_AUDIO_MPEG1:
- case ES_TYPE_AUDIO_MPEG2:
- case ES_TYPE_AUDIO_AAC:
- case ES_TYPE_AUDIO_AC3:
- case ES_TYPE_AUDIO_DTS:
- params.pes_type = DMX_PES_AUDIO;
- break;
- case ES_TYPE_TELETEXT:
- params.pes_type = DMX_PES_TELETEXT;
- break;
- case ES_TYPE_SUBTITLE:
- params.pes_type = DMX_PES_SUBTITLE;
- break;
- case ES_TYPE_DATA:
- params.pes_type = DMX_PES_PCR;
- break;
- default:
- params.pes_type = DMX_PES_OTHER;
- break;
- }
- }
+ int fd_tmp = open(dvbdevice(DVB_DEV_DEMUX,_card_number_option), O_RDWR);
- int fd_tmp = open(dvbdevice(DVB_DEV_DEMUX,_card_number_option), O_RDWR);
-
- if (fd_tmp < 0)
- {
- ERRNO(QString("Could not open demux device."));
- return;
- }
-
- if (_software_filter_option)
- {
- GENERAL("Using Software Filtering.");
- _software_filter_open = true;
- }
-
- if (ioctl(fd_tmp, DMX_SET_PES_FILTER, ¶ms) < 0)
- {
- close(fd_tmp);
+ if (fd_tmp < 0)
+ {
+ ERRNO(QString("Could not open demux device."));
+ return;
+ }
- ERRNO(QString("Failed to set demux filter."));
- return;
- }
+ if (ioctl(fd_tmp, DMX_SET_PES_FILTER, ¶ms) < 0)
+ {
+ close(fd_tmp);
- _pid_filters.push_back(fd_tmp);
+ ERRNO(QString("Failed to set demux filter."));
+ return;
}
+ _pid_filters.push_back(fd_tmp);
+
if (_record_transport_stream_option)
{
pid_ipack[pid] = NULL;
@@ -381,15 +331,50 @@
{
if ((*es).Record)
{
- OpenFilters((*es).PID, (*es).Type);
+ int pid = (*es).PID;
+ dmx_pes_type_t pes_type;
+
+ if (_hw_decoder_option)
+ {
+ switch ((*es).Type)
+ {
+ case ES_TYPE_AUDIO_MPEG1:
+ case ES_TYPE_AUDIO_MPEG2:
+ pes_type = DMX_PES_AUDIO;
+ break;
+ case ES_TYPE_VIDEO_MPEG1:
+ case ES_TYPE_VIDEO_MPEG2:
+ pes_type = DMX_PES_VIDEO;
+ break;
+ case ES_TYPE_TELETEXT:
+ pes_type = DMX_PES_TELETEXT;
+ break;
+ case ES_TYPE_SUBTITLE:
+ pes_type = DMX_PES_SUBTITLE;
+ break;
+ default:
+ pes_type = DMX_PES_OTHER;
+ break;
+ }
+ }
+ else
+ pes_type = DMX_PES_OTHER;
+
+ OpenFilters(pid, (*es).Type, pes_type);
- if ((*es).PID == m_pmt.PCRPID)
+ if (_hw_decoder_option)
+ {
+ // Set PCRPID if it's not the same as video
+ if ((pes_type == DMX_PES_VIDEO) && (pid != m_pmt.PCRPID) && (m_pmt.PCRPID != 0))
+ OpenFilters(m_pmt.PCRPID, ES_TYPE_UNKNOWN, DMX_PES_PCR);
+ }
+ else if (pid == m_pmt.PCRPID)
need_pcr_pid = false;
}
}
- if (_record_transport_stream_option && need_pcr_pid)
- OpenFilters(m_pmt.PCRPID, ES_TYPE_UNKNOWN);
+ if (!_hw_decoder_option && need_pcr_pid && (m_pmt.PCRPID != 0))
+ OpenFilters(m_pmt.PCRPID, ES_TYPE_UNKNOWN, DMX_PES_OTHER);
if (_pid_filters.size() == 0 && pid_ipack.size() == 0)
@@ -409,6 +394,8 @@
isVideo.clear();
+ RECORD(QString("AutoPID for ServiceID=%1, PCRPID=%2").arg(m_pmt.ServiceID).arg(m_pmt.PCRPID));
+
// Wanted languages:
QStringList Languages = QStringList::split(",", gContext->GetSetting("PreferredLanguages", ""));
@@ -421,7 +408,8 @@
StreamTypes += ES_TYPE_AUDIO_AC3;
if (_record_transport_stream_option)
{
- // PS recorder can't handle these
+ // The following types are only supported with TS recording
+ StreamTypes += ES_TYPE_AUDIO_DTS;
StreamTypes += ES_TYPE_AUDIO_AAC;
StreamTypes += ES_TYPE_TELETEXT;
StreamTypes += ES_TYPE_SUBTITLE;
@@ -459,10 +447,9 @@
continue; // Ignore this stream
}
- if (!_record_transport_stream_option)
+ if (_hw_decoder_option)
{
- // The MPEG PS decoder in Myth currently only handles one stream
- // of each type, so make sure we don't already have one
+ // Limit hardware decoders to one A/V stream
switch ((*es).Type)
{
case ES_TYPE_VIDEO_MPEG1:
@@ -477,17 +464,11 @@
continue; // Ignore this stream
break;
- case ES_TYPE_AUDIO_AC3:
- if (flagged.contains(ES_TYPE_AUDIO_AC3))
- continue; // Ignore this stream
- break;
-
default:
break;
}
}
-
if (Languages.isEmpty() // No specific language wanted
|| (*es).Language.isEmpty() // Component has no language
|| Languages.contains((*es).Language)) // This language is wanted!
@@ -783,7 +764,6 @@
case PRIVATE_STREAM1:
break;
case AUDIO_STREAM_S ... AUDIO_STREAM_E:
- buffer[3] = 0xc0; // fix audio ID to 0xC0
break;
case VIDEO_STREAM_S ... VIDEO_STREAM_E:
@@ -795,7 +775,6 @@
unsigned int state = 0xFFFFFFFF, v = 0;
int prvcount = -1;
- buffer[3] = 0xe0; // fix video ID to 0xE0
while (bufptr < &buffer[pos] + datalen)
{
if (++prvcount < 3)
Index: libs/libmythtv/dvbrecorder.h
===================================================================
RCS file: /var/lib/mythcvs/mythtv/libs/libmythtv/dvbrecorder.h,v
retrieving revision 1.24
diff -u -r1.24 dvbrecorder.h
--- libs/libmythtv/dvbrecorder.h 31 Jan 2005 05:49:56 -0000 1.24
+++ libs/libmythtv/dvbrecorder.h 28 Mar 2005 13:13:35 -0000
@@ -48,7 +48,7 @@
void LocalProcessDataTS(unsigned char *buffer, int len);
void CloseFilters();
- void OpenFilters(uint16_t pid, ES_Type type);
+ void OpenFilters(uint16_t pid, ES_Type type, dmx_pes_type_t pes_type);
void SetDemuxFilters();
void AutoPID();
@@ -59,7 +59,7 @@
int _card_number_option;
bool _record_transport_stream_option;
bool _dvb_on_demand_option;
- bool _software_filter_option;
+ bool _hw_decoder_option;
// DVB stuff
DVBChannel* dvbchannel;
@@ -67,7 +67,6 @@
PMTObject m_pmt;
unsigned char prvpkt[3];
vector<int> _pid_filters;
- bool _software_filter_open;
bool _reset_pid_filters; // set when we want to generate a new filter set
// Stream IDs for the PS recorder
Index: libs/libmythtv/siparser.cpp
===================================================================
RCS file: /var/lib/mythcvs/mythtv/libs/libmythtv/siparser.cpp,v
retrieving revision 1.12
diff -u -r1.12 siparser.cpp
--- libs/libmythtv/siparser.cpp 28 Mar 2005 01:30:25 -0000 1.12
+++ libs/libmythtv/siparser.cpp 28 Mar 2005 13:13:36 -0000
@@ -760,6 +760,14 @@
switch (descriptor_tag)
{
+ case 0x05: // Registration Descriptor
+ {
+ QString format = QString::fromLatin1((const char*) descriptor + 2, 4);
+ if (format == "DTS1")
+ e.Type = ES_TYPE_AUDIO_DTS;
+ }
+ break;
+
case 0x0A: // ISO 639 Language Descriptor
e.Language = ParseDescriptorLanguage(descriptor, descriptor_len);
break;
Index: libs/libmythtv/tv_rec.cpp
===================================================================
RCS file: /var/lib/mythcvs/mythtv/libs/libmythtv/tv_rec.cpp,v
retrieving revision 1.177
diff -u -r1.177 tv_rec.cpp
--- libs/libmythtv/tv_rec.cpp 28 Mar 2005 08:40:56 -0000 1.177
+++ libs/libmythtv/tv_rec.cpp 28 Mar 2005 13:13:37 -0000
@@ -701,7 +701,7 @@
nvr->SetOptionsFromProfile(&profile, videodev, audiodev, vbidev, ispip);
nvr->SetOption("dvb_on_demand", dvb_options.dvb_on_demand);
- nvr->SetOption("swfilter", dvb_options.swfilter);
+ nvr->SetOption("hw_decoder", dvb_options.hw_decoder);
nvr->SetOption("recordts", dvb_options.recordts);
nvr->SetOption("wait_for_seqstart", dvb_options.wait_for_seqstart);
nvr->SetOption("dmx_buf_size", dvb_options.dmx_buf_size);
@@ -1115,7 +1115,7 @@
MSqlQuery query(MSqlQuery::InitCon());
query.prepare("SELECT videodevice,vbidevice,audiodevice,"
"audioratelimit,defaultinput,cardtype,"
- "dvb_swfilter, dvb_recordts,"
+ "dvb_hw_decoder, dvb_recordts,"
"dvb_wait_for_seqstart,dvb_dmx_buf_size,"
"dvb_pkt_buf_size, skipbtaudio, dvb_on_demand,"
"firewire_port, firewire_node, firewire_speed,"
@@ -1153,7 +1153,7 @@
if (test != QString::null)
type = QString::fromUtf8(test);
- dvb_opts.swfilter = query.value(6).toInt();
+ dvb_opts.hw_decoder = query.value(6).toInt();
dvb_opts.recordts = query.value(7).toInt();
dvb_opts.wait_for_seqstart = query.value(8).toInt();
dvb_opts.dmx_buf_size = query.value(9).toInt();
Index: libs/libmythtv/tv_rec.h
===================================================================
RCS file: /var/lib/mythcvs/mythtv/libs/libmythtv/tv_rec.h,v
retrieving revision 1.63
diff -u -r1.63 tv_rec.h
--- libs/libmythtv/tv_rec.h 11 Mar 2005 19:18:51 -0000 1.63
+++ libs/libmythtv/tv_rec.h 28 Mar 2005 13:13:37 -0000
@@ -32,7 +32,7 @@
typedef struct _dvb_options_t
{
- int swfilter;
+ int hw_decoder;
int recordts;
int wait_for_seqstart;
int dmx_buf_size;
Index: libs/libmythtv/videosource.cpp
===================================================================
RCS file: /var/lib/mythcvs/mythtv/libs/libmythtv/videosource.cpp,v
retrieving revision 1.71
diff -u -r1.71 videosource.cpp
--- libs/libmythtv/videosource.cpp 19 Mar 2005 06:51:41 -0000 1.71
+++ libs/libmythtv/videosource.cpp 28 Mar 2005 13:13:37 -0000
@@ -766,13 +766,14 @@
};
};
-class DVBSwFilter: public CheckBoxSetting, public CCSetting {
+class DVBHwDecoder: public CheckBoxSetting, public CCSetting {
public:
- DVBSwFilter(const CaptureCard& parent):
- CCSetting(parent, "dvb_swfilter") {
- setLabel(QObject::tr("Do NOT use DVB driver for filtering."));
- setHelpText(QObject::tr("(BROKEN) This option is used to get around "
- "filtering limitations on some DVB cards."));
+ DVBHwDecoder(const CaptureCard& parent):
+ CCSetting(parent, "dvb_hw_decoder") {
+ setLabel(QObject::tr("Use hardware MPEG decoder"));
+ setHelpText(QObject::tr("If your DVB card has a built in MPEG decoder "
+ "you can activate it here. "
+ "(Only for full featured cards & certain USB devices)."));
};
};
@@ -1982,7 +1983,7 @@
VerticalConfigurationGroup* rec = new VerticalConfigurationGroup(false); rec->setLabel(QObject::tr("Recorder Options"));
rec->setUseLabel(false);
- rec->addChild(new DVBSwFilter(parent));
+ rec->addChild(new DVBHwDecoder(parent));
rec->addChild(new DVBRecordTS(parent));
rec->addChild(new DVBNoSeqStart(parent));
rec->addChild(new DVBOnDemand(parent));
More information about the mythtv-dev
mailing list