RawReader.cpp 3.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173
  1. #include "main.h"
  2. #include "RawReader.h"
  3. #include "FileTypes.h"
  4. #include <shlwapi.h>
  5. #define NS_E_FILE_IS_CORRUPTED _HRESULT_TYPEDEF_(0xC00D080DL)
  6. bool IsMyExtension(const wchar_t *filename)
  7. {
  8. const wchar_t *ext = PathFindExtension(filename);
  9. if (ext && *ext)
  10. {
  11. ext++;
  12. return fileTypes.GetAVType(ext) != -1;
  13. }
  14. return false;
  15. }
  16. int RawMediaReaderService::CreateRawMediaReader(const wchar_t *filename, ifc_raw_media_reader **out_reader)
  17. {
  18. if (IsMyExtension(filename))
  19. {
  20. IWMSyncReader *reader = 0;
  21. if (!SUCCEEDED(WMCreateSyncReader(NULL, 0, &reader)))
  22. {
  23. return NErr_FailedCreate;
  24. }
  25. if (FAILED(reader->Open(filename)))
  26. {
  27. reader->Release();
  28. reader = 0;
  29. return NErr_FileNotFound; // TODO: check HRESULT
  30. }
  31. RawMediaReader *raw_reader = new RawMediaReader();
  32. if (!raw_reader)
  33. {
  34. reader->Close();
  35. reader->Release();
  36. return NErr_OutOfMemory;
  37. }
  38. int ret = raw_reader->Initialize(reader);
  39. if (ret != NErr_Success)
  40. {
  41. delete raw_reader;
  42. return ret;
  43. }
  44. *out_reader = raw_reader;
  45. return NErr_Success;
  46. }
  47. else
  48. {
  49. return NErr_False;
  50. }
  51. }
  52. #define CBCLASS RawMediaReaderService
  53. START_DISPATCH;
  54. CB(CREATERAWMEDIAREADER, CreateRawMediaReader);
  55. END_DISPATCH;
  56. #undef CBCLASS
  57. RawMediaReader::RawMediaReader()
  58. {
  59. reader=0;
  60. stream_num=0;
  61. buffer_used=0;
  62. end_of_file=false;
  63. length=0;
  64. buffer=0;
  65. next_output=0;
  66. }
  67. RawMediaReader::~RawMediaReader()
  68. {
  69. if (reader)
  70. {
  71. reader->Close();
  72. reader->Release();
  73. }
  74. if (buffer)
  75. {
  76. buffer->Release();
  77. }
  78. }
  79. int RawMediaReader::Initialize(IWMSyncReader *reader)
  80. {
  81. this->reader=reader;
  82. return NErr_Success;
  83. }
  84. int RawMediaReader::Read(void *out_buffer, size_t buffer_size, size_t *bytes_read)
  85. {
  86. /* we don't care about these, but the API does not allows NULL */
  87. QWORD sample_time = 0, duration = 0;
  88. size_t bytesCopied = 0;
  89. uint8_t *dest = (uint8_t *)out_buffer;
  90. for (;;)
  91. {
  92. if (buffer)
  93. {
  94. BYTE *bufferBytes = 0;
  95. DWORD bufferTotal = 0;
  96. buffer->GetBufferAndLength(&bufferBytes, &bufferTotal);
  97. if (buffer_used < bufferTotal)
  98. {
  99. size_t toCopy = min(bufferTotal - buffer_used, buffer_size);
  100. memcpy(dest, bufferBytes + buffer_used, toCopy);
  101. buffer_used += toCopy;
  102. buffer_size -= toCopy;
  103. dest += toCopy;
  104. bytesCopied += toCopy;
  105. if (buffer_used == bufferTotal)
  106. {
  107. buffer_used = 0;
  108. buffer->Release();
  109. buffer = 0;
  110. }
  111. }
  112. if (buffer_size == 0)
  113. {
  114. *bytes_read = bytesCopied;
  115. return NErr_Success;
  116. }
  117. }
  118. if (stream_num == 0)
  119. {
  120. DWORD outputs = 0;
  121. HRESULT hr=reader->GetOutputCount(&outputs);
  122. if (FAILED(hr))
  123. return NErr_Error;
  124. if (next_output >= outputs)
  125. return NErr_EndOfFile;
  126. hr=reader->GetStreamNumberForOutput(next_output, &stream_num);
  127. if (FAILED(hr))
  128. return NErr_Error;
  129. hr=reader->SetReadStreamSamples(stream_num, TRUE);
  130. if (FAILED(hr))
  131. return NErr_Error;
  132. next_output++;
  133. }
  134. DWORD flags = 0;
  135. HRESULT r = reader->GetNextSample(stream_num, &buffer, &sample_time, &duration, &flags, 0, 0);
  136. if (r == NS_E_NO_MORE_SAMPLES || r == NS_E_FILE_IS_CORRUPTED)
  137. {
  138. stream_num=0;
  139. }
  140. }
  141. return NErr_Error;
  142. }
  143. size_t RawMediaReader::Release()
  144. {
  145. delete this;
  146. return 0;
  147. }
  148. #define CBCLASS RawMediaReader
  149. START_DISPATCH;
  150. CB(RELEASE, Release);
  151. CB(RAW_READ, Read);
  152. END_DISPATCH;
  153. #undef CBCLASS