Hi. Nowadays, 64 bits systems are becoming quite common, and it would be nice to be able to easily play videos with proprietary codecs on those systems. I see 4 solutions to do that: - Using a 32 bits mplayer. Well, that works, of course, but it it not really convenient. As for me, I find it really inconvenient. - Having free decoders. Well, of course, this is the best solution, and the situation have greatly improved since last year. I thank the people responsible very much. Unfortunately, the result is not yet perfect. For example, the TV show that I download daily is decoded quite poorly (the image is very rose; I can provide samples if this not a known issue). - Using 64 bits windows DLLs. I have read that microsoft had finally released them, and I wonder if someone is working on it. - Using a separate 32 bits process just for the decoding, with pipes (or shared memory). This last solution seems to me especially interesting, because I think it is in the range of my abilities. Do you think I should start hacking on it? Regards, -- Nicolas George
Hello, On Wed, Jun 27, 2007 at 12:55:23PM +0200, Nicolas George wrote:
- Having free decoders. Well, of course, this is the best solution, and the situation have greatly improved since last year. I thank the people responsible very much. Unfortunately, the result is not yet perfect. For example, the TV show that I download daily is decoded quite poorly (the image is very rose; I can provide samples if this not a known issue).
If you use latest SVN that's not a known issue, no.
- Using 64 bits windows DLLs. I have read that microsoft had finally released them, and I wonder if someone is working on it.
I believe it when I see a link. It is rather hard to believe they would release codecs, given that there is not 64 bit "Windows Media Player" that could use it. Actually, given that for all I know there is no 64 bit DirectX there actually would be no way at all to use them...
- Using a separate 32 bits process just for the decoding, with pipes (or shared memory).
This last solution seems to me especially interesting, because I think it is in the range of my abilities. Do you think I should start hacking on it?
Sure, very interesting. As well as the possibility to let it run in a seccomp. Not sure how you would do it in order not to duplicate a lot of effort and code. Or maybe you could just convince the kernel developers to allow userspace programs to switch between 32 and 64 bit modes via syscall? Greetings, Reimar Döffinger
Le nonidi 9 messidor, an CCXV, Reimar Döffinger a écrit :
If you use latest SVN that's not a known issue, no.
I tried with yesterday SVN, and there was no change concerning wmv3. I will report it on ffmpeg-devel.
- Using 64 bits windows DLLs. I have read that microsoft had finally released them, and I wonder if someone is working on it. I believe it when I see a link.
One of my friends pretends to have it installed on its windows box, and he can be trusted on technical matters. I have asked for details and links.
Sure, very interesting. As well as the possibility to let it run in a seccomp.
I did not think of that. On the other hand, I thought of running it on non-x86 architecture with qemu; not sure that the speed would be there though.
Not sure how you would do it in order not to duplicate a lot of effort and code.
AFAIK, the major part of a video decoder job is to take encoded data from a buffer, and put decoded data into another buffer. My plan would be: 1. Build the parts of libmpcodecs that can not be built in 64 bits in 32 bits into a libmpcodecs32. This is only makefile hacking. 2. Build a binary around this libmpcodecs32. That requires some protocol implementation (especially if I want to handle control messages), and importing or reimplementing some utility functions (mpcodecs_get_image). 3. Create a new decoder that fork+execs the binary and uses it for the decoding. This will take some work, but I think it can be done. Regards, -- Nicolas George
Hello, On Wed, Jun 27, 2007 at 02:31:58PM +0200, Nicolas George wrote:
Le nonidi 9 messidor, an CCXV, Reimar Döffinger a écrit :
- Using 64 bits windows DLLs. I have read that microsoft had finally released them, and I wonder if someone is working on it. I believe it when I see a link.
One of my friends pretends to have it installed on its windows box, and he can be trusted on technical matters. I have asked for details and links.
Since finding out if a binary is 32 or 64 bits involves a major effort on Windows I'm not convinced he actually checked... [...]
1. Build the parts of libmpcodecs that can not be built in 64 bits in 32 bits into a libmpcodecs32. This is only makefile hacking.
I think this is a very bad idea, involving a major effort, libmpcodecs has strong dependencies in MPlayer and a lot of information that is simply useless for decoding. I think you should better consider providing RPC-like stubs of (for decoding DMO): DMO_VideoDecoder_Open DMO_VideoDecoder_SetDestFmt DMO_VideoDecoder_StartInternal DMO_VideoDecoder_Destroy DMO_VideoDecoder_DecodeInternal To implement these you need only the loader code, which should be much easier to compile stand-alone. Greetings, Reimar Döffinger
Le nonidi 9 messidor, an CCXV, Reimar Döffinger a écrit :
Since finding out if a binary is 32 or 64 bits involves a major effort on Windows I'm not convinced he actually checked...
I am quite sure he did, but I do not have the details yet.
I think this is a very bad idea, involving a major effort, libmpcodecs has strong dependencies in MPlayer and a lot of information that is simply useless for decoding. I think you should better consider providing RPC-like stubs of (for decoding DMO): DMO_VideoDecoder_Open DMO_VideoDecoder_SetDestFmt DMO_VideoDecoder_StartInternal DMO_VideoDecoder_Destroy DMO_VideoDecoder_DecodeInternal
To implement these you need only the loader code, which should be much easier to compile stand-alone.
My idea was that since libmpcodecs is higher-level than loader, embedding it would require actually less code duplication. I tried a quick and dirty approach to see by myself the amount of work. I have managed to build a stand-alone binary embedding vd_dmo, vd_dshow, vd_qtvideo and vd_vfw. It does absolutely nothing, but there is no undefined symbol. To achieve that, I had to define the following stubs: mpcodecs_get_image mpcodecs_config_vo mp_msg mp_msg_test get_path gCpuCaps divx_quality vo_format_name print_video_header I do not see anything monstrous. Regards, -- Nicolas George
Hello, On Fri, Jun 29, 2007 at 12:54:37PM +0200, Nicolas George wrote:
Le nonidi 9 messidor, an CCXV, Reimar Döffinger a écrit :
Since finding out if a binary is 32 or 64 bits involves a major effort on Windows I'm not convinced he actually checked...
I am quite sure he did, but I do not have the details yet.
I did not check 64 bit Vista, so it could well be. Neither did I have 64 bit W2K3 installed for long, so I might have overlooked something.
I think this is a very bad idea, involving a major effort, libmpcodecs has strong dependencies in MPlayer and a lot of information that is simply useless for decoding. I think you should better consider providing RPC-like stubs of (for decoding DMO): DMO_VideoDecoder_Open DMO_VideoDecoder_SetDestFmt DMO_VideoDecoder_StartInternal DMO_VideoDecoder_Destroy DMO_VideoDecoder_DecodeInternal
To implement these you need only the loader code, which should be much easier to compile stand-alone.
My idea was that since libmpcodecs is higher-level than loader, embedding it would require actually less code duplication.
Hardly since you always must extract loader, no way it can work without it.
I tried a quick and dirty approach to see by myself the amount of work. I have managed to build a stand-alone binary embedding vd_dmo, vd_dshow, vd_qtvideo and vd_vfw. It does absolutely nothing, but there is no undefined symbol. To achieve that, I had to define the following stubs:
mpcodecs_get_image mpcodecs_config_vo mp_msg mp_msg_test get_path gCpuCaps divx_quality vo_format_name print_video_header
I do not see anything monstrous.
Well, I see the problem if implementing functions like mp_msg, mpcodecs_config_vo and variables lib vo_format_name etc. because they must either be replaced by complete dummies or you need a way to call functions and access variables that currently aren't in function arguments from the 32 bit to the 64 bit binary (I admit the mp_msg problem still exists even when splitting out only the loader, but it is in less places). For the DMO functions all data you need is already in the functions call arguments and the data they point to may be passed via shared memory. As far as security is concerned (if you care about the seccomp idea) it also seems much easier to check the DMO function return values for correctness than e.g. the mpcodecs_config_vo parameters. Greetings, Reimar Doeffinger
Le primidi 11 messidor, an CCXV, Reimar Doeffinger a écrit :
Hardly since you always must extract loader, no way it can work without it.
I think I misunderstood what you were suggesting, I see better now. Yes, that could be an easy solution, but I fear the protocol would need a bit more work. Unfortunately, right now, I am stuck with either approaches. See below for details on my problem.
Well, I see the problem if implementing functions like mp_msg, mpcodecs_config_vo and variables lib vo_format_name etc. because they must either be replaced by complete dummies or you need a way to call functions and access variables that currently aren't in function arguments from the 32 bit to the 64 bit binary
That is not really an issue: global variables can always be passed as invisible arguments added by the RPC mechanism. The negotiation of pixel format in mpcodecs_config_vo could be more a problem, but I believe that it can be evacuated by deciding that all decoded data will be in YV12. ffmpeg's colorspace converters are probably better than microsoft's anyway... I have tried further to implement things, but I am stuck with a non-deterministic bug in the loader. I try a minimalistic program (at the end of this mail). All it does it call DMO_VideoDecoder_Open. I build it with: cc -I /tmp/mplayer -Wall -O4 -pthread -o testdmo main0.c \ -L /tmp/mplayer/loader -lloader /tmp/mplayer/osdep/mmap_anon.o \ /tmp/mplayer/cpudetect.o -lm /tmp/mplayer is a compilation tree, and the system is pure 32 bits (it's a Pentium 4). The result is that sometimes it work, and sometimes it fails with "IMediaObject ERROR: 0x805b369 input format not accepted (0x80040205 : -2147220987)", with probability about 1/2. Changing compilation options, compiling with -m32 on a Core2, etc., gives the same result. I am at a loss to find what I am doing wrong. As far as I can see, mplayer does exactly the same call, and it succeeds each time. If someone who understands the inner workings of the loader can enlighten me, that would be very helpful. Regards, -- Nicolas George <-------------------------------- main0.c --------------------------------> #include <stdio.h> #include <stdlib.h> #include "codec-cfg.h" #include "stream/stream.h" #include "libmpdemux/demuxer.h" #include "libmpdemux/stheader.h" #include "cpudetect.h" #include "codecs.conf.h" #include "loader/dmo/DMO_VideoDecoder.h" void mp_msg(int mod, int lev, const char *format, ... ) { } int mp_msg_test(int mod, int lev) { return(0); } char * get_path(void) { return("/tmp/registry"); } int main(void) { /* values from guignols-20070622.wmv */ BITMAPINFOHEADER bih = { .biSize = 44, .biWidth = 240, .biHeight = 180, .biPlanes = 1, .biBitCount = 24, .biCompression = 0x33564D57, .biSizeImage = 0, .biXPelsPerMeter = 0, .biYPelsPerMeter = 0, .biClrUsed = 0, .biClrImportant = 0, }; /* 73 is wmv9dmod.dll */ printf("73 -> %s\n", builtin_video_codecs[73].dll); GetCpuCaps(&gCpuCaps); DMO_VideoDecoder_Open(builtin_video_codecs[73].dll, &builtin_video_codecs[73].guid, &bih, 0, 0); return(0); }
Hello, On Fri, Jun 29, 2007 at 05:55:02PM +0200, Nicolas George wrote:
The negotiation of pixel format in mpcodecs_config_vo could be more a problem, but I believe that it can be evacuated by deciding that all decoded data will be in YV12. ffmpeg's colorspace converters are probably better than microsoft's anyway...
YV12 with some wmv3 video produces incorrect colours, so you actually do loose a little bit by not allowing other formats.
I have tried further to implement things, but I am stuck with a non-deterministic bug in the loader. I try a minimalistic program (at the end of this mail). All it does it call DMO_VideoDecoder_Open. I build it with:
cc -I /tmp/mplayer -Wall -O4 -pthread -o testdmo main0.c \ -L /tmp/mplayer/loader -lloader /tmp/mplayer/osdep/mmap_anon.o \ /tmp/mplayer/cpudetect.o -lm
-pthread should not be needed, though it should not hurt either.
/* values from guignols-20070622.wmv */ BITMAPINFOHEADER bih = { .biSize = 44,
sizeof(BITMAPINFOHEADER) == 40, so you forgot the 4 additional bytes after the struct. Probably the decoder needs those, but only gets random data with your code. Greetings, Reimar Döffinger
Le primidi 11 messidor, an CCXV, Reimar Döffinger a écrit :
YV12 with some wmv3 video produces incorrect colours, so you actually do loose a little bit by not allowing other formats.
Ok, I will try to take it into account. Do you have an example of such a file near at hand?
-pthread should not be needed, though it should not hurt either.
There is a pthread_create in win32.c; it is probably not called, but it needs to be resolved.
sizeof(BITMAPINFOHEADER) == 40, so you forgot the 4 additional bytes after the struct. Probably the decoder needs those, but only gets random data with your code.
Well spotted, thanks. I go back to my tests.
Hi. I now have something that works. There is still a lot of work to do (to support different images formats, for example; and to implement mp_msg in the helper), but at least I have a 64-bits binary of mplayer that is able to play guignols-20070622.wmv with the proprietary codecs, and the structure can be easily extended. The next step will be to integrate it in the mplayer source tree, but for that, I need some advice. My code adds three source files and one header file: - mplayer_helper32.c - remote_helper.c - remote_helper.h - vd_dmo_remote.c vd_dmo_remote.c must be built in the mplayer binary, as a replacement of vd_dmo.c. As such, I have decided to keep the driver name "dmo", so I do not have to change codecs.conf. Is it acceptable, or should I change it into dmo_remote? That would require duplicating all corresponding entries in codecs.conf. mplayer_helper32.c is the main loop of the 32-bits helper program, which will probably go in $PREFIX/libexec/mplayer/mplayer_helper32. I am not sure where to put it in the source tree. A dedicated subdirectory mplayer/helper32/ maybe? A dedicated directory is probably useful since a few source files must be built a second time in 32-bits mode: a place for the .o is needed. remote_helper.[ch] are the low-level communication functions, they are necessary both to mplayer_helper32 and to vd_dmo_remote. They probably can go in mplayer/helper32/, if that directory exists. Regarding the configuration options: on x86_64, it is possible to configure --enable-win32dll, the build will simply fail to build loader ("You need to define a CONTEXT for your CPU"). I think I can re-use the same option for this version, can't I? Are there remarks about these questions? I can show the code as it is right now, if someone is interested, but it is not easy to build. Regards, -- Nicolas George
Hi Reimar Döffinger! On 2007.06.27 at 14:49:14 +0200, Reimar Döffinger wrote next:
I believe it when I see a link. It is rather hard to believe they would release codecs, given that there is not 64 bit "Windows Media Player" that could use it.
Well according to this http://www.softpedia.com/get/Multimedia/Video/Codec-Packs-Video-Codecs/Vista... there is. Of course, even windows has problems with 64-bit codecs (due to absence of indeo and other important ones), but there is a growing list of 3rd party 64-bit codecs. I unpacked this "vista codecs pack" (you don't need vista for that at all ;)) and following codecs are there audioswitcher.ax ff_samplerate.dll MpaDecFilter.ax audxlib.dll ff_theora.dll MpaSplitter.ax avi2ac3filter.ax ff_tremor.dll MpegSplitter.ax AviSplitter.ax ffvdub.vdf NutSplitter.ax custom matrices ff_wmv9.dll OggSplitter.ax DSMSplitter.ax ff_x264.dll shoutcastsource.ax dtsac3source.ax flicsource.ax SSFSplitter.ax ffdshow.ax languages streamdrivethru.ax ff_kernelDeint.dll libavcodec.dll TomsMoComp_ff.dll ff_liba52.dll libmpeg2_ff.dll udpreader.ax ff_libdts.dll libmplayer.dll VSFilter.dll ff_libfaad2.dll MatroskaMuxer.ax vtsreader.ax ff_libmad.dll MatroskaSplitter.ax wavdest.ax ff_realaac.dll MP4Splitter.ax nice list, isn't it? ;)
Actually, given that for all I know there is no 64 bit DirectX there actually would be no way at all to use them...
I can assure you that there is, I have access to windows 2003 64-bit (should be pretty the same as xp 64-bit) and both 32-bit and 64-bit versions of directx dlls are present. Anyway, one of my friends who is windows guru says that he tried to make vista 64-bit codecs work outside of vista and failed (the ones from the list above would work, of course). 64-bit WMV/WMA/etc codecs from MS are so heavily DRMed so it's basically impossible to use them outside 64-bit vista environment. Maybe it would be possible with custom dmo loader which mplayer uses, but I wouldn't count on it. -- Vladimir
Hi, Vladimir Mosgalin wrote:
Hi Reimar Döffinger!
On 2007.06.27 at 14:49:14 +0200, Reimar Döffinger wrote next:
I believe it when I see a link. It is rather hard to believe they would release codecs, given that there is not 64 bit "Windows Media Player" that could use it.
Well according to this http://www.softpedia.com/get/Multimedia/Video/Codec-Packs-Video-Codecs/Vista... there is.
Of course, even windows has problems with 64-bit codecs (due to absence of indeo and other important ones), but there is a growing list of 3rd party 64-bit codecs. I unpacked this "vista codecs pack" (you don't need vista for that at all ;)) and following codecs are there
audioswitcher.ax ff_samplerate.dll MpaDecFilter.ax audxlib.dll ff_theora.dll MpaSplitter.ax avi2ac3filter.ax ff_tremor.dll MpegSplitter.ax AviSplitter.ax ffvdub.vdf NutSplitter.ax custom matrices ff_wmv9.dll OggSplitter.ax DSMSplitter.ax ff_x264.dll shoutcastsource.ax dtsac3source.ax flicsource.ax SSFSplitter.ax ffdshow.ax languages streamdrivethru.ax ff_kernelDeint.dll libavcodec.dll TomsMoComp_ff.dll ff_liba52.dll libmpeg2_ff.dll udpreader.ax ff_libdts.dll libmplayer.dll VSFilter.dll ff_libfaad2.dll MatroskaMuxer.ax vtsreader.ax ff_libmad.dll MatroskaSplitter.ax wavdest.ax ff_realaac.dll MP4Splitter.ax
nice list, isn't it? ;)
Note that all the ff* are ffmpeg libs, to the best of my knowledge. Guillaume
participants (5)
-
Guillaume Poirier -
Nicolas George -
Reimar Doeffinger -
Reimar Döffinger -
Vladimir Mosgalin