OK, so the issue turns out to be a race condition:
kill('SIGTERM',$pid);
That tells tcpdump to exit gracefully, and one of the things it does in there is write out statistics about the capture (i.e. how many packets). I noticed that if I put a print statement right after that kill, sometimes it showed up before the statistics, sometimes after. So the solution is to wait until tcpdump is done before continuing on to the next command that processes the output from tcpdump:
waitpid($pid,0);
system('tshark -r dumpcapfile ...')