2025-04-27 07:49:33 -04:00

308 lines
6.6 KiB
C++

/*
Copyright (c) 1999 Microsoft Corporation
Module Name:
AVIFileWriter.cpp
Abstract:
Implementation of CAVIFileWriter class
*/
#include "common.h"
#include "AVIFileWriter.h"
///////////////////////////////////////////////////////////////////////////////
//
// CAVIFileWriter::CAVIFileWriter
//
///////////////////////////////////////////////////////////////////////////////
CAVIFileWriter::CAVIFileWriter()
:m_pAVIFile(NULL),
m_pAudioStream(NULL),
m_nSampleSize(0)
{
LogMessage("CAVIFileWriter::CAVIFileWriter");
}
///////////////////////////////////////////////////////////////////////////////
//
// CAVIFileWriter::Initialize
//
// initialize avi library. attempt to create a file with the given name and
// format.
//
// if file creation fails, subsequent calls to write will fail.
//
///////////////////////////////////////////////////////////////////////////////
HRESULT CAVIFileWriter::Initialize(IN const CHAR *pszFileName,
IN const WAVEFORMATEX &WaveFormat)
{
HRESULT hr = S_OK;
//
// if initialization fails, the object's stream and file will be NULL, so
// subsequent Write() calls will fail
//
//
// would do a better argument checking in a real-life application
//
_ASSERTE(pszFileName);
//
// log file name and requested wave format
//
LogMessage("CAVIFileWriter::Initialize started.");
LogMessage(" file [%s] ", pszFileName);
LogFormat(&WaveFormat);
//
// initialize avi file library.
// when done with it, call AVIFileExit should be called on the same thread
//
AVIFileInit();
//
// create file
//
hr = AVIFileOpen(&m_pAVIFile,
pszFileName,
OF_WRITE | OF_CREATE | OF_SHARE_DENY_WRITE,
NULL);
if (FAILED(hr))
{
LogError("CAVIFileWriter::Initialize Failed to create file %s",
pszFileName);
m_pAVIFile = NULL;
return hr;
}
//
// fill in stream information
//
AVISTREAMINFO StreamInfo;
memset(&StreamInfo, 0, sizeof(StreamInfo));
StreamInfo.fccType = streamtypeAUDIO;
StreamInfo.dwQuality = -1;
m_nSampleSize = StreamInfo.dwSampleSize = WaveFormat.nBlockAlign;
strcpy(&StreamInfo.szName[0], "test audio stream");
//
// add an audio stream to the file
//
hr = AVIFileCreateStream(m_pAVIFile, &m_pAudioStream, &StreamInfo);
if (FAILED(hr))
{
LogError("CAVIFileWriter::CAVIFileWriter "
"failed to create audio stream");
AVIFileRelease(m_pAVIFile);
m_pAVIFile = NULL;
return hr;
}
//
// set format for the stream
//
hr = AVIStreamSetFormat(m_pAudioStream,
0,
(void*)&WaveFormat,
sizeof(WaveFormat) + WaveFormat.cbSize);
if ( FAILED(hr))
{
LogError("Failed to set stream format");
AVIFileRelease(m_pAVIFile);
m_pAVIFile = NULL;
AVIStreamRelease(m_pAudioStream);
m_pAudioStream = NULL;
return hr;
}
LogMessage("CAVIFileWriter::Initialize succeeded");
return S_OK;
}
///////////////////////////////////////////////////////////////////////////////
//
// CAVIFileWriter::~CAVIFileWriter
//
// if the file and stream were open, close them.
//
// uninitialize AVI library
//
///////////////////////////////////////////////////////////////////////////////
CAVIFileWriter::~CAVIFileWriter()
{
LogMessage("CAVIFileWriter::~CAVIFileWriter started");
if (NULL != m_pAudioStream)
{
AVIStreamRelease(m_pAudioStream);
m_pAudioStream = NULL;
}
if (NULL != m_pAVIFile)
{
AVIFileRelease(m_pAVIFile);
m_pAVIFile = NULL;
}
//
// uninitialize avi file libraries
//
AVIFileExit();
LogMessage("CAVIFileWriter::~CAVIFileWriter finished");
}
///////////////////////////////////////////////////////////////////////////////
//
// CAVIFileWriter::Write
//
// write the buffer into the open stream. return the number of bytes recorded.
//
// return S_OK on success, error code on failure
//
///////////////////////////////////////////////////////////////////////////////
HRESULT CAVIFileWriter::Write(IN BYTE *pBuffer,
IN ULONG nBytesToWrite,
IN OUT ULONG *pnBytesWritten)
{
if ( (NULL == m_pAudioStream) || (NULL == m_pAVIFile))
{
LogError("CAVIFileWriter::Write file or stream is not open");
return E_UNEXPECTED;
}
//
// AVIStreamWrite wants the number of samples we are recording
//
LONG nSamples2Write = nBytesToWrite / m_nSampleSize;
//
// write to file until dumped the whole buffer of until failure
//
HRESULT hr = S_OK;
ULONG nTotalBytesWritten = 0;
while ((hr == S_OK) && (nTotalBytesWritten < nBytesToWrite))
{
//
// bytes and samples written with the call
//
LONG nBytesWritten = 0;
LONG nSamplesWritten = 0;
hr = AVIStreamWrite(m_pAudioStream,
-1, // append at the end of the stream
nSamples2Write, // how many samples to write
pBuffer, // where the data is
nBytesToWrite, // how much data do we have
AVIIF_KEYFRAME, // self-sufficient data
&nSamplesWritten,// how many samples were written
&nBytesWritten); // how many bytes were written
//
// keep track of how many bytes made it into the file
//
nTotalBytesWritten += nBytesWritten;
}
//
// will return the number of bytes written
//
if (NULL != pnBytesWritten)
{
*pnBytesWritten = nTotalBytesWritten;
}
//
// either dumped the whole buffer or failed.
//
if (FAILED(hr))
{
LogError("CAVIFileWriter::Write Failed to write buffer hr = 0x%lx, "
"wrote %ld bytes", hr, nTotalBytesWritten);
}
else
{
LogMessage("CAVIFileWriter::Write Succeeded. Wrote %ld bytes",
nTotalBytesWritten);
}
return hr;
}