AviFile.cpp
上传用户:xjjlds
上传日期:2015-12-05
资源大小:22823k
文件大小:15k
- #include "StdAfx.h"
- #include "AviFile.h"
- //
- // CAviFile
- //
- CAviFile::CAviFile(IAsyncReader* pAsyncReader, HRESULT& hr)
- : CBaseSplitterFile(pAsyncReader, hr)
- {
- if(FAILED(hr)) return;
- hr = Init();
- }
- template<typename T>
- HRESULT CAviFile::Read(T& var, int offset)
- {
- memset(&var, 0, sizeof(var));
- HRESULT hr = Read((BYTE*)&var + offset, sizeof(var) - offset);
- return hr;
- }
- HRESULT CAviFile::Init()
- {
- Seek(0);
- DWORD dw[3];
- if(S_OK != Read(dw) || dw[0] != FCC('RIFF') || (dw[2] != FCC('AVI ') && dw[2] != FCC('AVIX')))
- return E_FAIL;
- Seek(0);
- HRESULT hr = Parse(0, GetLength());
- if(m_movis.GetCount() == 0) // FAILED(hr) is allowed as long as there was a movi chunk found
- return E_FAIL;
- if(m_avih.dwStreams == 0 && m_strms.GetCount() > 0)
- m_avih.dwStreams = m_strms.GetCount();
- if(m_avih.dwStreams != m_strms.GetCount())
- return E_FAIL;
- for(int i = 0; i < (int)m_avih.dwStreams; i++)
- {
- strm_t* s = m_strms[i];
- if(s->strh.fccType != FCC('auds')) continue;
- WAVEFORMATEX* wfe = (WAVEFORMATEX*)s->strf.GetData();
- if(wfe->wFormatTag == 0x55 && wfe->nBlockAlign == 1152
- && s->strh.dwScale == 1 && s->strh.dwRate != wfe->nSamplesPerSec)
- {
- // correcting encoder bugs...
- s->strh.dwScale = 1152;
- s->strh.dwRate = wfe->nSamplesPerSec;
- }
- }
- if(FAILED(BuildIndex()))
- EmptyIndex();
- return S_OK;
- }
- HRESULT CAviFile::Parse(DWORD parentid, __int64 end)
- {
- HRESULT hr = S_OK;
- CAutoPtr<strm_t> strm;
- while(S_OK == hr && GetPos() < end)
- {
- UINT64 pos = GetPos();
- DWORD id = 0, size;
- if(S_OK != Read(id) || id == 0)
- return E_FAIL;
- if(id == FCC('RIFF') || id == FCC('LIST'))
- {
- if(S_OK != Read(size) || S_OK != Read(id))
- return E_FAIL;
- size += (size&1) + 8;
- TRACE(_T("CAviFile::Parse(..): LIST '%c%c%c%c'n"),
- TCHAR((id>>0)&0xff),
- TCHAR((id>>8)&0xff),
- TCHAR((id>>16)&0xff),
- TCHAR((id>>24)&0xff));
- if(id == FCC('movi'))
- {
- m_movis.AddTail(pos);
- }
- else
- {
- hr = Parse(id, pos + size);
- }
- }
- else
- {
- if(S_OK != Read(size))
- return E_FAIL;
- TRACE(_T("CAviFile::Parse(..): '%c%c%c%c'n"),
- TCHAR((id>>0)&0xff),
- TCHAR((id>>8)&0xff),
- TCHAR((id>>16)&0xff),
- TCHAR((id>>24)&0xff));
- if(parentid == FCC('INFO') && size > 0)
- {
- switch(id)
- {
- case FCC('IARL'): // Archival Location. Indicates where the subject of the file is archived.
- case FCC('IART'): // Artist. Lists the artist of the original subject of the file; for example, 揗ichaelangelo.