PDA

View Full Version : How to create custom (streaming video) Phonon::MediaSource?



high_flyer
10th December 2009, 10:22
Qt4.5.3
Windows XP
MSVC 2008

I have trouble getting the information I need from the documentation about the above subject, and hope there is someone here who can point me in the right direction.
Here is my case and questions:
My aim is to create a MedaiSource for a video camera, and here is what I have done so far:
I have a QIODevice camera object as input.
I have a MediaSource object which takes the camera object as parameter. (MediaSource(QIODevice*))
I can get hold of the image data inside my camera object.
I have a MediaObject, which takes the above MediaSource as source. (see code below)
But I don't see how and where the Phonon frame work knows when my camera has a new frame, and how the frame data gets delivered to the Phonon Objects?

Maybe the question should be - which QIDevice methods should be implemented and how, so that the MediaSource will play by the Phonon rules?
At the moment my camera emits the readReady() signal when it gets a new frame, and the readData() function is implemented, in addition to isSequential() as per documentation.
Pointers to the correct places in the documentation are very welcome.
The only text that I found that says anything about constructing a custom MediaSource is the documentation for the MediaSource(QIODevice*) constructor:

If you need to fetch multimedia data from a source that is not supported by MediaSource, you should subclass QIODevice and use this MediaSource constructor. It is important that you reimplement QIODevice::isSequential(), as it is used by MediaSource to determine if the media source is seekable.

ioDevice is an arbitrary readable QIODevice subclass. If the device is not opened MediaSource will open it as QIODevice::ReadOnly.
But apparently, there is more to it than just what is stated here.

Current behavior of my code is as follows:
the code:


AxioCam *pCam = new AxioCam(0);
bool bOpen = pCam->open();
if(bOpen){
Phonon::MediaObject *pMediaObj = new Phonon::MediaObject();
Phonon::VideoWidget *pVideoWidget = new Phonon::VideoWidget();
Phonon::MediaSource *pMediaSource = new Phonon::MediaSource(pCam);
pMediaObj->setCurrentSource(*pMediaSource);
Phonon::createPath(pMediaObj,pVideoWidget);

}


Once Phonon::createPath() is called the following output is given:


TffdshowBase::Constructor
First-chance exception at 0x31122060 in AxioTest.exe: 0xC000001D: Illegal Instruction.
TffdshowDecAudio::Constructor
Join filter graph
TffdshowDecAudio::CheckConnect (input)
TffdshowDecAudio::CheckInputType
TffdshowDecAudio::getCodecId
TffdshowDecAudio::getCodecId: 44100 Hz, 2 channels
TffdshowDecAudio::getCodecId: codecId=0
Removed from filter graph
'AxioTest.exe': Loaded 'C:\WINDOWS\system32\wmpasf.dll'
'AxioTest.exe': Loaded 'C:\WINDOWS\system32\mpr.dll'
'AxioTest.exe': Loaded 'C:\WINDOWS\system32\dxmasf.dll'
'AxioTest.exe': Loaded 'C:\WINDOWS\system32\urlmon.dll'
'AxioTest.exe': Loaded 'C:\WINDOWS\system32\wininet.dll'
'AxioTest.exe': Loaded 'C:\WINDOWS\system32\drmclien.dll'
'AxioTest.exe': Loaded 'C:\WINDOWS\system32\msacm32.dll'
'AxioTest.exe': Loaded 'C:\Programme\PixiePack Codec Pack\FLVSplitter.ax'
TffdshowBase::Constructor
TffdshowDecAudio::Constructor
Join filter graph
TffdshowDecAudio::CheckConnect (input)
TffdshowDecAudio::CheckInputType
TffdshowDecAudio::getCodecId
TffdshowDecAudio::getCodecId: 44100 Hz, 2 channels
TffdshowDecAudio::getCodecId: codecId=0
TffdshowDecAudio::CheckConnect (input)
TffdshowDecAudio::CheckInputType
TffdshowDecAudio::getCodecId
TffdshowDecAudio::getCodecId: 44100 Hz, 2 channels
TffdshowDecAudio::getCodecId: codecId=0
TffdshowDecAudio::CheckConnect (input)
TffdshowDecAudio::CheckInputType
...
This continues recurcively for quite a while, only the 'Hz' value changes sometimes, then a bit of this:

