Sounds to me like a gateway issue. In a nutshell:
Since the IP phones use the BCM for call signalling, they have no problem setting up a call to each other because the BCM knows how to find each of the sets. Once the signalling is complete, the IP sets talk point to point. Problem is, if the Dlink routers don't know how to find each other's internal subnets, the point to point audio stream is getting lost.
The fix:
You need to enable tunnel to tunnel traffic on your head office router so that traffic from one branch can find the other branch. You also should put a route into each branch gateway that points to the head office router's IP for each branch subnet.
I think that should do it....somebody please wake me up if I've missed something.