00001
00002
00003
00004 #include <limits.h>
00005
00006 #include "atscdescriptors.h"
00007 #include "dvbdescriptors.h"
00008
00009 desc_list_t MPEGDescriptor::Parse(
00010 const unsigned char* data, uint len)
00011 {
00012 desc_list_t tmp;
00013 uint off = 0;
00014 while (off < len)
00015 {
00016 tmp.push_back(data+off);
00017 MPEGDescriptor desc(data+off);
00018 off += desc.DescriptorLength() + 2;
00019 }
00020 return tmp;
00021 }
00022
00023 desc_list_t MPEGDescriptor::ParseAndExclude(
00024 const unsigned char* data, uint len, int excluded_descid)
00025 {
00026 desc_list_t tmp;
00027 uint off = 0;
00028 while (off < len)
00029 {
00030 if ((data+off)[0] != excluded_descid)
00031 tmp.push_back(data+off);
00032 MPEGDescriptor desc(data+off);
00033 off += desc.DescriptorLength() + 2;
00034 }
00035 return tmp;
00036 }
00037
00038 desc_list_t MPEGDescriptor::ParseOnlyInclude(
00039 const unsigned char* data, uint len, int excluded_descid)
00040 {
00041 desc_list_t tmp;
00042 uint off = 0;
00043 while (off < len)
00044 {
00045 if ((data+off)[0] == excluded_descid)
00046 tmp.push_back(data+off);
00047 MPEGDescriptor desc(data+off);
00048 off += desc.DescriptorLength() + 2;
00049 }
00050 return tmp;
00051 }
00052
00053 const unsigned char* MPEGDescriptor::Find(const desc_list_t &parsed,
00054 uint desc_tag)
00055 {
00056 desc_list_t::const_iterator it = parsed.begin();
00057 for (; it != parsed.end(); ++it)
00058 {
00059 if ((*it)[0] == desc_tag)
00060 return *it;
00061 }
00062 return NULL;
00063 }
00064
00065 desc_list_t MPEGDescriptor::FindAll(const desc_list_t &parsed, uint desc_tag)
00066 {
00067 desc_list_t tmp;
00068 desc_list_t::const_iterator it = parsed.begin();
00069 for (; it != parsed.end(); ++it)
00070 {
00071 if ((*it)[0] == desc_tag)
00072 tmp.push_back(*it);
00073 }
00074 return tmp;
00075 }
00076
00077 static uint maxPriority(const QMap<uint,uint> &langPrefs)
00078 {
00079 uint max_pri = 0;
00080 QMap<uint,uint>::const_iterator it = langPrefs.begin();
00081 for (; it != langPrefs.end(); ++it)
00082 max_pri = max(max_pri, *it);
00083 return max_pri;
00084 }
00085
00086 const unsigned char* MPEGDescriptor::FindBestMatch(
00087 const desc_list_t &parsed, uint desc_tag, QMap<uint,uint> &langPrefs)
00088 {
00089 uint match_idx = 0;
00090 uint match_pri = UINT_MAX;
00091 int unmatched_idx = -1;
00092
00093 uint i = (desc_tag == DescriptorID::short_event) ? 0 : parsed.size();
00094 for (; i < parsed.size(); i++)
00095 {
00096 if (DescriptorID::short_event == parsed[i][0])
00097 {
00098 ShortEventDescriptor sed(parsed[i]);
00099 QMap<uint,uint>::const_iterator it =
00100 langPrefs.find(sed.CanonicalLanguageKey());
00101
00102 if ((it != langPrefs.end()) && (*it < match_pri))
00103 {
00104 match_idx = i;
00105 match_pri = *it;
00106 }
00107
00108 if (unmatched_idx < 0)
00109 unmatched_idx = i;
00110 }
00111 }
00112
00113 if (match_pri != UINT_MAX)
00114 return parsed[match_idx];
00115
00116 if ((desc_tag == DescriptorID::short_event) && (unmatched_idx >= 0))
00117 {
00118 ShortEventDescriptor sed(parsed[unmatched_idx]);
00119 langPrefs[sed.CanonicalLanguageKey()] = maxPriority(langPrefs) + 1;
00120 return parsed[unmatched_idx];
00121 }
00122
00123 return NULL;
00124 }
00125
00126 desc_list_t MPEGDescriptor::FindBestMatches(
00127 const desc_list_t &parsed, uint desc_tag, QMap<uint,uint> &langPrefs)
00128 {
00129 uint match_pri = UINT_MAX;
00130 int match_key = 0;
00131 int unmatched_idx = -1;
00132
00133 uint i = (desc_tag == DescriptorID::extended_event) ? 0 : parsed.size();
00134 for (; i < parsed.size(); i++)
00135 {
00136 if (DescriptorID::extended_event == parsed[i][0])
00137 {
00138 ExtendedEventDescriptor eed(parsed[i]);
00139 QMap<uint,uint>::const_iterator it =
00140 langPrefs.find(eed.CanonicalLanguageKey());
00141
00142 if ((it != langPrefs.end()) && (*it < match_pri))
00143 {
00144 match_key = eed.LanguageKey();
00145 match_pri = *it;
00146 }
00147
00148 if (unmatched_idx < 0)
00149 unmatched_idx = i;
00150 }
00151 }
00152
00153 if ((desc_tag == DescriptorID::extended_event) &&
00154 (match_key == 0) && (unmatched_idx >= 0))
00155 {
00156 ExtendedEventDescriptor eed(parsed[unmatched_idx]);
00157 langPrefs[eed.CanonicalLanguageKey()] = maxPriority(langPrefs) + 1;
00158 match_key = eed.LanguageKey();
00159 }
00160
00161 desc_list_t tmp;
00162 if (match_pri == UINT_MAX)
00163 return tmp;
00164
00165 for (uint i = 0; i < parsed.size(); i++)
00166 {
00167 if ((DescriptorID::extended_event == desc_tag) &&
00168 (DescriptorID::extended_event == parsed[i][0]))
00169 {
00170 ExtendedEventDescriptor eed(parsed[i]);
00171 if (eed.LanguageKey() == match_key)
00172 tmp.push_back(parsed[i]);
00173 }
00174 }
00175
00176 return tmp;
00177 }
00178
00179
00180 QString MPEGDescriptor::DescriptorTagString() const
00181 {
00182 switch (DescriptorTag())
00183 {
00184
00185 case DescriptorID::video:
00186 return QString("Video");
00187 case DescriptorID::audio:
00188 return QString("Audio");
00189 case DescriptorID::hierarchy:
00190 return QString("Hierarchy");
00191 case DescriptorID::registration:
00192 return QString("Registration");
00193 case DescriptorID::conditional_access:
00194 return QString("Conditional Access");
00195 case DescriptorID::ISO_639_language:
00196 return QString("ISO-639 Language");
00197 case DescriptorID::system_clock:
00198 return QString("System Clock");
00199 case DescriptorID::multiplex_buffer_utilization:
00200 return QString("Multiplex Buffer Utilization");
00201 case DescriptorID::copyright:
00202 return QString("Copyright");
00203 case DescriptorID::maximum_bitrate:
00204 return QString("Maximum Bitrate");
00205 case DescriptorID::private_data_indicator:
00206 return QString("Private Data Indicator");
00207 case DescriptorID::smoothing_buffer:
00208 return QString("Smoothing Buffer");
00209 case DescriptorID::STD:
00210 return QString("STD");
00211 case DescriptorID::IBP:
00212 return QString("IBP");
00213 case DescriptorID::mpeg4_video:
00214 return QString("MPEG-4 Video");
00215 case DescriptorID::mpeg4_audio:
00216 return QString("MPEG-4 Audio");
00217 case DescriptorID::IOD:
00218 return QString("IOD");
00219 case DescriptorID::SL:
00220 return QString("SL");
00221 case DescriptorID::FMC:
00222 return QString("FMC");
00223 case DescriptorID::external_es_id:
00224 return QString("External ES ID");
00225 case DescriptorID::mux_code:
00226 return QString("Multimpex Code");
00227 case DescriptorID::fmx_buffer_size:
00228 return QString("FMX buffer Size");
00229 case DescriptorID::multiplex_buffer:
00230 return QString("Multiplex Buffer");
00231 case DescriptorID::content_labeling:
00232 return QString("Content Labeling");
00233 case DescriptorID::metadata_pointer:
00234 return QString("Metadata Pointer");
00235 case DescriptorID::metadata:
00236 return QString("Metadata");
00237 case DescriptorID::metadata_std:
00238 return QString("Metadata Std");
00239 case DescriptorID::avc_video:
00240 return QString("AVC Video");
00241 case DescriptorID::ipmp:
00242 return QString("IPMP Digital Restrictions Management");
00243 case DescriptorID::avc_timing__hrd:
00244 return QString("AVC Timing & HRD");
00245
00246
00247 case DescriptorID::network_name:
00248 return QString("Network Name");
00249 case DescriptorID::service_list:
00250 return QString("Service List");
00251 case DescriptorID::dvb_stuffing:
00252 return QString("DVB Stuffing");
00253 case DescriptorID::satellite_delivery_system:
00254 return QString("Satellite Delivery System");
00255 case DescriptorID::cable_delivery_system:
00256 return QString("Cable Delivery System");
00257 case DescriptorID::VBI_data:
00258 return QString("VBI Data");
00259 case DescriptorID::VBI_teletext:
00260 return QString("VBI Teletext");
00261 case DescriptorID::bouquet_name:
00262 return QString("Bouquet Name");
00263 case DescriptorID::service:
00264 return QString("Service");
00265 case DescriptorID::country_availability:
00266 return QString("Country Availability");
00267 case DescriptorID::linkage:
00268 return QString("Linkage");
00269 case DescriptorID::NVOD_reference:
00270 return QString("NVOD Reference");
00271 case DescriptorID::dvb_time_shifted_service:
00272 return QString("DVB Time-shifted Service");
00273 case DescriptorID::short_event:
00274 return QString("Short Event");
00275 case DescriptorID::extended_event:
00276 return QString("Extended Event");
00277 case DescriptorID::time_shifted_event:
00278 return QString("Time-shifted Event");
00279 case DescriptorID::component:
00280 return QString("Component");
00281 case DescriptorID::mosaic:
00282 return QString("Mosaic");
00283 case DescriptorID::stream_identifier:
00284 return QString("Stream Identifier");
00285 case DescriptorID::CA_identifier:
00286 return QString("Conditional Access Identifier");
00287 case DescriptorID::content:
00288 return QString("Content");
00289 case DescriptorID::parental_rating:
00290 return QString("Parental Rating");
00291 case DescriptorID::teletext:
00292 return QString("Teletext");
00293 case DescriptorID::telephone:
00294 return QString("Telephone");
00295 case DescriptorID::local_time_offset:
00296 return QString("Local Time Offset");
00297 case DescriptorID::subtitling:
00298 return QString("Subtitling");
00299 case DescriptorID::terrestrial_delivery_system:
00300 return QString("Terrestrial Delivery System");
00301 case DescriptorID::multilingual_network_name:
00302 return QString("Multilingual Network Name");
00303 case DescriptorID::multilingual_bouquet_name:
00304 return QString("Multilingual Bouquet Name");
00305 case DescriptorID::multilingual_service_name:
00306 return QString("Multilingual Service Name");
00307 case DescriptorID::multilingual_component:
00308 return QString("Multilingual Component");
00309 case DescriptorID::private_data_specifier:
00310 return QString("Private Data Specifier");
00311 case DescriptorID::service_move:
00312 return QString("Service Move");
00313 case DescriptorID::short_smoothing_buffer:
00314 return QString("Short Smoothing Buffer");
00315 case DescriptorID::frequency_list:
00316 return QString("Frequency List");
00317 case DescriptorID::partial_transport_stream:
00318 return QString("Partial Transport Stream");
00319 case DescriptorID::data_broadcast:
00320 return QString("Data Broadcast");
00321 case DescriptorID::scrambling:
00322 return QString("Scrambling");
00323 case DescriptorID::data_broadcast_id:
00324 return QString("Data Broadcast Identifier");
00325 case DescriptorID::transport_stream:
00326 return QString("Transport Stream");
00327 case DescriptorID::DSNG:
00328 return QString("DSNG");
00329 case DescriptorID::PDC:
00330 return QString("PDC");
00331 case DescriptorID::AC3:
00332 return QString("AC-3");
00333 case DescriptorID::ancillary_data:
00334 return QString("Ancillary Data");
00335 case DescriptorID::cell_list:
00336 return QString("Cell List");
00337 case DescriptorID::cell_frequency_link:
00338 return QString("Cell Frequency Link");
00339 case DescriptorID::announcement_support:
00340 return QString("Announcement Support");
00341 case DescriptorID::application_signalling:
00342 return QString("Application Signalling");
00343 case DescriptorID::adaptation_field_data:
00344 return QString("Adaptation Field Data");
00345 case DescriptorID::service_identifier:
00346 return QString("Service Identifier");
00347 case DescriptorID::service_availability:
00348 return QString("Service Availability");
00349 case DescriptorID::default_authority:
00350 return QString("Default Authority");
00351 case DescriptorID::related_content:
00352 return QString("Related Content");
00353 case DescriptorID::TVA_id:
00354 return QString("TVA Id");
00355 case DescriptorID::dvb_content_identifier:
00356 return QString("DVB Content Identifier");
00357 case DescriptorID::time_slice_fec_identifier:
00358 return QString("Time Slice FEC Identifier");
00359 case DescriptorID::ECM_repetition_rate:
00360 return QString("ECM Repetition Rate");
00361
00362
00363 case DescriptorID::dvb_uk_channel_list:
00364 return QString("Possibly a DVB UK Channel List");
00365
00367 case DescriptorID::atsc_stuffing:
00368 return QString("ATSC Stuffing");
00369 case DescriptorID::audio_stream:
00370 return QString("Audio");
00371 case DescriptorID::caption_service:
00372 return QString("Caption Service");
00373 case DescriptorID::content_advisory:
00374 return QString("Content Advisory");
00375 case DescriptorID::dish_event_name:
00376 return QString("Dishnet EIT Name");
00377 case DescriptorID::dish_event_description:
00378 return QString("Dishnet EIT Description");
00379 case DescriptorID::extended_channel_name:
00380 return QString("Extended Channel Name");
00381 case DescriptorID::service_location:
00382 return QString("Service Location");
00383 case DescriptorID::atsc_time_shifted_service:
00384 return QString("ATSC Time-shifted Service");
00385 case DescriptorID::component_name:
00386 return QString("Component Name");
00387 case DescriptorID::DCC_departing_request:
00388 return QString("DCC Departing Request");
00389 case DescriptorID::DCC_arriving_request:
00390 return QString("DCC Arriving Request");
00391 case DescriptorID::DRM_control:
00392 return QString("Consumer Restrictions Control");
00393 case DescriptorID::atsc_content_identifier:
00394 return QString("Content Identifier");
00395
00396 default:
00397 return QString("Unknown(%1)").arg(DescriptorTag());
00398 }
00399 }
00400
00401 QString MPEGDescriptor::toString() const
00402 {
00403 QString str;
00404
00405 if (DescriptorID::registration == DescriptorTag())
00406 str = RegistrationDescriptor(_data).toString();
00407 else if (DescriptorID::ISO_639_language == DescriptorTag())
00408 str = ISO639LanguageDescriptor(_data).toString();
00409 else if (DescriptorID::avc_video == DescriptorTag())
00410 str = AVCVideoDescriptor(_data).toString();
00411 else if (DescriptorID::audio_stream == DescriptorTag())
00412 str = AudioStreamDescriptor(_data).toString();
00413 else if (DescriptorID::caption_service == DescriptorTag())
00414 str = CaptionServiceDescriptor(_data).toString();
00415 else if (DescriptorID::extended_channel_name == DescriptorTag())
00416 str = ExtendedChannelNameDescriptor(_data).toString();
00417 else if (DescriptorID::component_name == DescriptorTag())
00418 str = ComponentNameDescriptor(_data).toString();
00419 else if (DescriptorID::conditional_access == DescriptorTag())
00420 str = ConditionalAccessDescriptor(_data).toString();
00421 else if (DescriptorID::network_name == DescriptorTag())
00422 str = NetworkNameDescriptor(_data).toString();
00423 else if (DescriptorID::linkage == DescriptorTag())
00424 str = LinkageDescriptor(_data).toString();
00425 else if (DescriptorID::adaptation_field_data == DescriptorTag())
00426 str = AdaptationFieldDataDescriptor(_data).toString();
00427 else if (DescriptorID::ancillary_data == DescriptorTag())
00428 str = AncillaryDataDescriptor(_data).toString();
00429 else if (DescriptorID::cable_delivery_system == DescriptorTag())
00430 str = CableDeliverySystemDescriptor(_data).toString();
00431 else if (DescriptorID::satellite_delivery_system == DescriptorTag())
00432 str = SatelliteDeliverySystemDescriptor(_data).toString();
00433 else if (DescriptorID::terrestrial_delivery_system == DescriptorTag())
00434 str = TerrestrialDeliverySystemDescriptor(_data).toString();
00435 else if (DescriptorID::frequency_list == DescriptorTag())
00436 str = FrequencyListDescriptor(_data).toString();
00437 else if (DescriptorID::service == DescriptorTag())
00438 str = ServiceDescriptor(_data).toString();
00439 else
00440 {
00441 str.append(QString("%1 Descriptor (0x%2)")
00442 .arg(DescriptorTagString())
00443 .arg(int(DescriptorTag()), 0, 16));
00444 str.append(QString(" length(%1)").arg(int(DescriptorLength())));
00445
00446
00447 }
00448 return str;
00449 }
00450
00451 QString RegistrationDescriptor::toString() const
00452 {
00453 QString fmt = FormatIdentifierString();
00454 QString msg = QString("Registration Descriptor: '%1' ").arg(fmt);
00455 QString msg2 = "Unknown";
00456 if (fmt == "CUEI")
00457 msg2 = "SCTE 35 2003, Cable Digital Program Insertion Cueing Message";
00458 else if (fmt == "AC-3")
00459 msg2 = "ATSC audio stream A/52";
00460 else if (fmt == "GA94")
00461 msg2 = "ATSC program ID A/53";
00462 else
00463 msg2 = "Unknown, see http://www.smpte-ra.org/mpegreg.html";
00464 return msg + msg2;
00465 }
00466
00467 QString ConditionalAccessDescriptor::toString() const
00468 {
00469 return QString("Conditional Access: sid(0x%1) pid(0x%2) data_size(%3)")
00470 .arg(SystemID(),0,16).arg(PID(),0,16).arg(DataSize());
00471 }
00472
00473 QString ISO639LanguageDescriptor::toString() const
00474 {
00475 return QString("ISO-639 Language: code(%1) canonical(%2) eng(%3)")
00476 .arg(LanguageString()).arg(CanonicalLanguageString())
00477 .arg(iso639_key_toName(CanonicalLanguageKey()));
00478 }
00479
00480 QString AVCVideoDescriptor::toString() const
00481 {
00482 return QString("AVC Video: IDC prof(%1) IDC level(%2) sets(%3%4%5) "
00483 "compat(%6) still(%7) 24hr(%8)")
00484 .arg(ProfileIDC()).arg(LevelIDC())
00485 .arg(ConstaintSet0()).arg(ConstaintSet1()).arg(ConstaintSet2())
00486 .arg(AVCCompatible()).arg(AVCStill()).arg(AVC24HourPicture());
00487 }