PDA

View Full Version : how to save an avi file without recompressing (AVIFile API)? just saving raw stream?


xtknight
3rd June 2005, 19:46
EDIT: Alright I think I got EditStreamClone to work. Now how can I save the AVI file without recompressing it? :confused: I have called AVIMakeFileFromStreams() and have a pFile2 variable waiting to be written directly to an AVI file.

Sirber
3rd June 2005, 20:03
I'd be interrested by this tool to repair AVIs prior encoding.

xtknight
3rd June 2005, 20:15
I'd be interrested by this tool to repair AVIs prior encoding.

Yup thats one possible application for it...good to know. Well if I can get some code I'll include whomever gives it to me in my readme credits and this tool should be out the door soon thereafter. Freeware, open source under the GPL license of course. ;)

Sirber
3rd June 2005, 20:52
Why not using VDub code?

xtknight
3rd June 2005, 21:09
Why not using VDub code?

Hmm...well I'd prefer AVIFile because it's easier to use. I think VDub writes the chunks manually which is a little over my head. I don't want to copy VDub's method verbatim, especially if there's AVIFile code to do it just as well, but a lot easier to understand.

tarkvara
26th March 2006, 23:52
Did you ever figure out a way to do this? I'm trying to do the same thing, and it would be nice to use AVIFile to accomplish that.