Removed from filter graph
'AxioTest.exe': Loaded 'C:\WINDOWS\system32\iac25_32.ax', Binary was not built with debug information.
'AxioTest.exe': Loaded 'C:\Programme\Gemeinsame Dateien\Ahead\DSFilter\NeVideo.ax', Binary was not built with debug information.
First-chance exception at 0x02ed05d3 in AxioTest.exe: 0xC0000005: Access violation writing location 0x00000000.
First-chance exception at 0x02ecf788 in AxioTest.exe: 0xC0000005: Access violation writing location 0x00000000.
First-chance exception at 0x02ecf95f in AxioTest.exe: 0xC0000005: Access violation writing location 0x00000000.
First-chance exception at 0x02ecfc1a in AxioTest.exe: 0xC0000005: Access violation writing location 0x00000000.
...

And then again a bit of:
'AxioTest.exe': Loaded 'C:\WINDOWS\system32\ctagent.dll'
TffdshowBase::Constructor
TffdshowDecAudio::Constructor
Join filter graph
TffdshowDecAudio::CheckConnect (input)
TffdshowDecAudio::CheckInputType
TffdshowDecAudio::getCodecId
TffdshowDecAudio::getCodecId: 44100 Hz, 2 channels
TffdshowDecAudio::getCodecId: codecId=0
Removed from filter graph
TffdshowBase::Constructor
TffdshowDecAudio::Constructor
Join filter graph
TffdshowDecAudio::CheckConnect (input)
TffdshowDecAudio::CheckInputType
TffdshowDecAudio::getCodecId
....



At some stage the debugger stops with the error:

ASSERT failure in QCoreApplication::sendEvent: "Cannot send events to objects owned by different thread. Current thread a62be0. Receiver "(of type 'Phonon::VideoWidget') was created in thread 3c87b0",file kerlen\qcoreapplication.cpp line 296

Needles to say, as can be seen in my code, that I did NOT create my VideoWidget in another thread, so this seems to be a bug in the way Qt handles an error.
I think the problem is stack over run, due to the recursive call as can be seen in the debug output.
The question is, what triggered this recursive behavior?
If I use a normal mp3 file as parameter for my MediaSource, in the same code above, the code runs with no problems.
So I think the problem is with the QIDevice subclass implementation, namely, that it is not doing something, doing something wrong, or both, in respect to the way Phonon is using it.

What is troubling me is that in the output 'TffdshowDecAudio' is being used, even though my source is a video and not audio, so I will try to see what I can find about that.
The thing is that on the VideoWidget documentation (Phonon framework overview) it says:

The VideoWidget does not need to be set to a Category, it is automatically classified to VideoCategory, we only need to assure that the audio is also classified in the same category. (this is written for an example of a video that contains audio)
While writing this post I noticed the following in the MediaSource(QIODevice *) documentation:

Warning: On Windows, we only support QIODevices containing the avi, mp3, or mpg formats. Use the constructor that takes a file name to open files (the Qt backend does not use a QFile internally).

This might explain the problem.
It looks like I will have to subclass MediaSource and add a streaming QIDevice support, or wait for Qt4.6 to be released as it has QIODeviceStream support.
But please let me know if you know more about this.

Any pointers or ideas about things to test or try or documentation would be very appreciated.

Thanks!.

trungdok
17th February 2017, 19:54
Hi,
Have you ever figured this out?
Thanks.

high_flyer
17th February 2017, 20:30
Puh... to be honest, I can't remember any more... this thread is 7 years old!
If something comes up I will post.
My guess is that I didn't figure the problem as it was laid out in the post since I'd probably would post the solution.
Maybe I found a different way of approaching my problem, or something similar.