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

多媒体编程

开发平台:

Visual C++

  1. #include "StdAfx.h"
  2. #include <mmreg.h>
  3. #include "DiracSplitterFile.h"
  4. #include <initguid.h>
  5. #include "........includemoreuuids.h"
  6. CDiracSplitterFile::CDiracSplitterFile(IAsyncReader* pAsyncReader, HRESULT& hr)
  7. : CBaseSplitterFile(pAsyncReader, hr)
  8. , m_rtDuration(0)
  9. {
  10. if(SUCCEEDED(hr)) hr = Init();
  11. m_pBuff.SetSize(1024, 1024);
  12. }
  13. HRESULT CDiracSplitterFile::Init()
  14. {
  15. HRESULT hr = E_FAIL;
  16. Seek(0);
  17. UINT64 hdr;
  18. if(FAILED(Read((BYTE*)&hdr, sizeof(hdr))) || hdr != 0x43415249442D574Bui64) // KW-DIRAC
  19. return E_FAIL;
  20. dirac_decoder_t* decoder = dirac_decoder_init(0);
  21. __int64 limit = min(GetLength(), 2048);
  22. while(GetPos() < limit)
  23. {
  24. BYTE b;
  25. if(!Next(b)) {ASSERT(0); break;}
  26. if(b == RAP_START_CODE)
  27. {
  28. __int64 pos = GetPos() - 5;
  29. if(!Next(b)) {ASSERT(0); break;}
  30. __int64 len = GetPos() - pos;
  31. Seek(pos);
  32. m_mt.majortype = MEDIATYPE_Video;
  33. m_mt.subtype = MEDIASUBTYPE_DiracVideo;
  34. m_mt.formattype = FORMAT_DiracVideoInfo;
  35. m_mt.SetSampleSize(1);
  36. DIRACINFOHEADER* dvih = (DIRACINFOHEADER*)m_mt.AllocFormatBuffer(FIELD_OFFSET(DIRACINFOHEADER, dwSequenceHeader) + len);
  37. memset(m_mt.Format(), 0, m_mt.FormatLength());
  38. dvih->cbSequenceHeader = len - 5;
  39. Read((BYTE*)&dvih->dwSequenceHeader[0], len);
  40. dirac_buffer(decoder, (BYTE*)&dvih->dwSequenceHeader[0], (BYTE*)&dvih->dwSequenceHeader[0] + len);
  41. if(dirac_parse(decoder) != STATE_SEQUENCE) {ASSERT(0); break;}
  42. if(decoder->seq_params.frame_rate.denominator)
  43. dvih->hdr.AvgTimePerFrame = 10000000i64 * decoder->seq_params.frame_rate.denominator / decoder->seq_params.frame_rate.numerator;
  44. dvih->hdr.bmiHeader.biSize = sizeof(dvih->hdr.bmiHeader);
  45. dvih->hdr.bmiHeader.biWidth = decoder->seq_params.width;
  46. dvih->hdr.bmiHeader.biHeight = decoder->seq_params.height;
  47. dvih->hdr.bmiHeader.biCompression = m_mt.subtype.Data1;
  48. dvih->hdr.dwInterlaceFlags = 0;
  49. if(decoder->seq_params.interlace) dvih->hdr.dwInterlaceFlags |= AMINTERLACE_IsInterlaced;
  50. if(decoder->seq_params.topfieldfirst) dvih->hdr.dwInterlaceFlags |= AMINTERLACE_Field1First;
  51. dvih->hdr.dwPictAspectRatioX = dvih->hdr.bmiHeader.biWidth;
  52. dvih->hdr.dwPictAspectRatioY = dvih->hdr.bmiHeader.biHeight;
  53. m_rtDuration = 0;// dvih->hdr.AvgTimePerFrame * decoder->seq_params.num_frames; // WTF
  54. hr = S_OK;
  55. break;
  56. }
  57. }
  58.     dirac_decoder_close(decoder);
  59. return hr;
  60. }
  61. UINT64 CDiracSplitterFile::UnsignedGolombDecode()
  62. {    
  63.     int M = 0;
  64. while(M < 64 && !BitRead(1))
  65. M++;
  66. UINT64 info = 0;
  67.     for(int i = 0; i < M; i++)
  68. info |= BitRead(1) << i;
  69. return (1ui64<<M)-1 + info;
  70. }
  71. bool CDiracSplitterFile::Next(BYTE& code, __int64 len)
  72. {
  73. BitByteAlign();
  74. UINT64 qw = -1;
  75. do
  76. {
  77. if(len-- == 0 || GetPos() >= GetLength()) return(false);
  78. qw = (qw << 8) | (BYTE)BitRead(8);
  79. }
  80. while((qw&0xffffffff00) != ((UINT64)START_CODE_PREFIX<<8));
  81. code = (BYTE)(qw & 0xff);
  82. return(true);
  83. }
  84. const BYTE* CDiracSplitterFile::NextBlock(BYTE& code, int& size, int& fnum)
  85. {
  86. BYTE* pBuff = m_pBuff.GetData();
  87. code = NOT_START_CODE;
  88. size = 0;
  89. // TODO: make sure we are at a start code right now
  90. while(GetPos() < GetLength())
  91. {
  92. if(GetPos() <= GetLength() - 5)
  93. {
  94. UINT64 qw = BitRead(40, true);
  95. if(size == 0)
  96. {
  97. if((qw & 0xffffffff00) == ((UINT64)START_CODE_PREFIX<<8) && (qw & 0xff) != NOT_START_CODE)
  98. code = (BYTE)(qw & 0xff);
  99. if(isFrameStartCode(code))
  100. {
  101. __int64 pos = GetPos();
  102. Seek(pos + 5);
  103. fnum = (int)UnsignedGolombDecode();
  104. Seek(pos);
  105. }
  106. }
  107. else
  108. {
  109. if((qw & 0xffffffff00) == ((UINT64)START_CODE_PREFIX<<8) && (qw & 0xff) != NOT_START_CODE)
  110. break;
  111. }
  112. }
  113. if(size >= m_pBuff.GetSize())
  114. {
  115. int newsize = max(1024, size*2);
  116. m_pBuff.SetSize(newsize, newsize);
  117. pBuff = m_pBuff.GetData();
  118. }
  119. pBuff[size++] = (BYTE)BitRead(8);
  120. }
  121. return pBuff;
  122. }