If you're getting worse quality, it's probably because you're using the -b flag incorrectly. It used to refer to just video bitrate, but with the recent ffmpeg/avconv syntax overhaul, it now refers to overall bitrate. So the first pass is telling avconv that it has 800kbit/s to play with for the video, but the second pass is telling it that it has (800-128)=672kbit/s to work with.
What the first pass does is create a sort of roadmap for the second pass to take advantage of - this place is an action scene, it needs a higher bitrate; this is a slow conversation, it needs less - that sort of thing. Because it's working with incorrect information, the roadmap is incorrect.
Use -b:v instead (and -b:a instead of -ab), like so:
avconv -y -i video.mpg -s 640x360 -pass 1 -threads auto -c:v libxvid -b:v 672k -r 24 -f avi -an /dev/null
avconv -i video.mpg -s 640x360 -pass 2 -threads auto -c:v libxvid -b:v 672k -r 24 -g 300 -bf 2 -c:a libmp3lame -ac 2 -b:a 128k -ar 48000 video.avi
Also, a lot of those options are possibly unnecessary, as avconv will use the same options the input has. Unless you're resizing the video, omit the
-s 640x360 bit. Likewise, unless you need to change the framerate, omit the
-r 24, and unless you really need to change the sampling rate, omit the
-ar 48000. Obviously, if you know that you need them, leave them in.