AxibugEmuOnline/References/virtuanessrc097-master/AviWriter.cpp
2024-08-05 17:58:53 +08:00

230 lines
12 KiB
C++
Raw Permalink Blame History

This file contains invisible Unicode characters

This file contains invisible Unicode characters that are indistinguishable to humans but may be processed differently by a computer. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

//
// AVI File Writer
//
#include "aviwriter.h"
#include "macro.h"
#pragma comment(lib, "vfw32.lib")
CAVIWriter::CAVIWriter() :
m_pAviFile(NULL),
m_pVideoStream(NULL),
m_pAudioStream(NULL),
m_pVideoStreamCompress(NULL),
m_pVideoFormat(NULL),
m_FrameNumber(0),
m_SampleNumber(0)
{
::AVIFileInit();
ZEROMEMORY( &m_VideoStreamInfo, sizeof(m_VideoStreamInfo) );
m_VideoStreamInfo.fccType = streamtypeVIDEO;
m_VideoStreamInfo.fccHandler = comptypeDIB;
m_VideoStreamInfo.dwQuality = (DWORD)-1;
// default formats
SetAudioFormat( 44100, 16, 1 );
SetFrameRate( 100, 60*100 );
ZEROMEMORY( &m_VideoOption, sizeof(m_VideoOption) );
m_VideoOption.fccType = streamtypeVIDEO;
m_VideoOption.fccHandler = comptypeDIB;
ZEROMEMORY( &m_Compvers, sizeof(m_Compvers) );
m_Compvers.cbSize = sizeof(COMPVARS);
m_Compvers.dwFlags = ICMF_COMPVARS_VALID;
m_Compvers.fccHandler = comptypeDIB;
m_Compvers.lQ = ICQUALITY_DEFAULT;
m_Compvers.lKey = 15;
}
CAVIWriter::~CAVIWriter()
{
Close();
::AVIFileExit();
}
bool CAVIWriter::Open( const char* fname )
{
if( !m_pVideoFormat )
return false;
::DeleteFile( fname );
if( ::AVIFileOpen( &m_pAviFile, fname, OF_WRITE | OF_CREATE, NULL ) ) {
return false;
}
// Video Stream
if( ::AVIFileCreateStream( m_pAviFile, &m_pVideoStream, &m_VideoStreamInfo ) ) {
Close();
return false;
}
if( ::AVIMakeCompressedStream( &m_pVideoStreamCompress, m_pVideoStream, &m_VideoOption, NULL ) != AVIERR_OK ) {
Close();
return false;
}
if( ::AVIStreamSetFormat( m_pVideoStreamCompress, 0, m_pVideoFormat, m_pVideoFormat->biSize + m_pVideoFormat->biClrUsed * sizeof(RGBQUAD) ) ) {
Close();
return false;
}
// Audio Stream
if( ::AVIFileCreateStream( m_pAviFile, &m_pAudioStream, &m_AudioStreamInfo ) ) {
Close();
return false;
}
if( ::AVIStreamSetFormat( m_pAudioStream, 0, &m_AudioFormat, sizeof(WAVEFORMATEX) ) ) {
Close();
return false;
}
m_FrameNumber = 0;
m_SampleNumber = 0;
return true;
}
void CAVIWriter::Close()
{
if( m_pAudioStream ) {
::AVIStreamClose( m_pAudioStream );
m_pAudioStream = NULL;
}
if( m_pVideoStreamCompress ) {
::AVIStreamClose( m_pVideoStreamCompress );
m_pVideoStreamCompress = NULL;
}
if( m_pVideoStream ) {
::AVIStreamClose( m_pVideoStream );
m_pVideoStream = NULL;
}
if( m_pAviFile ) {
::AVIFileClose( m_pAviFile );
m_pAviFile = NULL;
}
}
bool CAVIWriter::SelectVideoFormat( HWND hWnd )
{
m_Compvers.dwFlags = ICMF_COMPVARS_VALID;
m_Compvers.lpState = NULL;
m_Compvers.cbState = 0;
if( !::ICCompressorChoose( hWnd, ICMF_CHOOSE_DATARATE | ICMF_CHOOSE_KEYFRAME,
m_pVideoFormat, NULL, &m_Compvers, NULL) )
return false;
m_VideoStreamInfo.fccHandler = m_Compvers.fccHandler;
ZEROMEMORY( &m_VideoOption, sizeof(m_VideoOption) );
m_VideoOption.fccType = streamtypeVIDEO;
m_VideoOption.fccHandler = m_Compvers.fccHandler;
m_VideoOption.dwKeyFrameEvery = m_Compvers.lKey;
m_VideoOption.dwQuality = m_Compvers.lQ;
m_VideoOption.dwBytesPerSecond = m_Compvers.lDataRate;
m_VideoOption.dwFlags = ((m_Compvers.lDataRate > 0) ? AVICOMPRESSF_DATARATE : 0)
|((m_Compvers.lKey > 0 ) ? AVICOMPRESSF_KEYFRAMES : 0);
::ICCompressorFree( &m_Compvers );
return true;
}
void CAVIWriter::SetVideoFormat( BITMAPINFOHEADER* bih )
{
m_pVideoFormat = bih;
}
void CAVIWriter::SetAudioFormat( const DWORD rate, const WORD bits, const INT channels )
{
m_AudioFormat.wFormatTag = WAVE_FORMAT_PCM;
m_AudioFormat.nSamplesPerSec = rate;
m_AudioFormat.wBitsPerSample = bits;
m_AudioFormat.nChannels = channels;
m_AudioFormat.nBlockAlign = m_AudioFormat.nChannels * m_AudioFormat.wBitsPerSample / 8;
m_AudioFormat.nAvgBytesPerSec = m_AudioFormat.nSamplesPerSec * m_AudioFormat.nBlockAlign;
m_AudioFormat.cbSize = 0;
ZEROMEMORY( &m_AudioStreamInfo, sizeof(m_AudioStreamInfo) );
m_AudioStreamInfo.fccType = streamtypeAUDIO;
// m_AudioStreamInfo.fccHandler = comptypeDIB;
m_AudioStreamInfo.fccHandler = m_AudioFormat.wFormatTag;
m_AudioStreamInfo.dwScale = m_AudioFormat.nBlockAlign;
m_AudioStreamInfo.dwInitialFrames = 1;
m_AudioStreamInfo.dwRate = m_AudioFormat.nAvgBytesPerSec;
m_AudioStreamInfo.dwQuality = (DWORD)-1;
m_AudioStreamInfo.dwSampleSize = m_AudioFormat.nBlockAlign;
}
void CAVIWriter::SetFrameRate( const DWORD scale, const DWORD rate )
{
m_FrameRate = rate;
// ZEROMEMORY( &m_VideoStreamInfo, sizeof(m_VideoStreamInfo) );
// m_VideoStreamInfo.fccType = streamtypeVIDEO;
// m_VideoStreamInfo.fccHandler = comptypeDIB;
m_VideoStreamInfo.dwScale = scale;
m_VideoStreamInfo.dwRate = rate;
// m_VideoStreamInfo.dwQuality = (DWORD)-1;
}
bool CAVIWriter::WriteVideo( const char* video )
{
if( !m_pAviFile )
return false;
#if 0
DWORD dwFlags = 0;
if( m_VideoOption.dwFlags & AVICOMPRESSF_KEYFRAMES ) {
if( (m_FrameNumber % m_VideoOption.dwKeyFrameEvery) == 0 ) {
dwFlags = AVIIF_KEYFRAME;
}
}
if( ::AVIStreamWrite( m_pVideoStreamCompress, m_FrameNumber, 1, (void*)video,
m_pVideoFormat->biSizeImage, dwFlags, NULL, NULL ) ) {
Close();
return false;
}
#else
if( ::AVIStreamWrite( m_pVideoStreamCompress, m_FrameNumber, 1, (void*)video,
m_pVideoFormat->biSizeImage, AVIIF_KEYFRAME, NULL, NULL ) ) {
Close();
return false;
}
#endif
m_FrameNumber++;
return true;
}
bool CAVIWriter::WriteAudio( const char* audio, const int length )
{
if( !m_pAviFile )
return false;
int samples = length / m_AudioFormat.nBlockAlign;
if( ::AVIStreamWrite( m_pAudioStream, m_SampleNumber, samples, (void*)audio,
length, 0, NULL, NULL ) ) {
Close();
return false;
}
m_SampleNumber += samples;
return true;
}
bool CAVIWriter::WriteFrame( const char* video, const char* audio, const int length )
{
if( !WriteVideo( video ) )
return false;
if( !WriteAudio( audio, length ) )
return false;
return true;
}