It’s late, which means two things — first, I should be in bed, and second, I’m writing the coolest code evar.
With my little DVD toolkit programs I’ve been writing to learn C, I’ve had the idea bounce around in my head a lot to write a tiny (tiny, super tiny, seriously tiny) DVD player. For no other reason than to learn more C. I’m not interested in features in the least (right now), since I don’t even *use* a DVD player to debug ripping and archiving all my DVDs. Well, that’s not true. I’ll use VLC if I don’t want to patiently track down the valid track on a poisoned DVD layout. But that’s rare, and it’s just for gathering information.
There’s a couple of other ideas I’d thought about with doing direct DVD to some kind of manipulation, and each time, the idea is either shut down as in it’s stupid or it’s just completely unnecessary and something I’d never use. One was to write “dvd_mkv” which would just extract the data off a track, and dump it directly into a Matroska container. That’s a cool idea and all, but I’d never need it. In fact, I went the opposite direction and added the feature to dvd_copy to print to stdout, and I just use avconv to dump the stream straight to a MKV myself. It’s simple, and I can select the streams. Perfect.
Here’s how that’d work, by the way:
$ dvd_copy /dev/sr0 | avconv -i – -codec copy dvd_longest_track.mkv
That program’s already in my tree. I need to roll that out to distros though. That’s another post though.
So, getting raw data off isn’t a big problem (although I can’t use that method to get vobsubs off, booooooo), and there’s no real reason to hack on something.
I have tried, though, in the past, and it’s been really frustrating. I’ve tried a lot with the libav libraries, and I just can’t get it completely figured out. I’m not going to rail on their code or applications or libraries in the slightest, because that’s certainly not the case, there is *nothing* wrong on their end. There’s a high learning curve (which I’m sure few people would disagree with me), and I’m an absolute novice at C, so, realistically, the goal is pretty much out of reach at the time. Combine that with the fact I’d never use it, and I kind of meh out. (I should note though that I did get some code written so I could parse enough data on a DVD directly to get some video info. A small amount of metadata, but still, it’s cool as an accomplishment. I just noticed it’s in my tree as well. Go crazy.)
Moving on, though, if the barrier to entry was much smaller, I might be more interested in tackling it.
Enter first, libmpeg2.
The libmpeg2 project is amazing, and the code is really simple to use (as in, I can read it and partly understand it), and it’s what libav* uses for decoding anyway. I managed to write a program I use as a test case, dvd_extract_mpeg2, which copies the raw video straight off of the DVD — unencrypted of course, and it filters out the garbage in there as well. I’ll probably pull it from the repo at some point or another, but for now you can see the code here. I should make it really, really clear that I *did not* write the MPEG2 decoding in there, it’s wholesale lifted from libmpeg2’s code (open source free software for the win, yo).
*That* one was a lot of fun to write, because it was the first time I was accessing the data directly and writing straight to a file. This was way before dvd_copy was a thing, so it was pretty exciting at the time. The code works, and I actually *do* use this one a lot even though it was never really intended as anything more than a fun tool to build, and it comes in handy when I just want to quickly look at the video of a source DVD. I don’t really need anything to extract the audio, because I either in the past would re-encode the AC3 audio, or do what I do now which is copy it straight to the target stream, so I never bothered writing anything. I probably never will.
I was playing with libmpeg2 for some reason this week … probably debugging some video … and I realized that mpeg2dec has an option to playback video directly. Hmm. That gave me an idea. Then I saw that it could use SDL as an output option. Hmmmmm. That gave me more ideas. I started thinking to myself, “If there was a simpler way, or at least, an alternate way to display the video, maybe I should look at that?”
So I started looking at libsdl. SDL (Simple DirectMedia Library) really is that … it’s really simple. I started reading through the documentation, and it’s super easy to understand. It’s one of those things you look through it, and ask yourself, “is that it?” thinking you missed a major part somewhere, as if there was more to it you were completely unaware of. It’s really simple. I loves it.
I’ve slowly been walking through the API documentation and poking at their samples and writing tiny little snippets to see if can understand it, and I’ve already made remarkable progress. I can’t remember when I started, but it’s only been a few days and I already figured out how to get it display a bitmap image on the screen. That may sound simple, but consider that I had *never* imagined in my life that I’d be writing anything related to a GUI since it seemed so complex and overwhelming to me, and the fact that I could even get one tiny little image displayed in a window with so little effort has completely blown me away. SDL2 also for the win, yo.
I’ve been tinkering with the code, believing that I’m understanding it right, and I got it to display one bitmap, then load another one, and switch to that. This is huge progress, by the way.
So for fun tonight, I exported the opening sequence to Teen Titans into bitmaps, and put it in a loaded sequence of my little window program. It’s pretty awesome. :D I’ve got a screenshot here, which is only a screenshot and not the sequential video, but for me it’s a little milestone marker for me. I’m having a lot of fun. (Note the incredibly short list of headers there, by the way … holy cats!)
There’s already some cool stuff I’m learning (aside from libsdl and C), which is video and image formats in general.
One of the reasons I wanted to learn C (and likewise put it off for so long) was to take something that seemed so complex and nebulous and see if I could figure it out. For me, anything written in C was just amazing. I’d pop open the code, be completely confused, understand a tiny bit, and then completely get lost again. It was just overwhelming how hard it looked, and assumed I’d never be able to really understand it.
Interestingly enough, what finally got me to learn it was having a purpose to write applications in C — namely, stuff to access DVDs. Without that, the only reason I would have looked into it would have been to play around with it a bit. The novelty quickly wears off though, especially with something so difficult.
The same effect is happening with me trying to understand audio and video though. Again, it seems like this massive *thing* that’s just *out there* that is only observable, but never able to quite understand. It’s like the X-Files of code.
I’m already learning though, that things aren’t as scary and complex as that. The big hurdle is actually getting me to process new ideas and new ways that things *can be*. I would go into more detail about what I mean there, but I can’t even put it into my words myself. All I can say is that my understanding is growing.
So, I’m having fun. Will I ever get a tiny little DVD player written that goes into my tree? Probably. Will I ever *use* it? Probably not. It’ll most likely end up to be a hobby project, something I can be proud of and play around with it when I feel like it. Those are the best kinds of programs though, the ones where I learn the most.
Final wrap-up, I want to throw a shout out to dxr3player, which also gave me the inspiration to do this … it also uses libmpeg2 and a52dec to decode the video and audio directly, something I’d never thought of doing before. The ogle DVD player got me started thinking about alternate ways to do playback as well. Thanks guys!
A link to my DVDs wiki is probably in order as well.