Know your enemy
Until Cino or Cineroma get released, the only realistic video playback solution for RISC OS is !KinoAMP. KinoAMP can only play MPEG1/2 files, using a software decoder. However it does support some hardware acceleration, either by using Geminus or Thomas Milius's free IntelDMA module. An unaccelerated Iyonix only appears to be capable of playback at 2 million pixels/sec, but by using the IntelDMA module the pixel rate can be increased to 5 million/sec. The pixel rate, in case you're wondering, is calculated using the following formula:
pixel rate = width * height * fps
This means that, for a pixel rate of 5 million/sec, you can watch a 512x384 video at 25fps. Unfortunately it isn't as simple as this, as Adrian Lees discovered some time ago. The Iyonix's onboard sound processor suffers from distortion when large amounts of data are sent through the memory bus. This means that although you can play video at 512x384, it won't sound very nice. After a fair bit of experimenting I've found that the maximum pixel rate that appears to avoid sound distortion is 3.25 million pixels/sec. This gives a resolution of 416x312 for 4:3 programmes, and 480x270 for 16:9 widescreen (Both at 25fps). Even at this pixel rate there are occasionally some audio problems, but stopping and starting the video or moving the window around the screen seems to fix it - like it's some kind of precise timing issue.
Of course pixel rate isn't the only factor that affects playback. Video and audio bitrate, as well as the media source (hard disc, RAM, network, etc.) will all have an effect. If you were to encode at 512x384x25fps, you'd find that the maximum video bitrate that can be decoded is around 1000kbps. For me this resulted in 98% of frames displayed; increasing it to 1300kbps gave 91%; and 2000kbps gave 83%. However since we aren't encoding at 512x384x25fps due to sound issues, you should be able to use bitrates higher than 1000kbps if you want. I find that 850kbps looks fine at 416x312x25fps, so to try and conserve my disc space I'm sticking to that.
Audio rate has much less of an impact, so it's more a question of how much disc space you want to use and what quality you can stand. In this article I'm using 48khz audio encoded at 128kbps. The lowest I'd recommend you go for general use is 96kbps - any lower than that and the quality will drop considerably.
Due to the low total bitrate (around 1000kbps), the filing system you're using won't make much of a difference to an Iyonix. I've successfully streamed from RAM, hard disc, and network (via NFS) without any problems.
A StrongARM RiscPC, on the other hand, will have a much tougher time. I found that 288x216x25fps, with 250kbps video and 48khz audio at 96kbps would result in around 95% of frames displayed in a 16bpp mode, with NFS as the video source. Playing from hard disc increased the value to 97% - and RAM gave 100%. Increasing the bitrate or pixelrate only lowered the performance, as did switching to a 32bpp mode. This would suggest that the maximum pixel rate is around 1.5M.
Currently, for an A9Home I'd expect the values to be somewhere inbetween the performance of an unaccelerated Iyonix (Which can display at 320x240x25fps) and that of a StrongARM. However when KinoAMP or Geminus support use of the A9's DMA controller I suspect the performance will improve, perhaps to that which I'm using on my Iyonix, as the A9 (hopefully) won't be held back by sound distortion.
If you want to experiment yourself, remember that the MPEG video width and height must be a multiple of 2 pixels, and that framerate conversion will generally produce bad results.
The source
For me, all my source videos are MPEG2 files recorded using the Digital TV card in my PC. This means that they're typically 720x576 (interlaced) at 25fps, with video bitrates of around 2500kpbs, and 48khz MP2 format audio at bitrates of 128kbps and above. Trying to play them back on an Iyonix (streaming the files over NFS) results in a measly 35% of frames being displayed, giving a 9fps slideshow. Reducing to 50% scale only makes matters worse, as it prevents IntelDMA from being used. Things may be different for Geminus users, but I doubt 100% framerate can be achieved at any reasonable resolution (If at all).
Most of the rest of this article (in particular the script at the end) will assume your source video is in the same format as mine. Changing the script to work with other formats should be relatively simple, however.
The destination
There are two output formats that my script uses. These can easily be changed in the script itself:
- MPEG1 video at 416x312x25fps, 850kbps, with 48khz MP2 audio at 128kbps
- MPEG1 video at 480x270x25fps, 850kbps, with 48khz MP2 audio at 128kbps (for 16:9 widescreen programmes. For a StrongARM, you'd want 328x184x25fps)
The tools
I'm using 4 tools running on my Windows PC to perform the conversion. However these are all cross-platform, so should be readily available on Linux or MacOS.
- ffmpeg
This is the main workhorse. Available for Windows, Linux and MacOS, ffmpeg can decode and encode a plethora of audio and video formats. Unfortunately the builtin MP2 encoder produces very poor output at low bitrates, which is why I use toolame instead. - toolame
Toolame is an MP2 encoder, in a similar vein to the 'lame' MP3 encoder. Windows versions are available on the sourceforge pages, but Linux or MacOS users may have to compile their own. Just make sure you get version 0.2k instead of 0.2l - the 0.2l output appears to be broken and won't work with Winamp or ffmpeg. - Perl
I'm using Perl to automate the conversion process. A script scans my input folder and converts the vieos, storing them in the output folder. - mpgtx
mpgtx is a small app that can report on the format of MPEG files. It's used by the Perl script to identify what output resolution to use. I think it's possible to do away with this and use ffmpeg to report the file information, but it's something I haven't tried.
The process
My Perl script uses a 6-stage process on each file it converts:
- Run mpgtx on the file, to identify the picture format (4:3 or 16:9). This dictates the output resolution (416x312 or 480x270)
- Run 'ffmpeg -i INPUTFILE -vcodec mpeg1video -r 25 -s RESOLUTION -b 850k -acodec copy temp.mpg' to encode the video. '-acodec copy' causes ffmpeg to merely copy the source audio - this is so that it can later be extracted and run through toolame.
- Run 'ffmpeg -i temp.mpg -ar 48000 temp.wav' to extract the audio from the output file to a .wav. I'm using the output file instead of the source file in an attempt to maintain A/V sync, as it's feasible that the timeline has been altered a bit by the video conversion process (dropping frames, correcting timestamps, etc.) So far it seems to have worked, but I haven't tried using the source file as the audio source, so it's possible that my fears are unfounded.
- Run 'toolame -s 48 -b 128 temp.wav temp.mp2' to encode the audio
- Run 'ffmpeg -i temp.mpg -i temp.mp2 -vcodec copy -acodec copy -map 0:0 -map 1:0 OUTPUTFILE' to replace the original audio with the new stream.
- Delete the temporary files
The script
The Perl script below will automate the above process, examining each file in the input folder and converting them to files in the output folder if a copy doesn't already exist. It also performs the audio conversion as a seperate step - this is because before getting toolame working, I merely left the audio at the source bitrate. The Perl script therefore accounts for this by checking the audio bitrate of each output file, and fixing the bitrate on any files which haven't been converted yet.
I also discovered that some files weren't accepted by mpgtx as valid input, so have manually added their names and output resolution to an array at the top of the file. These files could be failing either because the TV card or Mpg2Cut2 wrote bad headers (Mpg2Cut2 is a GOP-based editor I've been using to remove ads from programmes. GOPchop is a similar program available for Linux)
mpgconv.pl (plain text version)
The result
82GB of movies and TV programmes converted to 30GB of Iyonix friendly MPEG1 files. On my 2GHz PC, an hour of TV footage can be converted in about 15-20 minutes using the above script.
When watching videos using KinoAMP, make sure you use DiskSample as the audio decoder, to avoid A/V desyncs and crashes when seeking through files. Also, when using the IntelDMA module, don't worry about the setting of the 'Scaler' option - IntelDMA will be used no matter what you choose (providing you watch at 100% scale).
As you can see above, you've also got to watch out for video decoding errors in KinoAMP. Note the phantom finger in the frame on the left, and the blurryness of the leg. These artifacts then vanish on the following frame (an I frame, shown on the right). The constant appearance and disappearance of these errors can be annoying - but both Winamp and my Zaurus play the videos fine, so I can only assume it's a problem with KinoAMP.
Q&A
A brief Q&A with some fellow TIB staff:
Q. | Why not just watch them on the PC? Presumably you have to have it on to access the file anyway, so you could watch it in higher resolution straight away without having to wait for it to be converted. |
A. |
|
Q. | What about Google Video? |
A. | There seem to be two formats available from Google: Some quasi-propriatary Google Video format, and straight MPEG4. We can't play MPEG4 on RISC OS (for now, at least), but it can be converted to MPEG2 via ffmpeg. |
Q. | What about video conversion on RISC OS? |
A. | As evidenced by this newsgroup thread, there is a (rather old) port of ffmpeg for RISC OS. In the interests of SCIENCE I decided to have a go at using it to convert some of my videos. The first one I tried, it wasn't able to detect the input format, despite the file working fine with the latest PC version. The second one I tried was an MPEG4 from Google Video - it did detect the format, but then promptly told me it was unsupported. Then I tried another MPEG2, and this one worked - except it was encoding at a rate of about 25 frames every 10 minutes, and spitting out hundreds of errors. After an hour or so StrongED crashed, but the taskwindow kept running... until a while later when processing seemed to stop. The resulting MPEG1 file was almost entirely corrupt, only the audio track beared some resemblance to the source. There is hope, however - apparently ffmpeg is part of the GCCSDK autobuilder, so if you can put up with ludicrously slow conversion rates you should be able to grab the latest source and run it throug the autobuilder (Which will require a Unix-like environment, one which will typically come with a meaty PC, one which would be far better suited to doing video conversion than a RISC OS machine). |
Q. | What about VideoCD? |
A. | VideoCD uses a video resolution of 352x288 for PAL, and a bitrate of 1150kbps, with 224kbps MP2 audio. A quick test using a video encoded with those settings shows that (with help from IntelDMA/Geminus), an Iyonix can easily decode VideoCD quality video. All that remains is for the required software to be written to provide a frontend to the VCD filesystem structure. |
Q. | What about your Zaurus? |
A. | The 'better performance than an Iyonix' that I've initially touted only took into account the speed of an unaccelerated Iyonix. I haven't worked out the exact limits, but I do know that 384x288x25fps at 500kbps works fine, but 416x312x25fps at 850kbps is too much. 384x288x25fps is 2.8Mp/s; so for widescreen you'd want 432x240x25fps. It may be possible to increase the bitrate above 500kbps, but file size is more precious on such a small device. |