I would like someone to post a code which can load and save parameters of a
video codec, such as DivX, with the IAMVfwCompressDialogs Interface and the
Set and GetState methods...
I have read lots of answers in that newsgroup, but no one of them work with
me :-(
Thanks!!
So what have you tried, and how has it not worked?
--
Be seeing you.
> I would like someone to post a code which can load and
> save parameters of a video codec, such as DivX, with the
> IAMVfwCompressDialogs Interface and the Set and GetState
> methods...
See if the following helps you:
http://groups.google.com/groups?selm=O%24qYy2fqCHA.1776%40TK2MSFTNGP10
which refers to:
http://groups.google.com/groups?th=908728ad897d423
http://groups.google.com/groups?th=df9eb79ac6e9589d
http://groups.google.com/groups?th=cdef9149a22f830d
--
/**
* Alessandro Angeli
*
* MVP::DigitalMedia
*
* a dot angeli at biosys dot net
*/
> So what have you tried, and how has it not worked?
You're right, I could have begun with that...
I didn't tried ICOpen and ICConfigure... because I'd like to use only
DirectShow methods...
So I tried to use the IAMVfwCompressDialogs interface:
IAMVfwCompressDialogs *pCompressDialog = NULL;
IBaseFilter *pVideoCompressor = NULL;
hr = pVideoCompressor->QueryInterface(IID_IAMVfwCompressDialogs, (void **)
&pCompressDialog);
With that piece of code, I can make the Compressor Dialog to appear, but if
I change the settings nothing happens... (Except for the DivX compressor
which works, but not the bitrate...)
So I'd like to save the parameters of the video compressor to a file, and
to apply these parameters to the video compressor filter just before
connecting it to the GraphFilter...
> Michaël Delva wrote:
>
>> I would like someone to post a code which can load and
>> save parameters of a video codec, such as DivX, with the
>> IAMVfwCompressDialogs Interface and the Set and GetState
>> methods...
>
> See if the following helps you:
>
> http://groups.google.com/groups?selm=O%24qYy2fqCHA.1776%40TK2MSFTNGP10
>
> which refers to:
>
> http://groups.google.com/groups?th=908728ad897d423
>
> http://groups.google.com/groups?th=df9eb79ac6e9589d
>
> http://groups.google.com/groups?th=cdef9149a22f830d
>
>
I have already seen that post, but I don't suceed in using the
SendDriverMessage function...
> So I tried to use the IAMVfwCompressDialogs interface:
>
> IAMVfwCompressDialogs *pCompressDialog = NULL;
> IBaseFilter *pVideoCompressor = NULL;
>
> hr =
>
pVideoCompressor->QueryInterface(IID_IAMVfwCompressDialogs,
> (void **) &pCompressDialog);
>
> With that piece of code, I can make the Compressor Dialog
> to appear, but if I change the settings nothing
> happens... (Except for the DivX compressor which works,
> but not the bitrate...)
What do you do with the IAMVfwCompressDialogs interface
*after* getting a reference to it?
>> So what have you tried, and how has it not worked?
>You're right, I could have begun with that...
>
>I didn't tried ICOpen and ICConfigure... because I'd like to use only
>DirectShow methods...
>
>So I tried to use the IAMVfwCompressDialogs interface:
>
>IAMVfwCompressDialogs *pCompressDialog = NULL;
>IBaseFilter *pVideoCompressor = NULL;
>
>hr = pVideoCompressor->QueryInterface(IID_IAMVfwCompressDialogs, (void **)
>&pCompressDialog);
>
>With that piece of code, I can make the Compressor Dialog to appear,
No, that doesn't make any dialog appear. Code showing that you're gtting
the interface isn't interesting at all. What we need is the code you use
to actually do something with the interface.
>So I'd like to save the parameters of the video compressor to a file, and
>to apply these parameters to the video compressor filter just before
>connecting it to the GraphFilter...
GraphFilter?
--
Be seeing you.
> Michaël Delva wrote:
>
>> So I tried to use the IAMVfwCompressDialogs interface:
>>
>> IAMVfwCompressDialogs *pCompressDialog = NULL;
>> IBaseFilter *pVideoCompressor = NULL;
>>
>> hr =
>>
> pVideoCompressor->QueryInterface(IID_IAMVfwCompressDialogs,
>> (void **) &pCompressDialog);
>>
>> With that piece of code, I can make the Compressor Dialog
>> to appear, but if I change the settings nothing
>> happens... (Except for the DivX compressor which works,
>> but not the bitrate...)
>
> What do you do with the IAMVfwCompressDialogs interface
> *after* getting a reference to it?
>
>
>
Excuse me, I have forgotten a lign of code:
hr = pCompressDialog->ShowDialog(VfwCompressDialog_Config,handle);
handle is the handle of the window which I make the compressor dialog to
appear.
Well, after making the dialog visible, I'd like to save the compressor
parameters to a file, and after I'd like to set these settings to the
compressor, using the GetState and SetState functions...
DWORD cb = SendDriverMessage(ICM_GETSTATE,NULL,0);
LPBYTE pb = new BYTE[cb];
if(ICERR_OK != SendDriverMessage(ICM_GETSTATE,pb,cb)) {
/// ERROR!
}
....
if(ICERR_OK != SendDriverMessage(ICM_SETSTATE,pb,cb)) {
/// ERROR!
}
The ICM driver messages are documented in the "Video for
Windows" section of the Platform SDK. A good example of
direct usage of VCM (=ICM=VfW) codecs is the source code of
VirtualDub (www.virtualdub.org), which uses the VfW function
ICSendMessage() (SendDriverMessage() is the DirectShow
wrapper for ICSendMessage()).
Michaël Delva wrote:
--
Thanks, that was the piece of code I didn't find...
So if I consider there are 3 steps:
Show Dialog
GetState
SetState
In which order should I use them?
> So if I consider there are 3 steps:
> Show Dialog
> GetState
> SetState
>
> In which order should I use them?
GetState() wheh you have a new state to save, which is
usually after you manually configure the codec with
ShowDialog(). SetState() when you have an already saved
state and you want to configure the codec programmatically
instead of manually.
> Michaël Delva wrote:
>
>> So if I consider there are 3 steps:
>> Show Dialog
>> GetState
>> SetState
>>
>> In which order should I use them?
>
> GetState() wheh you have a new state to save, which is
> usually after you manually configure the codec with
> ShowDialog(). SetState() when you have an already saved
> state and you want to configure the codec programmatically
> instead of manually.
>
Well, it's working, but not perfectly: the settings I save in a file are wrong.
For example, if I select the Cinepak Codec by Radius and I choose the Black And White compression, I have in my file the word 'colr' and the compression is made with colors...
Here is my code to save the codec settings:
DWORD cb = pCompressDialog->SendDriverMessage(ICM_GETSTATE,NULL,0);
LPBYTE pb = new BYTE[cb];
hr = pCompressDialog->ShowDialog(VfwCompressDialog_Config,handle);
hr = pCompressDialog->SendDriverMessage(ICM_GETSTATE,(long)pb,cb);
if (FAILED(hr))
ShowMessage("Impossible de récupérer l'état du driver");
AnsiString path_fichier = "H:\\Temp\\codec.txt";
if (FileExists(path_fichier))
DeleteFile(path_fichier);
TFileStream *file = new TFileStream(path_fichier,fmCreate);
file->Write(pb,cb);
delete file;
delete[] pb;
And to load the settings (it's when I construct the Graph to save my video in a file)
hr = pGraph->AddFilter(pVideoCompressor,L"Video Compressor");
if (FAILED(hr))
{
ShowMessage("Impossible d'ajouter le filtre de compression vidéo");
return hr;
}
IAMVfwCompressDialogs *pCompressDialog = NULL;
hr = pVideoCompressor->QueryInterface(IID_IAMVfwCompressDialogs, (void **)&pCompressDialog);
if (FAILED(hr))
{
ShowMessage("Impossible de créer pCompressDialog");
return false;
}
else
{
DWORD cb = pCompressDialog->SendDriverMessage(ICM_GETSTATE,NULL,0);
LPBYTE pb = new BYTE[cb];
TFileStream *file = new TFileStream("H:\\Temp\\codec.txt",fmOpenRead);
file->Read(pb,cb);
delete file;
hr = pCompressDialog->SetState(pb,cb);// SendDriverMessage(ICM_SETSTATE,(long)pb,cb);
if (FAILED(hr))
ShowMessage("Impossible de définir l'état du driver");
delete[] pb;
}
pCompressDialog->Release();
// Loop through the groups and get the output pins.
for (int i = 0; i < NumGroups; i++)
{
IPin *pPin;
if (pRenderEngine->GetGroupOutputPin(i, &pPin) == S_OK)
{
// Connect the pin.
hr = pBuilder->RenderStream(NULL, NULL, pPin, pVideoCompressor, pMux);
pVideoCompressor->Release();
pPin->Release();
}
}
Is the SETSTATE correctly placed in the code?
And what's wrong with all that?
Thanks
Anyway, I would get the state buffer size after showing the
dialog (maybe the size depends on the settings). Also, when
you load the settings, do not get the buffer size from the
codec but from the file size (same reason as before). Last,
the documentation is unclear but I think the HRESULT
returned from SendDriverMessage() is not an HRESULT but the
ICSendMessage() result code: so, ICERR_OK is the same as
S_OK, but other ICM errors will not be FAILED() in the
HRESULT sense, thus I'd explicitly check whether the result
is ICERR_OK).
Michaël Delva wrote:
--
Some of DivX codecs e.g. 5.0.3 version need call ICSetState with NULL
parameters before
call ICSetState with valid data. ( If you work with AVI Compressor,
accordingly, you will need call
IAMVfwCompressDialogs::SetState( NULL, 0 ) )
---
Vsevolod V. Burkutsky
AGAVA Software company
http://dsfilters.agava.com