MasamuneXGP
19th June 2006, 22:22
Hello all. I'm coding a program which requires video decoding, in a respect similar to VirtualDub. I started out using the vfw API, using functions such as AVIStreamGetFrame and the like, and that was working well. However, the idea of only supporting avi files didn't sit well with me, and using AVISynth scripts to support other containers isn't particularly stable, especially when it comes to things like h264 MP4 files, which I really want my program to be able to support. I'd much rather support the containers natively.
So anyway I started posting here and other places trying to figure out what I should use as an alternative to vfw. I got three recommendations. AVIDemux, GStreamer, and libavcodec. As I will explain, the only one I've had moderate success with is the last one, but first, can anyone suggest anything else that I could use?
Anyway, first I looked into AVIDemux. It does indeed decode MP4 files quite magnificently, however, I really don't know where to begin with respect to implementing it in my program... I'm guess whoever recommended it to me meant for me to look through the source and just copy what they were doing, but I'd much from a relatively simple library of functions that I could use...
Then I looked into GStreamer. Now, this is a win32 program I'm making here. GStreamer is linux, but I hear there's a win32 port. But getting the thing to compile was so much of a nightmare I gave up pretty quickly.
Finally I tried libavcodec. I downloaded the ffmpeg source, and (with a few headaches) managed to get it to compile. I compiled the test program (here: http://www.inb.uni-luebeck.de/~boehme/libavcodec_update.html ) and threw a bunch of different video containers at it. Sure it enough, it could decode all them (although Matroska files seemed to spit out some strange debug error messages in the console window) so that's cool. However, I do have a problem. For my program to be able to display video, I need the frame rate and total number of frames in the video file. libavcodec's AVStream struct is supposed to have this information, but strangely, it's only correct for some containers. The four member variables in question seem to be AVStream.duration, AVStream.nb_frames, AVStream.r_frame_rate, and AVStream.time_base. The former two tell me the number of frames, and the latter two tell me the frame rate. However, they're not always correct for all containers. For instances, AVI files have the number of frames in .duration, but nb_frames seems to always be 0, also the frame rate is in .time_base, but .r_framerate is totally wrong. MPG files on the other hand have the frame rate in .r_frame_rate, whereas .time_base is incorrect. MP4 files seem to get all four perfect. But most importantly, both frame count variables are empty for OGM files, and for MKV files, all four are incorrect, meaning I have no way of telling the frame rate or the frame count for MKV files. Obviously this is not acceptable.
So what are my options? The only thing I can think of using mkvtoolnix's mkvinfo.exe internally, but that sounds ridiculously inefficient. And I don't even know if there is anything similar for OGMs. Ugh... Is libavcodec even worth it?
Thanks for your insight doom9ers, and I apologize for my lengthy post.
So anyway I started posting here and other places trying to figure out what I should use as an alternative to vfw. I got three recommendations. AVIDemux, GStreamer, and libavcodec. As I will explain, the only one I've had moderate success with is the last one, but first, can anyone suggest anything else that I could use?
Anyway, first I looked into AVIDemux. It does indeed decode MP4 files quite magnificently, however, I really don't know where to begin with respect to implementing it in my program... I'm guess whoever recommended it to me meant for me to look through the source and just copy what they were doing, but I'd much from a relatively simple library of functions that I could use...
Then I looked into GStreamer. Now, this is a win32 program I'm making here. GStreamer is linux, but I hear there's a win32 port. But getting the thing to compile was so much of a nightmare I gave up pretty quickly.
Finally I tried libavcodec. I downloaded the ffmpeg source, and (with a few headaches) managed to get it to compile. I compiled the test program (here: http://www.inb.uni-luebeck.de/~boehme/libavcodec_update.html ) and threw a bunch of different video containers at it. Sure it enough, it could decode all them (although Matroska files seemed to spit out some strange debug error messages in the console window) so that's cool. However, I do have a problem. For my program to be able to display video, I need the frame rate and total number of frames in the video file. libavcodec's AVStream struct is supposed to have this information, but strangely, it's only correct for some containers. The four member variables in question seem to be AVStream.duration, AVStream.nb_frames, AVStream.r_frame_rate, and AVStream.time_base. The former two tell me the number of frames, and the latter two tell me the frame rate. However, they're not always correct for all containers. For instances, AVI files have the number of frames in .duration, but nb_frames seems to always be 0, also the frame rate is in .time_base, but .r_framerate is totally wrong. MPG files on the other hand have the frame rate in .r_frame_rate, whereas .time_base is incorrect. MP4 files seem to get all four perfect. But most importantly, both frame count variables are empty for OGM files, and for MKV files, all four are incorrect, meaning I have no way of telling the frame rate or the frame count for MKV files. Obviously this is not acceptable.
So what are my options? The only thing I can think of using mkvtoolnix's mkvinfo.exe internally, but that sounds ridiculously inefficient. And I don't even know if there is anything similar for OGMs. Ugh... Is libavcodec even worth it?
Thanks for your insight doom9ers, and I apologize for my lengthy post.