AviFile.cpp
上传用户:xjjlds
上传日期:2015-12-05
资源大小:22823k
文件大小:15k
源码类别:

多媒体编程

开发平台:

Visual C++

  1. #include "StdAfx.h"
  2. #include "AviFile.h"
  3. //
  4. // CAviFile
  5. //
  6. CAviFile::CAviFile(IAsyncReader* pAsyncReader, HRESULT& hr)
  7. : CBaseSplitterFile(pAsyncReader, hr)
  8. {
  9. if(FAILED(hr)) return;
  10. hr = Init();
  11. }
  12. template<typename T> 
  13. HRESULT CAviFile::Read(T& var, int offset)
  14. {
  15. memset(&var, 0, sizeof(var));
  16. HRESULT hr = Read((BYTE*)&var + offset, sizeof(var) - offset);
  17. return hr;
  18. }
  19. HRESULT CAviFile::Init()
  20. {
  21. Seek(0);
  22. DWORD dw[3];
  23. if(S_OK != Read(dw) || dw[0] != FCC('RIFF') || (dw[2] != FCC('AVI ') && dw[2] != FCC('AVIX')))
  24. return E_FAIL;
  25. Seek(0);
  26. HRESULT hr = Parse(0, GetLength());
  27. if(m_movis.GetCount() == 0) // FAILED(hr) is allowed as long as there was a movi chunk found
  28. return E_FAIL;
  29. if(m_avih.dwStreams == 0 && m_strms.GetCount() > 0)
  30. m_avih.dwStreams = m_strms.GetCount();
  31. if(m_avih.dwStreams != m_strms.GetCount())
  32. return E_FAIL;
  33. for(int i = 0; i < (int)m_avih.dwStreams; i++)
  34. {
  35. strm_t* s = m_strms[i];
  36. if(s->strh.fccType != FCC('auds')) continue;
  37. WAVEFORMATEX* wfe = (WAVEFORMATEX*)s->strf.GetData();
  38. if(wfe->wFormatTag == 0x55 && wfe->nBlockAlign == 1152 
  39. && s->strh.dwScale == 1 && s->strh.dwRate != wfe->nSamplesPerSec)
  40. {
  41. // correcting encoder bugs...
  42. s->strh.dwScale = 1152;
  43. s->strh.dwRate = wfe->nSamplesPerSec;
  44. }
  45. }
  46. if(FAILED(BuildIndex()))
  47. EmptyIndex();
  48. return S_OK;
  49. }
  50. HRESULT CAviFile::Parse(DWORD parentid, __int64 end)
  51. {
  52. HRESULT hr = S_OK;
  53. CAutoPtr<strm_t> strm;
  54. while(S_OK == hr && GetPos() < end)
  55. {
  56. UINT64 pos = GetPos();
  57. DWORD id = 0, size;
  58. if(S_OK != Read(id) || id == 0)
  59. return E_FAIL;
  60. if(id == FCC('RIFF') || id == FCC('LIST'))
  61. {
  62. if(S_OK != Read(size) || S_OK != Read(id))
  63. return E_FAIL;
  64. size += (size&1) + 8;
  65. TRACE(_T("CAviFile::Parse(..): LIST '%c%c%c%c'n"), 
  66. TCHAR((id>>0)&0xff), 
  67. TCHAR((id>>8)&0xff), 
  68. TCHAR((id>>16)&0xff),
  69. TCHAR((id>>24)&0xff));
  70. if(id == FCC('movi'))
  71. {
  72. m_movis.AddTail(pos);
  73. }
  74. else
  75. {
  76. hr = Parse(id, pos + size);
  77. }
  78. }
  79. else
  80. {
  81. if(S_OK != Read(size))
  82. return E_FAIL;
  83. TRACE(_T("CAviFile::Parse(..): '%c%c%c%c'n"), 
  84. TCHAR((id>>0)&0xff), 
  85. TCHAR((id>>8)&0xff), 
  86. TCHAR((id>>16)&0xff),
  87. TCHAR((id>>24)&0xff));
  88. if(parentid == FCC('INFO') && size > 0)
  89. {
  90. switch(id)
  91. {
  92. case FCC('IARL'): // Archival Location. Indicates where the subject of the file is archived.
  93. case FCC('IART'): // Artist. Lists the artist of the original subject of the file; for example, 揗ichaelangelo.