Recently I've run across a couple of groups trying to replace the video of a Playstation 1 game. As we have to do the same thing with S.E. Lain, I thought I would share some insight as to how it might be done with the highest quality output.
Since there are many things that go into encoding mpeg video, that step is best left to programs that know how to juggle those options, such as ffmpeg. It also allows you to tweak those options, and use its advanced features to get the best results.
So here is how you do it, broken down into 6 ridiculously complicated steps.
- Convert your video into 4:2:0 yuv4mpeg2, but using the PSX specific rgb->yuv conversion.
- Feed the yuv4mpeg2 video into ffmpeg at an allowed fps and create a mpeg1 movie with only I-frames (-intra). This should be done at a variety of different quality levels (-qscale from 1 to n).
- Parse the I-frames out of the movie and parse their macro-blocks
- Convert the mpeg1 VLCs to PSX VLCs
- Do this for every mpeg1 quality and pick the one that fits best within the amount of space available to the frame
- Multiplex the frames and construct all the sectors
If the new video is mostly just the old video with some changes (e.g. subtitles) then quality can improved tremendously with this variation.
- Use some method to determine which macro blocks to replace (manually picking them, or performing a diff on lossless video data, or a fuzzy diff on lossy video data)
- Only replace those macro blocks with new ones of the same qscale
- If the replaced data makes the frame too big, then either replace the entire frame with an ffmpeg created frame that will fit (qscale will probably be bigger), or remove some quality in the frame to make it smaller
- Multiplex the frames and construct all the sectors
Alternatively have ffmpeg write an AVI using MJPG codec and parse the JPEG frames and convert the JPEG VLCs to PSX VLCs (I'm not sure how to get ffmpeg to produce quality variations with the MJPG codec).