How to play video recorded from high-bitrate 4:2:2 sources on low-power systems

In a previous post, I told you about Fixing the audio on recorded programs from a certain network (which shall remain nameless). The technique for doing that involved the use of the ffmpeg software, and I suggest you read that article because it gives some information near the end of the article on how to obtain a correct version of ffmpeg. The technique I am about to discuss also uses ffmpeg.

If you are running a PVR/backend system such as TVHeadEnd, you may have tried recording programs from certain high-bitrate 4:2:2 feeds, and then found that they simply would not play back on your home theater PC device, particularly if you are using something low-powered like a single-board computer. You might get sound only, with a black picture (and maybe a few flashes of green or some other color), or the video just might play really slowly for a few seconds and then start breaking up. The solution to this is to use ffmpeg to convert the recorded program after you have finished recording it. This means you can’t watch the program live, but you can view it later.

When I first ran across this problem, I found a nice GUI-based program that could do the conversion, but it also took a ridiculous amount of time (about 8 hours to convert an hour of video). But also, it not only converted the video, but also the audio, which destroyed any hope of hearing surround sound. I then figured out that it was actually using ffmpeng to do that conversion, and that by running ffmpeg with only the necessary options I could cut the processing time down to around one-quarter of the time taken by the GUI-based program (or around twice the original running time of the program), plus I could set it to pass the audio and any subtitle streams unchanged. The line I used looks like this:

ffmpeg -loglevel quiet -y -i “original_recording.ts” -c copy -c:v libx264 -b:v 16711680 -pix_fmt yuv420p “converted_program.ts”

(The above is a single line, even if it does not display as such here.)

The -b:v 16711680 option sets the bitrate for the conversion and is the same as the one used by the GUI-based program. In my case it seems to produce a file that’s somewhere around half the size of the original. The video quality is still excellent. By the way, the -y option tells it to overwrite any existing file with the name you specify for the converted program file; if you want it to prompt you when there’s a file name conflict then leave that option out. The above line assumes you are converting a transport stream (.ts) file, if not, then change the extensions accordingly.

If the resulting file is still a little too “fat” for your equipment, then you can try reducing the -b:v value, with a corresponding loss of quality. The GUI-based program could use -b:v 7325135 and still considered that “high” quality, while -b:v 4229320 was considered somewhere between “high” and “standard” quality. Of course, you could go even lower, particularly if you will be playing the recording back on a much smaller screen. And, I do not think those numbers are in any way magic, and there is no reason you couldn’t stick with even decimal or hexadecimal numbers for your trials, so for example you could use 16777216, 8388608, 4194304, or 2097152 (corresponding to 0x1000000, 0x800000, 0x400000, and 0x200000 in hexadecimal) as your -b:v trial values. You just need to find that sweet spot where the video is of the best possible quality that will play without problems on your equipment.

There are many other options you can use with ffmpeg, including ones that will reduce the screen size in case you are watching on an older computer or tablet, or something else that does not have a 1080p screen, but I just wanted to show a simple conversion using the fewest number of options.

I will note that ffmpeg has a tendency to gobble up as much available CPU time as it can get while converting video. If you fear that it will steal needed CPU cycles from other programs (such as your backend software), you can use nice to keep it in check. For example, if you use:

nice -n 20 ffmpeg […options…]

It will cause ffmpeg to run at the lowest possible priority and give up CPU cycles to any other program that needs them. Nice can take values from -20 to + 20, with the higher the number indication how “nice” the program will be to other programs. Negative values will raise the priority of the program higher than normal, while positive values will give it lower priority than most other programs.

Similarly, you can use ionice to keep ffmpeg from hogging access to your storage devices. If you use:

ionice -c 3 ffmpeg […options…]

That will cause ffmpeg to give preference to any other program that needs access to your storage devices. You might want to use this if ffmpeg will run at the same time your backend software is recording programs to your hard drive. And yes, you can use both ionice and nice together:

ionice -c 3 nice -n 20 ffmpeg […options…]

Note that if you are running this from a shell script then you may need to specify the full paths to all the programs used, like this:

/usr/bin/ionice -c 3 /usr/bin/nice -n 20 /usr/local/bin/ffmpeg […options…]

The paths shown above are valid for most Debian/Ubuntu based systems. To find out where these programs are located on your system, you can use the which command. For example:

$ which ffmpeg


Leave a Reply

Fill in your details below or click an icon to log in: Logo

You are commenting using your account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s