00001
00002
00003
00004 #include <limits.h>
00005
00006 #include "sctedescriptors.h"
00007 #include "atscdescriptors.h"
00008 #include "dvbdescriptors.h"
00009 #include "mythmiscutil.h"
00010
00011 QMutex RegistrationDescriptor::description_map_lock;
00012 bool RegistrationDescriptor::description_map_initialized = false;
00013 QMap<QString,QString> RegistrationDescriptor::description_map;
00014
00015 desc_list_t MPEGDescriptor::Parse(
00016 const unsigned char *data, uint len)
00017 {
00018 desc_list_t tmp;
00019 uint off = 0;
00020 while (off < len)
00021 {
00022 tmp.push_back(data+off);
00023 MPEGDescriptor desc(data+off, len-off);
00024 if (!desc.IsValid())
00025 {
00026 tmp.pop_back();
00027 break;
00028 }
00029 off += desc.size();
00030 }
00031 return tmp;
00032 }
00033
00034 desc_list_t MPEGDescriptor::ParseAndExclude(
00035 const unsigned char *data, uint len, int excluded_descid)
00036 {
00037 desc_list_t tmp;
00038 uint off = 0;
00039 while (off < len)
00040 {
00041 if ((data+off)[0] != excluded_descid)
00042 tmp.push_back(data+off);
00043 MPEGDescriptor desc(data+off, len-off);
00044 if (!desc.IsValid())
00045 {
00046 if ((data+off)[0] != excluded_descid)
00047 tmp.pop_back();
00048 break;
00049 }
00050 off += desc.size();
00051 }
00052 return tmp;
00053 }
00054
00055 #include "mythlogging.h"
00056
00057 desc_list_t MPEGDescriptor::ParseOnlyInclude(
00058 const unsigned char *data, uint len, int excluded_descid)
00059 {
00060 desc_list_t tmp;
00061 uint off = 0;
00062 while (off < len)
00063 {
00064 if ((data+off)[0] == excluded_descid)
00065 tmp.push_back(data+off);
00066 MPEGDescriptor desc(data+off, len-off);
00067 if (!desc.IsValid())
00068 {
00069 if ((data+off)[0] == excluded_descid)
00070 tmp.pop_back();
00071 break;
00072 }
00073 off += desc.size();
00074 }
00075 return tmp;
00076 }
00077
00078 const unsigned char *MPEGDescriptor::Find(const desc_list_t &parsed,
00079 uint desc_tag)
00080 {
00081 desc_list_t::const_iterator it = parsed.begin();
00082 for (; it != parsed.end(); ++it)
00083 {
00084 if ((*it)[0] == desc_tag)
00085 return *it;
00086 }
00087 return NULL;
00088 }
00089
00090 desc_list_t MPEGDescriptor::FindAll(const desc_list_t &parsed, uint desc_tag)
00091 {
00092 desc_list_t tmp;
00093 desc_list_t::const_iterator it = parsed.begin();
00094 for (; it != parsed.end(); ++it)
00095 {
00096 if ((*it)[0] == desc_tag)
00097 tmp.push_back(*it);
00098 }
00099 return tmp;
00100 }
00101
00102 static uint maxPriority(const QMap<uint,uint> &langPrefs)
00103 {
00104 uint max_pri = 0;
00105 QMap<uint,uint>::const_iterator it = langPrefs.begin();
00106 for (; it != langPrefs.end(); ++it)
00107 max_pri = max(max_pri, *it);
00108 return max_pri;
00109 }
00110
00111 const unsigned char *MPEGDescriptor::FindBestMatch(
00112 const desc_list_t &parsed, uint desc_tag, QMap<uint,uint> &langPrefs)
00113 {
00114 uint match_idx = 0;
00115 uint match_pri = UINT_MAX;
00116 int unmatched_idx = -1;
00117
00118 uint i = (desc_tag == DescriptorID::short_event) ? 0 : parsed.size();
00119 for (; i < parsed.size(); i++)
00120 {
00121 if (DescriptorID::short_event == parsed[i][0])
00122 {
00123 ShortEventDescriptor sed(parsed[i]);
00124 QMap<uint,uint>::const_iterator it =
00125 langPrefs.find(sed.CanonicalLanguageKey());
00126
00127 if ((it != langPrefs.end()) && (*it < match_pri))
00128 {
00129 match_idx = i;
00130 match_pri = *it;
00131 }
00132
00133 if (unmatched_idx < 0)
00134 unmatched_idx = i;
00135 }
00136 }
00137
00138 if (match_pri != UINT_MAX)
00139 return parsed[match_idx];
00140
00141 if ((desc_tag == DescriptorID::short_event) && (unmatched_idx >= 0))
00142 {
00143 ShortEventDescriptor sed(parsed[unmatched_idx]);
00144 langPrefs[sed.CanonicalLanguageKey()] = maxPriority(langPrefs) + 1;
00145 return parsed[unmatched_idx];
00146 }
00147
00148 return NULL;
00149 }
00150
00151 desc_list_t MPEGDescriptor::FindBestMatches(
00152 const desc_list_t &parsed, uint desc_tag, QMap<uint,uint> &langPrefs)
00153 {
00154 uint match_pri = UINT_MAX;
00155 int match_key = 0;
00156 int unmatched_idx = -1;
00157
00158 uint i = (desc_tag == DescriptorID::extended_event) ? 0 : parsed.size();
00159 for (; i < parsed.size(); i++)
00160 {
00161 if (DescriptorID::extended_event == parsed[i][0])
00162 {
00163 ExtendedEventDescriptor eed(parsed[i]);
00164 QMap<uint,uint>::const_iterator it =
00165 langPrefs.find(eed.CanonicalLanguageKey());
00166
00167 if ((it != langPrefs.end()) && (*it < match_pri))
00168 {
00169 match_key = eed.LanguageKey();
00170 match_pri = *it;
00171 }
00172
00173 if (unmatched_idx < 0)
00174 unmatched_idx = i;
00175 }
00176 }
00177
00178 if ((desc_tag == DescriptorID::extended_event) &&
00179 (match_key == 0) && (unmatched_idx >= 0))
00180 {
00181 ExtendedEventDescriptor eed(parsed[unmatched_idx]);
00182 langPrefs[eed.CanonicalLanguageKey()] = maxPriority(langPrefs) + 1;
00183 match_key = eed.LanguageKey();
00184 }
00185
00186 desc_list_t tmp;
00187 if (match_pri == UINT_MAX)
00188 return tmp;
00189
00190 for (uint i = 0; i < parsed.size(); i++)
00191 {
00192 if ((DescriptorID::extended_event == desc_tag) &&
00193 (DescriptorID::extended_event == parsed[i][0]))
00194 {
00195 ExtendedEventDescriptor eed(parsed[i]);
00196 if (eed.LanguageKey() == match_key)
00197 tmp.push_back(parsed[i]);
00198 }
00199 }
00200
00201 return tmp;
00202 }
00203
00204 #define EMPTY_STR_16 "","","","", "","","","", "","","","", "","","","",
00205
00206 const char *descriptor_tag_strings[256] =
00207 {
00208 "", "",
00209 "Video", "Audio",
00210 "Hierarchy", "Registration",
00211 "Data Stream Alignment", "Target Background Grid",
00212 "Video Window", "Conditional Access",
00213 "ISO-639 Language", "System Clock",
00214 "Multiplex Buffer Utilization", "Copyright",
00215 "Maximum Bitrate", "Private Data Indicator",
00216
00217 "Smooting Buffer", "STD",
00218 "IBP", "DSM-CC Carousel Identifier",
00219 "DSM-CC Association Tag",
00220 "DSM-CC Deferred Association Tag",
00221 "Reserved(0x16)", "DSM-CC NPT Reference",
00222 "DSM-CC NPT Endpoint", "DSM-CC Stream Mode",
00223 "DSM-CC Stream Event", "MPEG-4 Video",
00224 "MPEG-4 Audio", "IOD",
00225 "SL", "FMC",
00226
00227 "External ES ID", "Multimpex Code",
00228 "FMX buffer Size", "Multiplex Buffer",
00229 "Content Labeling", "Metadata Pointer",
00230 "Metadata", "Metadata Std",
00231 "AVC Video", "IPMP DRM",
00232 "AVC Timing & HRD", "AAC Audio",
00233 "Flex Mux Timing", "",
00234 "", "",
00235
00236 EMPTY_STR_16
00237
00238 "Network Name", "Service List",
00239 "DVB Stuffing", "Satellite Delivery System",
00240 "Cable Delivery System", "VBI Data",
00241 "VBI Teletext", "Bouquet Name",
00242 "Service", "Country Availability",
00243 "Linkage", "NVOD Reference",
00244 "DVB Time-shifted Service", "Short Event",
00245 "Extended Event", "Time-shifted Event",
00246
00247 "Component", "Mosaic",
00248 "Stream Identifier",
00249 "Conditional Access Identifier",
00250 "Content", "Parental Rating",
00251 "Teletext", "Telephone",
00252 "Local Time Offset", "Subtitling",
00253 "Terrestrial Delivery System",
00254 "Multilingual Network Name",
00255 "Multilingual Bouquet Name",
00256 "Multilingual Service Name",
00257 "Multilingual Component",
00258 "Private Data Specifier",
00259
00260 "Service Move", "Short Smoothing Buffer",
00261 "Frequency List", "Partial Transport Stream",
00262 "Data Broadcast", "Scrambling",
00263 "Data Broadcast ID", "Transport Stream",
00264 "DSNG", "PDC",
00265 "AC-3", "Ancillary Data",
00266 "Cell List", "Cell Frequency Link",
00267 "Announcement Support", "Application Signalling",
00268
00269 "Adaptation Field Data", "Service Identifier",
00270 "Service Availability", "Default Authority",
00271 "Related Content", "TVA ID",
00272 "DVB Content Identifier", "Time Slice FEC Identifier",
00273 "ECM Repetition Rate", "DVB-S2 Delivery Identifier",
00274 "E-AC-3", "DTS",
00275 "AAC", "",
00276 "", "",
00277
00278 "ATSC Stuffing", "AC-3 Audio",
00279 "SCTE Frame Rate", "SCTE Extended Video",
00280 "SCTE Component Name", "ATSC Program Identifier",
00281 "Caption Service", "Content Advisory",
00282 "ATSC CA Descriptor", "ATSC Descriptor Tag",
00283 "SCTE CUE Identifier", "",
00284 "TimeStamp", "",
00285 "", "",
00286
00287 "SCTE Frequency Spec", "SCTE Modulation Params",
00288 "SCTE TSID", "SCTE Revision Detection",
00289 "SCTE Two part channel", "SCTE Channel Properties",
00290 "SCTE Daylight Savings", "SCTE AFD",
00291 "", "",
00292 "", "",
00293 "", "",
00294 "", "",
00295
00296 "Extended Channel Name", "Service Location",
00297 "ATSC Time-shifted Service","Component Name",
00298 "ATSC Data Service", "ATSC PID Count",
00299 "ATSC Download",
00300 "ATSC Multiprotocol Encapsulation",
00301 "DCC Departing Request", "DCC Arriving Request",
00302 "ATSC Restrictions Control","ATSC Genre",
00303 "SCTE MAC Address List", "ATSC Private Information",
00304 "ATSC Compatibility Wrap","ATSC Broadcaster Policy",
00305
00306 "", "",
00307 "", "",
00308 "", "",
00309 "ATSC Content ID", "",
00310 "", "",
00311 "", "",
00312 "", "",
00313 "", "",
00314
00315 EMPTY_STR_16
00316 EMPTY_STR_16
00317 EMPTY_STR_16
00318 EMPTY_STR_16
00319 };
00320
00321 static void comma_list_append(QString &str, QString extra)
00322 {
00323 if (str.isEmpty())
00324 str = extra;
00325 else
00326 str = str + ", " + extra;
00327 }
00328
00329 QString MPEGDescriptor::DescriptorTagString(void) const
00330 {
00331 QString str = descriptor_tag_strings[DescriptorTag()];
00332
00333 switch (DescriptorTag())
00334 {
00335 case PrivateDescriptorID::dvb_uk_channel_list:
00336 comma_list_append(str, "Possibly DVB UK Channel List");
00337 break;
00338 case PrivateDescriptorID::dish_event_rights:
00339 comma_list_append(str, "Possibly Dishnet Rights");
00340 break;
00341 case PrivateDescriptorID::dish_event_mpaa:
00342 comma_list_append(str, "Possibly Dishnet MPAA");
00343 break;
00344 case PrivateDescriptorID::dish_event_name:
00345 comma_list_append(str, "Possibly Dishnet EIT Name");
00346 break;
00347 case PrivateDescriptorID::dish_event_description:
00348 comma_list_append(str, "Possibly Dishnet EIT Description");
00349 break;
00350 case PrivateDescriptorID::dish_event_properties:
00351 comma_list_append(str, "Possibly Dishnet Properties");
00352 break;
00353 case PrivateDescriptorID::dish_event_vchip:
00354 comma_list_append(str, "Possibly Dishnet V-Chip");
00355 break;
00356 case PrivateDescriptorID::dish_event_tags:
00357 comma_list_append(str, "Possibly Dishnet Tag");
00358 break;
00359 case PrivateDescriptorID::premiere_content_order:
00360 comma_list_append(str, "Possibly Premiere DE Content Order");
00361 break;
00362 case PrivateDescriptorID::premiere_parental_information:
00363 comma_list_append(str, "Possibly Premiere DE Parental Information");
00364 break;
00365 case PrivateDescriptorID::premiere_content_transmission:
00366 comma_list_append(str, "Possibly Premiere DE Content Transmission");
00367 break;
00368 }
00369
00370 if (str.isEmpty())
00371 str = QString("Unknown(%1)").arg(DescriptorTag());
00372
00373 return str;
00374 }
00375
00376 #define SET_STRING(DESC_NAME) do { \
00377 if (IsValid()) { DESC_NAME d(_data, DescriptorLength()+2); \
00378 if (d.IsValid()) str = d.toString(); } } while (0)
00379
00380 QString MPEGDescriptor::toString() const
00381 {
00382 QString str;
00383
00384 if (DescriptorID::registration == DescriptorTag())
00385 SET_STRING(RegistrationDescriptor);
00386 else if (DescriptorID::iso_639_language == DescriptorTag())
00387 SET_STRING(ISO639LanguageDescriptor);
00388 else if (DescriptorID::avc_video == DescriptorTag())
00389 SET_STRING(AVCVideoDescriptor);
00390 else if (DescriptorID::ac3_audio_stream == DescriptorTag())
00391 SET_STRING(AudioStreamDescriptor);
00392 else if (DescriptorID::caption_service == DescriptorTag())
00393 SET_STRING(CaptionServiceDescriptor);
00394 else if (DescriptorID::extended_channel_name == DescriptorTag())
00395 SET_STRING(ExtendedChannelNameDescriptor);
00396 else if (DescriptorID::component_name == DescriptorTag())
00397 SET_STRING(ComponentNameDescriptor);
00398 else if (DescriptorID::conditional_access == DescriptorTag())
00399 SET_STRING(ConditionalAccessDescriptor);
00400 else if (DescriptorID::network_name == DescriptorTag())
00401 SET_STRING(NetworkNameDescriptor);
00402
00403
00404 else if (DescriptorID::adaptation_field_data == DescriptorTag())
00405 SET_STRING(AdaptationFieldDataDescriptor);
00406
00407
00408 else if (DescriptorID::cable_delivery_system == DescriptorTag())
00409 SET_STRING(CableDeliverySystemDescriptor);
00410 else if (DescriptorID::satellite_delivery_system == DescriptorTag())
00411 SET_STRING(SatelliteDeliverySystemDescriptor);
00412 else if (DescriptorID::terrestrial_delivery_system == DescriptorTag())
00413 SET_STRING(TerrestrialDeliverySystemDescriptor);
00414 else if (DescriptorID::frequency_list == DescriptorTag())
00415 SET_STRING(FrequencyListDescriptor);
00416 else if (DescriptorID::service == DescriptorTag())
00417 SET_STRING(ServiceDescriptor);
00418 else if (DescriptorID::stream_identifier == DescriptorTag())
00419 SET_STRING(StreamIdentifierDescriptor);
00420 else if (DescriptorID::default_authority == DescriptorTag())
00421 SET_STRING(DefaultAuthorityDescriptor);
00422 else if (DescriptorID::bouquet_name == DescriptorTag())
00423 SET_STRING(BouquetNameDescriptor);
00424 else if (DescriptorID::country_availability == DescriptorTag())
00425 SET_STRING(CountryAvailabilityDescriptor);
00426 else if (DescriptorID::service_list == DescriptorTag())
00427 SET_STRING(ServiceListDescriptor);
00428 else if (DescriptorID::scte_cue_identifier == DescriptorTag())
00429 SET_STRING(CueIdentifierDescriptor);
00430 else if (DescriptorID::scte_revision_detection == DescriptorTag())
00431 SET_STRING(RevisionDetectionDescriptor);
00433 else if (PrivateDescriptorID::dvb_uk_channel_list == DescriptorTag())
00434 SET_STRING(UKChannelListDescriptor);
00436 else if (IsValid())
00437 {
00438 str = QString("%1 Descriptor (0x%2) length(%3)")
00439 .arg(DescriptorTagString())
00440 .arg(DescriptorTag(),2,16,QChar('0'))
00441 .arg(DescriptorLength());
00442
00443
00444 }
00445 else
00446 {
00447 str = "Invalid Descriptor";
00448 }
00449 return str;
00450 }
00451
00454 QString MPEGDescriptor::toStringXML(uint level) const
00455 {
00456 QString indent_0 = xml_indent(level);
00457 QString indent_1 = xml_indent(level+1);
00458 QString str;
00459
00460 str += indent_0 + "<Descriptor>\n";
00461 str += indent_1 + QString("<Tag>0x%1</Tag>\n")
00462 .arg(DescriptorTag(),2,16,QChar('0'));
00463 str += indent_1 + QString("<Description>%1</Description>\n")
00464 .arg(DescriptorTagString(),0,16);
00465
00466 str += indent_1 + "<Data>";
00467 for (uint i = 0; i < DescriptorLength(); i++)
00468 {
00469 if (((i%8) == 0) && i)
00470 str += "\n" + indent_1 + " ";
00471 str += QString("0x%1 ").arg(_data[i+2],2,16,QChar('0'));
00472 }
00473
00474 str += "\n" + indent_1 + "</Data>\n";
00475
00476 str += indent_1 + "<Decoded>" + toString() + "</Decoded>\n";
00477
00478 str += indent_0 + "</Descriptor>";
00479
00480 return str;
00481 }
00482
00483 void RegistrationDescriptor::InitializeDescriptionMap(void)
00484 {
00485 QMutexLocker locker(&description_map_lock);
00486 if (description_map_initialized)
00487 return;
00488
00489 description_map["AC-3"] = "ATSC audio stream A/52";
00490 description_map["AVSV"] = "China A/V Working Group";
00491 description_map["BDC0"] = "Broadcast Data Corporation Software Data Service";
00492 description_map["BSSD"] = "SMPTE 302M-1998 Audio data as specified in (AES3)";
00493 description_map["CAPO"] = "SMPTE 315M-1999 Camera Positioning Information";
00494 description_map["CUEI"] = "SCTE 35 2003, Cable Digital Program Insertion Cueing Message";
00495 description_map["DDED"] = "LGEUS Digital Delivery with encryption and decryption";
00496 description_map["DISH"] = "EchoStar MPEG streams";
00497 description_map["DRA1"] = "Chinese EIS SJ/T11368-2006 DRA digital audio";
00498 description_map["DTS1"] = "DTS Frame size of 512 bytes";
00499 description_map["DTS2"] = "DTS Frame size of 1024 bytes";
00500 description_map["DTS3"] = "DTS Frame size of 2048";
00501 description_map["DVDF"] = "DVD compatible MPEG2-TS";
00502 description_map["ETV1"] = "CableLabs ETV info is present";
00503 description_map["GA94"] = "ATSC program ID A/53";
00504 description_map["GWKS"] = "GuideWorks EPG info";
00505 description_map["HDMV"] = "Blu-Ray A/V for read-only media (H.264 TS)";
00506 description_map["HDMX"] = "Matsushita-TS";
00507 description_map["KLVA"] = "SMPTE RP 217-2001 MXF KLV packets present";
00508 description_map["LU-A"] = "SMPTE RDD-11 HDSDI HD serial/video data";
00509 description_map["MTRM"] = "D-VHS compatible MPEG2-TS";
00510 description_map["NMR1"] = "Nielsen content identifier";
00511 description_map["PAUX"] = "Philips ES containing low-speed data";
00512 description_map["PMSF"] = "MPEG-TS stream modified by STB";
00513 description_map["PRMC"] = "Philips ES containing remote control data";
00514 description_map["SCTE"] = "SCTE 54 2003 Digital Video Service Multiplex and TS for Cable";
00515 description_map["SEN1"] = "ATSC Private Information identifies source of stream";
00516 description_map["SESF"] = "Blu-Ray A/V for ReWritable media (H.264 TS)";
00517 description_map["SPLC"] = "SMPTE Proposed 312M Splice Point compatible TS";
00518 description_map["SVMD"] = "SMPTE Proposed Video Metatdata Dictionary for MPEG2-TS";
00519 description_map["SZMI"] = "ATSC Private Info from Building B";
00520 description_map["TRIV"] = "ATSC Private Info from Triveni Digital";
00521 description_map["TSBV"] = "Toshiba self-encoded H.264 TS";
00522 description_map["TSHV"] = "Sony self-encoded MPEG-TS and private data";
00523 description_map["TSMV"] = "Sony self-encoded MPEG-TS and private data";
00524 description_map["TVG1"] = "TV Guide EPG Data";
00525 description_map["TVG2"] = "TV Guide EPG Data";
00526 description_map["TVG3"] = "TV Guide EPG Data";
00527 description_map["ULE1"] = "IETF RFC4326 compatible MPEG2-TS";
00528 description_map["VC-1"] = "SMPTE Draft RP 227 VC-1 Bitstream Transport Encodings";
00529
00530 for (uint i = 0; i <= 99; i++)
00531 {
00532 description_map[QString("US%1").arg(i, 2, QLatin1Char('0'))] =
00533 "NIMA, Unspecified military application";
00534 }
00535
00536 description_map_initialized = true;
00537 }
00538
00539 QString RegistrationDescriptor::GetDescription(const QString &fmt)
00540 {
00541 InitializeDescriptionMap();
00542
00543 QString ret = QString::null;
00544 {
00545 QMutexLocker locker(&description_map_lock);
00546 QMap<QString,QString>::const_iterator it = description_map.find(fmt);
00547 if (it != description_map.end())
00548 ret = *it;
00549 }
00550
00551 if (!ret.isNull())
00552 ret.detach();
00553
00554 return ret;
00555 }
00556
00557 QString RegistrationDescriptor::toString() const
00558 {
00559 QString fmt = FormatIdentifierString();
00560 QString msg = QString("Registration Descriptor: '%1' ").arg(fmt);
00561
00562 QString msg2 = GetDescription(fmt);
00563 if (msg2.isEmpty())
00564 msg2 = "Unknown, see http://www.smpte-ra.org/mpegreg/mpegreg.html";
00565
00566 return msg + msg2;
00567 }
00568
00569 QString ConditionalAccessDescriptor::toString() const
00570 {
00571 return QString("Conditional Access: sid(0x%1) pid(0x%2) data_size(%3)")
00572 .arg(SystemID(),0,16).arg(PID(),0,16).arg(DataSize());
00573 }
00574
00575 QString ISO639LanguageDescriptor::toString() const
00576 {
00577 return QString("ISO-639 Language: code(%1) canonical(%2) eng(%3)")
00578 .arg(LanguageString()).arg(CanonicalLanguageString())
00579 .arg(iso639_key_toName(CanonicalLanguageKey()));
00580 }
00581
00582 QString AVCVideoDescriptor::toString() const
00583 {
00584 return QString("AVC Video: IDC prof(%1) IDC level(%2) sets(%3%4%5) "
00585 "compat(%6) still(%7) 24hr(%8) FramePacking(%9)")
00586 .arg(ProfileIDC()).arg(LevelIDC())
00587 .arg(ConstaintSet0()).arg(ConstaintSet1()).arg(ConstaintSet2())
00588 .arg(AVCCompatible()).arg(AVCStill()).arg(AVC24HourPicture())
00589 .arg(FramePackingSEINotPresentFlag());
00590 }