Wednesday, February 14, 2007

Why I want an HD based DVD/Xvid player

Why I need an HD based DVD player
The reason is quite simple. I have two kids. The older is 3.5 years old and the younger is 2.5 years old. The both watch a fair amount of kids' DVD and like other kids their age, they love seeing the same movies over and over again. Like other kids their age, they've become experts at operating the DVD player and scratching the DVD discs quite hard.

There's no use, DVDs are much better than the old VHS videocasettes (I can't even watch VHS content anymore), but for sure, they're less kids-proof. What's can I say? They're less durable. When you rent a DVD that's not new it's more likely it will pause and skip and stutter than an old VHS tape. The tape deteriorates over time, and the initial quality is lower, but a DVD can become unusable much faster.

Why I need an HD based DVD player? So I can rip those kids DVDs and have them on a hard drive for repeated playback. I would then store the kids' DVDs up with my grown-up DVD collection. If you carefully protect your DVDs like I do, I hope we'll be able to watch them for many more years.

Why I need an HD based Xvid player
I'm downloading videos over the internet, usually using Azureus. I'd like to watch those videos on my 32" TV in the living room, not in the spare room where my computer is. These days, whenever I download something, I burn it on a CD-RW and take it to my DVD/Divx player that's connected to my TV. This wastes a lot of time. I still don't understand why it takes over 10 seconds for a DVD player to recognize a media once it's inserted, but that nothing compared to the few minutes it takes to erase the CD-RW and then rewrite it with the video I downloaded. In addition, CD-RW discs are generally not very reliable. Every once in a while the burn fails, or succeeds, but the player doesn't read the disc or freezes in the middle etc. I need something more reliable like an HD, where I'm sure the information is stored properly.


What I want from an HD based DVD/Xvid Player
I want to be able to play videos without being afraid that my media will be scratched (by my kids, not the player) or that I'll need to burn CD-RWs all the time. Wait, that's not enough. I'm picky and I have more demands:

  • I won't settle for image quality that's less than what I get from a DVD player. I have a Compaq/HP nw8000 laptop with TV out (S-Video), but the video out quality is not on par with DVD players. The image is washed out and I can't get overscan to work properly.
  • I won't settle for poor video decoding performance which introduces frame skips and other visual distractions.
  • I won't settle for something that outputs only NTSC or PAL. I have a multisystem TV, and I want to see PAL movies in PAL and NTSC movies in NTSC. A conversion is doable, but changing frame rates introduces some jitter to the video that really annoys the eye.
  • I'd be happy to be able to attach thumbnails to files, so that it's easier for my wife and kids to find the videos they want to play.
That's basically it. I don't think that's too much to ask...

Friday, January 19, 2007

What is Packed Bitstream?

Many Xvid encoded movies are encoded using Packed Bitstream. What is it? First of all, for me it's important since I have a stand-alone DVD player that can play Xvid encoded avi files, but only if they don't use packed bitstream. Whenever I obtain a movie, and before I burn it on a CD-RW, I have to check if it uses packed bitstream, and if it does, use a utility to convert it to a non-packed bitstream movie (more on that later).

Let me just say up front what packed bitstream is not - it's not saving any space. Actually, when "unpacking" a packed bitstream video the result is a bit smaller (but just a few KBs smaller).