xtknight
27th March 2006, 03:31
Nope, I never did figure it out. :(

Inc
27th March 2006, 11:39
Do open an avi via AviFileOpen, get the streamhandle by AvifileGetStream and later do use Avisafe (http://msdn.microsoft.com/library/default.asp?url=/library/en-us/multimed/htm/_win32_avisave.asp)
to write the video stream as raw video data into the target avifile.

PS: Im not shure if this workout also inkludes the decompressing to RAW data or if it just dumps the source videodata in its compressed state to the target avi.

tarkvara
28th March 2006, 00:35
Im not shure if this workout also inkludes the decompressing to RAW data or if it just dumps the source videodata in its compressed state to the target avi.

I can get this part to work. The problem I have is that calling AVISave will recompress the file. The footage I have has already been compressed, and I just want to save it (with a few edits) into a new file without recompressing it.

Or am I missing something obvious here? Is there a way to tell AVISave to not do any recompression?

Thanks,

E.

Inc
28th March 2006, 09:14
Do pass arguments to a Avicompressoptions structure directly:
http://msdn.microsoft.com/library/default.asp?url=/library/en-us/multimed/htm/_win32_avicompressoptions_str.asp

Or you can choose AviSaveOptions which fills out the structure mentioned above
http://msdn.microsoft.com/library/default.asp?url=/library/en-us/multimed/htm/_win32_avisaveoptions.asp
When using this a dialogbox appears where you can choose the target compression code, from there you could choose a raw format or i.E. HuffYUV etc.

squid_80
28th March 2006, 09:31
I can get this part to work. The problem I have is that calling AVISave will recompress the file. The footage I have has already been compressed, and I just want to save it (with a few edits) into a new file without recompressing it.

Or am I missing something obvious here? Is there a way to tell AVISave to not do any recompression?

Thanks,

E.
Here's how I'd do it:
Call AVIFileInit.
Call AVIFileOpen to create a new file (returns PAVFILE*).
Call AVIFileCreateStream to make a new stream (requires an AVISTREAMINFO struct to describe the stream).
Call AVIStreamSetFormat to write a format header to match whatever compression is being used.
Call AVIStreamWrite for each frame.
Call (in order) AVIStreamRelease, AVIFileRelease, AVIFileExit.

Bester
29th March 2006, 10:42
Here is some code, opening and saving...
Your first frame should be an I-frame. If not the B or P frames can't be reconstructed. DV-video works fine.

case 20000:
{
//MessageBox(hwnd," Open AVI ","Information",MB_OK | MB_ICONINFORMATION);

AVIFileOpen(&pAviIn, "C:\\...\\Test.avi", OF_READ, NULL);

rc = AVIFileInfo(pAviIn, &pFileInfo, sizeof(AVIFILEINFO));
int i;
for (i = 0; i < pFileInfo.dwStreams; i++)
{
rc = AVIFileGetStream(pAviIn, &pAviStream, 0L, i);
if (rc) break;

rc = AVIStreamInfo(pAviStream, &StreamInfo, sizeof(AVISTREAMINFO));
if (StreamInfo.fccType == streamtypeVIDEO)
pVideoStream = pAviStream;
else if (StreamInfo.fccType == streamtypeAUDIO)
pAudioStream = pAviStream;
}
//if(pVideoStream != 0) MessageBox(hwnd," AVI opened. ","Information",MB_OK | MB_ICONINFORMATION);
bFileOpen = TRUE;

pVideoFrame = AVIStreamGetFrameOpen(pVideoStream, (LPBITMAPINFOHEADER)AVIGETFRAMEF_BESTDISPLAYFMT);

hDrawDibDC = DrawDibOpen();

InvalidateRect(hwnd,0,TRUE);
}

break;

case 20002:
{
LONG nAviStreams = 0L; // number of pAviStreams[];
PAVISTREAM pStreams[2] = { NULL, NULL };
PAVISTREAM pAviTmpStream = NULL;

AVICOMPRESSOPTIONS Options[2];
LPAVICOMPRESSOPTIONS pOptions[2];

AVIFILEINFO pFileInfo;
AVISTREAMINFO pStreamInfo;

AVIFILEINFO pFileInfo2;
AVISTREAMINFO pStreamInfo2;


//AVIFileOpen(&pAviOut, "AviCopy.avi", OF_CREATE|OF_WRITE, NULL);
//pStreams[0] = pVideoStream;

LPVOID frame_format;
LONG frame_format_size;
char msg2[50] = "";

AVIStreamReadFormat(pVideoStream, 0, 0, &frame_format_size);
sprintf(msg2,"FormatSize: %ld ",frame_format_size);
MessageBox(0,msg2,"",MB_OK);
frame_format = malloc(frame_format_size);
AVIStreamReadFormat(pVideoStream, 0, frame_format, &frame_format_size);

AVIFileOpen(&pAviOut, "AviStreamCreate.avi", OF_CREATE|OF_WRITE, NULL);
AVIStreamInfo(pVideoStream, &pStreamInfo, sizeof(AVISTREAMINFO));
sprintf(msg2,"InfoTest: %d ",pStreamInfo.rcFrame.right );
MessageBox(0,msg2,"",MB_OK);

AVIFileCreateStream(pAviOut, &pAviTmpStream, &pStreamInfo);
AVIStreamSetFormat(pAviTmpStream, 0, frame_format, frame_format_size);

LPVOID frame = 0;
LONG frame_size;
int n = 0;
while(AVIStreamRead(pVideoStream, n, 1, NULL, 0, &frame_size, NULL) == 0 && n < 10)
{
frame = malloc(frame_size);
//sprintf(msg2,"FrameSize: %ld ",frame_size);
//MessageBox(0,msg2,"",MB_OK);
AVIStreamRead(pVideoStream, n, 1, frame, frame_size, NULL, NULL);
if(AVIStreamIsKeyFrame(pAviStream, n))
{
AVIStreamWrite(pAviTmpStream, n, 1, frame, frame_size, AVIIF_KEYFRAME, NULL, NULL);
//MessageBox(0,"Key","",MB_OK);
}
else
{
AVIStreamWrite(pAviTmpStream, n, 1, frame, frame_size, 0, NULL, NULL);
}
free(frame);
frame = 0;
n++;
sprintf(msg2,"Frame: %ld ",n);
SetWindowText(hwnd,msg2);
}
sprintf(msg2,"Anzahl Frames: %d ",n);
MessageBox(0,msg2,"",MB_OK);
free(frame_format);
AVIStreamRelease(pAviTmpStream);
/*// get save (compression) options
int i;
for (i = 0; i < 1; i++)
{
// AVISaveOptions takes an array of pointers to our
// compression options (cleared)
pOptions[i] = &Options[i];
memset(pOptions[i], 0, sizeof(AVICOMPRESSOPTIONS));
}

AVISaveOptions(hwnd, 0, 1,pStreams,pOptions);

AVISave("AviEdit.avi", NULL, SaveCallback, 1,pStreams[0], pOptions[0]);
AVISaveOptionsFree(1, pOptions);*/

AVIFileRelease(pAviOut);

}

break;

squid_80
29th March 2006, 11:31
Not really sure about the last part of your example... It all makes sense with the AVIFileCreateStream and AVIStreamWrite calls up until AVIStreamRelease... But then you start doing stuff with what appears to be uninitialized arrays and making AVISave calls when AviStreamCreate.avi should already have been written for you...

Bester
29th March 2006, 12:00
The AVISave stuff is commented out and redundant, it was part of some earlier tests... So u can delete this:

/*// get save (compression) options
int i;
for (i = 0; i < 1; i++)
{
// AVISaveOptions takes an array of pointers to our
// compression options (cleared)
pOptions[i] = &Options[i];
memset(pOptions[i], 0, sizeof(AVICOMPRESSOPTIONS));
}

AVISaveOptions(hwnd, 0, 1,pStreams,pOptions);

AVISave("AviEdit.avi", NULL, SaveCallback, 1,pStreams[0], pOptions[0]);
AVISaveOptionsFree(1, pOptions);*/

squid_80
29th March 2006, 12:10
Sorry I didn't see the comment start/ends.