diff options
| author | Felix Domke <felix.domke@multimedia-labs.de> | 2009-07-16 23:41:52 +0200 |
|---|---|---|
| committer | Felix Domke <felix.domke@multimedia-labs.de> | 2009-07-16 23:41:52 +0200 |
| commit | 37bac1d63115720ca83f064e0e4f5426271fc364 (patch) | |
| tree | bb3c2f65db1ac96f86328035c7bd4f7bcb2aa1ed /lib/dvb | |
| parent | ff69eecfab66bbfa534d8a766c001c79a13ac90e (diff) | |
| parent | f834b32700be1cde60218fea84756fdc91fddacd (diff) | |
| download | enigma2-37bac1d63115720ca83f064e0e4f5426271fc364.tar.gz enigma2-37bac1d63115720ca83f064e0e4f5426271fc364.zip | |
Merge branch 'master' of git.opendreambox.org:/git/enigma2
Diffstat (limited to 'lib/dvb')
| -rw-r--r-- | lib/dvb/db.cpp | 5 | ||||
| -rw-r--r-- | lib/dvb/demux.cpp | 41 | ||||
| -rw-r--r-- | lib/dvb/pmt.cpp | 121 | ||||
| -rw-r--r-- | lib/dvb/scan.cpp | 35 | ||||
| -rw-r--r-- | lib/dvb/specs.h | 2 |
5 files changed, 125 insertions, 79 deletions
diff --git a/lib/dvb/db.cpp b/lib/dvb/db.cpp index ffc62f6c..109d6a64 100644 --- a/lib/dvb/db.cpp +++ b/lib/dvb/db.cpp @@ -175,7 +175,10 @@ int eDVBService::checkFilter(const eServiceReferenceDVB &ref, const eDVBChannelQ res = m_service_name_sort == query.m_string; break; case eDVBChannelQuery::tProvider: - res = m_provider_name == query.m_string; + if (query.m_string == "Unknown" && m_provider_name.empty()) + res = 1; + else + res = m_provider_name == query.m_string; break; case eDVBChannelQuery::tType: res = ref.getServiceType() == query.m_int; diff --git a/lib/dvb/demux.cpp b/lib/dvb/demux.cpp index 11465186..6d925405 100644 --- a/lib/dvb/demux.cpp +++ b/lib/dvb/demux.cpp @@ -35,6 +35,13 @@ #define HAVE_ADD_PID #ifdef HAVE_ADD_PID + +#if HAVE_DVB_API_VERSION > 3 +#ifndef DMX_ADD_PID +#define DMX_ADD_PID _IOW('o', 51, __u16) +#define DMX_REMOVE_PID _IOW('o', 52, __u16) +#endif +#else #define DMX_ADD_PID _IO('o', 51) #define DMX_REMOVE_PID _IO('o', 52) @@ -42,6 +49,7 @@ typedef enum { DMX_TAP_TS = 0, DMX_TAP_PES = DMX_PES_OTHER, /* for backward binary compat. */ } dmx_tap_type_t; +#endif #endif @@ -493,12 +501,17 @@ eDVBTSRecorder::~eDVBTSRecorder() RESULT eDVBTSRecorder::start() { + std::map<int,int>::iterator i(m_pids.begin()); + if (m_running) return -1; if (m_target_fd == -1) return -2; + if (i == m_pids.end()) + return -3; + char filename[128]; #ifndef HAVE_ADD_PID #if HAVE_DVB_API_VERSION < 3 @@ -527,10 +540,16 @@ RESULT eDVBTSRecorder::start() ::ioctl(m_source_fd, DMX_SET_BUFFER_SIZE, 1024*1024); dmx_pes_filter_params flt; +#if HAVE_DVB_API_VERSION > 3 + flt.pes_type = DMX_PES_OTHER; + flt.output = DMX_OUT_TSDEMUX_TAP; +#else flt.pes_type = (dmx_pes_type_t)DMX_TAP_TS; - flt.pid = (__u16)-1; - flt.input = DMX_IN_FRONTEND; flt.output = DMX_OUT_TAP; +#endif + flt.pid = i->first; + ++i; + flt.input = DMX_IN_FRONTEND; flt.flags = 0; int res = ::ioctl(m_source_fd, DMX_SET_PES_FILTER, &flt); if (res) @@ -549,10 +568,12 @@ RESULT eDVBTSRecorder::start() m_thread->start(m_source_fd, m_target_fd); m_running = 1; - - for (std::map<int,int>::iterator i(m_pids.begin()); i != m_pids.end(); ++i) + + while (i != m_pids.end()) { startPID(i->first); - + ++i; + } + return 0; } @@ -675,7 +696,12 @@ RESULT eDVBTSRecorder::startPID(int pid) m_pids[pid] = fd; #else while(true) { +#if HAVE_DVB_API_VERSION > 3 + __u16 p = pid; + if (::ioctl(m_source_fd, DMX_ADD_PID, &p) < 0) { +#else if (::ioctl(m_source_fd, DMX_ADD_PID, pid) < 0) { +#endif perror("DMX_ADD_PID"); if (errno == EAGAIN || errno == EINTR) { eDebug("retry!"); @@ -698,7 +724,12 @@ void eDVBTSRecorder::stopPID(int pid) if (m_pids[pid] != -1) { while(true) { +#if HAVE_DVB_API_VERSION > 3 + __u16 p = pid; + if (::ioctl(m_source_fd, DMX_REMOVE_PID, &p) < 0) { +#else if (::ioctl(m_source_fd, DMX_REMOVE_PID, pid) < 0) { +#endif perror("DMX_REMOVE_PID"); if (errno == EAGAIN || errno == EINTR) { eDebug("retry!"); diff --git a/lib/dvb/pmt.cpp b/lib/dvb/pmt.cpp index 13ed6b98..e1aa096d 100644 --- a/lib/dvb/pmt.cpp +++ b/lib/dvb/pmt.cpp @@ -17,6 +17,7 @@ #include <dvbsi++/subtitling_descriptor.h> #include <dvbsi++/teletext_descriptor.h> #include <dvbsi++/video_stream_descriptor.h> +#include <dvbsi++/registration_descriptor.h> eDVBServicePMTHandler::eDVBServicePMTHandler() :m_ca_servicePtr(0), m_dvb_scan(0), m_decode_demux_num(0xFF) @@ -209,11 +210,11 @@ int eDVBServicePMTHandler::getProgramInfo(struct program &program) { const ProgramMapSection &pmt = **i; program.pcrPid = pmt.getPcrPid(); - + ElementaryStreamInfoConstIterator es; for (es = pmt.getEsInfo()->begin(); es != pmt.getEsInfo()->end(); ++es) { - int isaudio = 0, isvideo = 0; + int isaudio = 0, isvideo = 0, issubtitle = 0, forced_video = 0, forced_audio = 0; videoStream video; audioStream audio; audio.component_tag=video.component_tag=-1; @@ -239,17 +240,21 @@ int eDVBServicePMTHandler::getProgramInfo(struct program &program) //break; fall through !!! case 0x02: // MPEG 2 video isvideo = 1; + forced_video = 1; //break; fall through !!! case 0x03: // MPEG 1 audio case 0x04: // MPEG 2 audio: - if (!isvideo) + if (!isvideo) { isaudio = 1; + forced_audio = 1; + } //break; fall through !!! case 0x0f: // MPEG 2 AAC if (!isvideo && !isaudio) { isaudio = 1; audio.type = audioStream::atAAC; + forced_audio = 1; } //break; fall through !!! case 0x11: // MPEG 4 AAC @@ -257,6 +262,7 @@ int eDVBServicePMTHandler::getProgramInfo(struct program &program) { isaudio = 1; audio.type = audioStream::atAACHE; + forced_audio = 1; } case 0x80: // user private ... but blueray LPCM if (!isvideo && !isaudio) @@ -280,13 +286,12 @@ int eDVBServicePMTHandler::getProgramInfo(struct program &program) case 0x06: // PES Private case 0xEA: // TS_PSI_ST_SMPTE_VC1 for (DescriptorConstIterator desc = (*es)->getDescriptors()->begin(); - desc != (*es)->getDescriptors()->end(); ++desc) + desc != (*es)->getDescriptors()->end(); ++desc) { uint8_t tag = (*desc)->getTag(); - if (!isaudio && !isvideo) + /* check descriptors to get the exakt stream type. */ + if (!forced_video && !forced_audio) { - /* PES private can contain AC-3, DTS or lots of other stuff. - check descriptors to get the exakt type. */ switch (tag) { case AUDIO_STREAM_DESCRIPTOR: @@ -325,6 +330,7 @@ int eDVBServicePMTHandler::getProgramInfo(struct program &program) s.language_code = (*it)->getIso639LanguageCode(); // eDebug("add dvb subtitle %s PID %04x, type %d, composition page %d, ancillary_page %d", // s.language_code.c_str(), s.pid, s.subtitling_type, s.composition_page_id, s.ancillary_page_id); + issubtitle=1; program.subtitleStreams.push_back(s); } break; @@ -349,6 +355,8 @@ int eDVBServicePMTHandler::getProgramInfo(struct program &program) // eDebug("add teletext subtitle %s PID %04x, page number %d, magazine number %d", // s.language_code.c_str(), s.pid, s.teletext_page_number, s.teletext_magazine_number); program.subtitleStreams.push_back(s); + issubtitle=1; + default: break; } } @@ -373,13 +381,8 @@ int eDVBServicePMTHandler::getProgramInfo(struct program &program) break; case REGISTRATION_DESCRIPTOR: /* some services don't have a separate AC3 descriptor */ { - /* libdvbsi++ doesn't yet support this descriptor type, so work around. */ - if ((*desc)->getLength() < 4) - break; - unsigned char descr[6]; - (*desc)->writeToBuffer(descr); - int format_identifier = (descr[2] << 24) | (descr[3] << 16) | (descr[4] << 8) | (descr[5]); - switch (format_identifier) + RegistrationDescriptor *d = (RegistrationDescriptor*)(*desc); + switch (d->getFormatIdentifier()) { case 0x44545331 ... 0x44545333: // DTS1/DTS2/DTS3 isaudio = 1; @@ -394,15 +397,17 @@ int eDVBServicePMTHandler::getProgramInfo(struct program &program) audio.type = audioStream::atLPCM; break; case 0x56432d31: // == 'VC-1' - if (descr[6] == 0x01) // subdescriptor tag + { + const AdditionalIdentificationInfoVector *vec = d->getAdditionalIdentificationInfo(); + if (vec->size() > 1 && (*vec)[1] == 0x01) // subdescriptor tag { - if (descr[7] >= 0x90) // profile_level + if ((*vec)[2] >= 0x90) // profile_level video.type = videoStream::vtVC1; // advanced profile else video.type = videoStream::vtVC1_SM; // simple main isvideo = 1; } - break; + } default: break; } @@ -422,39 +427,57 @@ int eDVBServicePMTHandler::getProgramInfo(struct program &program) } switch (tag) { - case ISO_639_LANGUAGE_DESCRIPTOR: - if (!isvideo) + case ISO_639_LANGUAGE_DESCRIPTOR: + if (!isvideo) + { + int cnt=0; + const Iso639LanguageList *languages = ((Iso639LanguageDescriptor*)*desc)->getIso639Languages(); + /* use last language code */ + for (Iso639LanguageConstIterator i(languages->begin()); i != languages->end(); ++i, ++cnt) { - int cnt=0; - const Iso639LanguageList *languages = ((Iso639LanguageDescriptor*)*desc)->getIso639Languages(); - /* use last language code */ - for (Iso639LanguageConstIterator i(languages->begin()); i != languages->end(); ++i, ++cnt) - { - if (cnt == 0) - audio.language_code = (*i)->getIso639LanguageCode(); - else - audio.language_code += "/" + (*i)->getIso639LanguageCode(); - } + if (cnt == 0) + audio.language_code = (*i)->getIso639LanguageCode(); + else + audio.language_code += "/" + (*i)->getIso639LanguageCode(); } - break; - case STREAM_IDENTIFIER_DESCRIPTOR: - audio.component_tag = - video.component_tag = - ((StreamIdentifierDescriptor*)*desc)->getComponentTag(); - break; - case CA_DESCRIPTOR: - { - CaDescriptor *descr = (CaDescriptor*)(*desc); - program.caids.insert(descr->getCaSystemId()); - break; } - default: - break; + break; + case STREAM_IDENTIFIER_DESCRIPTOR: + audio.component_tag = + video.component_tag = + ((StreamIdentifierDescriptor*)*desc)->getComponentTag(); + break; + case CA_DESCRIPTOR: + { + CaDescriptor *descr = (CaDescriptor*)(*desc); + program.caids.insert(descr->getCaSystemId()); + break; + } + default: + break; } } + default: break; } - if (isaudio) + if (issubtitle && (isaudio || isvideo)) + eDebug("ambiguous streamtype for PID %04x detected.. forced as subtitle!", (*es)->getPid()); + else if (isaudio && isvideo) + eDebug("ambiguous streamtype for PID %04x detected.. forced as video!", (*es)->getPid()); + if (issubtitle) + continue; + else if (isvideo) + { + video.pid = (*es)->getPid(); + if ( !program.videoStreams.empty() && video.pid == cached_vpid ) + { + program.videoStreams.push_back(program.videoStreams[0]); + program.videoStreams[0] = video; + } + else + program.videoStreams.push_back(video); + } + else if (isaudio) { audio.pid = (*es)->getPid(); @@ -468,17 +491,6 @@ int eDVBServicePMTHandler::getProgramInfo(struct program &program) program.audioStreams.push_back(audio); } - else if (isvideo) - { - video.pid = (*es)->getPid(); - if ( !program.videoStreams.empty() && video.pid == cached_vpid ) - { - program.videoStreams.push_back(program.videoStreams[0]); - program.videoStreams[0] = video; - } - else - program.videoStreams.push_back(video); - } else continue; } @@ -494,7 +506,6 @@ int eDVBServicePMTHandler::getProgramInfo(struct program &program) } ret = 0; - /* finally some fixup: if our default audio stream is an MPEG audio stream, and we have 'defaultac3' set, use the first available ac3 stream instead. (note: if an ac3 audio stream was selected before, this will be also stored diff --git a/lib/dvb/scan.cpp b/lib/dvb/scan.cpp index 1c8e4d2e..19c10868 100644 --- a/lib/dvb/scan.cpp +++ b/lib/dvb/scan.cpp @@ -5,6 +5,7 @@ #include <dvbsi++/terrestrial_delivery_system_descriptor.h> #include <dvbsi++/cable_delivery_system_descriptor.h> #include <dvbsi++/ca_identifier_descriptor.h> +#include <dvbsi++/registration_descriptor.h> #include <lib/dvb/specs.h> #include <lib/dvb/esection.h> #include <lib/dvb/scan.h> @@ -292,32 +293,36 @@ void eDVBScan::PMTready(int err) ElementaryStreamInfoConstIterator es; for (es = pmt.getEsInfo()->begin(); es != pmt.getEsInfo()->end(); ++es) { - int isaudio = 0, isvideo = 0, is_scrambled = 0; + int isaudio = 0, isvideo = 0, is_scrambled = 0, forced_audio = 0, forced_video = 0; switch ((*es)->getType()) { - case 0xEA: // TS_PSI_ST_SMPTE_VC1 case 0x1b: // AVC Video Stream (MPEG4 H264) case 0x10: // MPEG 4 Part 2 case 0x01: // MPEG 1 video case 0x02: // MPEG 2 video isvideo = 1; + forced_video = 1; //break; fall through !!! case 0x03: // MPEG 1 audio case 0x04: // MPEG 2 audio case 0x0f: // MPEG 2 AAC case 0x11: // MPEG 4 AAC - if (!isvideo) + if (!isvideo) + { + forced_audio = 1; isaudio = 1; + } case 0x06: // PES Private case 0x81: // user private + case 0xEA: // TS_PSI_ST_SMPTE_VC1 for (DescriptorConstIterator desc = (*es)->getDescriptors()->begin(); desc != (*es)->getDescriptors()->end(); ++desc) { uint8_t tag = (*desc)->getTag(); - if (!isaudio && !isvideo) + /* PES private can contain AC-3, DTS or lots of other stuff. + check descriptors to get the exakt type. */ + if (!forced_video && !forced_audio) { - /* PES private can contain AC-3, DTS or lots of other stuff. - check descriptors to get the exakt type. */ switch (tag) { case 0x1C: // TS_PSI_DT_MPEG4_Audio @@ -335,16 +340,11 @@ void eDVBScan::PMTready(int err) break; case REGISTRATION_DESCRIPTOR: /* some services don't have a separate AC3 descriptor */ { - /* libdvbsi++ doesn't yet support this descriptor type, so work around. */ - if ((*desc)->getLength() < 4) - break; - unsigned char descr[6]; - (*desc)->writeToBuffer(descr); - int format_identifier = (descr[2] << 24) | (descr[3] << 16) | (descr[4] << 8) | (descr[5]); - switch (format_identifier) + RegistrationDescriptor *d = (RegistrationDescriptor*)(*desc); + switch (d->getFormatIdentifier()) { - case 0x41432d33: // == 'AC-3' case 0x44545331 ... 0x44545333: // DTS1/DTS2/DTS3 + case 0x41432d33: // == 'AC-3' case 0x42535344: // == 'BSSD' (LPCM) isaudio = 1; break; @@ -362,12 +362,13 @@ void eDVBScan::PMTready(int err) if (tag == CA_DESCRIPTOR) is_scrambled = 1; } + default: break; } - if (isaudio) - have_audio = true; - else if (isvideo) + if (isvideo) have_video = true; + else if (isaudio) + have_audio = true; else continue; if (is_scrambled) diff --git a/lib/dvb/specs.h b/lib/dvb/specs.h index fdbaea1c..6be938cb 100644 --- a/lib/dvb/specs.h +++ b/lib/dvb/specs.h @@ -48,7 +48,7 @@ public: m_spec.pid = ServiceDescriptionSection::PID; m_spec.tid = ServiceDescriptionSection::TID; m_spec.tidext = tsid; - m_spec.timeout = 20000; // ServiceDescriptionSection::TIMEOUT; + m_spec.timeout = 60000; // ServiceDescriptionSection::TIMEOUT; m_spec.flags = eDVBTableSpec::tfAnyVersion | eDVBTableSpec::tfHaveTID | eDVBTableSpec::tfCheckCRC | eDVBTableSpec::tfHaveTIDExt | eDVBTableSpec::tfHaveTimeout; |
