After a large amount of experimentation, and tons of help from the guys over on the #Xna IRC channel, we were finally able to figure out the problem. To explain the solution, I must first explain a tiny bit about the architecture of the Scurvy.Media content pipeline.
- Decode each frame of the video as individual textures. The pipeline currently only supports AVI video using the AVIFile library from CodeProject.
- Write the contents of each frame sequentially into one large .XNB file through the content writer.
- At runtime, open a stream (and keep it open), and read each texture one at a time in a separate thread.
- use .SetData to set the contents of a texture based on whatever the current Frame is.� Technically speaking, there are two textures at play for the purpose of double buffering ... but that's largely irrelevant to the topic at hand :-)
Now that I've explained the architecture, I'll explain the solution to one of the issues.� Mainly, it's the fact that the color order on the xbox platform is *different* than it is on windows.� Why that is I don't know, I wasn't able to find very many sources of information on this, but c'est la vie :-)
XBox:
- RGBA
- BGRA
byte[] xpix = new byte[pix.Length]; for (int i = 0; i < pix.Length; i += 4) {the code snippet above takes a byte array that uses four bytes per channel.� And it just puts it into a copy of the byte array.� Technically, I could have used the same array and just rearranged the byte values as I go ... but perhaps that's an improvement for another day.
��� int first = i, second = i + 1, third = i + 2, fourth = i + 3; ��� xpix[first] = pix[third]; //x=red ��� xpix[second] = pix[second]; //x=green ��� xpix[third] = pix[first];//x=blue ��� xpix[fourth] = pix[fourth];//x=alpha� }
b.SetPixelData(xpix);
But Avast! There still be problems on the high waters!
After making that change, the colors were still not right.� What we eventually realized is that I was writing byte data directly from windows (who's x86 architecture is little-endian), to be read from the xbox (who's powerpc architecture is big-endian).
Sooooo ... the answer was this:
byte[] xpix = new byte[pix.Length]; for (int i = 0; i < pix.Length; i += 2) {Right before writing the byte array to disk ... I flip every other byte.� Once I did that, the video was alight with correct coloration :-)
��� int first = i, second = i + 1; ��� xpix[first] = pix[second]; ��� xpix[second] = pix[first]; }
output.Write(xpix.Length); output.Write(xpix);
Again, a huge thanks to the guys on the #xna IRC channel.� This wouldn't have been possible without them.