parsePMT_(data, offset) {
    const StringUtils = shaka.util.StringUtils;
    const result = {
      audio: -1,
      video: -1,
      id3: -1,
      audioCodec: '',
      videoCodec: '',
    };
    const sectionLength = ((data[offset + 1] & 0x0f) << 8) | data[offset + 2];
    const tableEnd = offset + 3 + sectionLength - 4;
    // to determine where the table is, we have to figure out how
    // long the program info descriptors are
    const programInfoLength =
      ((data[offset + 10] & 0x0f) << 8) | data[offset + 11];
    // advance the offset to the first entry in the mapping table
    offset += 12 + programInfoLength;
    while (offset < tableEnd) {
      const pid = ((data[offset + 1] & 0x1f) << 8) | data[offset + 2];
      const esInfoLength = ((data[offset + 3] & 0x0f) << 8) | data[offset + 4];
      switch (data[offset]) {
        case 0x06:
          // stream_type 6 can mean a lot of different things in case of DVB.
          // We need to look at the descriptors. Right now, we're only
          // interested in a few audio and video formats,.
          if (esInfoLength > 0) {
            let parsePos = offset + 5;
            let remaining = esInfoLength;
            // Descriptor info: https://www.streamguru.de/mpeg-analyzer/supported-descriptor-list/
            while (remaining > 2) {
              const descriptorId = data[parsePos];
              const descriptorLen = data[parsePos + 1] + 2;
              switch (descriptorId) {
                // Registration descriptor
                case 0x05: {
                  const registrationData =
                      data.subarray(parsePos + 2, parsePos + descriptorLen);
                  const registration =
                      StringUtils.fromCharCode(registrationData);
                  if (result.audio == -1 && registration === 'Opus') {
                    result.audio = pid;
                    result.audioCodec = 'opus';
                  } else if (result.video == -1 && registration === 'AV01') {
                    result.video = pid;
                    result.videoCodec = 'av1';
                  }
                  break;
                }
                // DVB Descriptor for AC-3
                case 0x6a:
                  if (result.audio == -1) {
                    result.audio = pid;
                    result.audioCodec = 'ac3';
                  }
                  break;
                // DVB Descriptor for EC-3
                case 0x7a:
                  if (result.audio == -1) {
                    result.audio = pid;
                    result.audioCodec = 'ec3';
                  }
                  break;
                // DVB Descriptor for AAC
                case 0x7c:
                  if (result.audio == -1) {
                    result.audio = pid;
                    result.audioCodec = 'aac';
                  }
                  break;
                // DVB extension descriptor
                case 0x7f:
                  if (result.audioCodec == 'opus') {
                    const extensionDescriptorId = data[parsePos + 2];
                    let channelConfigCode = null;
                    // User defined (provisional Opus)
                    if (extensionDescriptorId === 0x80) {
                      channelConfigCode = data[parsePos + 3];
                    }

                    if (channelConfigCode == null) {
                      // Not Supported Opus channel count.
                      break;
                    }
                    const channelCount = (channelConfigCode & 0x0F) === 0 ?
                        2 : (channelConfigCode & 0x0F);
                    this.opusMetadata_ = {
                      channelCount,
                      channelConfigCode,
                      sampleRate: 48000,
                    };
                  }
                  break;
              }
              parsePos += descriptorLen;
              remaining -= descriptorLen;
            }
          }
          break;
        // SAMPLE-AES AAC
        case 0xcf:
          break;
        // ISO/IEC 13818-7 ADTS AAC (MPEG-2 lower bit-rate audio)
        case 0x0f:
          if (result.audio == -1) {
            result.audio = pid;
            result.audioCodec = 'aac';
          }
          break;
        // LOAS/LATM AAC
        case 0x11:
          if (result.audio == -1) {
            result.audio = pid;
            result.audioCodec = 'aac-loas';
          }
          break;
        // Packetized metadata (ID3)
        case 0x15:
          if (result.id3 == -1) {
            result.id3 = pid;
          }
          break;
        // SAMPLE-AES AVC
        case 0xdb:
          break;
        // ITU-T Rec. H.264 and ISO/IEC 14496-10 (lower bit-rate video)
        case 0x1b:
          if (result.video == -1) {
            result.video = pid;
            result.videoCodec = 'avc';
          }
          break;
        // ISO/IEC 11172-3 (MPEG-1 audio)
        // or ISO/IEC 13818-3 (MPEG-2 halved sample rate audio)
        case 0x03:
        case 0x04:
          if (result.audio == -1) {
            result.audio = pid;
            result.audioCodec = 'mp3';
          }
          break;
        // HEVC
        case 0x24:
          if (result.video == -1) {
            result.video = pid;
            result.videoCodec = 'hvc';
          }
          break;
        // AC-3
        case 0x81:
          if (result.audio == -1) {
            result.audio = pid;
            result.audioCodec = 'ac3';
          }
          break;
        // EC-3
        case 0x84:
        case 0x87:
          if (result.audio == -1) {
            result.audio = pid;
            result.audioCodec = 'ec3';
          }
          break;
        default:
          // shaka.log.warning('Unknown stream type:', data[offset]);
          break;
      }
      // move to the next table entry
      // skip past the elementary stream descriptors, if present
      offset += esInfoLength + 5;
    }
    return result;
  }
Parse PMT

@param {Uint8Array} data
@param {number} offset
@return {!shaka.util.TsParser.PMT}
@private