Log in

View Full Version : Compressor parameter load/save problem and dual pass


mandm
23rd November 2002, 00:09
I'm trying to write a dual pass for M&M.

To load and save the paraemters I use (thank int21h):


void SaveCodecParams(const char* filename, COMPVARS* cvar)
{
LONG lStateSize = 0;
void* memState = NULL;
FILE* fileState = fopen(filename,"wb");

lStateSize = ICGetStateSize(cvar->hic);
memState = malloc(lStateSize);
if (ICGetState(cvar->hic, memState, lStateSize) < 0)
{
_RPTF0(_CRT_WARN,"\tSaveCodecParams\tError ICGetState\n");
return;
}

fwrite(&cvar->fccHandler, sizeof(cvar->fccHandler), 1, fileState);
fwrite(&cvar->lKey, sizeof(cvar->lKey), 1, fileState);
fwrite(&cvar->lQ, sizeof(cvar->lQ), 1, fileState);
fwrite(&cvar->lDataRate, sizeof(cvar->lDataRate), 1, fileState);
fwrite(&lStateSize, sizeof(lStateSize), 1, fileState);
fwrite(memState, lStateSize, 1, fileState);
free(memState);

fclose(fileState);
}

void LoadCodecParams(void)
{
int NbPassFile = 0;
FILE* fileState;

if ((fileState = fopen("M&M Avi 1.par", "r")) != NULL)
ReadCodecParam(fileState, pcompvars); // Read 1st pass codec state
else
ZeroMemory(pcompvars,sizeof(COMPVARS));


if ((fileState = fopen("M&M Avi 2.par", "r")) != NULL)
ReadCodecParam(fileState, pcompvars2); // Read 2st pass codec state
else
ZeroMemory(pcompvars2,sizeof(COMPVARS));
}


The files are created correctly and correctly read.


First point is:
why, after that I have saved and reloaded the data when I perform the:


ZeroMemory(&birgb, sizeof(BITMAPINFOHEADER));
birgb.biSize = sizeof(BITMAPINFOHEADER);
birgb.biWidth = Clip_Width;
birgb.biHeight = Clip_Height;
birgb.biPlanes = 1;
birgb.biBitCount = 24;
birgb.biCompression = BI_RGB;
birgb.biSizeImage = Clip_Width * Clip_Height * 3;
lpbirgb = &birgb;
memcpy_amd(pcvar,pcvar_s,sizeof(COMPVARS));
pcvar->cbSize = sizeof(COMPVARS);
if (ICCompressorChoose(hWnd, ICMF_CHOOSE_DATARATE | ICMF_CHOOSE_KEYFRAME | ICMF_CHOOSE_PREVIEW,
lpbirgb, NULL, pcvar, sZ2))


where pcvar is pcompvars for first pass and pcompvars2 for second pass the properties in the avi codec details is not correct ?

Second
We handle multiple files sequences.
the sequence is
open file 1
first pass
reset parameters
second pass
open file 2
etc...

now for the first file everithing is ok... first pass then second pass (only if I set the parameters not if I reload them from file)
but file 2 will do 2 times "second pass" this even if I switch correctly the parameters.



opts.cbFormat = sizeof(birgb);
opts.fccType = streamtypeVIDEO;
opts.fccHandler = ((do2pass && !is2pass) || (!do2pass)) ? compvars.fccHandler : compvars2.fccHandler;
opts.dwKeyFrameEvery = ((do2pass && !is2pass) || (!do2pass)) ? compvars.lKey : compvars2.lKey;
opts.dwQuality = ((do2pass && !is2pass) || (!do2pass)) ? compvars.lQ : compvars2.lQ;
opts.dwBytesPerSecond = ((do2pass && !is2pass) || (!do2pass)) ? compvars.lDataRate<<10 : compvars2.lDataRate<<10;
opts.dwFlags = AVICOMPRESSF_VALID | AVICOMPRESSF_KEYFRAMES | AVICOMPRESSF_DATARATE;
opts.dwInterleaveEvery = 0;
opts.lpFormat = lpbirgb;
opts.cbParms = ((do2pass && !is2pass) || (!do2pass)) ? compvars.cbState : compvars2.cbState ;
opts.lpParms = ((do2pass && !is2pass) || (!do2pass)) ? compvars.lpState : compvars2.lpState ;

...

if (AVIFileOpen(&pfile, VideoOut, OF_WRITE | OF_CREATE, NULL) != AVIERR_OK)
{
AVIKill();
ThreadKill(1);
}

if (AVIFileCreateStream(pfile, &ps, &strinfo) != AVIERR_OK)
{
AVIKill();
ThreadKill(1);
}

if (AVIMakeCompressedStream(&psCompressed, ps, lpopts, NULL) != AVIERR_OK)
{
AVIKill();
ThreadKill(1);
}


Any help ?
Any idea ?

[Toff]
23rd November 2002, 01:23
To load and save the paraemters I use (thank int21h)


Humm ! And me, am I stinking ? as we say in french.
No, I'm joking ;)
It's more Avery Lee than me that wrote this code.

But I see that you are doing some copy & paste without much understanding what's behind.

1)
You don't have to call ICCompressorChoose when you load the data this way. (I think so because I don't see the code for ReadCodecParam but I have a pretty good idea of how it must look ;))

2) I don't really understand the 2nd point
But I know how to have something a bit cleaner ;)
Why don't you pass a COMPVAR to your save function ?

so instead of :
void MySaveFunction()
{
...
opts.fccHandler = ((do2pass && !is2pass) || (!do2pass)) ? compvars.fccHandler : compvars2.fccHandler;
...
}

you have :

void MySaveFunction(COMPVAR* cvar)
{
...
opts.fccHandler = cvar.fccHandler;
...
}

mandm
24th November 2002, 22:42
Toff,
I need more help:

1)
I have a dialog where I ask the user to configure the codec and then store the configuration in a file.
With the code for int21h I show in the dialog the name of the codec and the FourCC.

So if I :
- open the program,
- configure first pass and second pass
- exit the program

the parameters are saved in 2 files

when I open back the program I reload this files.

In the dialog the name and FourCC are correct but if open the configuration dialog (ICCompressorChoose) of the codec it is not configured.

Now from the .Net help for ICCompressorChoose:

Remarks
Before using this function, set the cbSize member of the COMPVARS structure to the size of the structure. Initialize the rest of the structure to zeros unless you want to specify some valid defaults for the dialog box. If specifying defaults, set the dwFlags member to ICMF_COMPVARS_VALID and initialize the other members of the structure. For more information about initializing the structure, see the ICSeqCompressFrameStart function and COMPVARS.


2)
this is more difficult.
the M&M program allows you to work on sequence of files (just, for example, as VTS_01_xx ;))

If a dual pass compressor is choosen I have to:

- open file 1
- set 1° pass compvars
- perform pass 1
- set 2° pass compvars
- perform pass 2
- close file 1

- open file 2
- set 1° pass compvars
- perform pass 1
- set 2° pass compvars
- perform pass 2
- close file 2

Now on first file it works fine, first pass then 2° pass, avi created is ok.
From file 2 the compressors starts directly in 2° pass even if I have switched back to compvars of first pass.

The code about opts. (in my original post) is about the switching between compvars and compvars2

I do not understand why first time it works (file 1 pass1->pass2), second time (file 1 pass2 -> file 2 pass1) does not.

M&M

mandm
25th November 2002, 12:07
Toff,
I've put online the code (1.1 beta sources)

If you can help us...


.. you are welcome !!! :cool: ;)


M&M