Frame (or VOP) Types
Before we can talk about packed bitstream, we'll need to talk about frame types. In MPEG4 talk, each encoded image of the movie is called a VOP (Video Object Plane). A VOP is usually equivalent to a frame: here's the explanation from Wikipedia: "In MPEG-4, VOP refers to a "Video Object Plane" which is effectively a Video frame." (We'll later see that packed bitstream is exactly where a VOP is not a frame). Here are the VOP types (I'll intermix frames and VOPs, since at this point we can consider them the same):
  • I-VOP (Intra): A frame encoded like a still image (much like a JPEG image). Why aren't all frames encoded like that? It's not efficient. Here's why:
  • P-VOP (Previous): A frame that encodes only the changes from the previous frame (we'll be more accurate shortly). In many (actually most) cases, a video frame is very similar to the its preceeding frame. It makes sense to encode a frame by saying "this frame is exactly like the previous frame, except for the following changes". P-VOPs are much more efficient than I-VOPs.
  • B-VOP (Bi-directional) - we'll discuss these in a moment.
When would you use I-VOPs and when would you use P-VOPs? Theretically, you'd use an I-VOP for the first frame of the movie, and all the rest would be P-VOPs. Of course, whenever there's a scene cut, it makes sense to use an I-VOP, descibing the changes between unrelated frames is more complex that describing a frame.

This is theoretically, mainly because of the following reason: If you want to jump to a specific frame, you have to decode all the frames from the previous I-VOP to the current frame. The frame itself doesn't contain enough information to be seen. Decoding many frames is a long process. Therefore, it's important to have I-VOPs not too far apart. Two comments on this: First: while DVD is MPEG2 and not MPEG4, it also has I-Frames and P-Frames (and also B-Frames), and each chapter mark always points to an I-Frame. Makes sense, right? Second, in many Xvid encoded movies, there are sometimes long scenes where there are I-VOPs every 300 frames! This is very good for overall compression, but seeking takes quite some time.

What about B-VOPs? B-VOPs are encoded based on the previous I-VOP or P-VOP, and also the next I-VOP or P-VOP. The MPEG group found that in many cases, describing a frame as the sum of changes from previous and next frames is more efficient than just the changes from a previous frame. Why? I don't know but the 'E' in MPEG stands for 'Experts', so they know what they say. To complete the picture, I'll just say that P-VOPs are encoded from the previous I-VOP or P-VOP, but never from a previous B-VOP. This means that you B-VOPs never affect the quality of any other frames but themselves, which means you can compress them as much as you want, and it will affect only the current frame. That's not true for I-VOPs or P-VOPs.

Frame Type Example
Let's say we want to encode a sequence of 10 frames. We might end up with the following sequence of frames (or VOPs):



The first frame (frame 0) uses an I-VOP. Frame 3 is encoded based on frame 0, frame 6 is encoded based on frame 3, etc. Frames 1 and 2 are encoded based on frames 0 and 3. Frames 4 and 5 are encoded based on frames 3 and 6, etc. Makes sense, right?

Playback Issues
This is all fine, but how can the player decode a B-VOP if the P-VOP it's based on is later in the stream? What if we'll have much more than 2 consecutive B-VOPs before the P-VOB they're based on? The answer is simple, we need to rearrange the order of the frames as the appear in the stream (or in the file). Here's how this is done in non-packed bitstream files:



The P-VOP preceeds the B-VOPs that depend on it. Of course, it's marked in a special way so that it will not be shown in the stream order. There's still a problem. If the player starts shows frame 0 as soon as it reads it, it will have nothing to show when it reads the next frame. It has to read two frames before encountering the B-VOP it should show next (frame 2). The solution is to insert a playback delay:
  • When the player reads and decodes frame 0 (I), it displays nothing.
  • When the player reads and decodes frame 1 (P), it displays frame 0.
  • When the player reads and decodes frame 2 (B), it displays frame 2.
  • When the player reads and decodes frame 3 (B), it displays frame 3.
  • When the player reads and decodes frame 4 (P), it displays frame 1.
It seems that the player needs a single frame delay to be able to play the stream properly. I read somewhere that the player actually uses a 3 frame delay.

Packed Bitstream
A video stream that uses packed bitstream tackles this issue using a different method:



The change here is that a single frame in the stream includes 2 VOPs. Whenever a future P-VOP or I-VOP is needed, it's included within the frame that needs it. Certain frames need no VOP data, since it was already included in a previous frame. In this case an N-VOP (nop? null?) is used. This is an empty VOP that takes up very little space.
There's no need to delay the playback, but on the other hand, the player has to be capable of decoding two VOPs during the time of a single frame.

Unpacking Packed Bitstream Files
I don't know if packed bitsream is better or not for encoders, players, developers, etc. I only know that my standalone DVD player can't handle packed bitstream, so I have to "unpack" such files. If you need this as well, I know of two options you may use:
  • Use Moitah's Mpeg4 Modifier, either in its GUI or command line version.
  • Use UnpackMP4, a Java conversion of Moitah's command line version. I created the Java port since I wanted to use it on Linux and didn't want to install Mono. Also, I was missing basic Linux behavior like being able to convert multiple files in a single call. When I ported the application, I also optimized it so that it runs faster than Moitah's version, but I have to addmit that the newest Mpeg4 Modifier runs a bit faster than my port (tested only on Windows).
Happy unpacking.

Thursday, December 28, 2006

Field Dominance (or Why Interlaced Sucks)

In a previous post, I said HD 1080i sucks because interlaced, in general, sucks. I went on to explain a few things there. Recently I edited a home movie from old footage of my niece (for her birthday), and tackled a nasty interlaced issue called "Field Dominance". Here's one more reason why interlaced video should be abandoned...

Let's skip the definition on interlaced video (You can always pick it up from Wikipedia), I want to concentrate on working with interlaced video while editing movies - I've used Pinnacle Studio and tried Adobe Premiere. If the content was progressive, 3 consecutive frames might have looked something like this:



But the video is interlaced, so you know how it looks like - the infamous comb lines. So allow me to demonstrate this as if interlacing was not done line by line, but rather in chunks of lines:



Wait, that's not the only possible way the video could look like, there's another option:



Do you see the difference? It's quite subtle - in the first image, the car is a bit backwards on the even lines. This means that the even lines were captured first, and then the odd lines. This is called bottom field first. In the second image, the odd lines were captured first and then the even lines. This is called top field first. Which field is first? This is called field dominance, and it's one more thing you need to worry about when using interlaced video.

Where's the problem? When you're showing the interlaced movie, you have to know which field to show first (and send it first to the TV). If you get it wrong, you're sending the data at the wrong time. In our case the car would move a bit backwards, and then more forwards, then a bit backwards, and then forwards, etc. If you don't understand if completely, just believe me, it looks really bad.

How did I end up having a movie with field dominance issues? I used old video materials for my video, from multiple sources. I captured most of the video using a VCR connected to an Analog-toDV converter, but some of the video was already converted to DVD. The problem was that all my captured material was bottom field first (as is standard in DV), and the DVD originated video was top field first. When you combine TFF and BFF videos, you're bound to have jittery video in the scenes where the field dominance is wrong.

The real problem is that you don't see this problem until you actually see the video on an interlaced device. You see the regular comb lines, but have no way of knowing if the video is BFF or TFF.

Fortunately, I still had my original assets (video material), so I just had to reverse the field dominance on these specific video files. I originally thought of writing a VirtualDub plugin for this, but (of course), there's an excellent plugin called Reverse Field Dominance already available written by Donald A. Graft.

Of course, reversing the field dominance comes with a price:
  • You have to reencode the video, so if, for example, you're working with DV material, you loose something.
  • You either bring everything one pixel up (best solution in my mind) or shift the content one field earlier or later. In any case you introduce either a spatial or temporal change to the video.
What can I say, just use progressive video if you can.

Friday, November 24, 2006

Mission Impossible: Upload Faster Than Your Upload Limit

Warning: this is a very technical post. Read at your own risk...

The Problem
There's a certain US show that airs on Wednesday nights. When it's Wednesday night in the US, it's actually early morning in Israel, where I live. By Thursday morning Israel time, there's already a torrent for downloading a high quality, commercial free, video of that certain show. The episode takes 350MB, and usually takes 4-7 hours to download. That's great, since I usually watch the episode on Thursday night Israel Time, which is less than a day after it originally aired.

But what about my fellow workers at the office? Usually they only get to see the episode on Sunday, since the weekend in Israel starts on Friday. But for the new season that started in October I decided I would try to "provide" the episodes on Thursdays. That's not that easy: let's say the download (which I'm doing at my home) finishes at 2 PM. Transferring 350MB would take around 5.5 hours (My actual upload speed from home is 18KB/Sec). This brings us to 7:30 PM on Thursday - most of my co-workers try to leave earlier on Thursday, and start the weekend "early". If I could only download the episode a little faster, and it would be at the office by 6:30 PM, it would be just in time.

The Solution
I usually start the download (using Azureus) at 7 AM when I wake up. Then I need to wake up the kids, dress them up, take them to kindergarten, take a shower, pack up the laptop and go to work. It's probably around 9 AM by the time I leave my home for work. Since I take my laptop from home to work, it can be used for "file transferring". By 9 AM 20% to 30% of the download already completed, so I perform the following steps:
  • I make a copy of the video file on my home computer, and then copy that copy to my laptop, which I take to work.
  • I go to work and wait for the download to complete. I use the Azureus HTML WebUI plugin to monitor the download progress from work.
  • When the download completes, I create a binary diff file between the copy I took at 9 AM and the complete file. The diff file is smaller than 350MB. For example, if by 9 AM I already downloaded 100 MB, the diff file would be around 250 MB.
  • I then stop Azureus (to get maximum upload speed to the office), and transfer the diff file to work. A 250MB file transfer takes "only" 4 hours.
  • At work I apply the diff file as a patch to the copy of the 9 AM file and get the finalized file.
  • I never forget to start Azureus once again, and make sure I seed the file for a long time.
The Technical Details
The first time I tried this "trick". I wasn't sure there was a program that could take two binary files, and produce a difference file that could later be used to patch one into the other. But since I use Ubuntu at home, and I have a friend (and co-worker) who's a Linux expert. I was sure that if I take a copy of the video download before it's completed, I would find a way (asking my friend) to patch it to be complete.

I was right. My friend told my about a tools called bsdiff. But after looking at its man page, I saw I wouldn't be able to use it. To do its magic it would require 5.8GB of memory (17 times the size of the original file, aparently it's optimized for executables, which as usually small). I only have 320MB. Still, the bsdiff documentation mentioned another tool - xdelta, which was supposed to produce larger diff files, but doesn't require so much memory.

Indeed it worked, and here's what I did:
  • 9 AM at home:
    copy episode.avi ep-9am.avi
  • I then copy ep-9am.avi to my laptop computer, so I have it at work later.
  • 2 PM at home (using Putty to access my home computer from work):
    xdelta delta ep-9am.avi episode.avi episode.patch
  • I then copy the file from home to work using WinSCP.
  • 6 PM at work:
    xdelta patch episode.patch ep-9am.avi episode.avi
That's it - I get the episode fast enough for weekend viewing by my co-workers. If you need xdelta on Ubuntu/Debian you can simply use:
sudo apt-get install xdelta

If you're using Windows, you'll need to get a Windows port of this tool, which is supposed to exist.

Disclaimer
You could watch the unmentioned TV show on one of the cable channels in Israel, but you'll see episodes that were broadcast in the US last year. Since we're in Israel, we're blocked (based on Geolocation information) from downloading the episodes from legitimate places (like the Apple Store). For some of us that's not acceptable, so we need to download the episodes and over the internet using BitTorrent. Hopefully, this phenomenon would be widespread enough to force the content providers to allow for international, legal distribution of their content. I would be willing to pay for such a service.

Tuesday, November 21, 2006

I'm Too Old For My Job

Yesterday I saw this piece of code in a unit test (We're using JUnit like everyone else) we have for one of our components:

Timestamp dawnOfTheAges = new Timestamp(0);

I immediately e-mailed the person who wrote the code complaining about the fact that constructing a Timestamp like this creates something that's much more recent than the dawn of the ages. It's midnight as it was celebrated at any London pub on January 1st, 1970. Hell, how could this be the dawn of time if I was born over a year before that?

I'm too old for my job as a programmer...

Saturday, November 18, 2006

Linux, Microsoft and XNA

About a year ago I decided to give Linux a chance (I chose Ubuntu). I assume I'm not an average PC user since I've been a programmer since 1986, so if someone could use Linux as the operating system for a desktop computer (my home computer), I should be able to do it as well.

In the last year I used Linux (I'm definitely not an expert, and I don't have the time to become one), and found many great things it can do, but also a lot of shortcomings. During this time I found myself wondering a lot about what's missing (or wrong) in Linux that prevents me from recommending it to my relatives (for whom I provide regular technical support).

At this point, there are quite a few reasons why non-technical people should not switch to Linux. One that's been there for quite a while is that modern games are not ported to Linux. A PC is still used a lot for games, and that's where Linux fails. Don't get me wrong - after working a bit with Linux, it looks like it's inherently better than Windows when it comes to many aspects like handling files, security, and networking. Still, I assume many people won't switch to Linux because there are no games.

Enters Microsoft XNA. It's main purpose is to let hobbyists develop games more easily - for Windows and for the Xbox 360. I gave it a try and it looks like an excellent framework - I only tried 2D stuff and still managed to see its power and simplicity. I think XNA will be a success.

The real question is if we're going to stop playing games on PCs, and start playing them mostly on game consoles.
  • If the answer is yes, then Microsoft just made it easy for small publishers to create small games for the Xbox 360, but it will loose one of the main reasons not to switch to Linux. In this case, it's also important for Sony to come up with something similar to XNA really fast...
  • If the answer is no, then XNA is a really nice framework for building PC games, and the Linux community should start working on an alternative. Microsoft was smart in investing in DirectX a decade ago, and if PCs are going to be used a lot for playing games in the future, this is another smart move from Microsoft.
The open source community can definitely build an XNA alternative for Linux. Something that would make developing Linux games a breeze. I'll join such a project, but I'm too new to Linux to be able to contribute significantly. Any volunteers?

Tuesday, November 14, 2006

Why HD 1080i Sucks (and 1080p Doesn't)

CNET published a recent article saying on a visual comparison, they can't see substantial difference between 1080i sets and 1080p sets (The case against 1080p). I find such articles alarming. I think 1080i sucks, and here's why.

Simply put, 1080i sucks because interlaced broadcasting sucks.

The real issue with interlaced content is not the TV set. I know CNET is all about telling people what equipment to buy, but the real issue is the content itself. When your content is interlaced you don't have frames, you have half-frames that are interleaved. It's not that terrible when all the TVs are also interlaced, and all have the same resolution.

But this is not the case anymore. Now you can watch HDTV on displayes with various resolutions such as 1920x1080 (full HD), 1280x720 (the lower resolution HD), or even 1366x768 (which is a wide version of the popular 1024x768 computer resolution, useful when you need to use your display for movies as well as a computer monitor).

Now here's the tricky part - if you don't have complete frames, you can't resize the image. What you need to do is break the 1920x1080 resolution into two images, each 1920x540, scale each image, and then try to combine the result into a complete frame once again (or maybe keep it interlaced). The results of this process are not excellent. Another option is to try to recreate the full frames from the half frames you have, but doing this properly is the kind of magic that consts a lot of money, I mentioned that ealier in my post "HDTV is cheaper than your old TV".

You might think your safe if you bought a 1920x1080 set, but I've already heard of plans to manufacture 2560x1536 sets. If your content is 1080i, it will be hard to scale properly for the TV of the future (or next year's projectors?!?).

Here's another good reason why interlaced sucks - because display technologies today are progressive. LCD, Plasma, and DLP are all progressive technologies. When you feed them interlace content, they have to process it somehow (deinterlace) to fit their progressive nature. Sure, if your original material is progressive (film) and you "convert" it to interlaced, it will look well when you play it back on progressive devices, but if your material was shot by an 1080i camcorder, this conversion will either have interlacing artifact, or you'll loose some sharpness.

When modern HDTV was concieved in the US in the mid 1990s, CRT was the dominating technology, and the people who concieved HDTV were visionairs, but still had a limited vision. They thought the amount of information in a 1080p (at 60 full frames per second) would be too much. Well, it's not too much now, even before 1080i is popular, and just to make sure what I need when I say 1080p, I want a set that supports 1080p at 24 full frames per second, so that movie transfers would be as accurate as possible. 1080 @ 24p contains less information than 1080 @ 60i (If someone starts shooting movies at 60 frames per second, I'll be happy to see it on a 1080 @ 60p set).

I don't really care if CNET recommends 1080i sets over 1080p sets because they're cheaper, but if this means it will take more time until we have enough content in 1080p, then that's a shame. And CNET is right about one thing - 1080p content looks good even on a 1080i set (assuming it can accept it).