NAT does tuple mapping - src/dst addr/port and protocol. That is - two TCP mappings can use the same local external port even if they go to the same remote address, for as long as they connect to a different remote port.
This is true, but consider that while there are 16 bits of ports on both source and destination, in reality, nearly all traffic flows to a very short list of ports. Most connections, and connections are what matters here, not total traffic, are going to have a port 80 or 443 on one side of the connection or the other. So while I think 12 bits is too low, in practical use, you aren't getting the 32 bits you think you are getting. Considering source port restrictions, I think saying single-level nat extends IPv4 with another 16 bits is not too far off. Of course, that is still a lot of IPs.
Of course, nat has a bunch of other pain in the ass problems, especially in that if I want to be able to track abuse, I've got to log every new connection (flow, whatever) that you make. When I get a complaint, I've got to match that up to my logs, which can be goddamn difficult if the complainer's clock isn't just right.
With static IPs it's way easier to track abuse, and I don't have to actively log what you are doing, just who has what IP when, and because IPs stick around a lot longer than connections, I'm way less vulnerable to clock drift.
Shortly after submitting my reply I had a similar thought but after some googling I cannot find any source that this kind of "port sharing" NAT is actually used. Looking at RFC 3022 "Traditional IP Network Address Translator" it looks like usually unique port numbers are allocated per connection. Maybe there are protocol subtitles or security implications that keep implementors from going with "port sharing" NAT?
My argument still stands in case all peers behind a common NAT router try to access the same IPv4 server (which may just happen with centralized services like youtube/facebook/google). It also stands in case UDP based services are used (stuff depending on a Cone NAT and using STUN like VoIP or online gaming).
NAT does tuple mapping - src/dst addr/port and protocol. That is - two TCP mappings can use the same local external port even if they go to the same remote address, for as long as they connect to a different remote port.