How to encode video using VFW?

Tech-Archive recommends: Repair Windows Errors & Optimize Windows Performance



Hi,

I've some problems with Video For Windows library, I looked previous posts
and couldn't find any relevant post...

I want to compress an uncompressed video file using mpeg2. After some search
it seems that Video For Windows (VFW) is suitable for the job. (I'm using
Visual c++ 6)

I have implemented some piece of code according to below pattern,

First, please have a look at the pattern and inform me if there is any
conceptual mistake.

1. select codec
2. open input video
3. get input video stream
4. get input video's stream format
5. get output video's stream format (by ICCompressGetFormat)
6. create output file
7. create output stream (how to fill avistreaminfo struct correctly?)
8. get frames by one by, compress frame, write compressed frame to
outputStream
9. Close streams and files...


I have written some piece of code but I have some diffuculties in filling
lots of header/information headers.
As a result my code compressed an uncompressed avi of 162 mbs into 165 mbs
and the video quality is awful::(

Here is the code,
What is the bug(s) ?
--------------------------------------

#define RETURN_IF_ERR(hr) if(hr!=0) \
void CVideoCapDlg::OnCodecSelect()
{
_pc.cbSize = sizeof(COMPVARS);

if (TRUE == ICCompressorChoose( NULL, ICMF_CHOOSE_ALLCOMPRESSORS, NULL,
NULL, &_pc, "Select Compressor"))
{


}else
{
// Codec did not selected
}

}


void CVideoCapDlg::OnCompress()
{
LONG hr;

char * cpInFileName = "video.avi";
char * cpOutFileName = "videoOut.avi";
PAVIFILE pInFile;
PAVIFILE pOutFile;
AVIFILEINFO pInFileInf;
PAVISTREAM pInStream;
PAVISTREAM pOutStream;
AVISTREAMINFO pOutStreamInf;

// open AVIFile library
AVIFileInit();

// open input avi file
hr = AVIFileOpen(&pInFile, cpInFileName, OF_SHARE_DENY_WRITE, NULL);
RETURN_IF_ERR(hr)

// get file info
hr = AVIFileInfo(pInFile, &pInFileInf, sizeof(AVIFILEINFO));
RETURN_IF_ERR(hr)


// get video stream
hr = AVIFileGetStream( pInFile, &pInStream, streamtypeVIDEO, 0);
RETURN_IF_ERR(hr)

// fill input stream bitmapInfoHeader
// size is set as sizeof(BITMAPINFOHEADER) bec we only want header info

LPBITMAPINFO pBitmapInfoIn = new BITMAPINFO();
long iHeaderSize = sizeof(BITMAPINFO);
hr = AVIStreamReadFormat( pInStream , 0,(void*) pBitmapInfoIn,
&iHeaderSize);
RETURN_IF_ERR(hr)

// get compressor output format
LPBITMAPINFO pBitmapInfoOut = new BITMAPINFO();
hr = ICCompressGetFormat(_pc.hic, pBitmapInfoIn, pBitmapInfoOut); //
get format
RETURN_IF_ERR(hr)

// is conversion possible?
DWORD res;
res = ICCompressQuery(_pc.hic, (LPBITMAPINFO) pBitmapInfoIn,
(LPBITMAPINFO)pBitmapInfoOut);
if (res==ICERR_BADFORMAT)
return;

// get frame start and count

int iFrameStart = AVIStreamStart(pInStream);
int iFrameCount = AVIStreamLength(pInStream);
int iFrameOffset = 0;

// open video stream for frame grab
PGETFRAME pFrameHandler ;
pFrameHandler = AVIStreamGetFrameOpen(pInStream, NULL);

// COMPRESS VIDEO STREAMS

// Find the worst-case buffer size used in compression.
DWORD dwCompressBufferSize = ICCompressGetSize(_pc.hic, pBitmapInfoIn,
pBitmapInfoOut);


// create output avi file
AVISTREAMINFO si;

hr = AVIFileOpen(&pOutFile, cpOutFileName, OF_WRITE | OF_CREATE, NULL);
RETURN_IF_ERR(hr)

ZeroMemory((LPVOID)&pOutStreamInf,sizeof(pOutStreamInf));
pOutStreamInf.fccType = streamtypeVIDEO;
pOutStreamInf.fccHandler = _pc.fccHandler;
pOutStreamInf.dwScale = 10000;
pOutStreamInf.dwRate = 300000;
pOutStreamInf.dwQuality = 10000;
pOutStreamInf.dwLength = 375;
pOutStreamInf.dwSuggestedBufferSize = dwCompressBufferSize ;

hr = AVIFileCreateStream(pOutFile, &pOutStream, &pOutStreamInf);
RETURN_IF_ERR(hr)

hr = AVIStreamSetFormat( pOutStream,0,pBitmapInfoOut,
sizeof(BITMAPINFOHEADER));
RETURN_IF_ERR(hr)

AVIStreamInfo( pOutStream, &si, sizeof(si));


// Allocate a buffer and get lpOutput to point to it.
HGLOBAL h = GlobalAlloc(GHND, dwCompressBufferSize);
LPVOID lpOutputBuffer = (LPVOID)GlobalLock(h);

LPVOID frame;
DWORD dwCkID;
DWORD dwCompFlags;
DWORD dwFlags = 0;

LPVOID lpNew = GlobalAlloc(GMEM_MOVEABLE,
pBitmapInfoOut->bmiHeader.biSizeImage);


if (ICCompressBegin(_pc.hic, pBitmapInfoIn, pBitmapInfoOut) == ICERR_OK)
{

while( (frame = AVIStreamGetFrame(pFrameHandler,iFrameStart +
iFrameOffset)) != NULL)
{


if (ICCompress( _pc.hic, dwFlags , &pBitmapInfoOut->bmiHeader,
lpOutputBuffer,&pBitmapInfoIn->bmiHeader , frame,
&dwCkID, &dwCompFlags, iFrameOffset,
0, 0, NULL, NULL) == ICERR_OK)
{


hr = AVIStreamWrite(pOutStream, iFrameOffset , 1,lpOutputBuffer ,
dwCompressBufferSize, 0 ,
NULL, NULL);

}
else
{
return;
}

iFrameOffset++;
}

AVIStreamRelease(pOutStream);
AVIFileRelease(pOutFile);


ICCompressEnd(_pc.hic); // terminate compression
}
else
{
// Handle the error identifying the unsupported format.
}
AVIStreamRelease(pInStream);
AVIFileRelease(pInFile);
delete pBitmapInfoIn;
delete pBitmapInfoOut;
}



.



Relevant Pages

  • Re: how to use third party codecs with windows media encoder
    ... not the stream. ... uncompressed RGB on the video pin and compress it? ... You can not use the ASFWMWriter filter ...
    (microsoft.public.win32.programmer.directx.video)
  • Re: VMR Mixing Mode and Seeking Problem
    ... decoder's output pin, and called SetStreamActiveState*before* ... passing BeginFlush downstream to the VMR. ... the VMR connected to the 2nd video stream has ...
    (microsoft.public.win32.programmer.directx.video)
  • Re: Digital Signage, Multimedia Steaming etc.
    ... A full featured video editing software is a major undertaking imo. ... However if you need to stream different video streams to each client, ... simultanious clients is no small task. ... 4.There will be 5-10 distribution servers. ...
    (borland.public.delphi.thirdpartytools.general)
  • Re: Stream DVDs with full dolby digital from vob files possible? (extenders?)
    ... stream to some device.. ... DVD or more than 60 hours of HD video from your camera. ... when i switch to the tv in the livingroom, ... if i were stuck using a keyboard out in the living ...
    (alt.video.dvd)
  • Re: Skywise
    ... That last one is very funny to hear coming from a bird. ... Keep up the good work with the video. ... there was so much salmon that they could cross the stream on ... reaches of the main stream is a step in the right direction. ...
    (sci.geo.geology)