Roku Developer Program

Join our online forum to talk to Roku developers and fellow channel creators. Ask questions, share tips with the community, and find helpful resources.
cancel
Showing results for 
Show  only  | Search instead for 
Did you mean: 
trime
Visitor

Can Roku play mp4s with cmov atoms?

I've got some mp4s with cmov[1] atoms. If I try and play such a file using roVideoScreen, I get a status -5 ('Content contains no playable tracks.').

I'm doing it like this:
content = {}
content.Stream = { url:"http://servername/path/to/file.mp4"
quality:false
contentid:"testing-data"}
content.StreamFormat = "mp4"
my_video_screen.SetContent(content)

In theory I could translate the video if there's space to save it on the tmp device (by decompressing the cmov atom and fixing up the moov atom length to account for it), but
* This seems pretty low level, and I'm surprised it doesn't just work? Am I doing something completely wrong? Is there some secret content.StreamFormat I should be using? The code works fine for media without compressed metadata (ie normal moov atoms containing mvhd and trak atoms)
* There don't seem to be any built in functions for decompressing data. I guess it's conceivable to implement deflate in brightscript, but perhaps not much fun 😞 Surely the roku can already do this (since code is uploaded in zip files, for instance!), but I cannot see how to do it in brightscript

Does anyone have any experience, or can anyone offer any suggestions?

[1] https://developer.apple.com/library/mac ... H204-33313
0 Kudos
3 REPLIES 3
RokuMarkn
Visitor

Re: Can Roku play mp4s with cmov atoms?

No, cmov atoms are not currently supported. The tmp filesystem only has a few tens of megabytes of space, even less while the video player is running, so storing a movie there would probably not work even if you could decompress it.

--Mark
0 Kudos
trime
Visitor

Re: Can Roku play mp4s with cmov atoms?

Thanks for the response. Is there any plan to support them in a future firmware version?
0 Kudos
trime
Visitor

Re: Can Roku play mp4s with cmov atoms?

I've written some code that does the job. In case anyone else was wondering, this is the approach I used:

Supposing I want to play
http://www.example.com/media.mp4
, which has a compressed cmov atom. First, we create a socket, bind it to some port (say, 9000) and listen on it. Then we pass a URL to roVideoScreen like
http://localhost:9000/proxy?url=http://www.example.com/media.mp4
.

When we get the connection on port 9000, parse the HTTP request (I don't think there's any support for this in BrightScript? In any case, I wrote my own parser using a finite state machine to try and overcome the lack of threads). Then we know the real URL, so we can connect to the host on the right port and send an HTTP request to get the moov atom (paying attention to the length for later). The moov atom contains a cmov atom, and inside is the cmvd atom. Decompress the cmvd section using the appropriate decompressor. (I had to implement inflate in Brightscript since there doesn't appear to be any API to zlib. I didn't bother with any other kinds of compression since zlib seems the most prevalent) Next, we know the size of the old and new moov segments, so we can compute the change in size. At this point, we can respond to the connection on port 9000 with a content-length which is the content-length of the target media file plus the difference in moov sizes. We can also start delivering the media file up until the moov atom.

Meanwhile, we need to adjust the pointers in any moov.trak.mdia.minf.stbl.stco atoms as well. All of these need to have the delta added to them as well. After this, it's just a matter of sending back the altered moov atom and then copying subsequent packets from one stream to the other.

This works surprisingly well on my Roku 3. There's just a pause in loading while it decompresses the cmvd atom. While it might work so well with older hardware, the inflation could well be optimised. It's hard to tell what's efficient and what's not without performance measuring tools, though.

So the upshot is: Can you do it? Yes. Should you do it? Probably not. Really, this should be implemented on the other side of the VM barrier. Doing it in BrightScript was an interesting project, but ultimately, I think it's enough to drive anyone insane.

If anyone would like the code, please PM me.

I've also got a few questions about development that don't really seem to be answered in the docs. Any comments or thoughts would be appreciated. Answers even more so 🙂
* Is there a way to efficiently copy part of an array? For example, an Append() with start and length arguments? I did it with a for loop and calls to .Shift() and .Push(). This seems hopelessly inefficient!
* Is there any way to truncate an array? (This could be done via the Append(start, length) to a new array, if it existed. It might not be very efficient, though)
* Is there some way to print a unique identifier for an object? For example, I ended up with a LOT of roByteArrays floating around in queues as I was managing the copying of data from one socket to another. Debugging would've been much simpler if I could print out the address of each object, or if that's too dangerous for device security, some hash of the address or other unique identifier?
* Are there any tools for measuring performance, like a high resolution timer?
* A lack of threads seems quite limiting. Has anyone explored creating a threading library? (I realise that without interrupts, they'd have to be cooperative rather than pre-emptive, but after writing a single-threaded HTTP server, and several other single-threaded, multi-client servers in BrightScript, I'll take what I can get!). I'm wondering if a meta-language could be 'compiled' (in the spirit of CSS 'compilers'. Transformed, really) into BrightScript to provide this kind of support

trime
0 Kudos